Skip to content

Canvases, the workspace and state ownership

A canvas — a dashboard, a query workbench — sits beside the chat and shows what the agents are building while they build it. The person edits it too. That makes it shared state, and shared state needs one rule above all: every key has exactly one writer.

The workspace

The agents keep a compact record of what the conversation built in the AG-UI state, under kaboo_workspace:

Key What it holds
focus Where the agents are working now: a dashboard or query id, and the widgets they touched.
dashboards Each dashboard's id, title, version and widgets — by id, never data.
queries Each saved query's id, title and columns.
sources The data sources the conversation uses.
pending Work an agent started and hasn't finished.
changes What each agent did, in order: "Added 2 widgets on Churn by region".

Tool results write it through state effects: a mapper per tool turns a successful call into JSON Patch operations, which reach the browser as STATE_DELTAs the moment the call succeeds (kaboo-workflows: Shared state).

Following the agent

  • Follow mode. The canvas opens whatever focus names, and points out the widgets the agent touched. The person can turn it off.
  • Presence. useAgentPresence() says which sub-agents are working and on which tool.
  • Ghost widgets. useLiveToolCalls(/plot_widgets$/) returns the plot calls in flight with their arguments so far, so the widgets an agent is writing show as outlines before the call runs.
  • What Kaboo did. changes is a readable log, with links to what each change touched.

Lab scenario: delegate-dashboard.

Telling the agent what the person sees

The agents read the workspace at every model call, through workspace views, so they extend what exists instead of listing and reading it first. In the lab, extending a dashboard takes two tool calls with a view and four without (workspace-extend against workspace-extend-read; yarn lab compare workspace-vs-read --live for a real model).

What the person does on the canvas reaches the agent two ways:

  • Context, for what they are looking at: useAgentContext sends the open dashboard's version and a summary with every run, so "this chart" means the chart on screen.
  • Actions, for intents: "Ask Kaboo" on a widget, or changing a variable, sends a readable message with a structured kaboo_action in forwardedProps, which the host can route to a workflow without parsing text (workspace-refresh).

Who owns each key

Key Writer The browser
kaboo_sessions kaboo-workflows: the agents' transcripts and a paused run never sees it
kaboo_workspace kaboo-workflows' state effects sees it, read-only
your keys, such as kaboo_references the browser owns them

kaboo-runtime enforces the split: server keys come only from the store, a browser's copy is ignored, and a hidden key never reaches the browser, live or on replay (kaboo-runtime: Replay & state). A host vouches for a server key of its own by returning it from enrich.

Dashboards themselves stay out of state: they live in their service, the canvas fetches them, and the workspace holds only their ids and versions. The person's edits go to the service; the agents see them through context and the next effect, never by the browser writing the workspace.