Skip to main content

ADR-022: assistant-ui + AG-UI as the Customer Product Shell

FieldValue
StatusProposed
Date2026-07-29
Decision DraftersWS-5 (qa-engineer + code-reviewer, tech-lead review gate) — drafted per frontend-stack-deep-research-2026.md §11's own recommendation
Decision MakersHITL approval required before this ADR may be marked Accepted — not self-approved by WS-5, per this ADR's own mission charter
Supersedes-scopeNarrows ADR-003's scope, does not supersede it — see "Relationship to ADR-003" below
Scoring superseded byCC-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 triggerCC-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-UICopilotKit + AG-UIWhy the delta
Solo velocity (20)44Both 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)55Tie — CopilotKit is the AG-UI steward (1st-party client); assistant-ui maintains its own AG-UI runtime + fallback wires
Python/Jupyter/Vizro (20)54Same 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)33Tie — both BYO auth/RBAC/tenancy
Business value (15)54Our 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)43assistant-ui ships Realtime/Dictation/SpeechSynthesis adapters; CopilotKit voice is DIY
Weighted /10087 🥇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 one apps/web codebase, 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_bridge is 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 drift vizro_link vs vizro_dashboard, and papermill_run's result shape never actually including the HTML the frontend needs — see services/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-sdk 0.1.5, ag-ui-protocol/ag-ui#439 open) — 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 + gated papermill_run) at the agui_claude_bridge layer — the newer evidence_table/vizro_dashboard tool 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 frozen packages/agui-contract fixture + 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 updating scripts/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

AlternativeWeighted scoreVerdictWhen to reconsider
LibreChat (adopt platform)77/100Best 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'sIf the customer product ever needs to become a generic multi-agent chat platform rather than a branded product — unlikely for this portfolio
CopilotKit + AG-UI79/100Real, viable alternative on the identical wire — see §A head-to-head aboveIf 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/100Pure-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/100Cleanest AgentCore-native chat front end surveyed, but Bedrock-only — zero Anthropic-direct path, cannot run the local-first phase at allPattern-mine its CDK constructs for the Phase 3 AgentCore migration; don't build the product on it now
Anthropic chat-sdk quickstart58/100Reference 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/100Component/pattern donor only — zero releases/changelog, no Dockerfile, no tenant/RBAC schemaCopy 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…ImpactPre-positioned answer
WI-1assistant-ui stalls (YC bus factor, ~3 people)UI layer onlySwap 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-2CopilotKit gates more behind Cloud pricingNoneWe 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-32027: Platform·IDP needs a copilot inside Vizro/Backstage pagesAdditiveCopilotKit sidecar speaks to the same /agui/* endpoints — two clients, one wire
WI-4AG-UI pre-1.0 churn breaks eventsContainedWire 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-5Claude Agent SDK upgrade breaks the bridgeContainedWe 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-6Resume needs a form-filling copilot at launchNoneassistant-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/ through console/tmp/p0-ws5/ — DoD evidence bundles per work stream, including a real docker compose up of 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 via uv run --package <name> pytest ...).
  • frontend-stack-deep-research-2026.md (parent research, 5-agent verified, 2026-07-28) and frontend-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.