Skip to content

Add SDK canvas runtime support#1401

Open
jmoseley wants to merge 24 commits into
mainfrom
jmoseley/sdk-canvas-runtime-support
Open

Add SDK canvas runtime support#1401
jmoseley wants to merge 24 commits into
mainfrom
jmoseley/sdk-canvas-runtime-support

Conversation

@jmoseley
Copy link
Copy Markdown
Contributor

@jmoseley jmoseley commented May 23, 2026

What changed

  • Adds the Node extension canvas surface (createCanvas, canvas declarations, handler contexts, errors, and exports) and wires session create/resume to send canvases, requestCanvasRenderer, requestExtensions, and stable extensionInfo.
  • Adds focused Rust canvas support with Canvas, CanvasHandler, direct canvas.open|focus|reload|close|action.invoke provider callback routing, and host APIs under session.canvas() for discover, list_open, open, focus, reload, close, and invoke_action.
  • Aligns the SDK contracts with the runtime branch: displayName is required for canvas declarations, session.canvas.listOpen is a real RPC, resume consumes openCanvases, and capabilities.ui.canvases is boolean.
  • Adds ExtensionInfo { source, name } / extensionInfo so consumers can opt into stable agent-facing extension IDs like github-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 typecheck
  • cd nodejs && npm run lint (existing warnings only)
  • cd nodejs && npx vitest run test/client.test.ts test/extension.test.ts
  • cd rust && cargo +nightly-2026-04-14 fmt --check
  • cd rust && cargo clippy --all-features --all-targets -- -D warnings
  • cd rust && cargo test --all-features

@jmoseley jmoseley requested a review from a team as a code owner May 23, 2026 04:50
Copilot AI review requested due to automatic review settings May 23, 2026 04:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 canvas module (declarations, handler traits, dispatch, host RPC types) and wires SessionConfig / ResumeSessionConfig to serialize canvas-related fields on session.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 + extensionInfo on session create/resume, and routes direct canvas.* 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

Comment thread rust/src/session.rs Outdated
Comment thread rust/src/canvas.rs Outdated
Comment thread rust/src/canvas.rs Outdated
Comment thread nodejs/src/client.ts Outdated
Comment thread nodejs/src/client.ts Outdated
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

github-actions Bot and others added 8 commits May 24, 2026 06:51
- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code
quicktype emits the freeform 'canvas_json_schema' field as 'Any', and the
post-processor was adding '= None' to every bare ': Any' annotation. That
turned the synthesized root RPC dataclass field into a defaulted argument
followed by required fields (canvas_list, ...), which made Python raise
'non-default argument follows default argument' at import time and broke
every Python SDK test plus the scenario import checks.

Scope the post-processor so RPC definition fields keep their required Any
annotation, matching the rest of the registry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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>
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>
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>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jmoseley and others added 16 commits May 24, 2026 00:23
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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>
@jmoseley jmoseley force-pushed the jmoseley/sdk-canvas-runtime-support branch from 1202bc1 to c50b728 Compare May 24, 2026 07:24
@jmoseley jmoseley changed the base branch from main to update-copilot-1.0.53-2 May 24, 2026 07:25
@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

This PR adds canvas support to the Node.js and Rust SDKs. The following new surface area is not yet present in the Python, Go, or .NET SDKs:

Missing from Python, Go, and .NET

1. SessionConfig / ResumeSessionConfig fields

The following new parameters are added to Node.js SessionConfig/ResumeSessionConfig but are absent in all three other SDKs:

Node.js (camelCase) Python (snake_case) Go (PascalCase) .NET (PascalCase)
canvases?: Canvas[] canvases Canvases Canvases
requestCanvasRenderer?: boolean request_canvas_renderer RequestCanvasRenderer RequestCanvasRenderer
requestExtensions?: boolean request_extensions RequestExtensions RequestExtensions
extensionInfo?: ExtensionInfo extension_info ExtensionInfo ExtensionInfo

2. ExtensionInfo type

Node.js and Rust both define ExtensionInfo { source, name } for stable agent-facing extension IDs. Python, Go, and .NET have no equivalent type.

3. Canvas provider callback handling

Node.js registers server-side handlers for canvas.open, canvas.close, and canvas.action.invoke RPC requests. These are not wired in Python, Go, or .NET.

4. Session-level canvas host APIs

Rust exposes session.canvas() with host-side methods: discover, list_open, open, close, invoke_action. Python, Go, and .NET have no equivalent.

5. SessionCapabilities.ui.canvases

Node.js now uses a typed SessionCapabilities that includes capabilities.ui.canvases: boolean. This capability flag is absent from the other SDK capability models.


Suggestion

If canvas support is intended to be a first-class SDK feature (vs. a Node.js/Rust-only prototype), I'd suggest tracking follow-up issues to bring Python, Go, and .NET into parity. At minimum, the SessionConfig field additions (canvases, extensionInfo, requestCanvasRenderer, requestExtensions) would ensure those SDKs can at least declare canvas interest when creating sessions, even before full provider-callback and host-API support is added.

If this is intentionally a staged rollout (Node.js + Rust first), that's a perfectly reasonable approach — just worth noting in the PR description so downstream consumers know which SDKs support canvas today.

Generated by SDK Consistency Review Agent for issue #1401 · ● 7M ·

Base automatically changed from update-copilot-1.0.53-2 to main May 24, 2026 07:48
@jmoseley jmoseley enabled auto-merge May 24, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants