Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[WIP] Node SDK canvas launch admission and retention - #2637

Draft
ulugbekna wants to merge 3 commits into
mainfrom
ulugbekna/canvas-sdk-bindings
Draft

[WIP] Node SDK canvas launch admission and retention#2637
ulugbekna wants to merge 3 commits into
mainfrom
ulugbekna/canvas-sdk-bindings

Conversation

@ulugbekna

@ulugbekna ulugbekna commented Sep 12, 2026

Copy link
Copy Markdown

Summary

Experimental Node-only SDK bindings for hosts embedding canvas extensions:

  • Attach a typed, connection-owned extensionLaunchProvider before the RPC handshake, and require { contractVersion: 1 } before create/resume. Unsupported negotiation fails closed; omitting the option preserves legacy launching.
  • Expose client.rpc.session.retain({ sessionId }) and session.rpc.retain() with exact null acknowledgements and the session.retained event. Global retention works while create is pending, without manufacturing a conversation turn.
  • Forward enableScriptSafety in initial create/resume requests, before newly initialized extension work.
  • Make teardown idempotent before registration and under overlapping request/connection cancellation, preserving synchronous resolver entry/error identity and rejecting late grants or stale acknowledgements.

Includes generated bindings, public exports, loopback regressions, and documentation. Cross-language high-level parity is a separate follow-up, as noted by the consistency review; generated wire types or an older launch-provider API in another SDK do not imply these semantics.

Reproducible schemas and source provenance

The initial P1 source candidate started at dcfbb93859bea38837234a6dd82b64d545f32624, with the reviewed B2 initial-safety and B3 cancellation refinements. P2 merges actual main f45c46fd1812f8bed5b4cbc250f47177c83068f0 through signed merge 954f6bc86ef846a45112192977b105e8d72fdbca, preserving both upstream FFI and canvas test typechecking. The source package remains 0.0.0-dev; CLI 1.0.84-5 is inherited from main, not a fabricated compatibility pin.

Commit 861f7794257745126c03bff5ade9070de4a65646 fixes the actual Codegen Check failure rather than leaving it as a draft gate. The default Node generator now combines the checksum-verified pinned release schemas with scripts/codegen/experimental/canvas.schema.json. This checked-in input contains exact reviewed canonical producer fragments, producer schema hashes, and released predecessor fingerprints. A field must match the recorded predecessor or already match the reviewed target; unexpected release changes fail generation instead of being silently overwritten. Release inputs are not modified, explicit schema arguments remain complete caller-supplied inputs, and the other SDK generators remain on the release schema.

The ordinary all-language npm run generate, followed by the repository's existing pinned nightly formatting step, now reproduces the committed files with a clean working tree. No CI check, workflow selection, dependency graph, or runtime capability negotiation was disabled or weakened. The P2-authored generated differences are provenance headers and declaration/method ordering, not new launch/retention wire types or operation bodies.

This source PR is not the separate @github/[email protected] + B3 image adopted by the VS Code integration. That source-built backport starts at f13e4a2cc7e4e220974d2333142234e162a3252e and retains CLI pin 1.0.83. Its frozen source/package/native receipts and installed carrier are unchanged. No P2 carrier backport is needed for the generator-only remediation. Earlier P1/B3/native evidence is not relabeled as execution of P2.

Validation boundary

Fresh P2 source/build validation on macOS arm64, Node 24.18.0:

  • 125 focused cases covering schema revision drift/idempotence/isolation, TypeScript generation, public launch admission, initial safety forwarding, retention, and FFI lifecycle; separate merge-time shutdown coverage also passed.
  • Implementation/test and new codegen-module typechecks; existing formatting, lint, and ESM/CJS/declaration build.
  • Ordinary all-language generation plus the existing nightly formatting step, including a post-commit clean-worktree reproduction.
  • Two strict public-package loopback runs, ESM and CommonJS, with 24 grouped cases each against [email protected]: pending-create retention, early permissions, failed startup, repeated teardown/disconnect, original errors, overlapping cancellation, and no late-grant reuse.

GitHub checks run against the latest pushed head. Local P2 qualification does not claim a new native/platform/source/model-resume matrix. Prior separately labeled compatible-runtime counter/SSE, retention/cold-resume/offline-domain persistence, and startup-negative receipts remain distinct. Final native OSS integration is consumer-owned.

Runtime and policy limits

Reproducible generated bindings do not make the experimental runtime contract available in the pinned release. A compatible runtime must still implement launch-v1 acknowledgement, retention, and initial script-safety configuration; an older runtime is rejected on explicit admission opt-in. Runtime review/release and qualification of a supported SDK/runtime pair remain separate release work.

The required order is source approval, successful retention, then an approved launch recipe. Top-level extension effects can precede joinSession or canvas open; create/resume completion is not canvas-registry readiness.

The compatible runtime keeps a disconnected launch-provider connection authoritative. Same-runtime replacement may be refused; the SDK propagates that refusal rather than bypassing ownership. An SDK-owned runtime restart permits fresh negotiation.

enableScriptSafety: true enables read-only shell-command classification under runtime/managed policy, not a policy override, blanket tool approval, or extension sandbox. It is not retroactive protection for running work. The setting is in-memory: cold omission defaults to classification disabled, while resident omission preserves the current value. Hosts requiring it must explicitly set true before each create/cold resume.

This remains a WIP draft; no PR merge, package release, installed-consumer change, or feature enablement is included.

Attach the connection-owned launch provider before handshake and require
an explicit v1 acknowledgement before session creation or resume.
Expose global and scoped no-turn retention with canonical null results,
and forward initial script-safety configuration before new extension work.

Make cancellation teardown safe before registration and under overlapping
request/connection cancellation, preserving synchronous resolver errors.
Add focused public loopback coverage and document runtime/release limits.

Co-authored-by: Copilot App <[email protected]>
Preserve both upstream FFI lifecycle test typechecking and the canvas
launch-provider regressions when reconciling the test configuration.
Inherit main's released CLI 1.0.84-5 pin and generated updates unchanged.

Co-authored-by: Copilot App <[email protected]>
@github-actions

This comment has been minimized.

@github-actions github-actions Bot 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.

Generated by SDK Consistency Review Agent for #2637 · copilot · sonnet50 · 85.3 AIC · ⌖ 12.5 AIC · ⊞ 8.3K

Comments that could not be inline-anchored

nodejs/src/types.ts:2611

enableScriptSafety is added here for Node.js session config, and the underlying wire field already exists in the generated RPC types for Go, .NET, Python, Java, and Rust. However, none of those SDKs expose it on their public session-open/resume option types yet (e.g. go/types.go SessionOpenOptions, dotnet/src/Types.cs, python/copilot/client.py kwargs, java/sdk/.../SessionConfig.java + SessionRequestBuilder, rust/src/types.rs). Consider a follow-up to wire this through the other SDKs…

nodejs/src/client.ts:520

The new extensionLaunchProvider connection option (with contractVersion-gated registration, session.retain, cancellation-token propagation, and explicit launch: null deny semantics) is only exposed here in Node.js in this PR. Rust already has an earlier equivalent (ClientOptions::with_extension_launch_provider) but does not yet include these new capabilities, and Go/.NET/Python/Java have no public API surface for registering a launch provider at all (only generated RPC types). If this c…

Check in the reviewed experimental schema fragments and their exact
released predecessor fingerprints. Apply them in ordinary Node codegen
without modifying release inputs or overriding an unexpected new contract.
Keep explicit schema inputs and the other SDK generators unchanged.

Add regression coverage for revision drift, idempotence, source isolation,
and retained-event insertion. Document the Node-only experimental scope
and preserve the compatible-runtime negotiation and release requirements.

Co-authored-by: Copilot App <[email protected]>
@github-actions

Copy link
Copy Markdown
Contributor

SDK Consistency Review — PR #2637

This PR touches Node.js only (nodejs/src, nodejs/test, nodejs/README.md, plus the shared scripts/codegen/ typegen used to generate Node bindings, and an experimental canvas schema revision). No other language SDK source files (python/, go/, dotnet/src/, java/sdk/src/main/, rust/src/) are modified by this PR.

Two features are added exclusively to the Node.js high-level API:

  1. extensionLaunchProvider (connection-owned extension launch admission, contract-version-1 registration, session.retain(), cancellation-token support). The wire-level RPC shapes already exist in generated code for all six SDKs, and Rust already has a partial hand-written implementation (rust/src/extension_launch_provider.rs, ClientOptions::with_extension_launch_provider), but Rust's version predates and doesn't include the new sessionId/defaultLaunch resolve-request fields, the ExtensionLaunchProviderRegistrationResult contract-version acknowledgement, or cancellation support that Node now has. Go, .NET, Java, and Python have no high-level exposure of this feature at all.
  2. enableScriptSafety on SessionConfig/ResumeSessionConfig. The underlying wire field (SessionOpenOptions.enableScriptSafety) already exists in generated code for every SDK (from an earlier CLI pin update), but only Node.js now threads it through its high-level session-creation API.

The PR's own README changes are explicit that this launch-admission surface is "currently Node-only" and that "High-level parity in the other SDKs is a separate follow-up" — so this divergence appears intentional and scoped deliberately. I've left two inline review comments flagging the specific gaps (extension launch provider parity, and the simpler enableScriptSafety passthrough) for tracking, in case a follow-up issue should be filed for the other five SDKs.

No naming/design inconsistencies were found within the Node.js changes themselves — the added APIes follow existing SDK conventions (camelCase, optional fields, @experimental tagging).

Generated by SDK Consistency Review Agent for #2637 · copilot · sonnet50 · 126.1 AIC · ⌖ 12.5 AIC · ⊞ 8.3K ·

@github-actions github-actions Bot 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.

Generated by SDK Consistency Review Agent for #2637 · copilot · sonnet50 · 126.1 AIC · ⌖ 12.5 AIC · ⊞ 8.3K

Comment thread nodejs/src/types.ts
Comment thread nodejs/src/types.ts
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.

1 participant