Expose local cross-session discovery and delivery - #2616
dfrysinger wants to merge 9 commits into
Conversation
Add a hand-written typed `Session::admit_authenticated_cross_session_input` for the runtime's private direct-host-only `session.lifecycle.admitAuthenticatedCrossSessionInput` method. The public request types carry only caller-variable fields; the wire `version`, `kind`, `origin`, and `integrity` discriminators are stamped by private wire types during request conversion. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b6a7c90-1ad5-47e3-83a3-a87b895fb13c
Add session-bound Node and Rust SDK operations for listing active local peers and sending an exact-ID message through the runtime contract. Preserve typed refused, not-delivered, and ambiguous outcomes without retrying an uncertain delivery. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Generated by SDK Consistency Review Agent for #2616 · copilot · sonnet50 · 110.6 AIC · ⌖ 13.3 AIC · ⊞ 8.3K
| /// [`Client::call`](crate::Client::call)). If the caller's future is | ||
| /// dropped after the frame is enqueued, the admission still lands and | ||
| /// the runtime processes it normally. | ||
| pub async fn admit_authenticated_cross_session_input( |
There was a problem hiding this comment.
Cross-SDK consistency: admit_authenticated_cross_session_input (backed by session.lifecycle.admitAuthenticatedCrossSessionInput, plus the new CrossSessionInput/CrossSessionPresentation/CrossSessionRecipientContext types) is added only to the Rust SDK. Since this is documented as usable by "a host embedding the SDK in-process (or over the direct local transport)", Node.js hosts embedding the SDK in-process would plausibly want the same capability, but no equivalent was added to nodejs/src/session.ts in this PR. If this omission is intentional (e.g., Node hosts don't embed the runtime the same way), consider noting that in the PR description; otherwise this looks like a parity gap worth tracking for the Node SDK, and eventually Python/Go/.NET/Java if this capability becomes broadly useful.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved critical code-generation, compatibility, re-export, and API-boundary issues remain.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 2
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
rust/src/session.rs — Keep the private admission producer out of the public API |
|
rust/src/types.rs — Preserve the public rpc type import path |
What changed in this PR
Adds local cross-session discovery and exact-target delivery APIs for Node and Rust, with source binding, typed delivery errors, and authenticated admission.
Changes:
- Adds generated and high-level discovery/delivery APIs.
- Adds authenticated admission models and typed terminal errors.
- Updates bindings, exports, code generation, and focused tests.
| File | Summary / review notes |
|---|---|
scripts/codegen/typescript.ts |
Ensures bound source session IDs override caller parameters. |
rust/tests/session_test.rs |
Tests admission, discovery, delivery, and failure outcomes. |
rust/src/types.rs |
Adds admission models and wire conversion. Critical (1 vote): preserve the public github_copilot_sdk::rpc::PermissionDecisionSource facade. Nit (1 vote): use an explicit named conversion instead of From. |
rust/src/session.rs |
Adds Rust discovery, delivery, and admission APIs. Critical (2 votes): keep authenticated admission behind an internal host adapter. Nit (1 vote): add experimental notices to the public methods. |
rust/src/lib.rs |
Preserves structured RPC error data. |
rust/src/generated/session_events.rs |
Adds cross-session event types and fields. Critical (1 vote each): preserve the stable permission-source re-export and apply compatibility protection such as #[non_exhaustive] to extended public event structs. |
rust/src/generated/rpc.rs |
Adds generated Rust RPC methods. |
rust/src/generated/api_types.rs |
Adds generated request and result types. |
rust/src/errors.rs |
Adds typed delivery error variants. |
nodejs/tsconfig.test.json |
Updates test TypeScript configuration. |
nodejs/test/session-send-session-message.test.ts |
Tests delivery and terminal error behavior. |
nodejs/test/session-list-messageable-sessions.test.ts |
Tests discovery and source binding. |
nodejs/src/types.ts |
Exposes cross-session types. |
nodejs/src/session.ts |
Adds Node discovery, delivery, and typed errors. Nit (1 vote): document targetSessionId explicitly. |
nodejs/src/index.ts |
Exports new public Node APIs. |
nodejs/src/generated/session-events.ts |
Adds generated cross-session event types. |
nodejs/src/generated/rpc.ts |
Adds generated cross-session RPC bindings. Critical (1 vote): regenerate all schema-derived language outputs or explicitly change the generation contract, since the shared codegen check currently lacks corresponding Python, Go, and .NET definitions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| pub async fn admit_authenticated_cross_session_input( | ||
| &self, | ||
| request: AdmitAuthenticatedCrossSessionInputRequest, | ||
| ) -> Result<(), Error> { |
| PermissionDecisionReject, PermissionDecisionSurface, PermissionDecisionUserNotAvailable, | ||
| PermissionResponseCapability, | ||
| }; | ||
| pub use crate::generated::session_events::PermissionDecisionSource; |
Define unreleased discovery and delivery wire types in the SDK facade while leaving generated bindings reproducible from the pinned CLI schema. Replace unreachable compile assertions with callable type checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
This reverts commit dc77d92.
This comment has been minimized.
This comment has been minimized.
|
The official GitHub Copilot App consumer is now open: https://github.com/github/github-app/pull/15507\n\nThese PRs align Runtime, SDK, and App on one public local cross-session messaging protocol. The App vendors SDK commit d8aaeed and proves bidirectional local App/CLI delivery without remote control or remote session export. |
|
Thanks for iterating on this. Three things to resolve before this is ready for review:
I'm moving this to draft until the runtime dependency lands and the SDK surface (and its tests) can be built against real runtime behavior. Please mark it ready for review once that's true. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
Preserve the Node and Rust cross-session messaging APIs while adopting current SDK main, including the new Runtime host and model allowlist coverage. Remove a stale source-text assertion after upstream moved session wrappers out of generated RPC code; behavioral source-binding coverage remains. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
This comment has been minimized.
This comment has been minimized.
Preserve session-bound cross-session messaging APIs while adopting the current generated SDK surfaces and generalized Rust RPC error data. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea23a388-a87d-436d-8110-4f7f543141d6
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Generated by SDK Consistency Review Agent for #2616 · copilot · sonnet50 · 38.3 AIC · ⌖ 11.8 AIC · ⊞ 8.1K
| */ | ||
| enableSessionStore?: boolean; | ||
|
|
||
| /** | ||
| * Whether this session participates in local cross-session messaging | ||
| * discovery and delivery. Defaults to true when omitted. | ||
| */ |
There was a problem hiding this comment.
New enableCrossSessionMessaging config option is added here (and in Rust's SessionConfig/ResumeSessionConfig), but not in Python, Go, .NET, or Java. If this feature is intended for all SDKs, consider adding the equivalent option (enable_cross_session_messaging in Python, EnableCrossSessionMessaging in Go/.NET, enableCrossSessionMessaging in Java) to keep config surfaces in parity, similar to the existing enableSessionStore option present in all six SDKs.
| return (response as { messageId: string }).messageId; | ||
| } | ||
|
|
||
| /** | ||
| * Lists active local sessions that this bound session can select by exact | ||
| * ID for cross-session messaging. The result grants no delivery authority; | ||
| * call {@link sendSessionMessage} with a selected `sessionId`. | ||
| * | ||
| * @experimental | ||
| */ | ||
| async listMessageableSessions( | ||
| params: ListMessageableSessionsRequest = {} | ||
| ): Promise<ListMessageableSessionsResult> { | ||
| return this.connection.sendRequest("session.listMessageableSessions", { | ||
| ...params, | ||
| sessionId: this.sessionId, | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Sends one authenticated non-user message from this bound session to an | ||
| * exact active local session. | ||
| * | ||
| * Success reports recipient admission, not completion of delegated work. | ||
| * An ambiguous error means delivery may have started and is never retried. | ||
| * | ||
| * @experimental | ||
| */ | ||
| async sendSessionMessage(params: SendSessionMessageRequest): Promise<SendSessionMessageResult> { | ||
| try { | ||
| return await this.connection.sendRequest("session.sendSessionMessage", { | ||
| ...params, | ||
| sessionId: this.sessionId, | ||
| }); | ||
| } catch (error) { | ||
| if (error instanceof ResponseError) { | ||
| const translated = parseSendSessionMessageErrorData(error.data); | ||
| if (translated) { | ||
| throw new SendSessionMessageError( | ||
| translated.code, | ||
| error.message, | ||
| translated.messageId | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
New listMessageableSessions() / sendSessionMessage() methods (mirrored in Rust's Session::list_messageable_sessions / Session::send_session_message) introduce a new cross-session-messaging API surface. This is not yet present in Python, Go, .NET, or Java. Consider tracking follow-up work to add equivalent methods (list_messageable_sessions/send_session_message for Python/Rust conventions, ListMessageableSessions/SendSessionMessage for Go/.NET, listMessageableSessions/sendSessionMessage for Java) with the same request/result shapes and SendSessionMessageError (refused/not-delivered/ambiguous) error taxonomy for full feature parity.
SDK Consistency Review — PR #2616This PR adds a new cross-session messaging feature (session-to-session message delivery and discovery) plus its supporting
I confirmed (via repo-wide search) that no equivalent APIs or config flag exist yet in Python, Go, .NET, or Java — no Suggested follow-ups
If cross-session messaging is intentionally being rolled out CLI-first or Node/Rust-first (e.g., behind an experimental flag, as the Everything else in this PR (the
|
There was a problem hiding this comment.
Generated by SDK Consistency Review Agent for #2616 · copilot · sonnet50 · 45 AIC · ⌖ 12 AIC · ⊞ 8.1K
| * | ||
| * @experimental | ||
| */ | ||
| async listMessageableSessions( |
There was a problem hiding this comment.
New cross-session messaging API (listMessageableSessions / sendSessionMessage) is added here for Node.js and mirrored in Rust (rust/src/session.rs), but I could not find equivalent methods in Python, Go, .NET, or Java. If this feature should have parity across all six SDKs (as enableSessionStore and other session-scoped methods do), please add list_messageable_sessions/send_session_message-style methods to those SDKs, or note that this is an intentional Node/Rust-first rollout.
| * Whether this session participates in local cross-session messaging | ||
| * discovery and delivery. Defaults to true when omitted. | ||
| */ | ||
| enableCrossSessionMessaging?: boolean; |
There was a problem hiding this comment.
enableCrossSessionMessaging is added to the Node.js session config and mirrored in Rust (SessionConfig::enable_cross_session_messaging / ResumeSessionConfig::enable_cross_session_messaging), but no equivalent flag exists yet in Python, Go, .NET, or Java session configs. Consider adding it to the remaining SDKs for parity, similar to how enableSessionStore is implemented everywhere.
| /// The runtime derives the source identity from this bound session. Pass | ||
| /// `None` to list all messageable sessions or a request containing an | ||
| /// exact-name filter. Discovery grants no delivery authority. | ||
| pub async fn list_messageable_sessions( |
There was a problem hiding this comment.
Rust adds list_messageable_sessions/send_session_message here, matching the new Node.js API in nodejs/src/session.ts. This new cross-session messaging feature (and its enable_cross_session_messaging config flag) currently only exists in Node.js and Rust — Python, Go, .NET, and Java don't have equivalents yet. Worth tracking as a follow-up for the other four SDKs if this isn't an intentional staged rollout.
|
Superseded by https://github.com/github/copilot-agent-runtime/pull/19586. Runtime now owns the canonical |

Summary
Runtime dependency
This SDK surface consumes the local transport, provenance, target-claim, and recipient-admission contract in github/copilot-agent-runtime#19586. The runtime owns wire security and recipient admission. The SDK exposes only source-bound discovery and delivery so CLI and App consumers do not implement separate local protocols. Same-computer discovery and delivery do not require remote control or remote export.
The unreleased discovery and delivery wire types live in the hand-written SDK facades until the runtime schema reaches the SDK pinned CLI release. Generated files remain reproducible from that pinned release.
Companion integration
Validation