github / github/copilot-sdk

Code-generate inbound (server→client) RPC dispatch for the Rust SDK

Đang mở
#1,764 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
enhancement
Ngôn ngữ chính
Java
Star
10.5k
Fork
1.5k
Merge trung bình
1 ngày 11 giờ
Pull request đã merge (30 ngày)
128

Mô tả

## 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 new `clientGlobal.*` (`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 the `clientGlobal` bucket in #1689 required teaching all four `scripts/codegen/*.ts` generators about it.
- **Rust** generates only the inbound **wire types** (`generated/api_types.rs`) and **method-name constants** (`rpc_methods::*` in `generated/rpc.rs`). The per-group **dispatch + handler trait** is hand-written, consistently, across all three inbound groups:
- `canvas.*` → `rust/src/canvas_dispatch.rs`
- `sessionFs.*` → `rust/src/session_fs_dispatch.rs`
- `llmInference.*` → `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:

1. **Do all three groups, not a one-off.** Rust's hand-written-dispatch convention is currently uniform across `canvas`, `sessionFs`, and `llmInference`. Generating only `llmInference` (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.

2. **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 dispatch `match` + method constants); the value is future-proofing and symmetry, not LOC.

3. **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` (read `clientSession` + `clientGlobal`), emitting into `rust/src/generated/`.
- [ ] Migrate `canvas_dispatch.rs`, `session_fs_dispatch.rs`, and `copilot_request_handler.rs` to implement/use the generated trait + dispatch instead of their hand-rolled `match` + 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 `clientGlobal` bucket 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`.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
rust, typescript
Lĩnh vực
api, backend-api-design, tooling
Loại issue
Tái cấu trúc
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.