Technical reference
トランスクリプトの衛生管理
OpenClaw は実行前(モデルコンテキストの構築時)に、トランスクリプトへプロバイダー固有の修正を適用します。これらのほとんどは、厳格なプロバイダー要件を満たすために使用されるメモリ内の調整です。これとは別に、セッションの読み込み前にセッションファイルの修復パスが保存済み JSONL を書き換えることもありますが、対象は不正な行、または永続的なレコードとして無効な保存済みターンに限られます。配信済みのアシスタント応答はディスク上に保持されます。プロバイダー固有のアシスタントプリフィル除去は、送信ペイロードの構築時にのみ行われます。
修復が行われると、アトミック置換の前に元のファイルが一時的な
*.bak-<pid>-<ts> 兄弟ファイルへ書き込まれ、置換が成功すると削除されます。
バックアップが保持されるのは、クリーンアップ自体が失敗した場合のみであり、
その場合はパスが返されます。
対象範囲は次のとおりです。
- 実行時専用のプロンプトコンテキストをユーザーに表示されるトランスクリプトターンに含めない
- ツール呼び出し ID のサニタイズ
- ツール呼び出し入力の検証
- ツール結果のペアリング修復
- ターンの検証/順序付け
- 思考署名のクリーンアップ
- Thinking 署名のクリーンアップ
- 画像ペイロードのサニタイズ
- プロバイダーでのリプレイ前に空のテキストブロックをクリーンアップ
- プロバイダーでのリプレイ前に、未完了の推論のみで構成された長さ制限ターンをクリーンアップ
- ユーザー入力の出所タグ付け(セッション間でルーティングされたプロンプト用)
- Bedrock Converse のリプレイ用に空のアシスタントエラーターンを修復
トランスクリプトの保存に関する詳細は、 セッション管理の詳細を参照してください。
グローバルルール:実行時コンテキストはユーザートランスクリプトではない
ターンのモデルプロンプトには実行時/システムコンテキストを追加できますが、 これはエンドユーザーが作成したコンテンツではありません。OpenClaw は、Gateway の応答、 キューに入ったフォローアップ、ACP、CLI、および埋め込み OpenClaw 実行用に、 トランスクリプト向けのプロンプト本文を別途保持します。保存される可視ユーザーターンでは、 実行時に拡張されたプロンプトではなく、このトランスクリプト本文を使用します。
実行時ラッパーがすでに永続化されている従来のセッションでは、Gateway の履歴サーフェスが、 WebChat、TUI、REST、または SSE クライアントへメッセージを返す前に表示用の射影を適用します。
実行箇所
すべてのトランスクリプト衛生処理は、埋め込みランナーに集約されています。
- ポリシーの選択:
src/agents/transcript-policy.ts(resolveTranscriptPolicy。provider、modelApi、およびmodelIdをキーとして使用) - サニタイズ/修復の適用:
src/agents/embedded-agent-runner/replay-history.ts内のsanitizeSessionHistory
トランスクリプト衛生処理とは別に、セッションファイルは必要に応じて 読み込み前に修復されます。
src/agents/session-file-repair.ts内のrepairSessionFileIfNeededsrc/agents/embedded-agent-runner/run/attempt.tsおよびsrc/agents/embedded-agent-runner/compact.tsから呼び出される
グローバルルール:画像のサニタイズ
サイズ制限によるプロバイダー側の拒否を防ぐため、画像ペイロードは常にサニタイズされます (サイズ超過の base64 画像を縮小/再圧縮)。これは、ビジョン対応モデルにおける 画像由来のトークン負荷の制御にも役立ちます。最大寸法を小さくするとトークン使用量が減り、 大きくすると詳細が保持されます。
実装:
src/agents/embedded-agent-helpers/images.ts内のsanitizeSessionMessagesImagessrc/agents/tool-images.ts内のsanitizeContentBlocksImages- 画像の最大辺は
agents.defaults.imageMaxDimensionPxで設定可能 (デフォルト:1200) - このパスでリプレイコンテンツを走査する際に、空のテキストブロックが削除されます。 空になったアシスタントターンはリプレイ用コピーから削除されます。空になったユーザーターンと ツール結果ターンには、空でないコンテンツ省略プレースホルダーが付与されます。
グローバルルール:不正なツール呼び出し
input と arguments の両方が欠落しているアシスタントのツール呼び出しブロックは、
モデルコンテキストの構築前に削除されます。これにより、部分的に永続化されたツール呼び出し
(たとえば、レート制限エラー後)が原因でプロバイダーに拒否されることを防ぎます。
実装:
src/agents/session-transcript-repair.ts内のsanitizeToolCallInputssanitizeSessionHistory(src/agents/embedded-agent-runner/replay-history.ts)で適用
グローバルルール:ツール結果のペアリング
プロバイダー固有の呼び出し ID が書き換えられる前に、各アシスタントターン内で ツール結果がツール呼び出しの出現箇所とペアリングされます。プロバイダーが生成した ID は 後続のターンで繰り返される場合があるため、繰り返された呼び出しに隣接する結果は その出現箇所との対応を維持します。位置がずれた結果が移動されるのは、未解決の出現箇所のうち 所有可能なものが厳密に 1 つだけの場合です。曖昧な余剰結果は削除され、結果が欠落した 出現箇所には合成エラー結果が付与されます。
実装:src/agents/session-transcript-repair.ts 内の
sanitizeToolUseResultPairing
グローバルルール:未完了または無言の推論のみのターン
次のいずれかのイベント後、thinking または秘匿された thinking のコンテンツのみを含む アシスタントターンは、メモリ内のリプレイ用コピーから除外されます。
- プロバイダーの出力制限により、未完了の推論状態でターンが終了した場合。
- 無言応答のクリーンアップによって、ターン内で唯一可視だった
NO_REPLYテキストが削除された場合。
無言応答のクリーンアップにより、厳格なプロバイダーが会話を再構築する際に、 非表示の推論が後続のアシスタントツール使用ターンへ結合されることを防ぎます。
空の長さ制限ターンは変更されません。可視テキスト、ツール呼び出し、または不明な コンテンツブロックを含む長さ制限ターンも同様です。ツール呼び出しまたは不明な コンテンツブロックを含む無言応答ターンも変更されません。保存済みトランスクリプトは 書き換えられません。
実装:src/agents/embedded-agent-runner/replay-history.ts 内の
normalizeAssistantReplayContent
グローバルルール:セッション間入力の出所
エージェントが sessions_send を介して別のセッションへプロンプトを送信すると
(エージェント間の応答/通知ステップを含む)、OpenClaw は作成されたユーザーターンを
message.provenance.kind = "inter_session" とともに永続化します。
OpenClaw はさらに、ルーティングされたプロンプトテキストの前に同一ターンの
[Inter-session message] ... isUser=false マーカーを付加し、アクティブなモデル呼び出しが
別セッションの出力と外部エンドユーザーの指示を区別できるようにします。このマーカーには、
利用可能な場合、送信元セッション、チャンネル、およびツールが含まれます。プロバイダーとの
互換性のため、トランスクリプトでは引き続き role: "user" を使用しますが、
可視テキストと出所メタデータの両方で、そのターンがセッション間データであることを示します。
コンテキストの再構築時、OpenClaw は出所メタデータのみを持つ古い永続化済みの セッション間ユーザーターンにも同じマーカーを適用します。
プロバイダーマトリックス(現在の動作)
OpenAI / OpenAI Codex
- 画像のサニタイズのみ。
- OpenAI Responses/Codex のトランスクリプトでは、孤立した推論署名 (後続のコンテンツブロックがない単独の推論項目)を削除し、モデルのルート切り替え後は リプレイ可能な OpenAI 推論を削除します。
- 暗号化された空の要約項目を含む、リプレイ可能な OpenAI Responses の
推論項目ペイロードを保持します。これにより、手動/WebSocket リプレイでも、
必要な
rs_*状態とアシスタント出力項目の対応が維持されます。 - ネイティブ ChatGPT Codex Responses は、セッションの
prompt_cache_keyを 保持しながら、以前の項目 ID なしで過去の Responses の推論/メッセージ/関数ペイロードを リプレイすることにより、Codex のワイヤー互換性に従います。 - OpenAI Responses 系のリプレイでは、同一モデルの正規の
call_*|fc_*推論ペアを保持しますが、pi-ai ペイロードへの変換前に、 不正または長すぎるcall_id/関数呼び出し項目 ID を決定論的に正規化します。 - ツール結果のペアリング修復では、実際に一致した出力を移動し、
結果が欠落したツール呼び出しに対して Codex 形式の
aborted出力を合成する場合があります。 - ターンの検証や並べ替えは行いません。思考署名も除去しません。
OpenAI 互換 Chat Completions
- ローカルおよびプロキシ形式の OpenAI 互換サーバーへ
reasoningやreasoning_contentなどの過去ターンの推論フィールドが送信されないよう、 履歴内のアシスタントの thinking/推論ブロックはリプレイ前に除去されます。 - 現在の同一ターン内のツール呼び出し継続では、ツール結果がリプレイされるまで、 アシスタントの推論ブロックをツール呼び出しに付随させたままにします。
reasoning: trueを持つカスタム/セルフホストのモデルエントリでは、 リプレイされた推論メタデータが保持されます。- プロバイダー所有の例外では、ワイヤープロトコルがリプレイされた 推論メタデータを必要とする場合、この処理を無効にできます。
Google(Generative AI / Gemini CLI / Antigravity)
- ツール呼び出し ID のサニタイズ:厳密な英数字。
- ツール結果のペアリング修復および合成ツール結果。
- ターンの検証(Gemini 形式のターン交互配置)。
- Google のターン順序修正(履歴がアシスタントで始まる場合、小さなユーザーブートストラップを先頭に追加)。
- Antigravity Claude:thinking 署名を正規化し、署名のない thinking ブロックを削除。
Anthropic / Minimax(Anthropic 互換)
- ツール結果のペアリング修復および合成ツール結果。
- ターンの検証(厳格な交互配置を満たすため、連続するユーザーターンを結合)。
- thinking が有効な場合、末尾のアシスタントプリフィルターンは、 Cloudflare AI Gateway のルートを含む送信 Anthropic Messages ペイロードから除去されます。
- セッションが圧縮されている場合、Compaction 前のアシスタントの thinking 署名は、 プロバイダーでのリプレイ前に除去されます。Thinking 署名は生成時に会話のプレフィックスへ 暗号学的に結び付けられています。Compaction 後はプレフィックスが変化するため (元のコンテンツが要約コンテンツに置き換えられます)、元の署名をリプレイすると Anthropic は「Invalid signature in thinking block」というエラーでリクエストを拒否します。 thinking テキストは署名なしブロックとして保持され、その後、以下のルールで処理されます。
- リプレイ署名が欠落、空、または空白のみの thinking ブロックは、 プロバイダー変換前に除去されます。その結果アシスタントターンが空になる場合、 OpenClaw は空でない推論省略テキストを使用してターンの形状を維持します。
- 除去が必要な古い thinking のみのアシスタントターンは、 プロバイダーアダプターがリプレイターンを削除しないよう、空でない推論省略テキストに置き換えられます。
Amazon Bedrock(Converse API)
- 空のアシスタントストリームエラーターンは、リプレイ前に空でない
フォールバックテキストブロックへ修復されます。Bedrock Converse は
content: []を含む アシスタントメッセージを拒否するため、stopReason: "error"と空のコンテンツを持つ永続化済み アシスタントターンも、読み込み前にディスク上で修復されます。 - 空白のテキストブロックのみを含むアシスタントストリームエラーターンは、 無効な空白ブロックをリプレイする代わりに、メモリ内のリプレイ用コピーから削除されます。
- セッションが圧縮されている場合、上記の Anthropic と同じ理由により、 Compaction 前のアシスタントの thinking 署名は Converse でのリプレイ前に除去されます。
- リプレイ署名が欠落、空、または空白のみの Claude thinking ブロックは、 Converse でのリプレイ前に除去されます。その結果アシスタントターンが空になる場合、 OpenClaw は空でない推論省略テキストを使用してターンの形状を維持します。
- 除去が必要な古い thinking のみのアシスタントターンは、 Converse のリプレイで厳格なターン形状を維持できるよう、空でない推論省略テキストに置き換えられます。
- リプレイでは、OpenClaw の配信ミラーおよび Gateway が挿入した アシスタントターンを除外します。
- 画像のサニタイズにはグローバルルールが適用されます。
Mistral(モデル ID に基づく検出を含む)
- ツール呼び出し ID のサニタイズ:strict9(英数字、長さ 9)。
OpenRouter Gemini
- 思考署名のクリーンアップ:base64 ではない
thought_signature値を除去 (base64 は保持)。
OpenRouter Anthropic
- 推論が有効な場合、検証済みの OpenRouter OpenAI 互換 Anthropic モデルの ペイロードから末尾のアシスタントプリフィルターンが除去され、Anthropic への直接接続および Cloudflare Anthropic のリプレイ動作と一致します。
その他すべて
- 画像のサニタイズのみ。
過去の動作(2026.1.22 より前)
2026.1.22 リリースより前の OpenClaw は、複数レイヤーのトランスクリプト 衛生処理を適用していました。
- transcript-sanitize 拡張機能はコンテキストを構築するたびに実行され、次の処理を行うことができました。
- ツール使用と結果のペアリングを修復する。
- ツール呼び出し ID をサニタイズする(
_/-を保持する非厳格モードを含む)。
- ランナーはプロバイダー固有のサニタイズも実行していたため、 処理が重複していました。
- プロバイダーポリシーの外部でも追加の変更が行われていました。これには、
永続化前にアシスタントのテキストから
<final>タグを除去すること、 空のアシスタントエラーターンを破棄すること、ツール呼び出し後のアシスタントの コンテンツを切り詰めることが含まれていました。
この複雑さにより、プロバイダー間のリグレッション(特に
openai-responses call_id|fc_id のペアリング)が発生しました。2026.1.22 のクリーンアップでは、
この拡張機能を削除し、ロジックをランナーに集約し、OpenAI については画像のサニタイズを除き
変更なしとしました。