feat: support optional message provenance across all SDKs - #2564
Conversation
Expose optional source in all six high-level SDK send APIs and preserve it through cloning and send-and-wait paths. Add a handwritten Rust typed-RPC builder, wire regressions, local runtime coverage, and documentation of acknowledgement and reply semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
SDK Consistency ReviewReviewed PR #2564, which adds an optional message provenance Result: ✅ Consistent across all six SDKs.
Observations:
No API naming or behavioral inconsistencies found. Nice job keeping this feature addition uniform across the entire SDK surface.
|
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation consistently forwards and omits provenance as specified, with comprehensive cross-SDK regression coverage.
Review tier: Balanced
Findings: None
What changed in this PR
Exposes optional message provenance across all six SDKs while preserving existing send behavior.
Changes:
- Adds
sourceto high-level send APIs and Rust typed RPC. - Preserves source through cloning and send-and-wait paths.
- Adds cross-language serialization, omission, delivery-mode, and runtime tests plus documentation.
| File | Description |
|---|---|
rust/src/types.rs |
Adds source option and builder. |
rust/src/session.rs |
Forwards source to JSON-RPC. |
rust/src/rpc.rs |
Adds typed-request source builder. |
rust/tests/session_test.rs |
Tests Rust wire behavior. |
rust/tests/api_types_test.rs |
Tests typed request serialization. |
rust/tests/e2e/copilot_request_handler.rs |
Tests runtime propagation. |
python/copilot/session.py |
Adds source keyword forwarding. |
python/test_session.py |
Tests Python send paths. |
nodejs/src/types.ts |
Adds TypeScript source option. |
nodejs/src/session.ts |
Forwards source in requests. |
nodejs/test/session-source.test.ts |
Tests Node.js serialization. |
go/types.go |
Adds source fields. |
go/session.go |
Forwards source when sending. |
go/session_test.go |
Tests Go send paths. |
dotnet/src/Types.cs |
Adds cloneable source property. |
dotnet/src/Session.cs |
Serializes source in requests. |
dotnet/test/Unit/CloneTests.cs |
Tests source cloning. |
dotnet/test/Unit/ClientSessionLifetimeTests.cs |
Tests .NET send behavior. |
java/sdk/src/main/java/com/github/copilot/rpc/MessageOptions.java |
Adds source accessors and cloning. |
java/sdk/src/main/java/com/github/copilot/rpc/SendMessageRequest.java |
Adds wire source field. |
java/sdk/src/main/java/com/github/copilot/CopilotSession.java |
Copies source into requests. |
java/sdk/src/test/java/com/github/copilot/MessageSourceTest.java |
Tests Java provenance behavior. |
docs/features/steering-and-queueing.md |
Documents provenance semantics. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Closing this PR to avoid competing implementations while consolidating the agent-provenance work on top of #2550. The original implementation remains preserved on this branch. The follow-up will retain the needed identified-agent support, regression coverage, and documentation; #2550 alone does not yet cover that agent provenance requirement. #2563 remains open. The choice of a stacked or replacement PR is still pending. |
|
Consolidation is now complete in #2573, merged into main. It incorporates the typed user/system API from #2550 and adds identified-agent sources, regression coverage, and documentation. This PR remains closed as the earlier alternative implementation. SDK completion and downstream integration status are tracked in #2563. |
Summary
Fixes #2563.
Expose the runtime's existing
sourcefield through the high-level send APIs in all six SDKs. This lets applications forward agent-originated messages without losing their provenance.Motivating application failure
In the GitHub Copilot app, an orchestrator can receive a child-agent status update that needs no visible acknowledgement. A successful completion without assistant text or tool calls can nevertheless produce
No response was returned. Send your message again to retry.and mark the session as needing input. This pressures agents to produce unnecessary replies and encourages resending messages that were already accepted.The investigation confirmed successful empty completions being converted into errors when cross-session messages lacked structured sender provenance. It did not establish that every empty completion was intentional. Existing runtime behavior permits silent completion for agent-sourced turns; sender information in prompt text does not supply that provenance.
This PR is the SDK prerequisite, not the complete application fix. The app must also pass trusted sender source through its send and retry paths and handle resulting events correctly. Source identifies origin, not a general must-reply flag, and genuine human-turn errors must remain distinguishable.
API changes
MessageOptions.sourcesource=onsendandsend_and_waitMessageOptions.Source *stringMessageOptions.SourceMessageOptions.getSource()/setSource(...)MessageOptions.source/with_source(...), plus handwrittenrpc::SendRequest::with_source(...)Source is omitted when unset and forwarded unchanged when supplied. Clone and send-and-wait paths preserve it. Billing, delivery modes, attachments, display prompts, tracing, and correlation defaults remain unchanged. Generated files, schema visibility, dependencies, and CLI pins are untouched.
The shared steering documentation distinguishes provenance, delivery urgency, and response expectations. A successful high-level
sendacknowledgement returns a message ID and confirms acceptance, not recipient consumption. An accepted message should not be automatically resent merely because no visible reply appears.Validation
Targeted validation completed locally on macOS arm64:
session-source.test.tsandsession-send-and-wait.test.ts; typecheck, declaration emission, ESLint, and Prettier passedtest_session.py; Ruff and ty passedgo vet .passedmvn verify -pl sdk -Pskip-test-harness -Dtest=MessageSourceTest,MessageAttachmentTest,ConfigCloneTest -DskipITs: 60 tests passed, including 16 provenance tests covering both delivery modes; Checkstyle, scoped Spotless, and Java 25 overlay verification passedsession_testandapi_types_test; all test targets compiled; all-target Clippy, formatting, and rustdoc passedThe Rust local-runtime regression also executed against official standalone Copilot CLI 1.0.83. Its eight cases cover high-level and typed-RPC sends, enqueue and immediate delivery, and supplied and omitted source. The test uses synthetic inference and verifies the resulting
user.messageprovenance and correlation.Fresh code-review passes found no significant issues in the final six-language change set. The subsequent documentation-only acknowledgement clarification was reviewed separately.
Limits
Full E2E suites and cross-platform execution were not run locally. The new non-Rust regressions exercise request serialization and loopback transport, not live model sessions.
This is SDK passthrough, not an end-to-end remote-provenance guarantee. Mission Control currently accepts and locally echoes source but drops it from remote HTTP delivery. No remote transport redesign or consumer-app integration is included.