Skip to main content
Urbicon UI

A2UIViewexperimental

Renders a trusted-catalog A2UI (Agent-to-UI, v0.9.1 basic subset) payload into live, interactive Urbicon components — whitelist-only and fail-loud.

Scenario
Loading...
Loading syntax highlighting...

01 How it works

A2UI (Agent-to-UI) lets an agent describe an interface as data, not executable code. The agent never ships components or scripts — it emits JSONL envelopes that reference a trusted catalog your app already ships. A2UIView is the renderer for the Urbicon subset of A2UI v0.9.1 basic: it maps the twelve catalog components onto real Urbicon primitives and renders them live and interactive.

The enforcement thesis

An agent is untrusted. If it could emit arbitrary markup or handlers, the surface would be an injection vector. A2UIView removes that class of risk by construction: the payload is a reference into a catalog you control. A component name the registry does not know is a fault chip, not a mystery element; a prop the registry does not declare never reaches a Svelte component; a { call } function binding resolves to nothing. There is no {@html}, no dynamic import, no restProps spread from the payload anywhere in the path.

Incremental & two-way

The payload is the accumulated envelope array — stream by extending it immutably ([...prev, envelope]). A2UIView applies only the newly appended envelopes, so local input edits survive a mid-stream update. Inputs write straight into the surface data model; bound text updates live; the model syncs to the agent only on an action.

Policy-gated media

Image sources and Text markdown links pass the same strict-by-default urlPolicy as StreamingMarkdown. Every external image is blocked unless its prefix is allowlisted; a blocked image renders an alt chip instead.

02 Examples

Golden-file replay — progressive rendering

The agent's envelopes arrive one JSONL line at a time; the consumer only extends the payload array. While streaming, a reference to a not-yet-defined child renders a skeleton placeholder — components fill in as their envelopes land, and the Button dispatches a spec-exact action event when clicked.
Loading...
Loading syntax highlighting...

A broken payload becomes a fault chip

Video is not in the basic subset. Instead of rendering something the catalog never sanctioned, A2UIView drops a visible fault chip in its place and reports the fault through onValidationError as a spec-compatible issue the consumer can relay to the agent.
Loading...
Loading syntax highlighting...

03 Integration

Wire it in via partRenderers.a2ui

A2UIView is deliberately not a default ChatMessage part renderer — keeping it opt-in keeps it out of the base conversation bundle. Register it per surface as the a2ui renderer; ChatMessageList forwards partRenderers to every ChatMessage. Couple the part's streaming flag to the owning message's status so dangling references degrade to placeholders while the reply is in flight and become faults once it settles.

ChatMessage wiring

Loading...
Loading syntax highlighting...

Generate the agent prompt

Never hand-roll the catalog description. a2uiSystemPrompt() renders the envelope rules, the twelve-component subset (props, required flags, enums), the binding forms ({ path } only — function calls are explicitly forbidden), the root rule, child-vs-children, the template form and the action rules, straight from the registry that validates the payload. It omits the transport — how envelopes reach the client is app-specific, so append that yourself.

System prompt

Loading...
Loading syntax highlighting...

04 Accessibility

Real controls, real labels

Each catalog component maps onto a real Urbicon primitive — TextField to Input/Textarea, CheckBox to Checkbox, ChoicePicker to RadioGroup, Slider to Slider — so labels, roles and keyboard behaviour come from the library, not from ad-hoc markup. A component's accessibility.label becomes an aria-label.

Streaming placeholders

While streaming, a not-yet-defined reference renders a Skeleton with an sr-only label (pendingLabel), so assistive tech announces a loading state rather than an empty gap.

Faults are text

A rejected component renders a fault chip with a readable label (unsupportedLabel) alongside its danger icon — the reason is text, not colour alone. Envelope-level faults render in a danger Alert with its errorTitle.

05 API Reference

14 props
14 props 1 required

No matching properties

No matching properties

06 Installation

Import

Loading...
Loading syntax highlighting...