ADR-022: assistant-ui + AG-UI as the Customer Product Shell
| Field | Value |
|---|---|
| Status | Proposed |
| Date | 2026-07-29 |
| Decision Drafters | WS-5 (qa-engineer + code-reviewer, tech-lead review gate) — drafted per frontend-stack-deep-research-2026.md §11's own recommendation |
| Decision Makers | HITL approval required before this ADR may be marked Accepted — not self-approved by WS-5, per this ADR's own mission charter |
| Supersedes-scope | Narrows ADR-003's scope, does not supersede it — see "Relationship to ADR-003" below |
| Scoring superseded by | CC-ADR-061 (in progress) — re-scored 2026-07-31 from our built position (22 files, 2,798 LOC of working code). The greenfield matrix below is retained for history; the narrowed analysis appears in CC-ADR-061. |
| Review trigger | CC-ADR-061 §C (in progress) — Trigger conditions for reversal (TR-1 through TR-5) |
Context
The pentagon portfolio (CloudOps · Runbooks, FinOps · FOCUS, Resume · Premium,
Platform · IDP, Command · Center) needs a customer-facing, white-label
product shell — distinct from the internal, sovereign ops console ADR-003
already settled (Open WebUI, BC1, 2026-03-11). ADR-003 explicitly scoped
itself to the internal pipeline-engine surface and flagged this exact gap in
its own alternatives table: "AG-UI + CopilotKit — CA: 80% — Best for
real-time agent progress panels, but no pipeline engine — When to
Reconsider: BC2+ sidecar alongside Open WebUI". frontend-stack-deep-research-2026.md
(5-agent-verified, 2026-07-28) is the BC2+ research this ADR formalizes, and
its own §11 flags a real, pre-existing drift this ADR is also chartered to
resolve: shared-chat-surface-adoption-pattern.md describes LibreChat
(the tool actually running internally today) while citing ADR-003
(Open WebUI) as its authority — two different products, one stale
citation.
This ADR was drafted by WS-5 (integration/E2E/review-gate work stream) after
building and verifying a real, working P0 walking skeleton on this stack
(WS-0 through WS-5, evidence in console/tmp/p0-ws0/ through
console/tmp/p0-ws5/) — the decision below reflects what was actually built
and tested, not a paper evaluation.
Decision
Build the customer-facing product shell on assistant-ui (MIT, headless
React) with the AG-UI protocol as the single wire contract, over a thin
Python/FastAPI gateway running the Claude Agent SDK (console/services/gateway,
this portfolio's now-real implementation of the pattern). Weighted score
87/100 in the parent research's 6-candidate matrix (assistant-ui+AG-UI 87
🥇, LibreChat 77 🥈, Chainlit 69 🥉, AWS GenU 62, Anthropic chat-sdk
quickstart 58, vercel/chatbot 56 — see frontend-stack-deep-research-2026.md
§4 for the full scoring matrix and §3 for weights) — the only candidate
that spans all three backend phases (local Docker → Anthropic Managed Agents
→ AWS Bedrock AgentCore) without a front-end rewrite, and the only one where
runbooks PyPI, Jupyter/papermill, and Vizro plug in as first-class Python
citizens.
LibreChat stays as the internal, sovereign ops console (config-not-fork, per the existing shared-chat-surface pattern) — this ADR does not touch that decision's substance, only its citation (see "Relationship to ADR-003").
§A head-to-head: assistant-ui vs CopilotKit (both AG-UI clients)
Note: This greenfield matrix below is retained for history. The decision has been re-examined from our current built position (22 files, 2,798 LOC of working code deployed) and refined — scoring and reuse-to-TTM analysis have moved to CC-ADR-061 (in progress).
Both are MIT clients of the same AG-UI wire, so this is a UI-layer decision
only — the FastAPI gateway, Claude-SDK bridge, MCP tool plane, and the
AgentCore path are identical and 100% preserved either way (frontend-stack-p0-prompt-pack-2026.md
§A, verified 2026-07-28):
| Criterion (weight) | assistant-ui + AG-UI | CopilotKit + AG-UI | Why the delta |
|---|---|---|---|
| Solo velocity (20) | 4 | 4 | Both scaffold fast; assistant-ui ships docs-as-MCP for talent-bench agents, CopilotKit's drop-in Sidebar/Chat is equally quick but less white-label out of the gate |
| Claude + portability (20) | 5 | 5 | Tie — CopilotKit is the AG-UI steward (1st-party client); assistant-ui maintains its own AG-UI runtime + fallback wires |
| Python/Jupyter/Vizro (20) | 5 | 4 | Same Python backend; assistant-ui's artifacts + thread management map 1:1 to rendering Plotly/papermill in a chat console — this P0 build's PapermillArtifactToolUI and CostChartToolUI are exactly that mapping, now real code, not a hypothesis |
| Enterprise day-1 (20) | 3 | 3 | Tie — both BYO auth/RBAC/tenancy |
| Business value (15) | 5 | 4 | Our products are chat-first consoles (Claude-clone + artifacts + approval cards); CopilotKit's copilot-in-app UX fits 2027 Platform·IDP embedded assistants better than 2026 revenue products |
| Voice (5) | 4 | 3 | assistant-ui ships Realtime/Dictation/SpeechSynthesis adapters; CopilotKit voice is DIY |
| Weighted /100 | 87 🥇 | 79 🥈 |
Decision, sharpened: assistant-ui is the product shell; CopilotKit is the contracted fallback client and the 2027+ embedded-copilot sidecar — exactly what ADR-003's own alternatives table foreshadowed at 80%. One gateway, one wire, two possible faces.
Consequences
Gains
- ~80% front-end reuse per new product launch — one white-label shell
serves CloudOps/FinOps/Resume/Platform/Command today; this P0 build already
demonstrates 3 of the 5 products (
/cloudops,/finops,/resume) sharing oneapps/webcodebase, one env-driven brand config (lib/env.ts), and one AG-UI wire. - Backend-portability is an env-var change, not a rewrite — the AG-UI
wire is identical from today's Docker-local gateway through Anthropic
Managed Agents to AWS Bedrock AgentCore (native AG-UI support since
2026-03-13, 14 regions including ap-southeast-2 Sydney). Verified in
this build: the gateway's
agui_claude_bridgeis a ~300-LOC owned fork (per WI-5's pre-positioned answer below), not a vendored dependency — the portability claim is backed by code we actually control. - Notebooks and dashboards become governed product surfaces — papermill
evidence artifacts and the Vizro CxO dashboard render inside the same
chat shell (
PapermillArtifactToolUI,VizroFrameToolUI), not as separate embedded apps a customer has to context-switch to. This P0 build is the first real proof of that claim, not the research report's promise of it — WS-5 found and fixed two integration seams where the actual wiring didn't yet match this promise (tool-name driftvizro_linkvsvizro_dashboard, andpapermill_run's result shape never actually including the HTML the frontend needs — seeservices/gateway/src/gateway/mcp_stubs.py's module docstring for the full writeup). Both are fixed and covered by a new regression test (services/gateway/tests/test_mcp_stubs.py) and a real, twice-green Playwright E2E (console/tmp/p0-ws5/). - Reversibility is a designed-in risk control, not an afterthought — per WI-1 below, a stalled assistant-ui project costs ~1-2 sprints of UI-layer rework, not a gateway/tool-plane rewrite, because both AG-UI clients speak the identical wire.
Losses / open risks
- Gaps to own, not buy: auth/RBAC/tenancy is BYO on both assistant-ui and CopilotKit — neither ships enterprise SSO out of the box (unlike ADR-003's Open WebUI, which has this natively for the internal surface).
- The Claude-Agent-SDK → AG-UI bridge is community-grade upstream
(
ag-ui-claude-sdk0.1.5,ag-ui-protocol/ag-ui#439open) — this portfolio forks and owns ~300 LOC of glue (packages/agui_claude_bridge, now real code with its own replay-contract test suite) rather than depending on that upstream package directly. This is a maintenance commitment, not a one-time cost. - AG-UI itself is pre-1.0 — event-shape churn is a real risk (WI-4 below); mitigated by pinning the wire version and running contract fixtures in CI, not by assuming stability.
- This P0 build surfaced that the "byte-compatible against live gateway"
contract test only exercises the ORIGINAL 20-event happy path (text +
finops_cost_summary+ gatedpapermill_run) at theagui_claude_bridgelayer — the newerevidence_table/vizro_dashboardtool calls this WS-5 pass added are covered by the frontend E2E fixture (apps/web/tests/fixtures/happy_path_finops.jsonl) but not yet by the frozenpackages/agui-contractfixture + its generator script. Flagged as a P1 debt item (see WS-5's PR-style review), not fixed here — the contract fixture is explicitly documented as "never hand-edited," and properly extending it means updatingscripts/generate_fixtures.py, out of scope for a "hunt seams, don't add features" pass.
Relationship to ADR-003 (supersedes-scope, not a supersession)
ADR-003 (Accepted, 2026-03-11) remains Accepted and unchanged in substance for its actual scope: Open WebUI as the internal, sovereign BC1 pipeline engine. This ADR does not reopen or supersede that decision.
What this ADR does formally record, per the parent research's own §11 finding: ADR-003's alternatives table already scored "AG-UI + CopilotKit" at 80% with the explicit note "BC2+ sidecar alongside Open WebUI" — this ADR is that BC2+ promotion, now built and running (this P0 skeleton), for the customer-facing surface specifically, which was never ADR-003's scope in the first place (ADR-003's context is explicitly "xOps BC1", the internal ops interface).
Housekeeping fix this ADR requests: shared-chat-surface-adoption-pattern.md
currently describes LibreChat while citing ADR-003 (Open WebUI) as
its authority — a real citation drift the parent research flagged (§11) and
this ADR formally resolves by recording, in one place: LibreChat is the
internal shared chat surface (config-not-fork of the BC1 pipeline-engine
pattern ADR-003 established), and assistant-ui + AG-UI (this ADR) is the
customer product shell. Two different products, two different documents'
worth of citation, not one shared reference.
Alternatives Considered
| Alternative | Weighted score | Verdict | When to reconsider |
|---|---|---|---|
| LibreChat (adopt platform) | 77/100 | Best enterprise-day-1 score (free OIDC/SAML/LDAP/RBAC) but ~781k LOC generic chat platform, not a white-label product shell — this is ADR-003's internal-surface answer, not this ADR's | If the customer product ever needs to become a generic multi-agent chat platform rather than a branded product — unlikely for this portfolio |
| CopilotKit + AG-UI | 79/100 | Real, viable alternative on the identical wire — see §A head-to-head above | If assistant-ui stalls (WI-1) or a 2027+ Platform·IDP embedded-copilot-in-existing-app need arrives (WI-3) — CopilotKit is the pre-positioned answer for both |
| Chainlit (Python framework) | 69/100 | Pure-Python, in-process Claude Agent SDK, but maintainer risk (original team stepped back 2025-05-01, Literal AI shut down 2025-10-31) | Demos only — not a 2026-2030 product foundation |
| AWS GenU (CDK platform) | 62/100 | Cleanest AgentCore-native chat front end surveyed, but Bedrock-only — zero Anthropic-direct path, cannot run the local-first phase at all | Pattern-mine its CDK constructs for the Phase 3 AgentCore migration; don't build the product on it now |
| Anthropic chat-sdk quickstart | 58/100 | Reference implementation for Managed Agents session-mapping, not a product foundation (~15 files, auth is an explicit stub) | Steal the session-ID-as-conversation-ID + SSE pattern for the Phase-2 Managed Agents adapter |
| vercel/chatbot (template fork) | 56/100 | Component/pattern donor only — zero releases/changelog, no Dockerfile, no tenant/RBAC schema | Copy in AI Elements components (~45, shadcn registry) as donors to the assistant-ui shell if/when useful |
What-if analysis (solo-founder 2026–2030, from frontend-stack-p0-prompt-pack-2026.md §A)
| # | What if… | Impact | Pre-positioned answer |
|---|---|---|---|
| WI-1 | assistant-ui stalls (YC bus factor, ~3 people) | UI layer only | Swap client to CopilotKit (MIT, $27M-funded steward). Gateway/tools/agents untouched; est. 1-2 sprints of UI rework — primitives + styled components already live in-repo (shadcn-style copy-in) |
| WI-2 | CopilotKit gates more behind Cloud pricing | None | We never adopt Copilot Cloud (or assistant-ui Cloud); threads live in our own Postgres via the gateway — this P0 build's PRODUCT_POSTGRES_URL already reflects that policy, not a future intent |
| WI-3 | 2027: Platform·IDP needs a copilot inside Vizro/Backstage pages | Additive | CopilotKit sidecar speaks to the same /agui/* endpoints — two clients, one wire |
| WI-4 | AG-UI pre-1.0 churn breaks events | Contained | Wire pinned + contract fixtures in CI (packages/agui-contract, .github/workflows/p0.yml); gateway is the only process that speaks the protocol; AWS AgentCore native support anchors the spec going forward |
| WI-5 | Claude Agent SDK upgrade breaks the bridge | Contained | We own the forked ~300-LOC bridge (packages/agui_claude_bridge) with its own replay-contract test suite (tests/test_replay_contract.py, passing); CopilotKit docs now list Claude Agent SDK — upstream support is materializing (watch ag-ui-protocol/ag-ui#439) |
| WI-6 | Resume needs a form-filling copilot at launch | None | assistant-ui's form-demo pattern covers it natively — this P0 build's /resume route + fill_profile_field/submit_profile tools are exactly that pattern, now real and E2E-tested (console/tmp/p0-ws5/), not a future need |
Evidence
This ADR is grounded in a real, working build, not a paper evaluation:
console/tmp/p0-ws0/throughconsole/tmp/p0-ws5/— DoD evidence bundles per work stream, including a realdocker compose upof all 5 core services reporting healthy, and a Playwright golden-demo E2E passing twice consecutively (console/tmp/p0-ws5/e2e-run-1/,e2e-run-2/, screenshots, video).services/gateway/tests/,services/runbooks-mcp/tests/,services/insight/tests/,packages/agui_claude_bridge/tests/,packages/agui-contract/tests/— 74 passing unit/contract tests across the Python workspace (verified this WS-5 pass, properly scoped viauv run --package <name> pytest ...).frontend-stack-deep-research-2026.md(parent research, 5-agent verified, 2026-07-28) andfrontend-stack-p0-prompt-pack-2026.md§A (3 fresh primary-source verifications, same date) — full citation lists in each document's own Sources section.
Status note
This ADR is Proposed, not Accepted. Per this work stream's explicit charter ("HITL approves the ADR — do not mark Accepted"), WS-5 drafted this document from the research and the real build it also produced, but the Decision Makers row above is intentionally left for the HITL to complete upon review. Do not merge this ADR as Accepted without that sign-off.