Canvas RFC 001 a2ui
RFC001 — Canvas: A2UI (Agentto-UI) workspace
*uthor:*Koder Engineering *ate:*20260429 *tatus:*Accepted *odule:*servicesaicanvas (engine) + productshorizontalkanvas (flagship app) *rigin:*koderstack ticket #030 (RFC016), OpenClaw analysis 20260429 *enamed from:*RFC-016 (namespaced convention)
1. Summary
A protocol (A2UI) and runtime (canvas) that lets an agent describe ad-hoc UIs at runtime which the user's Koder client renders natively. Pair services/ai/canvas (engine) with products/horizontal/kanvas (flagship Flutter app) per the engine+product split established by project memory engine_product_pattern.
2. Problem
LLM agents can produce text and call tools, but they cannot create *hrowaway, task-shaped UIs*— a calculator at the right time, a form for an incident report, a diagram with editable nodes. OpenClaw's "Canvas" feature shows the value: a workspace where the agent paints purpose-built widgets that the user manipulates and the result feeds back into the conversation.
The Koder Stack today has Kode (chat agent) but no rendering surface for agent-emitted UIs.
3. Goals
- A serializable widget protocol (A2UI) that any Koder client can render.
- One engine that adapts the protocol to each rendering target (Flutter
initially; web and TUI later).
- A flagship app (Kanvas) that exposes Canvas as a first-class workspace,
alongside Kode for chat and Kortex for observability.
4. Non-Goals
- Replacing chat. Canvas augments chat — when the agent decides "a
widget is better here," it emits A2UI; when text suffices, it stays in text.
- A general-purpose UI framework. A2UI is a constrained subset designed
for safe agent emission, not for hand-coded apps.
5. A2UI Protocol
JSON over the existing chat transport (Koder Kode messages). Each message can carry one A2UI block:
{
"a2ui": {
"version": 1,
"view_id": "calc-2026-04-29-abc",
"root": {
"type": "Column",
"children": [
{"type": "Text", "value": "Quick calc"},
{"type": "TextInput", "id": "expr", "placeholder": "1+2*3"},
{"type": "Button", "label": "Compute", "action": "submit"}
]
},
"actions": {
"submit": {"target": "agent", "include_state": ["expr"]}
}
}
}Allowed widget types in v1 (Flutter parity):
Column, Row, Stack, Padding, SizedBox, Text, Markdown, Image, Icon,
TextInput, NumberInput, Slider, Checkbox, RadioGroup, Dropdown,
Button, IconButton, Card, Divider, ProgressBar, Chart{line,bar,pie},
Table, ListTile.
No code execution in widgets. Actions only target agent (round-trip via chat) or client:open_url (URL whitelisted at host level).
6. Engine Architecture
services/ai/canvas/ exposes:
- *TTP API*(
POST /api/v1/render) — agents send A2UI JSON,receive a stable
view_id. Internal use only — bot-side helper. - *alidator*— schema-checks JSON against the v1 widget grammar
before clients render.
- *tate store*— kdb-next, keyed by
view_id+user_id, holdscurrent widget state across messages.
- *dapter SDKs*—
engines/sdk/canvas-flutter/(Dart) rendersA2UI in any Koder Flutter app (Kode, Kanvas, Pass, …).
7. Kanvas — Flagship Product
products/horizontal/kanvas/ (Flutter, multiplatform per RFC006). Layout:
- Left rail: list of past Canvas sessions (per
view_id) - Main area: live A2UI render
- Right rail: chat with the agent that owns the canvas
Same agent backend as Kode, but Kanvas optimises for "agent-painted UI" flows (data dashboards, ad-hoc forms, diagrams).
8. Scope of Change
services/ai/canvas/— new sector with engine, HTTP API, validator,state store
engines/sdk/canvas-flutter/— Dart renderer SDKproducts/horizontal/kanvas/— Flutter app + landingservices/ai/kodeupdated to recognise A2UI blocks in agentresponses and call the Flutter renderer when present
infra/jet— domainkanvas.koder.dev(landing) andcanvas.koder.dev(engine API)
9. Execution Plan
| Phase | Deliverable |
|---|---|
| F1 | This RFC + scaffold (engine + Flutter SDK + Kanvas app) |
| F2 | A2UI v1 schema validator |
| F3 | enginessdkcanvas-flutter renders v1 widgets |
| F4 | Kanvas app v0.1 with chat + canvas split view |
| F5 | Kode integration (recognise A2UI in chat) |
| F6 | State store on kdb-next |
| F7 | A2UI v2 (richer charts, drag-drop layouts) |
10. Alternatives Considered
- *TML/JS as the rendering target.*Rejected: Flutter is the Koder
Stack's default UI surface; A2UI consumed in Flutter is consistent with every other client.
- *arkdown + custom syntax.*Rejected: insufficient interactivity.
Buttons, inputs, real
time state need firstclass widgets. - *ard-code widget catalogues per consumer.*Rejected: duplication
across Kode + Kanvas + future products.
11. References
- Memory
engine_product_pattern— every Koder SaaS gets engine + product - OpenClaw analysis (2026
0429) — origin of the Canvas concept services/ai/kode— primary agent that emits A2UIengines/sdk/koder_kit— Flutter base widgets (Canvas SDK builds atop)