Add SDK canvas runtime support#1401
Conversation
Add Node extension canvas APIs and direct canvas provider callback routing. Add Rust canvas declarations, provider handlers, create/resume wiring, and host session.canvas APIs aligned with the runtime schema. Validation: nodejs typecheck/lint/tests; rust fmt/check/clippy; cargo test --all-features. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose stable extension identity metadata on Node and Rust session create/resume options and forward extensionInfo on the wire for canvas providers. Validation: nodejs typecheck/lint/vitest; rust fmt/clippy/test --all-features. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds cross-SDK “canvas runtime” support, enabling SDK consumers to declare canvases, receive direct provider callbacks (canvas.*), and use host-side session.canvas.* RPCs with stable extension identity (extensionInfo)—without requiring the larger handler refactor from the prototype branch.
Changes:
- Rust: Introduces a new
canvasmodule (declarations, handler traits, dispatch, host RPC types) and wiresSessionConfig/ResumeSessionConfigto serialize canvas-related fields onsession.create/session.resume. - Rust: Adds
Session::canvas()host API and updates the session event loop/router to handle direct provider callback requests (canvas.open|focus|reload|close|action.invoke). - Node.js: Adds a canvas surface (
createCanvas, types, dispatch), forwards canvas declarations + request flags +extensionInfoon session create/resume, and routes directcanvas.*JSON-RPC requests to registered canvases with tests.
Show a summary per file
| File | Description |
|---|---|
| rust/tests/session_test.rs | Adds coverage for Rust canvas wire fields, provider dispatch routing, and SessionCanvas host API behavior. |
| rust/tests/e2e/elicitation.rs | Updates capability struct test to include the new ui.canvases field. |
| rust/src/wire.rs | Extends session create/resume wire payloads with canvases, request flags, and extension_info. |
| rust/src/types.rs | Adds ExtensionInfo, canvas config fields on session configs, resume result open-canvas capture, and UiCapabilities.canvases. |
| rust/src/session.rs | Adds SessionCanvas host API + open-canvas tracking and routes canvas.* provider callbacks through a per-session registry. |
| rust/src/router.rs | Adds debug logging when routing requests to a registered session. |
| rust/src/lib.rs | Exposes the new canvas module publicly. |
| rust/src/jsonrpc.rs | Adds debug logging for incoming JSON-RPC requests from the runtime. |
| rust/src/canvas.rs | New Rust canvas module: declarations, handler traits, registry + dispatch, request/response types, and unit tests. |
| nodejs/test/extension.test.ts | Verifies createCanvas is exported from the extension surface. |
| nodejs/test/client.test.ts | Adds tests for forwarding canvas fields on create/resume and for direct provider dispatch behavior. |
| nodejs/src/types.ts | Adds SessionCapabilities.ui.canvases, introduces ExtensionInfo, and extends session configs with canvas fields. |
| nodejs/src/session.ts | Adds per-session canvas registration and lookup to support direct dispatch routing. |
| nodejs/src/index.ts | Exports canvas APIs/types and ExtensionInfo from the main entrypoint. |
| nodejs/src/extension.ts | Exports canvas APIs/types and ExtensionInfo from the extension surface. |
| nodejs/src/client.ts | Forwards canvas fields on create/resume and registers handlers for direct canvas.* provider callbacks. |
| nodejs/src/canvas.ts | New Node canvas module: canvas declaration/types, createCanvas, and provider request dispatch helper. |
Copilot's findings
- Files reviewed: 17/17 changed files
- Comments generated: 5
This comment has been minimized.
This comment has been minimized.
Add CanvasInstanceAvailability, OpenCanvasInstance availability, and resume openCanvases seeding support to the Rust SDK. Validation: cargo +nightly-2026-04-14 fmt --check; cargo clippy --all-features --all-targets -- -D warnings; cargo test --all-features. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Validate canvas provider request payloads before routing, surface Rust canvas serialization and builder errors, and clarify list_open RPC behavior. Validation: nodejs typecheck/lint/vitest; rust fmt/clippy/test --all-features. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Remove stale focus/close/reload canvas agent-tool references and cover custom-tool permission payload passthrough for open_canvas. Validation: nodejs typecheck; cargo test --all-features permission_request_data_extracts_typed_kind. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Align canvas contribution and discovered canvas descriptions with the runtime schema, update canvas tool-surface docs, and cover open_canvas custom-tool permission payloads. Validation: nodejs typecheck/lint/vitest client+extension; rust fmt/clippy; cargo check --all-features --all-targets; targeted canvas and permission tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Align OpenCanvasInstance with the runtime schema by making availability required and updating canvas host/resume tests. Validation: cargo check --all-features --all-targets; cargo test --all-features canvas; targeted session canvas tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Rename the Node canvas provider option from onOpen to open and remove lifecycle handler options from the extension canvas API. Validation: nodejs typecheck; vitest client and extension tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Aligns the SDK canvas contract with copilot-agent-runtime
jmoseley/adr-implementation-plan commits 85b23bc264 and acdefc1bc1:
- Rename agentActions to actions on CanvasDeclaration and
DiscoveredCanvas (Rust + Node).
- Drop toolbar from CanvasContribution and CanvasOpenResponse, and
remove CanvasToolbarItemDeclaration / CanvasToolbarItem entirely.
- Drop SessionCanvas::focus and SessionCanvas::reload host APIs;
re-opening with the same instanceId now drives focus via
session.canvas.opened { reopen: true }, and reload is renderer-only.
- Drop canvas.focus / canvas.reload provider JSON-RPC routes and the
matching CanvasHandler::on_focus / on_reload hooks; canvas.close keeps
its dedicated dispatch path.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Lets extension authors observe canvas instance close events without adding back the dropped onFocus/onReload hooks. Fire-and-forget: the handler's return value is ignored and the provider response is still undefined. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Each entry in createCanvas({ actions }) may now carry its own optional
handler, co-located with the action's metadata. The top-level onAction
remains as a fallback for actions that don't define their own handler.
Dispatch order:
1. Per-action handler when set.
2. Top-level onAction otherwise.
3. canvas_action_no_handler if neither is wired.
The handler closure is stripped from the wire CanvasDeclaration sent on
session.create / session.resume; only the action's name, description,
and inputSchema reach the runtime. A new CanvasAction authoring type
sits on top of the existing CanvasAgentActionDeclaration wire type.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Per-action handlers are now the only dispatch path. Declared actions without a handler fall through to canvas_action_no_handler. Keeps the action's metadata and behavior co-located and removes a second indirection that always boiled down to a switch on actionName. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Drop CanvasToolDefinition, CanvasToolDefinitionDefer, and the CanvasOpenResponse.tools / OpenCanvasInstance.tools fields from both the Node and Rust SDKs. The CLI side is being removed in lockstep, so the wire contract no longer carries this field. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-SDK Consistency ReviewThis PR adds canvas runtime support to the Node.js and Rust SDKs. The following new public APIs are being added to Node.js: New public types/classes
New
|
Canvas providers need stable runtime contracts across SDKs so native hosts and extensions can declare canvases, handle provider callbacks, and drive canvas chrome without adopting the broader Rust handler refactor from the prototype branch.
What changed
createCanvas, canvas declarations, handler contexts, errors, and exports) and wires session create/resume to sendcanvases,requestCanvasRenderer,requestExtensions, and stableextensionInfo.Canvas,CanvasHandler, directcanvas.open|focus|reload|close|action.invokeprovider callback routing, and host APIs undersession.canvas()fordiscover,list_open,open,focus,reload,close, andinvoke_action.displayNameis required for canvas declarations,session.canvas.listOpenis a real RPC, resume consumesopenCanvases, andcapabilities.ui.canvasesis boolean.ExtensionInfo { source, name }/extensionInfoso consumers can opt into stable agent-facing extension IDs likegithub-app:<provider-name>instead of reconnect-specific fallback IDs.Notes for reviewers
The Rust implementation is additive and keeps the existing separate permission/user-input/tool handler model. Canvas provider callbacks are routed through a focused per-session canvas registry rather than a unified session handler refactor.
Validation
cd nodejs && npm run typecheckcd nodejs && npm run lint(existing warnings only)cd nodejs && npx vitest run test/client.test.ts test/extension.test.tscd rust && cargo +nightly-2026-04-14 fmt --checkcd rust && cargo clippy --all-features --all-targets -- -D warningscd rust && cargo test --all-features