Sanitize replayed turns before cross-provider request builds - #540
Merged
TheGreatAxios merged 5 commits intoAug 23, 2026
Merged
Conversation
The vendored transformMessages/createIDNormalizer repair layer was never wired into the adapter registry, so switching provider/model mid-session replayed foreign thinking-block signatures verbatim (provider 400s) and persisted refusal/citation/audio/video blocks crashed the Anthropic block builder. Dangling tool_calls also went unrepaired outside the gate-timeout path. Wrap the adapter registry so every resolved adapter's buildRequest first strips output-only unmappable block types and opaque provider signatures, then runs the vendored transformMessages to drop foreign thinking blocks and answer orphaned tool_calls with synthetic error results.
…ired-foreign-thinking
…ired-foreign-thinking
…ired-foreign-thinking
…ired-foreign-thinking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The vendored inference layer exports a repair pass (
transformMessages,createIDNormalizerinvendor/intx-inference/src/transform.ts) that wasnever called from anywhere. Consequences:
thinking-block signature verbatim, which the new provider 400s on. The
poisoned turn is already persisted, so every subsequent request in that
session fails identically.
citation, redacted_thinking, audio, video, code execution) crash the
Anthropic block builder outright once persisted and replayed.
gate-timeout path, not on ordinary cross-provider replay.
src/provider/replay-sanitizer.tswraps the adapter registry(
withReplaySanitizer) so every resolved adapter'sbuildRequestfirstsanitizes persisted history before building the outgoing request:
(
redacted_thinking,citation,audio,video,code_execution_request,code_execution_result) and convertsrefusalblocks to plain text.different provider is never handed back a signature it didn't mint.
transformMessagesfor what it already doescorrectly: dropping thinking blocks from foreign-model turns and
answering dangling tool_calls with the same synthetic
tool_result/isErrorshape the reactor's gate-timeout path uses.Wired into
src/provider/inference-dependencies.tsbetweenloadAdapterRegistryandcreateDependencies, so it covers the sharedregistry used by the primary agent, sub-agents, and the compaction
summarizer.
vendor/ is untouched — this reuses the exported vendor helpers rather than
duplicating their logic.
Test plan
bunx prettier --check/bunx eslinton touched filesbun run typecheckbun run buildbun test ./src ./tests ./evals(5122 pass, 1 pre-existing unrelatedfailure in
src/agent/lsp-availability.test.tsreproduces identicallyon
mainin this environment)src/provider/replay-sanitizer.test.ts:grok-signed thinking history builds cleanly against both the
Anthropic and Google paths with no signature/thinking on the wire; a
persisted refusal block doesn't break the Anthropic builder; a
dangling tool_call is repaired with a synthetic error result
Fixes CL-6905