*.bak-<pid>-<ts> перед атомарной заменой и удаляется после успешной замены; резервная копия сохраняется только если сама очистка завершается ошибкой (в этом случае путь возвращается в ответе).
Область охвата включает:
- Контекст промпта только для runtime, не попадающий в видимые пользователю ходы транскрипта
- Санитизацию id вызовов инструментов
- Проверку входных данных вызовов инструментов
- Восстановление сопоставления результатов инструментов
- Проверку / упорядочивание ходов
- Очистку сигнатур мыслей
- Очистку сигнатур thinking
- Санитизацию payload изображений
- Очистку пустых текстовых блоков перед replay провайдера
- Очистку неполных length-ходов только с reasoning перед replay провайдера
- Маркировку происхождения пользовательского ввода (для промптов, маршрутизированных между сессиями)
- Восстановление пустых assistant error-ходов для replay Bedrock Converse
Глобальное правило: runtime-контекст не является пользовательским транскриптом
Runtime/системный контекст может быть добавлен в промпт модели для хода, но это не контент, созданный конечным пользователем. OpenClaw хранит отдельное тело промпта для транскрипта, используемое для ответов Gateway, поставленных в очередь followup, ACP, CLI и встроенных запусков OpenClaw. Сохраненные видимые пользовательские ходы используют это тело транскрипта вместо промпта, обогащенного runtime-данными. Для legacy-сессий, в которых уже были сохранены runtime-обертки, поверхности истории Gateway применяют проекцию отображения перед возвратом сообщений клиентам WebChat, TUI, REST или SSE.Где это выполняется
Вся гигиена транскриптов централизована во встроенном runner:- Выбор политики:
src/agents/transcript-policy.ts - Применение санитизации/восстановления:
sanitizeSessionHistoryвsrc/agents/embedded-agent-runner/replay-history.ts
provider, modelApi и modelId, чтобы решить, что применять.
Отдельно от гигиены транскриптов файлы сессии восстанавливаются (если нужно) перед загрузкой:
repairSessionFileIfNeededвsrc/agents/session-file-repair.ts- Вызывается из
run/attempt.tsиcompact.ts(встроенный runner)
Глобальное правило: санитизация изображений
Payload изображений всегда санитизируются, чтобы предотвратить отклонение на стороне провайдера из-за ограничений по размеру (уменьшение масштаба/повторное сжатие слишком больших base64-изображений). Это также помогает контролировать вызванную изображениями нагрузку на токены для моделей с поддержкой vision. Более низкие максимальные размеры обычно уменьшают использование токенов; более высокие размеры сохраняют детализацию. Реализация:sanitizeSessionMessagesImagesвsrc/agents/embedded-agent-helpers/images.tssanitizeContentBlocksImagesвsrc/agents/tool-images.ts- Максимальная сторона изображения настраивается через
agents.defaults.imageMaxDimensionPx(по умолчанию:1200). - Пустые текстовые блоки удаляются, пока этот проход обходит содержимое replay. Assistant turns, которые становятся пустыми, удаляются из копии replay; user и tool-result turns, которые становятся пустыми, получают непустой placeholder для пропущенного содержимого.
Глобальное правило: некорректно сформированные вызовы инструментов
Блоки вызовов инструментов ассистента, в которых отсутствуют иinput, и arguments, удаляются
до построения контекста модели. Это предотвращает отклонения провайдерами из-за частично
сохраненных вызовов инструментов (например, после сбоя из-за ограничения частоты).
Реализация:
sanitizeToolCallInputsвsrc/agents/session-transcript-repair.ts- Применяется в
sanitizeSessionHistoryвsrc/agents/embedded-agent-runner/replay-history.ts
Глобальное правило: неполные ходы только с reasoning
Assistant turns, которые достигли лимита вывода провайдера только с thinking или redacted-thinking содержимым, исключаются из копии replay в памяти. Такие ходы содержат неполное состояние провайдера и могут нести частичную сигнатуру thinking. Пустые length turns остаются без изменений, как и length turns с видимым текстом, вызовами инструментов или неизвестными блоками содержимого. Сохраненные транскрипты не переписываются. Реализация:normalizeAssistantReplayContentвsrc/agents/embedded-agent-runner/replay-history.ts
Глобальное правило: происхождение ввода между сессиями
Когда агент отправляет промпт в другую сессию черезsessions_send (включая
шаги reply/announce между агентами), OpenClaw сохраняет созданный пользовательский ход с:
message.provenance.kind = "inter_session"
[Inter-session message ... isUser=false],
чтобы активный вызов модели мог отличить вывод чужой сессии
от внешних инструкций конечного пользователя. Этот маркер включает
исходную сессию, канал и инструмент, когда они доступны. Транскрипт по-прежнему использует
role: "user" для совместимости с провайдером, но видимый текст и metadata происхождения
оба помечают ход как данные между сессиями.
Во время перестроения контекста OpenClaw применяет тот же маркер к более старым сохраненным
пользовательским ходам между сессиями, у которых есть только metadata происхождения.
Матрица провайдеров (текущее поведение)
OpenAI / OpenAI Codex- Только санитизация изображений.
- Удалять осиротевшие сигнатуры reasoning (отдельные элементы reasoning без следующего блока содержимого) для транскриптов OpenAI Responses/Codex и удалять replayable OpenAI reasoning после смены маршрута модели.
- Сохранять payload элементов reasoning OpenAI Responses, пригодные для replay, включая зашифрованные элементы с пустым summary, чтобы ручной/WebSocket replay сохранял требуемое состояние
rs_*, сопоставленное с элементами вывода ассистента. - Native ChatGPT Codex Responses следует wire parity Codex, выполняя replay предыдущих Responses reasoning/message/function payload без предыдущих item IDs, сохраняя при этом
prompt_cache_keyсессии. - Replay семейства OpenAI Responses сохраняет канонические пары same-model reasoning
call_*|fc_*, но детерминированно нормализует некорректно сформированные или слишком длинныеcall_id/ item ids вызовов функций перед конвертацией payload для pi-ai. - Восстановление сопоставления результатов инструментов может перемещать реальные совпавшие outputs и синтезировать outputs в стиле Codex
abortedдля отсутствующих вызовов инструментов. - Нет проверки или переупорядочивания ходов.
- Отсутствующие outputs инструментов семейства OpenAI Responses синтезируются как
aborted, чтобы соответствовать нормализации replay Codex. - Нет удаления сигнатур мыслей.
- Исторические блоки thinking/reasoning ассистента удаляются перед replay, чтобы
локальные и proxy-style OpenAI-compatible серверы не получали поля reasoning предыдущих ходов,
такие как
reasoningилиreasoning_content. - Текущие продолжения вызовов инструментов в том же ходе сохраняют блок reasoning ассистента, прикрепленный к вызову инструмента, пока результат инструмента не будет replayed.
- Пользовательские/self-hosted записи моделей с
reasoning: trueсохраняют replayed metadata reasoning. - Исключения, принадлежащие провайдерам, могут отказаться от этого, когда их wire protocol требует replayed metadata reasoning.
- Санитизация id вызовов инструментов: строго alphanumeric.
- Восстановление сопоставления результатов инструментов и синтетические результаты инструментов.
- Проверка ходов (чередование ходов в стиле Gemini).
- Исправление порядка ходов Google (добавить в начало крошечный пользовательский bootstrap, если история начинается с assistant).
- Antigravity Claude: нормализовать сигнатуры thinking; удалять неподписанные блоки thinking.
- Восстановление сопоставления результатов инструментов и синтетические результаты инструментов.
- Проверка ходов (сливать последовательные user turns, чтобы соблюсти строгое чередование).
- Завершающие assistant prefill turns удаляются из исходящих Anthropic Messages payload, когда thinking включен, включая маршруты Cloudflare AI Gateway.
- Сигнатуры thinking ассистента до Compaction удаляются перед replay провайдера, когда сессия была compacted. Сигнатуры thinking криптографически привязаны к префиксу диалога на момент генерации; после Compaction префикс меняется (суммаризированный контент заменяется summary Compaction), поэтому replay исходных сигнатур приводит к отклонению запроса Anthropic с “Invalid signature in thinking block”. Текст thinking сохраняется как неподписанный блок и затем обрабатывается правилом ниже.
- Блоки thinking с отсутствующими, пустыми или blank replay-сигнатурами удаляются перед конвертацией провайдера. Если из-за этого assistant turn становится пустым, OpenClaw сохраняет форму хода с непустым omitted-reasoning текстом.
- Более старые assistant turns только с thinking, которые необходимо удалить, заменяются непустым omitted-reasoning текстом, чтобы адаптеры провайдера не удаляли replay turn.
- Пустые assistant stream-error turns восстанавливаются до непустого fallback-текстового блока
перед replay. Bedrock Converse отклоняет сообщения ассистента с
content: [], поэтому сохраненные assistant turns сstopReason: "error"и пустым содержимым также восстанавливаются на диске перед загрузкой. - Assistant stream-error turns, которые содержат только blank text blocks, удаляются из копии replay в памяти вместо replay недопустимого blank block.
- Сигнатуры thinking ассистента до Compaction удаляются перед Converse replay, когда сессия была compacted, по той же причине, что и Anthropic выше.
- Блоки Claude thinking с отсутствующими, пустыми или blank replay-сигнатурами удаляются перед Converse replay. Если из-за этого assistant turn становится пустым, OpenClaw сохраняет форму хода с непустым omitted-reasoning текстом.
- Более старые assistant turns только с thinking, которые необходимо удалить, заменяются непустым omitted-reasoning текстом, чтобы Converse replay сохранял строгую форму хода.
- Replay фильтрует delivery-mirror OpenClaw и внедренные Gateway assistant turns.
- Санитизация изображений применяется через глобальное правило.
- Санитизация id вызовов инструментов: strict9 (alphanumeric длиной 9).
- Очистка сигнатур мыслей: удалять не-base64 значения
thought_signature(сохранять base64).
- Завершающие assistant prefill turns удаляются из проверенных OpenRouter OpenAI-compatible Anthropic model payloads, когда reasoning включен, в соответствии с поведением replay напрямую Anthropic и Cloudflare Anthropic.
- Только санитизация изображений.
Историческое поведение (до 2026.1.22)
До релиза 2026.1.22 OpenClaw применял несколько слоев гигиены транскриптов:- transcript-sanitize extension выполнялся при каждом построении контекста и мог:
- Восстанавливать сопоставление tool use/result.
- Санитизировать ids вызовов инструментов (включая нестрогий режим, сохранявший
_/-).
- Runner также выполнял специфичную для провайдера санитизацию, что дублировало работу.
- Дополнительные мутации происходили вне политики провайдера, включая:
- Удаление тегов
<final>из текста ассистента перед сохранением. - Удаление пустых assistant error turns.
- Обрезку содержимого ассистента после вызовов инструментов.
- Удаление тегов
call_id|fc_id
для openai-responses). Очистка 2026.1.22 удалила extension, централизовала
логику в runner и сделала OpenAI no-touch за пределами санитизации изображений.