Skip to content

Tags: github/copilot-sdk

Tags

v1.0.0-beta.9

Toggle v1.0.0-beta.9's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Refactor Rust SDK errors to use structs with a `kind()` method (#1400)

* Refactor Rust SDK errors to use structs with a `kind()` method

The conventional `#[non_exhaustive] enum Error { ... }` pattern appears
safe but creates problems as a library evolves. This PR changes all
error types to the struct-with-`kind()` pattern, which also aligns with
the Azure SDK for Rust error design.

Why not a flat error enum:

- `#[non_exhaustive]` on the enum prevents exhaustive matching, but
  individual variants are still fixed. Adding a field to any variant —
  even just to improve an error message with a line number or file path
  — is a breaking change.
- Adding context data is harder than it looks. With a flat enum, new
  fields touch every affected variant and all match arms across the
  codebase. With a struct, new fields are added in one place and callers
  who don't use them are unaffected.
- A single enum conflates all failure modes, making it impossible to
  document or guarantee which variants a given function can actually
  return. Callers must handle unrelated variants they will never see, or
  accept a wildcard arm that silently swallows future additions.

The struct + kind pattern:

| Concern | Flat enum | Struct + `kind()` |
|---|---|---|
| Categorization | Match directly on variant | Call `.kind()` → `&*Kind` |
| Adding context | Breaking: add fields to variant | Non-breaking: add fields to struct |
| `non_exhaustive` | On enum; variants are fixed | Not needed on struct with only private fields |
| Simple display | Must match all variants | `format!("{err}")` — no match needed |

Callers who only want to display or propagate an error with `?` do not
need to call `.kind()` at all. Only callers who need to inspect the
failure category call `.kind()`, and they get a stable, scoped `*Kind`
enum to match against.

* Remove unnecessary error structs

Sticking with `*Kind` as a convention for error enums.

* Add backtrace support to Error struct

Enhanced the Error struct to include an optional backtrace, which is captured only when `RUST_BACKTRACE` is set. This change helps in debugging by providing context on error occurrences without inflating the Error size unnecessarily.

* Resolve PR feedback

rust/v1.0.0-beta.9

Toggle rust/v1.0.0-beta.9's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Refactor Rust SDK errors to use structs with a `kind()` method (#1400)

* Refactor Rust SDK errors to use structs with a `kind()` method

The conventional `#[non_exhaustive] enum Error { ... }` pattern appears
safe but creates problems as a library evolves. This PR changes all
error types to the struct-with-`kind()` pattern, which also aligns with
the Azure SDK for Rust error design.

Why not a flat error enum:

- `#[non_exhaustive]` on the enum prevents exhaustive matching, but
  individual variants are still fixed. Adding a field to any variant —
  even just to improve an error message with a line number or file path
  — is a breaking change.
- Adding context data is harder than it looks. With a flat enum, new
  fields touch every affected variant and all match arms across the
  codebase. With a struct, new fields are added in one place and callers
  who don't use them are unaffected.
- A single enum conflates all failure modes, making it impossible to
  document or guarantee which variants a given function can actually
  return. Callers must handle unrelated variants they will never see, or
  accept a wildcard arm that silently swallows future additions.

The struct + kind pattern:

| Concern | Flat enum | Struct + `kind()` |
|---|---|---|
| Categorization | Match directly on variant | Call `.kind()` → `&*Kind` |
| Adding context | Breaking: add fields to variant | Non-breaking: add fields to struct |
| `non_exhaustive` | On enum; variants are fixed | Not needed on struct with only private fields |
| Simple display | Must match all variants | `format!("{err}")` — no match needed |

Callers who only want to display or propagate an error with `?` do not
need to call `.kind()` at all. Only callers who need to inspect the
failure category call `.kind()`, and they get a stable, scoped `*Kind`
enum to match against.

* Remove unnecessary error structs

Sticking with `*Kind` as a convention for error enums.

* Add backtrace support to Error struct

Enhanced the Error struct to include an optional backtrace, which is captured only when `RUST_BACKTRACE` is set. This change helps in debugging by providing context on error occurrences without inflating the Error size unnecessarily.

* Resolve PR feedback

go/v1.0.0-beta.9

Toggle go/v1.0.0-beta.9's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Refactor Rust SDK errors to use structs with a `kind()` method (#1400)

* Refactor Rust SDK errors to use structs with a `kind()` method

The conventional `#[non_exhaustive] enum Error { ... }` pattern appears
safe but creates problems as a library evolves. This PR changes all
error types to the struct-with-`kind()` pattern, which also aligns with
the Azure SDK for Rust error design.

Why not a flat error enum:

- `#[non_exhaustive]` on the enum prevents exhaustive matching, but
  individual variants are still fixed. Adding a field to any variant —
  even just to improve an error message with a line number or file path
  — is a breaking change.
- Adding context data is harder than it looks. With a flat enum, new
  fields touch every affected variant and all match arms across the
  codebase. With a struct, new fields are added in one place and callers
  who don't use them are unaffected.
- A single enum conflates all failure modes, making it impossible to
  document or guarantee which variants a given function can actually
  return. Callers must handle unrelated variants they will never see, or
  accept a wildcard arm that silently swallows future additions.

The struct + kind pattern:

| Concern | Flat enum | Struct + `kind()` |
|---|---|---|
| Categorization | Match directly on variant | Call `.kind()` → `&*Kind` |
| Adding context | Breaking: add fields to variant | Non-breaking: add fields to struct |
| `non_exhaustive` | On enum; variants are fixed | Not needed on struct with only private fields |
| Simple display | Must match all variants | `format!("{err}")` — no match needed |

Callers who only want to display or propagate an error with `?` do not
need to call `.kind()` at all. Only callers who need to inspect the
failure category call `.kind()`, and they get a stable, scoped `*Kind`
enum to match against.

* Remove unnecessary error structs

Sticking with `*Kind` as a convention for error enums.

* Add backtrace support to Error struct

Enhanced the Error struct to include an optional backtrace, which is captured only when `RUST_BACKTRACE` is set. This change helps in debugging by providing context on error occurrences without inflating the Error size unnecessarily.

* Resolve PR feedback

20260527-0052Z-phase-04-pre-implementation

Toggle 20260527-0052Z-phase-04-pre-implementation's commit message

Verified

This commit was signed with the committer’s verified signature.
edburns Ed Burns
Plan and grader for phase 04

v1.0.0-beta.8

Toggle v1.0.0-beta.8's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
SDK: Align canvas with codegen pipeline, add e2e tests (#1413)

rust/v1.0.0-beta.8

Toggle rust/v1.0.0-beta.8's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
SDK: Align canvas with codegen pipeline, add e2e tests (#1413)

go/v1.0.0-beta.8

Toggle go/v1.0.0-beta.8's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
SDK: Align canvas with codegen pipeline, add e2e tests (#1413)

v1.0.0-beta.7

Toggle v1.0.0-beta.7's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Add SDK canvas runtime support (#1401)

* Add canvas runtime support to SDK

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>

* Add canvas provider RPC tracing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add extension info session option

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>

* Expose canvas resume durability fields

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>

* Address canvas SDK review feedback

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>

* Format Rust session imports

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Sync canvas tool surface docs

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>

* Require canvas descriptions

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>

* Require canvas instance availability

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 Node canvas open handler

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>

* Drop canvas toolbar and focus/reload surface

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>

* Restore optional onClose handler on Node canvas options

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>

* Support per-action handlers on Node canvas actions

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>

* Drop top-level onAction fallback on Node canvases

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>

* Normalize JSDoc style on CanvasAgentActionDeclaration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop stale wire-rename guards from canvas declaration test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Document canvas action dispatch divergence in Rust SDK

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Require handler on canvas actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Collapse CanvasAgentActionDeclaration into CanvasAction

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop debug log for inbound JSON-RPC requests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop canvas debug logs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove canvas tools field

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>

* rust: slim canvas surface to wire types + CanvasHandler

Move per-canvas registry, Canvas builder, dispatch helpers, and the
SessionCanvas host helper out of the SDK. The Rust canvas surface now
matches the other typed extension points (PermissionHandler /
UserInputHandler / HookHandler):

  SessionConfig
    .with_canvases([CanvasDeclaration, ...])
    .with_canvas_handler(Arc::new(MyHandler))

Removed:
  - canvas::Canvas, CanvasBuilder (declaration+handler bundle)
  - canvas::CanvasRegistry, build_registry, dispatch_canvas_*
  - session::SessionCanvas + Session::canvas() accessor
    (callers move to session.rpc().canvas().*)

Kept (the wire boundary + typed extension point):
  - All wire types (CanvasDeclaration, OpenCanvasInstance, ...)
  - CanvasHandler trait + on_open/on_action/on_close
  - SessionConfig/ResumeSessionConfig.canvases (now Vec<CanvasDeclaration>)
  - SessionConfig/ResumeSessionConfig.canvas_handler

handle_request dispatches canvas.open/close/action.invoke directly to
the handler; the per-canvas registry now lives in the app layer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* rust: drop canvas wire types duplicated by codegen

Removed CanvasInstanceAvailability, OpenCanvasInstance,
CanvasAgentActionDeclaration (-> CanvasAction), CanvasDiscoverResult,
DiscoveredCanvas, CanvasListOpenResult, CanvasOpenRequest,
CanvasCloseRequest, CanvasInvokeActionRequest, and
CanvasInvokeActionResult from canvas.rs; consumers import these from
crate::generated::api_types directly. The remaining hand-written types
(CanvasDeclaration, CanvasOpenResponse, handler trait, contexts,
CanvasError) are genuinely additive provider-authoring contracts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix broken intra-doc link to renamed CanvasAction type

The canvas wire types were deduplicated against generated/api_types.rs,
renaming CanvasAgentActionDeclaration to CanvasAction. A doc comment
in canvas.rs still referenced the old name, which broke cargo doc on CI
(broken_intra_doc_links is denied).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* go: add canvas runtime support

Mirrors the Rust SDK canvas surface in rust/src/canvas.rs:

- CanvasDeclaration, CanvasOpenResponse, CanvasHostContext,
  CanvasOpenContext / CanvasActionContext / CanvasLifecycleContext,
  CanvasError, CanvasHandler interface + CanvasHandlerDefaults, and
  ExtensionInfo.
- SessionConfig / ResumeSessionConfig: Canvases, RequestCanvasRenderer,
  RequestExtensions, CanvasHandler, ExtensionInfo.
- Inbound JSON-RPC dispatch for canvas.open, canvas.close, and
  canvas.action.invoke, with a canvas_handler_unset error envelope when
  no handler is installed and a canvas_handler_error envelope when a
  handler returns a non-CanvasError error.
- Session.OpenCanvases() surfaces the openCanvases snapshot from the
  session.resume response.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* python: add canvas runtime support

Mirrors the Rust SDK design: callers declare canvases on session.create
/ session.resume, install a single CanvasHandler, and the SDK dispatches
inbound canvas.open / canvas.close / canvas.action.invoke JSON-RPC
requests to that handler. Resume populates session.open_canvases from
the response. JSON-RPC dispatch was loosened to allow handlers to return
any JSON value (canvas.action.invoke result is arbitrary JSON).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* dotnet: add canvas runtime support

Ports the canvas runtime surface from the Rust SDK to the .NET SDK so
.NET hosts can declare canvases on session create/resume, advertise an
extension identity, and handle inbound canvas.open / canvas.close /
canvas.action.invoke RPC calls.

* New public Canvas.cs surface (CanvasDeclaration, ExtensionInfo,
  CanvasOpenResponse, CanvasHostContext, lifecycle/action/open contexts,
  CanvasError, ICanvasHandler, CanvasHandlerBase). All marked
  [Experimental(GHCP001)].
* SessionConfigBase gains Canvases, RequestCanvasRenderer,
  RequestExtensions, ExtensionInfo, CanvasHandler.
* CreateSession/ResumeSession requests forward the new fields and
  surface OpenCanvases on the response. CopilotSession exposes the
  returned canvases via OpenCanvases.
* CopilotClient registers canvas.open / canvas.close /
  canvas.action.invoke handlers and dispatches them to the session,
  which invokes the user's ICanvasHandler and returns structured
  CanvasError data via a new JsonRpc LocalRpcInvocationException path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review: openCanvases parity + Node API divergence note

- Node: add openCanvases accessor on CopilotSession and OpenCanvases
  field on ResumeSessionConfig so callers can both rehydrate from
  the resume response and pre-populate canvas state on resume.
- Node: document why createCanvas/Canvas intentionally diverges from
  the per-session CanvasHandler pattern used by Rust/Python/Go/.NET.
- Go: add ResumeSessionConfig.OpenCanvases, thread through to the
  resume request wire payload, and add a serialization test.
- .NET: add ResumeSessionConfig.OpenCanvases, thread through to the
  internal ResumeSessionRequest record, and add a serialization test.

Mirrors what Rust and Python already do, fixing wire-protocol parity
across SDKs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

rust/v1.0.0-beta.7

Toggle rust/v1.0.0-beta.7's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Add SDK canvas runtime support (#1401)

* Add canvas runtime support to SDK

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>

* Add canvas provider RPC tracing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add extension info session option

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>

* Expose canvas resume durability fields

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>

* Address canvas SDK review feedback

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>

* Format Rust session imports

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Sync canvas tool surface docs

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>

* Require canvas descriptions

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>

* Require canvas instance availability

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 Node canvas open handler

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>

* Drop canvas toolbar and focus/reload surface

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>

* Restore optional onClose handler on Node canvas options

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>

* Support per-action handlers on Node canvas actions

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>

* Drop top-level onAction fallback on Node canvases

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>

* Normalize JSDoc style on CanvasAgentActionDeclaration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop stale wire-rename guards from canvas declaration test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Document canvas action dispatch divergence in Rust SDK

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Require handler on canvas actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Collapse CanvasAgentActionDeclaration into CanvasAction

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop debug log for inbound JSON-RPC requests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop canvas debug logs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove canvas tools field

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>

* rust: slim canvas surface to wire types + CanvasHandler

Move per-canvas registry, Canvas builder, dispatch helpers, and the
SessionCanvas host helper out of the SDK. The Rust canvas surface now
matches the other typed extension points (PermissionHandler /
UserInputHandler / HookHandler):

  SessionConfig
    .with_canvases([CanvasDeclaration, ...])
    .with_canvas_handler(Arc::new(MyHandler))

Removed:
  - canvas::Canvas, CanvasBuilder (declaration+handler bundle)
  - canvas::CanvasRegistry, build_registry, dispatch_canvas_*
  - session::SessionCanvas + Session::canvas() accessor
    (callers move to session.rpc().canvas().*)

Kept (the wire boundary + typed extension point):
  - All wire types (CanvasDeclaration, OpenCanvasInstance, ...)
  - CanvasHandler trait + on_open/on_action/on_close
  - SessionConfig/ResumeSessionConfig.canvases (now Vec<CanvasDeclaration>)
  - SessionConfig/ResumeSessionConfig.canvas_handler

handle_request dispatches canvas.open/close/action.invoke directly to
the handler; the per-canvas registry now lives in the app layer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* rust: drop canvas wire types duplicated by codegen

Removed CanvasInstanceAvailability, OpenCanvasInstance,
CanvasAgentActionDeclaration (-> CanvasAction), CanvasDiscoverResult,
DiscoveredCanvas, CanvasListOpenResult, CanvasOpenRequest,
CanvasCloseRequest, CanvasInvokeActionRequest, and
CanvasInvokeActionResult from canvas.rs; consumers import these from
crate::generated::api_types directly. The remaining hand-written types
(CanvasDeclaration, CanvasOpenResponse, handler trait, contexts,
CanvasError) are genuinely additive provider-authoring contracts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix broken intra-doc link to renamed CanvasAction type

The canvas wire types were deduplicated against generated/api_types.rs,
renaming CanvasAgentActionDeclaration to CanvasAction. A doc comment
in canvas.rs still referenced the old name, which broke cargo doc on CI
(broken_intra_doc_links is denied).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* go: add canvas runtime support

Mirrors the Rust SDK canvas surface in rust/src/canvas.rs:

- CanvasDeclaration, CanvasOpenResponse, CanvasHostContext,
  CanvasOpenContext / CanvasActionContext / CanvasLifecycleContext,
  CanvasError, CanvasHandler interface + CanvasHandlerDefaults, and
  ExtensionInfo.
- SessionConfig / ResumeSessionConfig: Canvases, RequestCanvasRenderer,
  RequestExtensions, CanvasHandler, ExtensionInfo.
- Inbound JSON-RPC dispatch for canvas.open, canvas.close, and
  canvas.action.invoke, with a canvas_handler_unset error envelope when
  no handler is installed and a canvas_handler_error envelope when a
  handler returns a non-CanvasError error.
- Session.OpenCanvases() surfaces the openCanvases snapshot from the
  session.resume response.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* python: add canvas runtime support

Mirrors the Rust SDK design: callers declare canvases on session.create
/ session.resume, install a single CanvasHandler, and the SDK dispatches
inbound canvas.open / canvas.close / canvas.action.invoke JSON-RPC
requests to that handler. Resume populates session.open_canvases from
the response. JSON-RPC dispatch was loosened to allow handlers to return
any JSON value (canvas.action.invoke result is arbitrary JSON).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* dotnet: add canvas runtime support

Ports the canvas runtime surface from the Rust SDK to the .NET SDK so
.NET hosts can declare canvases on session create/resume, advertise an
extension identity, and handle inbound canvas.open / canvas.close /
canvas.action.invoke RPC calls.

* New public Canvas.cs surface (CanvasDeclaration, ExtensionInfo,
  CanvasOpenResponse, CanvasHostContext, lifecycle/action/open contexts,
  CanvasError, ICanvasHandler, CanvasHandlerBase). All marked
  [Experimental(GHCP001)].
* SessionConfigBase gains Canvases, RequestCanvasRenderer,
  RequestExtensions, ExtensionInfo, CanvasHandler.
* CreateSession/ResumeSession requests forward the new fields and
  surface OpenCanvases on the response. CopilotSession exposes the
  returned canvases via OpenCanvases.
* CopilotClient registers canvas.open / canvas.close /
  canvas.action.invoke handlers and dispatches them to the session,
  which invokes the user's ICanvasHandler and returns structured
  CanvasError data via a new JsonRpc LocalRpcInvocationException path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review: openCanvases parity + Node API divergence note

- Node: add openCanvases accessor on CopilotSession and OpenCanvases
  field on ResumeSessionConfig so callers can both rehydrate from
  the resume response and pre-populate canvas state on resume.
- Node: document why createCanvas/Canvas intentionally diverges from
  the per-session CanvasHandler pattern used by Rust/Python/Go/.NET.
- Go: add ResumeSessionConfig.OpenCanvases, thread through to the
  resume request wire payload, and add a serialization test.
- .NET: add ResumeSessionConfig.OpenCanvases, thread through to the
  internal ResumeSessionRequest record, and add a serialization test.

Mirrors what Rust and Python already do, fixing wire-protocol parity
across SDKs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

go/v1.0.0-beta.7

Toggle go/v1.0.0-beta.7's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Add SDK canvas runtime support (#1401)

* Add canvas runtime support to SDK

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>

* Add canvas provider RPC tracing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add extension info session option

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>

* Expose canvas resume durability fields

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>

* Address canvas SDK review feedback

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>

* Format Rust session imports

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Sync canvas tool surface docs

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>

* Require canvas descriptions

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>

* Require canvas instance availability

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 Node canvas open handler

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>

* Drop canvas toolbar and focus/reload surface

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>

* Restore optional onClose handler on Node canvas options

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>

* Support per-action handlers on Node canvas actions

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>

* Drop top-level onAction fallback on Node canvases

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>

* Normalize JSDoc style on CanvasAgentActionDeclaration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop stale wire-rename guards from canvas declaration test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Document canvas action dispatch divergence in Rust SDK

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Require handler on canvas actions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Collapse CanvasAgentActionDeclaration into CanvasAction

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop debug log for inbound JSON-RPC requests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop canvas debug logs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove canvas tools field

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>

* rust: slim canvas surface to wire types + CanvasHandler

Move per-canvas registry, Canvas builder, dispatch helpers, and the
SessionCanvas host helper out of the SDK. The Rust canvas surface now
matches the other typed extension points (PermissionHandler /
UserInputHandler / HookHandler):

  SessionConfig
    .with_canvases([CanvasDeclaration, ...])
    .with_canvas_handler(Arc::new(MyHandler))

Removed:
  - canvas::Canvas, CanvasBuilder (declaration+handler bundle)
  - canvas::CanvasRegistry, build_registry, dispatch_canvas_*
  - session::SessionCanvas + Session::canvas() accessor
    (callers move to session.rpc().canvas().*)

Kept (the wire boundary + typed extension point):
  - All wire types (CanvasDeclaration, OpenCanvasInstance, ...)
  - CanvasHandler trait + on_open/on_action/on_close
  - SessionConfig/ResumeSessionConfig.canvases (now Vec<CanvasDeclaration>)
  - SessionConfig/ResumeSessionConfig.canvas_handler

handle_request dispatches canvas.open/close/action.invoke directly to
the handler; the per-canvas registry now lives in the app layer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* rust: drop canvas wire types duplicated by codegen

Removed CanvasInstanceAvailability, OpenCanvasInstance,
CanvasAgentActionDeclaration (-> CanvasAction), CanvasDiscoverResult,
DiscoveredCanvas, CanvasListOpenResult, CanvasOpenRequest,
CanvasCloseRequest, CanvasInvokeActionRequest, and
CanvasInvokeActionResult from canvas.rs; consumers import these from
crate::generated::api_types directly. The remaining hand-written types
(CanvasDeclaration, CanvasOpenResponse, handler trait, contexts,
CanvasError) are genuinely additive provider-authoring contracts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix broken intra-doc link to renamed CanvasAction type

The canvas wire types were deduplicated against generated/api_types.rs,
renaming CanvasAgentActionDeclaration to CanvasAction. A doc comment
in canvas.rs still referenced the old name, which broke cargo doc on CI
(broken_intra_doc_links is denied).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* go: add canvas runtime support

Mirrors the Rust SDK canvas surface in rust/src/canvas.rs:

- CanvasDeclaration, CanvasOpenResponse, CanvasHostContext,
  CanvasOpenContext / CanvasActionContext / CanvasLifecycleContext,
  CanvasError, CanvasHandler interface + CanvasHandlerDefaults, and
  ExtensionInfo.
- SessionConfig / ResumeSessionConfig: Canvases, RequestCanvasRenderer,
  RequestExtensions, CanvasHandler, ExtensionInfo.
- Inbound JSON-RPC dispatch for canvas.open, canvas.close, and
  canvas.action.invoke, with a canvas_handler_unset error envelope when
  no handler is installed and a canvas_handler_error envelope when a
  handler returns a non-CanvasError error.
- Session.OpenCanvases() surfaces the openCanvases snapshot from the
  session.resume response.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* python: add canvas runtime support

Mirrors the Rust SDK design: callers declare canvases on session.create
/ session.resume, install a single CanvasHandler, and the SDK dispatches
inbound canvas.open / canvas.close / canvas.action.invoke JSON-RPC
requests to that handler. Resume populates session.open_canvases from
the response. JSON-RPC dispatch was loosened to allow handlers to return
any JSON value (canvas.action.invoke result is arbitrary JSON).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* dotnet: add canvas runtime support

Ports the canvas runtime surface from the Rust SDK to the .NET SDK so
.NET hosts can declare canvases on session create/resume, advertise an
extension identity, and handle inbound canvas.open / canvas.close /
canvas.action.invoke RPC calls.

* New public Canvas.cs surface (CanvasDeclaration, ExtensionInfo,
  CanvasOpenResponse, CanvasHostContext, lifecycle/action/open contexts,
  CanvasError, ICanvasHandler, CanvasHandlerBase). All marked
  [Experimental(GHCP001)].
* SessionConfigBase gains Canvases, RequestCanvasRenderer,
  RequestExtensions, ExtensionInfo, CanvasHandler.
* CreateSession/ResumeSession requests forward the new fields and
  surface OpenCanvases on the response. CopilotSession exposes the
  returned canvases via OpenCanvases.
* CopilotClient registers canvas.open / canvas.close /
  canvas.action.invoke handlers and dispatches them to the session,
  which invokes the user's ICanvasHandler and returns structured
  CanvasError data via a new JsonRpc LocalRpcInvocationException path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review: openCanvases parity + Node API divergence note

- Node: add openCanvases accessor on CopilotSession and OpenCanvases
  field on ResumeSessionConfig so callers can both rehydrate from
  the resume response and pre-populate canvas state on resume.
- Node: document why createCanvas/Canvas intentionally diverges from
  the per-session CanvasHandler pattern used by Rust/Python/Go/.NET.
- Go: add ResumeSessionConfig.OpenCanvases, thread through to the
  resume request wire payload, and add a serialization test.
- .NET: add ResumeSessionConfig.OpenCanvases, thread through to the
  internal ResumeSessionRequest record, and add a serialization test.

Mirrors what Rust and Python already do, fixing wire-protocol parity
across SDKs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>