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, holds

    current widget state across messages.

  • *dapter SDKs*— engines/sdk/canvas-flutter/ (Dart) renders

    A2UI 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 SDK
  • products/horizontal/kanvas/ — Flutter app + landing
  • services/ai/kode updated to recognise A2UI blocks in agent

    responses and call the Flutter renderer when present

  • infra/jet — domain kanvas.koder.dev (landing) and

    canvas.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, realtime 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 (20260429) — origin of the Canvas concept
  • services/ai/kode — primary agent that emits A2UI
  • engines/sdk/koder_kit — Flutter base widgets (Canvas SDK builds atop)

Source: ../home/koder/dev/koder/meta/docs/stack/rfcs/canvas-RFC-001-a2ui.md