コンテキスト
OpenClaw Gateway は現在、最小限の OpenAI 互換 Chat Completions エンドポイントを/v1/chat/completions で公開しています。詳細は OpenAI Chat Completions を参照してください。
Open Responses は、OpenAI Responses API をベースにしたオープンな推論標準です。エージェント型ワークフロー向けに設計されており、アイテムベースの入力と意味論的なストリーミングイベントを使用します。OpenResponses の仕様で定義されているのは /v1/responses であり、/v1/chat/completions ではありません。
目標
- OpenResponses のセマンティクスに準拠した
/v1/responsesエンドポイントを追加する - Chat Completions は、無効化しやすく、最終的に削除しやすい互換レイヤーとして維持する
- 独立して再利用できるスキーマにより、検証とパースを標準化する
非目標
- 初期フェーズで OpenResponses の全機能と同等にすること(画像、ファイル、ホスト型ツールを含む)
- 内部のエージェント実行ロジックやツールオーケストレーションを置き換えること
- 第 1 フェーズで既存の
/v1/chat/completionsの挙動を変更すること
調査の要約
参照元: OpenResponses OpenAPI、OpenResponses 仕様サイト、Hugging Face のブログ記事。 主な確認事項:POST /v1/responsesは、model、input(文字列またはItemParam[])、instructions、tools、tool_choice、stream、max_output_tokens、max_tool_callsなどのCreateResponseBodyフィールドを受け付けるItemParamは次の判別共用体で構成されるsystem、developer、user、assistantの各 role を持つmessagefunction_callとfunction_call_outputreasoningitem_reference
- 正常応答では
object: "response"、status、outputを含むResponseResourceが返る - ストリーミングでは、次のような意味論的イベントを使用する
response.created、response.in_progress、response.completed、response.failedresponse.output_item.added、response.output_item.doneresponse.content_part.added、response.content_part.doneresponse.output_text.delta、response.output_text.done
- 仕様上の必須要件は次のとおり
Content-Type: text/event-streamevent:は JSON のtypeフィールドと一致すること- 終端イベントはリテラルの
[DONE]であること
reasoningアイテムはcontent、encrypted_content、summaryを公開する場合がある- Hugging Face の例では、リクエストに
OpenResponses-Version: latestを含めている(任意ヘッダー)
提案アーキテクチャ
- Zod スキーマだけを持つ
src/gateway/open-responses.schema.tsを追加する(ゲートウェイ側 import は含めない) /v1/responses向けにsrc/gateway/openresponses-http.ts(またはopen-responses-http.ts)を追加するsrc/gateway/openai-http.tsは従来互換アダプターとしてそのまま維持する- 設定項目
gateway.http.endpoints.responses.enabledを追加する(デフォルトはfalse) gateway.http.endpoints.chatCompletions.enabledは独立させ、両エンドポイントを個別に切り替えられるようにする- Chat Completions が有効な場合は、従来機能であることを示す起動時警告を出す
Chat Completions の非推奨化方針
- 厳密なモジュール境界を維持し、responses と chat completions の間でスキーマ型を共有しない
- Chat Completions は設定による opt-in にして、コード変更なしで無効化できるようにする
/v1/responsesが安定した段階で、Chat Completions を legacy と明示するようドキュメントを更新する- 将来的な任意の施策として、Chat Completions リクエストを Responses ハンドラーへマップし、削除経路を単純化することを検討する
フェーズ 1 のサポート範囲
inputは文字列、または message role とfunction_call_outputを含むItemParam[]として受け付けるsystem/developerメッセージはextraSystemPromptに抽出する- エージェント実行時の現在メッセージには、最新の
userまたはfunction_call_outputを使う - 未対応の content part(画像 / ファイル)は
invalid_request_errorで拒否する output_textを含む単一の assistant message を返す- トークン集計が接続されるまでは、
usageは 0 埋めした値を返す
検証戦略(SDK なし)
- 次の対応範囲について Zod スキーマを実装する
CreateResponseBodyItemParamと message content part unionResponseResource- ゲートウェイで使用するストリーミングイベント形状
- スキーマは単一で独立したモジュールにまとめ、仕様との乖離を防ぎつつ、将来的な codegen にも対応しやすくする
ストリーミング実装(フェーズ 1)
- SSE 行には
event:とdata:の両方を含める - 必要となる最小シーケンス:
response.createdresponse.output_item.addedresponse.content_part.addedresponse.output_text.delta(必要に応じて繰り返す)response.output_text.doneresponse.content_part.doneresponse.completed[DONE]
テストと検証計画
/v1/responses向けに e2e カバレッジを追加する- 認証が必須であること
- 非ストリーミング応答の形状
- ストリームイベントの順序と
[DONE] - ヘッダーと
userを使ったセッションルーティング
src/gateway/openai-http.test.tsは変更しない- 手動確認として、
stream: trueを指定して/v1/responsesにcurlし、イベント順序と終端の[DONE]を確認する
ドキュメント更新(後続タスク)
/v1/responsesの使い方と例を説明する新しいドキュメントページを追加する/gateway/openai-http-apiに legacy 注記を追加し、/v1/responsesへの導線を設ける