Rust: ergonomic SamplingHandler + typed MCP sampling request on sampling.requested

オープン
#1,942 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
52/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
活発
技術スタック
rust

調査の方向性

rust/src/generated/session_events.rs と rust/src/handler.rs から始め、SamplingRequestedData と既存の handler traits を比較します。次に、rust/src/session.rs の session-builder の配線と、rust/src/generated/rpc.rs の sampling RPCs を追跡します。型付きの sampling request と登録済みの SamplingHandler が連携して動作し、既存の low-level methods も引き続き利用できれば完了です。

索引モデルが issue の本文から書いたものです。

説明

enhancement wishlist

Summary

The Rust binding exposes MCP sampling on the wire — the sampling.requested / sampling.completed events and the handle_pending_sampling (and execute_sampling / cancel_sampling_execution) methods — but there are two gaps for a consumer that wants to service MCP sampling requests itself (i.e. answer an MCP server's sampling/createMessage with its own model):

  1. The request content isn't on the typed event. SamplingRequestedData carries only { requestId, serverName, mcpRequestId } — not the MCP CreateMessageRequest params (the messages, modelPreferences, systemPrompt, maxTokens, etc.) that a handler needs to actually produce a completion. So a consumer receives "a sampling request happened" but not what to sample.
  2. There's no ergonomic handler. Every other consumer-serviced request has a first-class handler trait (PermissionHandler, ElicitationHandler, McpAuthHandler, UserInputHandler, …) wired on the session builder. Sampling has none — a consumer must subscribe to the raw sampling.requested event and call the low-level, Experimental handle_pending_sampling by hand.

Current state (public Rust binding)

  • rust/src/generated/session_events.rs:
    pub struct SamplingRequestedData {
        pub mcp_request_id: serde_json::Value,
        pub request_id: RequestId,
        pub server_name: String,
    }
    pub struct SamplingCompletedData { pub request_id: RequestId }
    
    No sampling request params (messages / model preferences) are present.
  • rust/src/generated/rpc.rs: handle_pending_sampling(UIHandlePendingSamplingRequest) -> UIHandlePendingResult, execute_sampling(...), cancel_sampling_execution(...) — all marked Experimental.
  • rust/src/handler.rs: ergonomic handler traits exist for permission, elicitation, MCP auth, user input, exit-plan-mode, auto-mode-switch — but not sampling.
  • rust/src/session.rs: those handlers are wired on the builder (e.g. mcp_auth_handler); there is no sampling equivalent.

Why this is needed

This is a developer-experience / completeness improvement for consumers that want to fulfill MCP sampling requests with their own inference instead of the default behavior. Today such a consumer:

  • can't get the request content from the typed event (has to reach past SamplingRequestedData), and
  • has to hand-wire the raw event + Experimental RPC instead of implementing one trait.

It is not a capability blocker (the low-level RPCs exist), so this is a quality-of-life ask, not urgent.

Proposed change

  1. Expose the MCP sampling request params on SamplingRequestedData as a typed field (the CreateMessageRequest params: messages, modelPreferences, systemPrompt, includeContext, maxTokens, temperature, stopSequences, metadata), so a handler can read what to sample directly from the event.
  2. Add an ergonomic SamplingHandler trait in rust/src/handler.rs mirroring McpAuthHandler:
    #[async_trait]
    pub trait SamplingHandler: Send + Sync + 'static {
        async fn handle(
            &self,
            session_id: SessionId,
            request_id: RequestId,
            request: SamplingRequest, // typed CreateMessageRequest params
        ) -> SamplingResult;          // completion, or None/err to reject
    }
    
    Wire it on the session builder alongside the other handlers, and have the binding translate the trait's result into the existing handle_pending_sampling call (and reject/cancel when the handler declines), so consumers never touch the raw event or the Experimental RPC directly.

Acceptance criteria

  • A consumer can register one SamplingHandler on the session builder and receive the typed MCP sampling request (messages + model preferences), returning a completion or a rejection.
  • The sampling request params are available as typed data (not only reachable via the untyped/low-level path).
  • The existing low-level handle_pending_sampling / execute_sampling methods continue to work for consumers that prefer them.

References

  • rust/src/handler.rs — existing handler-trait pattern (McpAuthHandler et al.) to mirror.
  • rust/src/generated/session_events.rsSamplingRequestedData / SamplingCompletedData.
  • rust/src/generated/rpc.rshandle_pending_sampling, execute_sampling, cancel_sampling_execution.
  • MCP spec — sampling/createMessage and its CreateMessageRequest params.
主要言語
Java
スター
10.5k
フォーク
1.5k
平均マージ
1日 12時間
マージ済み PR(30日)
133

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

github/copilot-sdk のほかの issue

github/copilot-sdk の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。