Skip to main content
Urbicon UI

Agent-generated UI (A2UI)

A chat where the agent answers with live UI instead of prose: A2uiStreamSplitter turns the token stream into a2ui parts, A2UIView renders them against a trusted catalog, and A2uiSurfaceRouter lets a later turn patch a form the agent sent earlier — the multi-step flow (pick a date → load slots → confirm) without rebuilding the surface.

A2UIView Chat ChatMessageList PromptInput

Live Preview

Real envelopes, no network. Pressing Show available times appends the patch an agent would send after calling its tool: the slots go into the data model and one re-sent container reveals a chooser bound to them. Nothing is rebuilt — a value you already picked survives the patch.

No action dispatched yet

Features

  • a2uiSystemPrompt() + a2uiFencedTransportSection(): catalog contract and wire format, generated from the same source the validator checks against
  • A2uiStreamSplitter: token stream → ordered text / a2ui parts, chunk-decomposition invariant
  • A2UIView with the Urbicon catalog and an optional data schema — fail-loud, whitelist-only rendering
  • A2uiSurfaceRouter + routeMessageParts(): envelopes from a later turn reach the message that owns the surface
  • Streaming grace for patched messages (result.targets) so half-arrived patches show placeholders, not error chips
  • sendDataModel: true — every action carries the full form state, read at click time
  • Choices bind to the data model (value: { path }); actions are reserved for fetch and commit
  • Fetched options live in the data model and bind via options: { path }
  • Validation issues relayed to the agent behind a [ui-error] prefix so it can repair its own surface

Server — assembling the system prompt

Three shipped sections plus your domain rules. The transport section is the prompt half of A2uiStreamSplitter, so the format the agent is told to write is by construction the format the client parses.

src/routes/api/chat/+server.ts

Loading...
Loading syntax highlighting...

Client — splitter, router, view

The three pieces in order: the splitter turns tokens into parts, the router delivers envelopes to the message that owns their surface, and A2UIView renders one payload. See the A2UI guide for why a patched message needs streaming grace and why a plain choice must not be an action.

src/routes/chat/+page.svelte

Loading...
Loading syntax highlighting...