Skip to content

[FEAT]: unified chat and ticket management ui - #6

Closed
Spencer Schoenberg (spencrr) wants to merge 4 commits into
microsoft:mainfrom
spencrr:dev/spencrr/ticket-webapp
Closed

[FEAT]: unified chat and ticket management ui#6
Spencer Schoenberg (spencrr) wants to merge 4 commits into
microsoft:mainfrom
spencrr:dev/spencrr/ticket-webapp

Conversation

@spencrr

@spencrr Spencer Schoenberg (spencrr) commented May 9, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a small FastAPI + React app that lets a viewer chat with the helpdesk agent in their browser, file tickets through a form, and watch the agent's tool calls render inline under each reply — the visual surface a customer would ship for an internal helpdesk console. Closes the gap left by the existing pytest-only demo flow.

What's new

Backend (helpdesk-agent/helpdesk-ui/helpdesk_ui/) — a sibling sub-package of helpdesk-agent, registered as a uv workspace member. Exposes:

Method Path Purpose
GET /api/tickets List inbox (newest first by mtime_ns).
GET /api/tickets/sample Seeded sample ticket (T-1003); 404 if absent.
GET /api/tickets/{id} Full envelope as the agent ingests it.
POST /api/tickets File a new ticket; allocates next T-####.
DELETE /api/tickets/{id} Remove a ticket.
POST /api/chat/stream One agent turn, streamed as Server-Sent Events.
GET /api/health Provider readout (model, kind) + package versions.
GET /api/tools Manifest tools [{name, description, parameters}].

The chat route is stateless per turn. The browser sends the full conversation; the server reconstructs an AgentSession, seeds it into InMemoryHistoryProvider's source key, and runs one turn against a fresh agent. SSE event vocabulary: delta -> tool_call -> tool_result (parsed args + result land atomically) -> final -> optional error.

Frontend (helpdesk-agent/helpdesk-ui/frontend/) — React 19 + Vite 8 + Tailwind v4 + TypeScript strict.

  • 3-pane resizable layout: conversations sidebar / chat pane / ticket inbox.
  • Header bar with wordmark, provider pill (model name when configured, "no provider" when not), and a light/dark theme toggle (default dark; persists per tab).
  • Streaming chat with blinking cursor, inline tool-call cards (shimmer placeholder while pending, atomic args+result on resolve), Stop button while streaming, pagehide abort.
  • Retry on the most recent error: rolls history back to the prior user message and resends.
  • Per-bubble model badge so older turns keep their original provider after a switch.
  • Markdown rendering in both user and assistant bubbles (sanitised by DOMPurify, allowlist-locked tags).
  • Empty-state with three pre-built prompts that name a ticket id; the inbox automatically badges those tickets as "discussed in chat" after submission.
  • Manual ticket form with "Load sample ticket" pre-fill (T-1003).

Conversations live in the browser's sessionStorage (per-tab, survives refresh). State store uses useSyncExternalStore so streaming token deltas don't trigger a full sessionStorage round-trip on every refresh.

Provider config lives in a typed discriminated union (helpdesk_agent/providers.py): OpenAIConfig | AzureKeyConfig | AzureEntraConfig. Single source of truth used by the chat client factory and /api/health. The agent's _build_chat_client is a match over the union — no scattered env reads.

Verification

uv sync
uv run ruff check
uv run ty check
uv run pytest
uv run pytest helpdesk-agent/helpdesk-ui/tests
( cd helpdesk-agent/helpdesk-ui/frontend && npm ci && npm run check && npm run build )
uv run helpdesk-ui

Samples

Weak

Weak

Hardened

Hardened

Breaking changes

Checklist

  • pre-commit run --all-files passes
  • Tests added or updated for changes
  • Documentation updated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR renames the existing helpdesk demo package to helpdesk-agent and adds a new sibling workspace package, helpdesk-ui, which provides a FastAPI backend and a React/Vite frontend for interactive chat + ticket CRUD with inline tool-call rendering.

Changes:

  • Rename helpdesk-bothelpdesk-agent across workspace config, tests, docs, and manifests.
  • Add helpdesk-ui backend (FastAPI) with SSE-based POST /api/chat/stream, ticket CRUD routes, and health/tools metadata routes.
  • Add helpdesk-ui frontend (React + Vite + Tailwind) implementing the 3-pane UI, streaming chat rendering, and sessionStorage-backed conversations.

Reviewed changes

Copilot reviewed 78 out of 86 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
uv.lock Updates uv workspace members and adds editable helpdesk-ui package dependencies/extras.
pyproject.toml Updates workspace members, ty paths, and Ruff per-file ignores for the new UI package.
README.md Updates root README demo link from helpdesk-bot to helpdesk-agent.
tests/helpdesk/init.py Renames smoke-test package description to helpdesk_agent.
tests/helpdesk/_helpers.py Renames demo dir constant and improves fake response typing.
tests/helpdesk/test_adapter.py Updates imports to helpdesk_agent.
tests/helpdesk/test_imports.py Updates public API import test for new package name/manifest name.
tests/helpdesk/test_patch.py Updates patch-application smoke test to the new directory/module names.
tests/helpdesk/test_security.py Updates security helper import path.
tests/helpdesk/test_storage.py Updates ticket surface/storage import path.
helpdesk-bot/helpdesk_bot/init.py Removes old package public re-exports (package rename).
helpdesk-bot/.gitignore Removes old demo-specific ignore file (moved to new layout).
helpdesk-agent/pyproject.toml Renames project to helpdesk-agent and adds [ui] extra.
helpdesk-agent/README.md Updates demo README for new name and references the new UI.
helpdesk-agent/mitigation.patch Updates patch metadata and file paths to helpdesk_agent.
helpdesk-agent/tests/conftest.py Updates demo test fixtures imports to helpdesk_agent.
helpdesk-agent/tests/test_xpia.py Updates XPIA tests to import from helpdesk_agent.
helpdesk-agent/helpdesk_agent/init.py Adds new helpdesk_agent public re-export surface.
helpdesk-agent/helpdesk_agent/adapter.py Updates adapter to helpdesk_agent and shares tool-arg parsing helper.
helpdesk-agent/helpdesk_agent/agent.py Renames agent, introduces provider union-based config, and adds history provider for replay.
helpdesk-agent/helpdesk_agent/manifest.py Updates manifest name and docstrings for HelpdeskAgent.
helpdesk-agent/helpdesk_agent/providers.py Adds discriminated-union provider detection from env vars.
helpdesk-agent/helpdesk_agent/security.py Adds shared security policy helpers for tests and tool-layer defense.
helpdesk-agent/helpdesk_agent/surface.py Updates defaults/docs for renamed demo and ticket dir resolution.
helpdesk-agent/helpdesk_agent/tool_calls.py Adds shared parse_arguments helper for framework tool-call arguments.
helpdesk-agent/data/tickets/T-1001.json Adds benign seed ticket.
helpdesk-agent/data/tickets/T-1002.json Adds benign seed ticket.
helpdesk-agent/data/tickets/T-1003.json Adds seeded sample ticket for UI + XPIA-like content.
helpdesk-agent/data/tickets/.gitignore Ignores ticket JSON files except the committed seeds.
helpdesk-agent/data/tickets/.gitkeep Updates directory keep-file comment.
helpdesk-agent/.gitignore Adds demo-local ignores (.env, .report/).
helpdesk-agent/.env.example Adds provider configuration examples for OpenAI/Azure OpenAI.
helpdesk-agent/helpdesk-ui/pyproject.toml Adds helpdesk-ui Python package and helpdesk-ui console script.
helpdesk-agent/helpdesk-ui/README.md Documents UI quickstart, API, security posture, and dev workflow.
helpdesk-agent/helpdesk-ui/helpdesk_ui/init.py Adds package docs and import-light design note.
helpdesk-agent/helpdesk-ui/helpdesk_ui/app.py Adds FastAPI app factory, security headers, body-size guard, and static serving.
helpdesk-agent/helpdesk-ui/helpdesk_ui/agent_runner.py Implements single-turn agent runner + SSE event serialization and tool-call extraction.
helpdesk-agent/helpdesk-ui/helpdesk_ui/schemas.py Adds Pydantic schemas for tickets and chat request/turn representation.
helpdesk-agent/helpdesk-ui/helpdesk_ui/routes/init.py Registers /api router and includes tickets/chat/meta routes.
helpdesk-agent/helpdesk-ui/helpdesk_ui/routes/chat.py Adds POST /api/chat/stream SSE endpoint.
helpdesk-agent/helpdesk-ui/helpdesk_ui/routes/meta.py Adds /api/health and /api/tools endpoints.
helpdesk-agent/helpdesk-ui/helpdesk_ui/routes/tickets.py Adds ticket list/get/create/delete + sample ticket endpoint.
helpdesk-agent/helpdesk-ui/tests/init.py Adds test package marker file.
helpdesk-agent/helpdesk-ui/tests/conftest.py Adds fixtures: temp ticket dir, seeded tickets, fake agent builder, SSE parsing.
helpdesk-agent/helpdesk-ui/tests/unit/init.py Adds unit test package marker file.
helpdesk-agent/helpdesk-ui/tests/unit/test_agent_runner.py Tests runner event stream, tool-call dedup, replay behavior, and union narrowing.
helpdesk-agent/helpdesk-ui/tests/unit/test_routes_chat.py Tests streaming chat endpoint validation + event ordering + size cap.
helpdesk-agent/helpdesk-ui/tests/unit/test_routes_meta.py Tests health/tools endpoints including env-driven provider detection.
helpdesk-agent/helpdesk-ui/tests/unit/test_routes_tickets.py Tests ticket CRUD routes, sorting, sample ticket, and dropped legacy endpoints.
helpdesk-agent/helpdesk-ui/tests/unit/test_schemas.py Tests schema aliasing and round-trips.
helpdesk-agent/helpdesk-ui/frontend/package.json Adds React/Vite/Tailwind/Biome/TypeScript frontend config.
helpdesk-agent/helpdesk-ui/frontend/biome.json Adds Biome lint/format configuration.
helpdesk-agent/helpdesk-ui/frontend/vite.config.ts Adds Vite config and /api proxy to backend.
helpdesk-agent/helpdesk-ui/frontend/tsconfig.json Adds strict TypeScript config.
helpdesk-agent/helpdesk-ui/frontend/tsconfig.tsbuildinfo Adds TS build cache artifact (should not be committed).
helpdesk-agent/helpdesk-ui/frontend/.gitignore Adds frontend-specific gitignore (currently minimal).
helpdesk-agent/helpdesk-ui/frontend/index.html Adds Vite entry HTML for the UI.
helpdesk-agent/helpdesk-ui/frontend/src/vite-env.d.ts Adds Vite type references.
helpdesk-agent/helpdesk-ui/frontend/src/styles.css Adds Tailwind v4 token-based theming + markdown/tool-call styling.
helpdesk-agent/helpdesk-ui/frontend/src/main.tsx Boots React app with an error boundary and root lookup.
helpdesk-agent/helpdesk-ui/frontend/src/App.tsx Implements the 3-pane resizable layout.
helpdesk-agent/helpdesk-ui/frontend/src/api.ts Implements typed fetch calls and SSE stream consumer for chat.
helpdesk-agent/helpdesk-ui/frontend/src/lib/conversations.ts Implements sessionStorage-backed conversation store with useSyncExternalStore.
helpdesk-agent/helpdesk-ui/frontend/src/lib/markdown.ts Adds marked + DOMPurify markdown rendering with allowlist.
helpdesk-agent/helpdesk-ui/frontend/src/lib/sse.ts Adds AbortSignal-aware SSE frame consumer.
helpdesk-agent/helpdesk-ui/frontend/src/lib/time.ts Adds relative-time helper for ticket timestamps.
helpdesk-agent/helpdesk-ui/frontend/src/lib/tools.ts Adds tool-manifest cache layer.
helpdesk-agent/helpdesk-ui/frontend/src/lib/useTheme.ts Adds sessionStorage-backed dark/light theme toggling.
helpdesk-agent/helpdesk-ui/frontend/src/components/* Adds UI components for header, chat, messages, ticket inbox/detail/form, etc.
.gitignore Extends root ignore set to include Node artifacts.
.github/workflows/ci.yml Adds a frontend CI job (npm ci + lint + typecheck + build).
.github/dependabot.yml Moves uv updates to helpdesk-agent and adds npm dependabot config for the frontend.
Files not reviewed (1)
  • helpdesk-agent/helpdesk-ui/frontend/package-lock.json: Language not supported
Comments suppressed due to low confidence (2)

helpdesk-agent/helpdesk_agent/agent.py:132

  • In the Azure provider branches, the selected model from detect_provider() is never passed into OpenAIChatClient, so the client may fall back to framework/env defaults and ignore the union’s single-source-of-truth config. Consider threading cfg.model (and/or enforcing it non-optional) into both Azure branches to keep provider selection deterministic and consistent with the config abstraction.
    helpdesk-agent/README.md:75
  • The setup snippet suggests uv run helpdesk-ui immediately after uv sync, but the server expects a built frontend at helpdesk-agent/helpdesk-ui/frontend/dist and will fail to start if it’s missing. Please add the npm ci && npm run build step here (or clarify an alternative like setting HELPDESK_UI_STATIC_DIR / running Vite dev).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread helpdesk-agent/helpdesk-ui/helpdesk_ui/app.py
Comment on lines +91 to +99
static_dir = _resolve_static_dir()
index_path = static_dir / "index.html"
assets_dir = static_dir / "assets"

app.mount("/assets", StaticFiles(directory=assets_dir), name="assets")

@app.get("/", include_in_schema=False)
async def _index() -> FileResponse:
return FileResponse(index_path)
Comment on lines +69 to +77
@app.middleware("http")
async def _max_body(
request: Request,
call_next: Callable[[Request], Awaitable[Response]],
) -> Response:
cl = request.headers.get("content-length")
if cl is not None and cl.isdigit() and int(cl) > _MAX_BODY_BYTES:
return Response(status_code=413, content="Payload too large")
return await call_next(request)
Comment thread helpdesk-agent/helpdesk-ui/frontend/index.html Outdated
Comment thread helpdesk-agent/helpdesk-ui/frontend/src/components/MessageList.tsx
Comment thread helpdesk-agent/helpdesk-ui/frontend/tsconfig.tsbuildinfo Outdated
- app.py: drop stale agent_factory docstring; create_app() takes no
  args, agent injection is via FastAPI dependency overrides.
- agent.py: thread cfg.model into both Azure branches so the provider
  union is the single source of truth (not framework env fallback).
- index.html: drop hardcoded bg-slate-950/text-slate-100 on <body> so
  data-theme="light" can actually take effect.
- MessageList.tsx: re-run auto-scroll on [messages, streaming] so the
  viewport stays pinned to the bottom during a streaming reply.
- README: document the npm ci && npm run build step before
  uv run helpdesk-ui.
- Untrack helpdesk-agent/helpdesk-ui/frontend/tsconfig.tsbuildinfo
  (already covered by *.tsbuildinfo in root .gitignore).
Comment thread helpdesk-agent/README.md
@@ -1,4 +1,4 @@
# HelpdeskBot: RAMPART XPIA Showcase
# HelpdeskAgent: RAMPART XPIA Showcase

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, this is a cool app and I appreciate how it demonstrates RAMPART. I think it's really good at demoing RAMPART.

But I think the goal for this is to make it as simple as possible. E.g. almost trivial to setup and run. We have opecnclaw for a realistic demo, but I think this the number one goal should be to be simple so that people can run RAMPART in the easiest possible way and easily understand what it's doing.

Are there ways we can simplify this? Make it easier to deploy, easier to understand how it works, etc?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Volkan has this for our PyRIT XPIA PR, I wonder if it's worth checking out https://github.com/KutalVolkan/ai_recruiter

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - my philosophy was to create a UI on top of the super-simple example for demo purposes so that we could show a quick flow-through of the underlying example app code. I can take a look at paring down a few things, but this should be easy to run 😸

In other words, this app optimizes for the demo recording more than the terminal walkthrough - which remains as a separate/standalone and straightforward interactive showcase of RAMPART😁

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can steer people toward inspecting the agent app code over the ui code in a few ways - this can even be a separate repo if we are so inclined. What do you think about leaving this for now and just adding some language in the README to guide demo participants toward the terminal example?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Rich on this as I mentioned it to you earlier as well .

I think we should keep the scope pretty tight for the demo. The main story we want to tell is create a poisoned ticket -> point the agent at it -> show RAMPART tests failing -> harden the agent -> show them passing again. We really just need a lightweight dev console for the agent and ticket system for this, rather than a full product UI.

The current version feels like it's solving a much bigger problem than we have right now. Having things like the full frontend build stack, streaming, persisted conversations, retries, theming, model badges, and health/tool endpoints is necessary for a real app, but I don't think they materially help with the demo. They just add a lot of surface area that we have to explain and maintain, which pulls attention away from the core point.

On top of that, there's the maintenance overhead to consider. Taking on a full SPA stack means inheriting npm build flows, lockfile churn, and potential CVE noise in a repo that's mostly Python. I just don't think that trade-off is worth it for a demo harness.

If you take a look at my PR for agent_ui/ (#4) , I’ve actually done this in just 3 files (vanilla HTML/JS and a tiny FastAPI backend). It doesn't have all the bells and whistles of your full app but it gives us a consistent interface, and all the demo features we need are fully doable with it.

I also don't think we should move this app to a different repo, I don't want users to hop from one repo to another to get something working. The examples should be self-contained.

Comment thread helpdesk-agent/README.md
Comment thread helpdesk-agent/helpdesk-ui/README.md
@spencrr Spencer Schoenberg (spencrr) closed this by deleting the head repository May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants