Skip to content

fix(ai-chat): preserve Anthropic replay tokens during persistence#1188

Merged
threepointone merged 2 commits into
mainfrom
fix/anthropic-replay-tokens
Mar 25, 2026
Merged

fix(ai-chat): preserve Anthropic replay tokens during persistence#1188
threepointone merged 2 commits into
mainfrom
fix/anthropic-replay-tokens

Conversation

@whoiskatrin
Copy link
Copy Markdown
Contributor

@whoiskatrin whoiskatrin commented Mar 25, 2026

Summary

  • stop truncating provider-executed web_search and web_fetch payloads when persisting chat history, because Anthropic replays those results verbatim on later turns
  • preserve nested opaque encrypted* fields in other provider tool payloads so replay tokens survive while large consumable strings can still be truncated
  • add regression tests for web_search.encryptedContent, nested web_fetch citation encryptedIndex, and mixed payloads that should still truncate non-opaque content

Problem

Issue #1185 reported that the persistence truncation added in #1150 corrupts Anthropic web-tool replay tokens. After a successful web search, the SDK persisted encrypted_content with the truncation marker appended, and the next turn replayed that damaged value back to Anthropic. Anthropic then rejected the conversation with a 400 and the thread became permanently stuck.

The core bug is that the current sanitizer treats all long strings in provider-executed tool payloads as consumable content, but some of them are opaque provider-owned replay artifacts.

What changed

  • AIChatAgent._truncateProviderExecutedToolPayloads() now skips truncation entirely for provider-executed web_search and web_fetch tool payloads
  • _truncateLargeStrings() now preserves strings under encrypted* keys verbatim, even when neighboring large fields are still compacted
  • regression coverage now proves we preserve:
    • web_search encryptedContent
    • web_fetch citation encryptedIndex
    • encryptedStdout while still truncating a sibling preview field

Reviewer Notes

  • this is intentionally a narrow hotfix, not a full persistence-policy redesign
  • I chose to preserve whole web_search / web_fetch payloads because these payloads are relatively small and Anthropic expects them to round-trip exactly; the storage savings from truncating them are low while the replay risk is high
  • I also added a generic encrypted* field escape hatch so newer Anthropic replay fields in other provider-executed tool payloads do not get truncated by default
  • if we want a longer-term cleanup, I think the right direction is separating replay-safe persistence from debug/storage compaction instead of relying on string-size heuristics in one sanitizer path

Testing

  • npm run test:workers -- --run src/tests/sanitize-messages.test.ts
  • npm run check

Related


Open with Devin

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 25, 2026

🦋 Changeset detected

Latest commit: 6133d6f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cloudflare/ai-chat Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Mar 25, 2026

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@1188

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@1188

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@1188

hono-agents

npm i https://pkg.pr.new/hono-agents@1188

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@1188

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@1188

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@1188

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@1188

commit: 6133d6f

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

Copy link
Copy Markdown
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice, thanks for this

@threepointone threepointone merged commit 806cf5b into main Mar 25, 2026
2 checks passed
@threepointone threepointone deleted the fix/anthropic-replay-tokens branch March 25, 2026 13:36
@github-actions github-actions Bot mentioned this pull request Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provider tool payload truncation (#1150) inadvertently breaks Anthropic web search multi-turn

2 participants