Chat Canvases
Canvases are special UI controls that Code Nodes can return with the _canvas
helper. The helper pins a rich experience into BotDojo Chat, stores it server-side, and keeps it accessible through the canvas tray for the rest of the session. This page focuses on how Code Nodes (and tools built on top of them) emit _canvas
responses so you can wire up dashboards, notebooks, or custom apps directly from your code.
Nodes that emit _canvas
- Code Node – Return
_canvas
from yourexecute
function to create or update any canvas type. - Build UI (Code Interpreter Canvas) – Spins up a sandboxed Python UI and always responds with
_canvas
metadata that reconnects to the notebook. - Desktop Canvas – Runs a remote desktop sandbox and returns
_canvas
when provisioning or refreshing the desktop session. - BrowserBase – Creates a BrowserBase automation session and returns
_canvas
the first time it provisions the browser experience. - Background Flow as Tool (with “Create Canvas” enabled) – Launches a background job and shares a monitoring canvas back to the chat.
All of these nodes ultimately surface their canvases by emitting an object with the _canvas
key, so the mechanics for consuming them in chat are identical.
Return _canvas
from a Code Node
Use the context.canvas
helper inside a Code Node (or any sandboxed runtime) to manage canvases:
export async function execute(input, node, context) {
const state = await context.sessionState.get('canvas-demo');
let canvasId = await state.getVariable('canvasId');
if (!canvasId) {
const created = await context.canvas.createCanvas({
canvasId: `customer-dashboard-${context.sessionId}`,
canvasType: 'iframe',
canvasData: {
url: `https://dash.example.com/embed/${context.sessionId}`,
title: 'Customer health',
agent_enabled: false,
},
});
canvasId = created.canvasId;
await state.setVariable('canvasId', canvasId);
} else {
await context.canvas.updateCanvas({
canvasId,
canvasType: 'iframe',
canvasData: {
url: `https://dash.example.com/embed/${context.sessionId}`,
title: 'Customer health',
lastRefreshedAt: new Date().toISOString(),
},
});
}
return {
status: 'ready',
_canvas: {
canvasId,
canvasType: 'iframe',
canvasData: {
url: `https://dash.example.com/embed/${context.sessionId}`,
title: 'Customer health',
},
},
};
}
Key points:
- Store the
canvasId
in session state so future invocations update the same canvas instead of creating duplicates. context.canvas.loadCanvas(canvasId)
returns the persisted definition if you need to inspect the current payload before deciding how to update it.- Returning the
_canvas
helper makes the chat aware of the latest state; you can keep the_canvas
payload minimal (only the fields the UI needs to render). - Set
canvasData.show_inline
to show the full canvas directly in the transcript; leave it unset to rely on the preview card plus the side tray entry.
Canvas types
Type | Typical use | Required data |
---|---|---|
iframe | Embed an external web app or dashboard. | canvasData.url (plus optional agent_enabled , title , show_inline ). |
code-interpreter | Launch or reconnect to a managed Python sandbox. | canvasData.codeInterpreterParams from the Code Interpreter Canvas tool; BotDojo fills in the sandbox URL. |
markdown | Persist long-form formatted content outside the main transcript. | canvasData.markdown and optional title . |
file | Preview an uploaded asset (PDF, image, etc.). | canvasData should include file metadata and a signed URL created via context.store.Documents . |
dojo-canvas | Host a custom experience built with botdojo-canvas-client . | canvasData.url (to your hosted app) and optional flags like agent_enabled or show_chat_default . |
All types are stored server-side so they can be replayed later or surfaced in external integrations, and they are all selectable from a Code Node response.
Create custom canvases
Custom canvases let you ship a full agent-enabled app inside chat. Use the 'dojo-canvas'
type to host a web experience that talks to the active flow through the BotDojo WebSocket. The interactive website agent example walks through wiring a Code Node that returns _canvas
alongside a canvas front end built with botdojo-canvas-client
. For a deeper dive into the overall pattern, see the Agentic UI solution.
- The canvas client reuses the
agent_socket_url
query parameter to connect back to the agent. - Your app can invoke tools, stream status messages, or react to state changes from the flow.
- Returning
_canvas
from your Code Node withcanvasType: 'dojo-canvas'
updates the embedded app without forcing users to leave the conversation.