[FEAT]: unified chat and ticket management ui - #6
[FEAT]: unified chat and ticket management ui#6Spencer Schoenberg (spencrr) wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
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-bot→helpdesk-agentacross workspace config, tests, docs, and manifests. - Add
helpdesk-uibackend (FastAPI) with SSE-basedPOST /api/chat/stream, ticket CRUD routes, and health/tools metadata routes. - Add
helpdesk-uifrontend (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
modelfromdetect_provider()is never passed intoOpenAIChatClient, so the client may fall back to framework/env defaults and ignore the union’s single-source-of-truth config. Consider threadingcfg.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-uiimmediately afteruv sync, but the server expects a built frontend athelpdesk-agent/helpdesk-ui/frontend/distand will fail to start if it’s missing. Please add thenpm ci && npm run buildstep here (or clarify an alternative like settingHELPDESK_UI_STATIC_DIR/ running Vite dev).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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) |
| @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) |
- 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).
| @@ -1,4 +1,4 @@ | |||
| # HelpdeskBot: RAMPART XPIA Showcase | |||
| # HelpdeskAgent: RAMPART XPIA Showcase | |||
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Volkan has this for our PyRIT XPIA PR, I wonder if it's worth checking out https://github.com/KutalVolkan/ai_recruiter
There was a problem hiding this comment.
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😁
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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:GET/api/ticketsmtime_ns).GET/api/tickets/sampleGET/api/tickets/{id}POST/api/ticketsT-####.DELETE/api/tickets/{id}POST/api/chat/streamGET/api/healthGET/api/tools[{name, description, parameters}].The chat route is stateless per turn. The browser sends the full conversation; the server reconstructs an
AgentSession, seeds it intoInMemoryHistoryProvider'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-> optionalerror.Frontend (helpdesk-agent/helpdesk-ui/frontend/) — React 19 + Vite 8 + Tailwind v4 + TypeScript strict.
pagehideabort.T-1003).Conversations live in the browser's
sessionStorage(per-tab, survives refresh). State store usesuseSyncExternalStoreso 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_clientis amatchover the union — no scattered env reads.Verification
Samples
Weak
Hardened
Breaking changes
Checklist
pre-commit run --all-filespasses