Skip to content

Add session-level canvasProvider field to Rust, Node, .NET, Go, and Python SDKs#1847

Open
jmoseley wants to merge 3 commits into
mainfrom
jmoseley-add-canvas-provider-sdk-field
Open

Add session-level canvasProvider field to Rust, Node, .NET, Go, and Python SDKs#1847
jmoseley wants to merge 3 commits into
mainfrom
jmoseley-add-canvas-provider-sdk-field

Conversation

@jmoseley

@jmoseley jmoseley commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

What

Adds an optional session-level canvasProvider field — a stable canvas-provider identity of shape { id: string, name?: string } — to the session create and session resume config/request types in the Rust, Node.js, .NET, Go, and Python SDKs.

This lets a host/control connection supply a stable canvas-provider extensionId so host-provided canvases restore across cold resume.

Why

github/copilot-agent-runtime#10519 ("Stable canvas provider identity for the built-in canvas provider") now reads params.canvasProvider on session.create / session.resume. Until now the published SDKs had no typed field for hosts to send this.

canvasProvider is a manually-registered JSON-RPC field (it is not in the generated api.schema.json, same as the existing canvases field), so the recent schema bump (#1828) did not surface it — it has to be hand-added.

Contract

  • CanvasProviderIdentity { id, name? }
    • id (required): opaque, used verbatim as the canvas extensionId (runtime recommends app:builtin:<windowId>).
    • name (optional): becomes the canvas extensionName; omitted from the wire when null.
  • Serializes on the wire as canvasProvider with nested id / name, mirroring the existing extensionInfo field placement in every location.

Changes

Each SDK mirrors the existing extensionInfo wiring exactly, placing canvasProvider immediately adjacent.

  • RustCanvasProviderIdentity struct + canvas_provider field on SessionConfig and ResumeSessionConfig (types/Debug/Default/into-wire/builder), wire structs in wire.rs, plus wire-assertion tests.
  • NodeCanvasProviderIdentity interface + canvasProvider? on SessionConfigBase, forwarded in both create/resume payloads, exported from index.ts, plus tests.
  • .NETCanvasProviderIdentity class + CanvasProvider property on SessionConfigBase (with copy-ctor + JsonSerializable), wire records in Client.cs, plus unit tests.
  • GoCanvasProviderIdentity struct + CanvasProvider field on SessionConfig, ResumeSessionConfig, and both wire request structs, forwarded in client.go, plus an end-to-end forwarding test. Also fixes a pre-existing gap: ExtensionInfo was declared on the Go config/wire structs but never actually forwarded in client.go for create or resume — it is now wired alongside canvasProvider.
  • PythonCanvasProviderIdentity dataclass (exported from copilot) + canvas_provider param forwarded on create_session / resume_session, plus serialize + end-to-end forwarding tests.

Testing

  • Rust: cargo test --all-features --test session_test, cargo fmt --check, cargo clippy clean.
  • Node: npx vitest run test/client.test.ts, npm run build, npm run lint clean.
  • .NET: dotnet test --filter CanvasTests.
  • Go: go test . (full package passes), go vet, gofmt clean.
  • Python: uv run pytest test_canvas.py test_client.py (canvasProvider serialize + forwarding tests pass), ruff check / ruff format clean.

Note

Java is intentionally not included here — the Java SDK currently lacks host-side canvas declaration entirely (no canvases field, no extensionInfo, no canvas handler registration on SessionConfig), so it needs full canvas-API parity first. The Java side of this change is brought in by #1848, which adds the host-side canvas declaration API and canvasProvider to the Java SDK.

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

Hosts can now supply a stable canvas-provider identity { id, name? } on
session.create and session.resume so host-provided canvases restore
across cold resume. Serializes as canvasProvider on the wire, mirroring
the existing extensionInfo field. Implements the runtime contract from
github/copilot-agent-runtime#10519.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 30, 2026 03:18
@jmoseley jmoseley requested a review from a team as a code owner June 30, 2026 03:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new optional session-level canvasProvider identity field to multiple SDKs (Rust, Node.js, .NET) so hosts can provide a stable canvas-provider identity across reconnects/cold resume, aligning SDK request payloads with runtime support for params.canvasProvider on session.create / session.resume.

Changes:

  • Rust: Introduces CanvasProviderIdentity and threads it through SessionConfig/ResumeSessionConfig into the explicit wire structs, with coverage in session wire tests.
  • Node.js: Adds CanvasProviderIdentity + canvasProvider? to session config types and forwards it in create/resume payloads, with client tests.
  • .NET: Adds CanvasProviderIdentity + CanvasProvider to session config base and JSON-RPC request records, with serialization and clone tests.
Show a summary per file
File Description
rust/tests/session_test.rs Adds assertions that canvasProvider is present on create/resume wire payloads.
rust/src/wire.rs Extends SessionCreateWire/SessionResumeWire to include canvas_provider serialized as canvasProvider.
rust/src/types.rs Adds CanvasProviderIdentity and adds canvas_provider to session config types + builders + into-wire mapping.
nodejs/test/client.test.ts Verifies canvasProvider is forwarded in session.create and session.resume payloads.
nodejs/src/types.ts Introduces CanvasProviderIdentity and adds canvasProvider? to SessionConfigBase.
nodejs/src/index.ts Re-exports CanvasProviderIdentity from the public Node.js entrypoint.
nodejs/src/client.ts Forwards canvasProvider into JSON-RPC payloads for create/resume.
dotnet/test/Unit/CanvasTests.cs Adds serialization coverage for CanvasProviderIdentity and clone-copy coverage for config fields.
dotnet/src/Types.cs Adds CanvasProvider to SessionConfigBase and includes CanvasProviderIdentity in source-gen serialization context.
dotnet/src/Client.cs Adds CanvasProvider to create/resume request records and forwards from config.
dotnet/src/Canvas.cs Introduces the CanvasProviderIdentity type with JSON property names.

Review details

  • Files reviewed: 11/11 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread rust/tests/session_test.rs Outdated
@github-actions

This comment has been minimized.

Indexing with ["name"] returns Value::Null both when the key is absent
and when it is present as null. Since the wire contract omits name when
None, assert the key is not present to catch a regression that would
serialize name: null.

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

This comment has been minimized.

Extend the session-level canvasProvider field to the Go and Python SDKs
for parity with Rust, Node, and .NET. Hosts can now send a stable
canvas-provider identity ({ id, name? }) on session.create and
session.resume so host-provided canvases restore across cold resume.

Go: add CanvasProviderIdentity, wire it onto SessionConfig,
ResumeSessionConfig, and both request structs, and forward it in
client.go. Also fix a pre-existing gap where ExtensionInfo was declared
but never forwarded on create/resume.

Python: add CanvasProviderIdentity dataclass, export it, and forward a
canvas_provider param on create_session/resume_session.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jmoseley jmoseley changed the title Add session-level canvasProvider field to Rust, Node, and .NET SDKs Add session-level canvasProvider field to Rust, Node, .NET, Go, and Python SDKs Jun 30, 2026
@jmoseley

Copy link
Copy Markdown
Contributor Author

⚠️ Python and Go are also missing `canvasProvider`

Both Python and Go have full canvas-API parity ... Neither was updated in this PR, which leaves them behind the other three SDKs.

Good catch — expanded this PR to cover both.

  • Go: added `CanvasProviderIdentity` in `canvas.go`, the `CanvasProvider` field on `SessionConfig`/`ResumeSessionConfig` and both wire request structs, and forwarding in `client.go`, plus an end-to-end forwarding test. While wiring it I also found a pre-existing gap: Go declared `ExtensionInfo` on the config/wire structs but never actually forwarded it in `client.go` for create or resume — it was dead. Fixed that alongside `canvasProvider` since they share the same precedence and code path.
  • Python: added the `CanvasProviderIdentity` dataclass (exported from `copilot`) and a `canvas_provider` param forwarded on `create_session`/`resume_session`, with serialize + end-to-end forwarding tests. (Python already forwarded `extension_info` correctly.)

Both mirror the existing `extensionInfo` placement exactly. Java still stays deferred for the reasons noted. PR title/description updated.

@github-actions

Copy link
Copy Markdown
Contributor

SDK Consistency Review ✅

This PR adds canvasProvider / CanvasProviderIdentity to five of the six SDKs with good consistency across all of them.

Cross-SDK alignment

SDK Type Session config field Wire field Exported
Rust CanvasProviderIdentity { id, name? } canvas_provider: Option<CanvasProviderIdentity> canvasProvider
Node.js CanvasProviderIdentity { id, name? } canvasProvider?: CanvasProviderIdentity canvasProvider
.NET CanvasProviderIdentity { Id, Name? } CanvasProvider: CanvasProviderIdentity? canvasProvider
Go CanvasProviderIdentity { ID, Name? } CanvasProvider *CanvasProviderIdentity canvasProvider
Python CanvasProviderIdentity(id, name?) canvas_provider: CanvasProviderIdentity | None canvasProvider
Java — intentionally deferred (see below)

All five implementations:

  • Use the same wire key canvasProvider with nested id / name
  • Omit name from the wire when absent (not serialized as null)
  • Cover both create_session and resume_session
  • Export CanvasProviderIdentity as a public type
  • Follow each language's naming conventions

Java gap (intentional)

Java is correctly deferred. The Java SessionConfig currently has no canvases, no extensionInfo, and no canvas handler — canvasProvider depends on that infrastructure. Tracking this as follow-up work is the right call.

Go ExtensionInfo forwarding fix (bonus)

The PR also fixes a pre-existing bug in Go's client.go where ExtensionInfo was declared on both the config and wire structs but silently never forwarded to the RPC payload. This fix is well-placed here and the new test (assertCanvasProviderForwarded) validates both fields together.

No cross-SDK inconsistencies found

The implementation is well-aligned across all five SDKs. No changes needed to other SDKs beyond the acknowledged Java gap.

Generated by SDK Consistency Review Agent for issue #1847 · sonnet46 1.5M ·

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