Skip to content

Providers and Agents ja

Hermes Agent edited this page Oct 1, 2026 · 1 revision

プロバイダとエージェント

English | 中文 | 日本語 | 한국어 | Español | Português | Русский

4 つのワイヤプロトコル(apiStyle)

lib/llm-client.js がプロトコル層。4 つのストリームはすべて 1 つの openSseStream() 骨格を共有する(fetch / エラー分類 / バジェット交渉 / 中断 / SSE フレーミング / 後処理)。各プロトコルが持つのは buildRequest + 純粋なイベントパーサだけ。SSE data: ペイロードの抽出は単一ソース(sseDataPayload、仕様どおりの複数 data 行の結合):

apiStyle エンドポイント 備考
chat /v1/chat/completions DeepSeek 流の reasoning_content もパースする
responses /v1/responses ネイティブの input_* マルチモーダル綴り
anthropic /v1/messages 2 つのブレークポイント(system + 最終メッセージ)に明示的な cache_control — Anthropic には暗黙のプレフィックスキャッシュがない
runs Hermes /v1/runs エージェントプロトコル: 承認 / clarification / ツール / thinking イベント

thinking: 'inline' | 'omit'(デフォルトは omit)は、推論テキストを delta ストリーム内の 1 つの <thinking> ブロックにインラインで乗せるかどうかを制御する。インラインを使うのはメインチャットとディテールスレッドだけ。runs の reasoning.available フィールドは回答のリプレイであって thinking ではない — エコーガードがこれを落とすのは正しい(ADR-0004)。

ターンリクエストのラダー

メインチャットでは、プロバイダ毎のリクエスト形状が 4 回再構築される(初期 / オーバーフロー再構築 / 継続 / タイムスタンプ書き換え)。これは createTurnRequest(prepare / rebuildFrom / continueWith / rewriteWith)として統一された — chat-handler が WHEN を持ち、ラダーが HOW を所有する。ディテールスレッドは意図的にこれを使わない(隔離セッションのセマンティクス、ADR-0007)。

出力バジェットと切り詰め

  • デフォルトの max_tokens は 32768。上限超えのバジェットを 400 で「拒否」するサーバには、エラーテキストから上限をパースして renegotiateOutputCap のリトライを 1 回与える。
  • finish_reason === 'length' → 1 回だけ無言の継続パス(反復防止の指示、delta は握りつぶす)。それでも切り詰められたら、DONE が outputTruncated を運び、パネルがトースト + ワンクリックの「続きへ」ボタンを出す。手動の max_tokens フィールドは意図的に存在しない — 「モデル毎の知識を要するノブは設計バグ」。

4 つのエージェント

エージェント チャネル セッション
Hermes /v1/runs サーバ側(sessionId をストレージに保存)。現ターンのパートは正規の text/image_url を使い、conversation_history は文字列のみ(strict 層の 422、2026-09-24 検証済み)
OpenCode opencode serve HTTP サーバ側。デフォルトはランダムポート → 固定 --port を推奨
OpenSquilla ローカルゲートウェイ ws://…/ws 会話毎に 1 ゲートウェイセッション。6 万文字超の添付は page-context.md ドキュメントとしてアップロード。オリジン許可リスト — セキュリティモデル参照
Agent Bridge @xiaohuzai/agent-bridge ローカルデーモン 1 つの HTTP プロトコルの背後で codex/claude/pi/gemini をアダプト。サブスクリプションのログインがモデルソースとして機能

共有層は lib/agent-turn.js: エージェントターンが送るのはユーザーの現ターン + 末尾のページコンテキスト実行「だけ」(トランスクリプトはサーバ側に置かれる。履歴の再送は決してない)。画像は pickTurnImages を通る(8 枚以下 / 3MiB 以下の URL バジェット。添付時と送信時のゲートが互いをミラーする)。会話の途中でエージェントプロバイダへ切り替えると「带上当前对话继续」が提示される = 1 回限りの backfill(プレーンテキストのトランスクリプト、末尾 20 万文字上限)。

クロスエントリのハンドオフ: エージェント側セッションの命名と ID(2026-10-01)

エージェントプロバイダではトランスクリプトはすでにサーバ側に置かれている(エージェントターンは現ターンだけを送る)— 「エージェント自身の UI に引き継がせる」ために要るのは、データ移動ではなく発見可能性。2 つの部品:

  • 自動命名: Hermes ターンの成功後、1 回限りの PATCH /api/sessions/{id}(上流オリジナル API。サーバがタイトルをサニタイズし、完全一致の衝突を拒否する)がタイトルを browsa: + 現ターンのユーザーテキストの最初の行(48 文字上限)に設定する。1 回だけスタンプするセマンティクス(hermesSessionTitled_<provider>、セッション id と同じライフサイクル): 成功も 4xx もスタンプする(タイトル衝突がターン毎のリトライループになってはならない)。トランスポート失敗(status 0)だけがスタンプされず、次の成功ターンへ持ち越される。PATCH は 10 秒でタイムアウトし、その await は 2.5 秒上限とレースするため、DONE が止まることは決してない。今日のチャネル: Hermes(PATCH /api/sessions/{id})と bridge/codex(デーモンの POST /threads/{id}/title → app-server の thread/name/set。codex 0.149.1 で実機検証 — 名前は codex の状態 DB に永続化され、codex resume は名前でも id でも解決する)。bridge 4 エージェントのピッカー可視性判定(ソース確認済み 2026-10-01): codex ✓(ピッカー述語は has_user_event = 1 AND title <> '' — 実ターンなら満たす。グローバルな状態 DB、cwd スコープなし。デーモンの POST /threads/{id}/title → app-server の thread/name/set で命名)。claude ✓ — bridge の transcriptFix: 'claude' が、確定したターンのたびにディスク上の自己スタンプされた entrypoint: sdk-* を cli に書き直すため(agent-bridge #56、Mac 確認済み)。クライアント側のリネームチャネルはなし(claude-agent-acp が自動命名する)。resume はピッカーからでも ID でも可能。pi ✓(ACP セッションは、ピッカーが読む pi 自身の cwd スコープ付きストアに入る。スコープトグル + 名前フィルタ。pi のネイティブ set_session_name RPC は session_info の名前エントリを書く — pi-acp はそれをターン内の /name コマンドとしてしか露出しておらず、bridge へはまだ配線されていない)。gemini ✓(リストが除外するのは kind:"subagent" だけ。bridge セッションは kind:"main"。ストアは ~/.gemini/tmp/<cwd>/chats/、cwd スコープ。命名チャネルなし — タイトルは最初のユーザーメッセージから来る)。opencode/squilla は未検証。ディテールスレッドの専用セッションは意図的に命名しない。)
  • セッション ID の表示: storage.getAgentSessionInfo が種類毎のセッションキー形状を単一所有する(bridge は activeModel || baseUrl でエンドポイント毎にキー)。セッションドロワーはリストの上に「Agent session」行(短い id + コピー)を描画する。LLM プロバイダ/セッションが存在しないときは非表示。

承認 / clarify リレー

エージェントのツール承認と clarification プロンプトは lib/handlers/approval-relay.js を経由して中継される(メインチャットは tabId キー、ディテールスレッドは subId キー)。ペンディングエントリの形状がディスパッチインターフェースそのもの。UI 側では、turn-chrome.js が両サーフェスで共有するターンクローム(待ちインジケータ、ツール進行、承認/clarify カード、使用量チップ)を担う。

プロバイダ選択 UI(確定済みの規則)

  • ドロップダウンが列挙するのは設定済みプロバイダだけ。到達可能なものが先(安定ソート)。設定がゼロなら無効化されたプレースホルダ 1 つ。
  • 保存された activeProvider が設定済みでなければ、最初の設定済みが自動選択「され、かつ」永続化される(設定変更ではなく状態修復)。最初に到達した ping も(1 回だけ)自動切替する。
  • マルチモデルプロバイダ: モデル ID をカンマ区切りで。モデル毎に 1 つのドロップダウン項目。resolveChatModel は、activeModel がそのプロバイダに属し続けている間だけそれを尊重する。
  • 両グループ(LLM / エージェント)はタブ付きカードとして描画される(エージェントグループはデフォルト折りたたみ。タブ順 [bridge, opencode, hermes] はテストでピン止め)。

CAPABILITY_HINTS の経済性(ADR-0010 — 縮小の再提案はしないこと)

すべての CHAT ターンのシステムプロンプト = ユーザーの systemPrompt + 返信言語の行 + CAPABILITY_HINTS + CHOICE_REQUEST_HINT。これはバイト安定のプレフィックスであり続けねばならない(ターン毎のキーワードゲートは、位置 0 から KV プロンプトキャッシュを壊す)。残っている各項目は、実際の描画バグで自分の価値を証明してきた — why 節を「整理」する前に、その AGENTS.md の履歴を読むこと。取りこぼしたフォーマットへの修正は、実行時検出ではなく「より良いヒント」。


権威版: Providers-and-Agents(英語) / Providers-and-Agents-zh(中文) — AI による初翻スナップショット、同期日 2026-10-01。

Clone this wiki locally