ADK-Rust エージェントを ACP 経由で公開する
エディターまたは別の ACP クライアントから ADK-Rust バイナリを起動し、コーディングインターフェース内でそのエージェントを使用する場合は、サーバー方式を使用します。Rust プロセスがエージェント、モデル、ツール、ワークフロー、セッション、メモリ、運用ポリシーを所有します。クライアントから見えるのは、ACP を通じて公開される機能とセッションのライフサイクルだけです。
サーバー機能をインストールする
[dependencies]
adk-acp = { version = "2.1.0", features = ["server"] }
エージェントをビルドして提供する
use adk_acp::server::{AcpServer, AcpServerConfigBuilder};
use adk_session::InMemorySessionService;
use std::sync::Arc;
let config = AcpServerConfigBuilder::new()
.agent(Arc::new(repository_agent))
.session_service(Arc::new(InMemorySessionService::new()))
.agent_name("repository-guide")
.agent_description("Explains and improves this Rust workspace")
.max_sessions(16)
.build()?;
let handle = AcpServer::run(config).await?;
handle.wait().await?;
サーバーは公式の SDK Agent ビルダーと stdio トランスポートを使用します。プロトコルのトラフィックのみが stdout に書き込まれるため、トレーシングと診断は stderr を使用するように設定してください。
ランタイムマッピング
ハンドラーは絶対 cwd を検証し、セッションの容量を確保し、ADK セッションを作成または再開して、設定されたエージェントを実行します。入力がアクティブな間、型付き ADK イベントは ACP session/update 通知に変換されます。
実装済みのライフサイクル
| ACP 操作 | ADK-Rust 動作 |
|---|---|
initialize | プロトコル v1 をネゴシエートし、正確な実装および機能メタデータを返します |
session/new | ワークスペースのパスを検証し、永続化された ADK セッションを 1 つ作成します |
session/prompt | 対応するコンテンツブロック(テキスト、リソースリンク、埋め込みリソース、画像、音声)を変換し、Runner をストリーミングします |
session/load | 永続化されたセッションを再アクティブ化し(cwd を検証)、完了前に保存された会話を順序付けられた session/update 通知として再生します |
session/cancel | アクティブな Runner の呼び出しをキャンセルし、キャンセルされた停止理由を返します |
$/cancel_request | セッションを破損させずに、一致する JSON-RPC リクエストをキャンセルします |
session/close | アクティブな処理をキャンセルし、セッション所有のプロセスを解放します |
session/list | 永続化された ACP から参照可能なセッションを一覧表示します |
session/resume | 元のセッションとワークスペースに再接続します |
session/fork | 永続化されたセッションを新しいセッション ID に分岐し、その履歴と関連する状態をコピーして、ソースは変更しません |
session/set_mode | エージェントのSessionControlsで宣言されたセッションモードを検証して記録し、CurrentModeUpdateを発行します |
session/set_config_option | エージェントのSessionControlsで宣言された設定値を検証して記録し、ConfigOptionUpdateを発行します |
session/delete | 永続化された履歴を削除し、アクティブなリソースを解放します |
1 つのセッションで同時に実行できるプロンプトは 1 つだけです。異なるセッションは、最大 max_sessions まで並行して実行できます。
イベントマッピング
- モデルのテキストは
agent_message_chunkになります。 - モデルの思考内容は
agent_thought_chunkになります。 - 埋め込みリソースの内容は ACP 埋め込みリソース
agent_message_chunkになります。 - ADK 関数呼び出しは、推論されたツール
kindを伴う ACP ツール開始更新になります。 - 関数のレスポンスは、結果の内容と影響を受けたファイルの場所で補足されたツール完了更新になり、元のツール呼び出しに対応付けられます。
- 使用量メタデータを含むイベントは
UsageUpdate通知(トークン数、および報告される場合は米ドルでのコスト)になります。 - エージェントが宣言したコマンドは、セッションがアクティブになると
AvailableCommandsUpdateになり、記録されたセッションタイトルはSessionInfoUpdateになります。 - 計画エントリは
Plan更新になります。このマッピングは存在しますが、ADK 計画プリミティブによって計画エントリが公開されるまで休止状態です。 - キャンセルは
StopReason::Cancelledになります。 - 正常な完了は
StopReason::EndTurnになります。
共有コンテンツモジュールは、ContentBlock ↔ adk_core::Part のマッピングを双方向で管理します。埋め込みリソースのプロンプトコンテンツは Part::EmbeddedResource にマッピングされ、元の URI、任意の MIME タイプ、コンテンツが保持されます。テキストリソースはそのまま保持され、バイナリリソースは通信時に base64 エンコードされ、内部では生のバイト列にデコードされます。画像および音声のプロンプトコンテンツは Part::InlineData にマッピングされ、MIME タイプ、デコードされたバイト列、アノテーション、画像の任意のソース URI が保持されます。これらのフィールドはセッション JSON に残り、session/load によって復元されます。プロンプトハンドラーは埋め込みリソース、画像、音声のコンテンツを受け付けるため、サーバーは embedded_context、image、audio のプロンプト機能を通知します。サーバーが通知していないコンテンツタイプを含むプロンプトは、部分的に処理されるのではなく、説明的なエラーとともに拒否されます。
読み込みと履歴の再生
session/load は、クライアントが再接続した際に、永続化されたセッションの表示可能な履歴を復元します。ハンドラーは session/resume と同じ方法でセッションを再アクティブ化します。つまり、呼び出し元が元の cwd を提供したことを検証し、不明な識別子に対してセッションが見つからないエラーを返します。その後、再生パスを実行します。セッションサービスを通じて永続化されたイベントを読み取り、保存されている各ユーザー、エージェント、思考、ツールのイベントを、それぞれ対応する session/update 通知に元の時系列順でマッピングしてから、読み込みリクエストを完了します。サーバーは load_session 機能を通知するため、クライアントは再接続して会話ビューを再構築できることを認識できます。
セッションモード、設定オプション、フォーク
エージェントは、AcpServerConfigBuilder::session_controls を通じて SessionControls
プロバイダーを提供することで、対話型セッション制御を有効にします。プロバイダーは、
利用可能なモード(SessionModeState)、設定オプション(選択項目と
切り替え項目)、および ACP スラッシュコマンドを宣言します。サーバーはプロバイダーが
宣言した内容をそのまま通知します。つまり、プロバイダーのないエージェントはモードもオプションも通知せず、
それらを session/new、session/load、session/resume、および
session/fork レスポンスで提供します。
session/set_mode は要求されたモード ID を通知済みの集合と照合して検証し、
それを記録して CurrentModeUpdate を発行します。不明な ID は拒否され、
現在のモードは変更されません。session/set_config_option は値をオプションに
宣言された選択肢と照合して検証し、それを記録して
ConfigOptionUpdate を発行します。不明なオプションや無効な値は拒否されます。どちらの
選択も ADK セッション状態内の acp:mode および acp:config:<id>
に保持されるため、読み込み、再開、フォークの後も維持されます。
session/fork は保持されたセッションを分岐します。元のセッションを読み込み、
新しいセッション ID を作成し、保存されたイベントと関連する状態(cwd、追加の
ディレクトリ、モード、設定)を新しいセッションにコピーして、新しい ID を返します。元の
セッションの保持された履歴は、バイト単位で変更されません。不明なセッション識別子を指定した
フォークは、セッションが見つからないエラーを返します。ハンドラーが登録されているため、サーバーは
fork セッション機能を通知します。
セッションのアクティベーション時に、サーバーはプロバイダーが宣言したコマンドごとに
AvailableCommandsUpdate も発行します(コマンドを何も宣言していない場合は発行しません)。また、
acp:title にセッションタイトルが記録されている場合(set_session_title で設定)、
そのタイトルを含む SessionInfoUpdate を発行します。Plan 更新マッピングも
存在しますが、ADK プランプリミティブがプラン項目を提供するまで休止状態です。
クライアントが提供する MCP サーバー
クライアントは stdio MCP サーバーを session/new または session/resume に含めることができます。
サーバーはプロセスを起動する前に、名前、コマンド、引数、環境エントリを検証します。その後、次の処理を行います。
- 各子プロセスをセッションワークスペースで起動する;
- 制限付きの起動ハンドシェイクを適用する;
- 接続を ADK
McpToolsetとしてラップする; - その Runner 呼び出しにツールセットを注入する;
- 終了、削除、起動失敗、またはサーバーのシャットダウン時に MCP サービスをキャンセルする。
呼び出しスコープのツールセットは現在、LlmAgent および CodeActAgent によって解決されます。オプションの HTTP および SSE MCP トランスポートは、サーバーによって通知されません。
永続化に関する判断
InMemorySessionService は、ローカルエディタプロセスやテストに適しています。セッションをプロセスの再起動後も維持する必要がある場合は、永続的なサービスを使用してください。再開時には、呼び出し元が元の cwd を提供することが検証されます。セッションを別のプロジェクトに黙って再接続することはできません。
ツール承認の境界
サーバーは ADK のツール確認をネイティブの ACP 権限リクエストに橋渡しします。設定された agent がプロンプトターン中に ToolConfirmationRequest で一時停止した場合 — agent がツール呼び出しに対する人間の承認を待機しているときに event.actions.tool_confirmation で通知されます — サーバーはツールとその引数を記述した session/request_permission リクエストを送信し、クライアントの結果を待機してから、対応する判断で実行を再開します。承認は許可に、拒否またはキャンセルはいずれも拒否にマッピングされるため、キャンセルされたリクエストによってツールが実行されることはありません。各結果はその関数呼び出し識別子によって正確な呼び出しと関連付けられ、RunConfig::tool_confirmation_decisions を通じて runner に返されます。
ネストされた session/request_permission は、外側の session/prompt をすでに処理しているタスクから、ConnectionTo::spawn を通じて生成されます。そのため接続のディスパッチループをブロックせず、外側のプロンプト応答も完了します。公式の Rust SDK では、ネストされた双方向リクエストの後に外側のプロンプト応答が失われるという以前の懸念は、この一時停止・再開フローでは再現しません。このことはインメモリ相互運用性テストで確認されています。
サーバー所有のツール認可、読み取り専用ツール、RBAC、ガードレール、ワークフロー割り込みは、承認を完全に ADK-Rust プロセス内で行う必要がある場合でも引き続き利用できます。外部の ACP エージェント向けのクライアント側権限パスも完全に実装されています。
安全にデプロイする
- 意図したプロジェクトワークスペースでバイナリを起動します。
cwdと追加のルートは、OS の分離ではなくコンテキストとして扱います。- 信頼できないプロンプトやコマンドには、
adk-sandbox、コンテナ、または別のプロセス境界を適用します。 - モデルと MCP の認証情報は、クライアントのシークレットストアまたはプロセス環境に保持します。
- バナー、デバッグオブジェクト、ログをプロトコルの標準出力に書き込まないでください。
- 再開をプロセスの再起動後も維持する必要がある場合は、永続的な
SessionServiceを使用します。 - 有限のセッション制限を設定し、非アクティブなセッションを終了します。
実行可能な acp_server crate には、Gemini ベースのエージェント、ワークスペース内に制限された読み取りツール、標準エラー出力へのトレース、エディタープロセスの設定が含まれています。