Code-generate inbound (server→client) RPC dispatch for the Rust SDK
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Refactor
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- rust, typescript
- Domain
- api, backend-api-design, tooling
Research direction
Start with scripts/codegen/rust.ts and compare inbound emission in scripts/codegen/{csharp,go,python,typescript}.ts. Then inspect rust/src/canvas_dispatch.rs, rust/src/session_fs_dispatch.rs, and rust/src/copilot_request_handler.rs, preserving the ergonomic traits and streaming bridge. Done means generated inbound traits and dispatch replace the hand-written matches while cargo build, clippy, and the full Rust e2e suite remain green.
Written by the indexing model from the issue text.
Description
Background
The SDK protocol has two directions of RPC:
- Outbound (client→server): the SDK calls into the runtime.
- Inbound (server→client): the runtime calls back into the SDK — e.g.
clientSession.*(canvas,sessionFs) and the newclientGlobal.*(llmInference) callbacks added in #1689.
For inbound dispatch, the four SDKs split into two camps:
-
C#, Go, Python, TypeScript code-generate the inbound handler scaffolding (handler interfaces + the dispatch/registration glue) from
api.schema.json. Adding theclientGlobalbucket in #1689 required teaching all fourscripts/codegen/*.tsgenerators about it. -
Rust generates only the inbound wire types (
generated/api_types.rs) and method-name constants (rpc_methods::*ingenerated/rpc.rs). The per-group dispatch + handler trait is hand-written, consistently, across all three inbound groups:canvas.*→rust/src/canvas_dispatch.rssessionFs.*→rust/src/session_fs_dispatch.rsllmInference.*→rust/src/copilot_request_handler.rs(dispatch)
Each follows the identical shape: prefix-check → match
rpc_methods::*constant → deserialize generated params → call the hand-written handler trait → serialize the result. -
Java has no codegen pipeline at all (entire RPC surface hand-authored), so it's out of scope here.
Proposal
Bring Rust to parity with the other generated SDKs by code-generating the inbound handler trait + dispatch helper per group into rust/src/generated/, so future inbound callbacks (new clientSession / clientGlobal groups) come for free, as they already do in C#/Go/Python/TS.
Why this is its own PR, not part of #1689
This was investigated during #1689 and deliberately deferred:
-
Do all three groups, not a one-off. Rust's hand-written-dispatch convention is currently uniform across
canvas,sessionFs, andllmInference. Generating onlyllmInference(the group #1689 touches) would trade Rust's internal consistency for cross-SDK symmetry and leave a confusing one-off. The clean change converts all three groups together — a cross-cutting refactor of shipped, well-tested dispatchers and their public trait surfaces (CanvasHandler,SessionFsProvider,CopilotRequestHandler), out of scope for a callbacks PR. -
Generate only the low-level wire trait; keep ergonomic traits + streaming bridges hand-written. The public
CopilotRequestHandler(send_request+open_websocket) does not mirror the wire methods (httpRequestStart+httpRequestChunk); ~1200 lines bridge frame-oriented streaming ↔ that 2-method seam with stateful exchange correlation. Codegen should emit only the thin wire-level trait + dispatch (mirroring what TS generates), with the ergonomic traits and the llmInference bridge staying hand-written. Net hand-written savings are small (≈ the dispatchmatch+ method constants); the value is future-proofing and symmetry, not LOC. -
Validation. The streaming handler is heavily covered by Rust e2e (cancel / error / session-id) record-replay tests that should gate the refactor in CI.
Suggested scope of work
- Add inbound handler-trait + dispatch emission to
scripts/codegen/rust.ts(readclientSession+clientGlobal), emitting intorust/src/generated/. - Migrate
canvas_dispatch.rs,session_fs_dispatch.rs, andcopilot_request_handler.rsto implement/use the generated trait + dispatch instead of their hand-rolledmatch+ local method-name constants. - Keep ergonomic public traits (
CanvasHandler,SessionFsProvider,CopilotRequestHandler) and the llmInference streaming bridge hand-written. - Verify
cargo build+ clippy + the full Rust e2e suite stay green.
References
- PR #1689 (LLM inference callbacks) — where the
clientGlobalbucket and the C#/Go/Python/TS generator changes landed. - Generators with inbound support:
scripts/codegen/{csharp,go,python,typescript}.ts(emitClientGlobalApiRegistration/emitClientSessionApiRegistration). - Rust generator (outbound only today):
scripts/codegen/rust.ts.
- Dominant language
- Java
- Stars
- 10.5k
- Forks
- 1.5k
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 130
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from github/copilot-sdk
-
agentic-workflows
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
github/copilot-sdk#2760 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
github/copilot-sdk#2759 ·
-
documentation
Difficulty 1/5 Under an hour Newbie friendliness 85/100
github/copilot-sdk#2758 ·
-
agentic-workflows
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
github/copilot-sdk#2709 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 78/100
github/copilot-sdk#2673 ·
All issues in github/copilot-sdk
Similar issues
-
documentation
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
inu-appcenter/memorIN-backend#288 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
frontend maui-pilot pilot-ask question
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
area/plugin
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
kestra-io/plugin-kestra#190 ·