feat(ai-chat): add sanitizeMessageForPersistence hook and Anthropic tool payload truncation#1150
Merged
threepointone merged 3 commits intomainfrom Mar 23, 2026
Merged
feat(ai-chat): add sanitizeMessageForPersistence hook and Anthropic tool payload truncation#1150threepointone merged 3 commits intomainfrom
threepointone merged 3 commits intomainfrom
Conversation
Introduce a protected sanitizeMessageForPersistence(message) hook on AIChatAgent to allow custom per-message transforms before persistence (defaults to identity). Add server-side truncation of large string values in provider-executed tool parts (e.g. Anthropic code_execution / text_editor) to avoid persisting huge payloads; truncation appends a marker with the original length and uses a 500-char cutoff. Update docs to describe the hook and built-in sanitization steps, add tests covering truncation and the custom hook, register a CustomSanitizeAgent for testing, and include a changeset entry. Closes #1118.
🦋 Changeset detectedLatest commit: 20d7798 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
Change _truncateLargeStrings to reserve space for the truncation marker so the total length (content + marker) stays within PROVIDER_TOOL_MAX_STRING_LENGTH. Use a computed contentLength (clamped to >=0) so re-running truncation on already-truncated strings is a no-op. Update tests to assert lengths are <= threshold (500) and add an idempotency test that re-persisting truncated messages does not alter stored content.
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
Adds a user-overridable hook for customizing message sanitization before persistence, and built-in truncation of large Anthropic server-side tool payloads. Closes #1118.
Problem
inputandoutputcan contain 200KB+ of text. After a few exchanges, messages balloon to 1MB+ of dead weight — the model has already consumed the results._sanitizeMessageForPersistencewasprivate, so users had no way to strip provider-specific or domain-specific bloat from persisted messages.Solution
Built-in Anthropic truncation: For any tool part with
providerExecuted === true, large string values ininputandoutputare recursively truncated to 500 characters with a size marker (e.g."… [truncated, original length: 10000]"). This only applies to provider-executed tools — user-defined tool outputs are untouched.User-overridable hook: A new
protected sanitizeMessageForPersistence(message)method that subclasses can override. It runs after all built-in sanitization, so the framework's own cleanup is never bypassable. The default implementation is identity (returns the message unchanged).The full sanitization pipeline is now:
itemId,reasoningEncryptedContent)Usage
Changes
packages/ai-chat/src/index.ts— AddedsanitizeMessageForPersistenceprotected hook,_truncateProviderExecutedToolPayloadsand_truncateLargeStringsstatic helpers, updated_sanitizeMessageForPersistencepipeline and JSDocpackages/ai-chat/src/tests/sanitize-messages.test.ts— 4 new tests: provider-executed tool truncation, no truncation for user tools, custom hook invocation, hook ordering with built-in sanitizationpackages/ai-chat/src/tests/worker.ts— AddedCustomSanitizeAgenttest agentpackages/ai-chat/src/tests/wrangler.jsonc— Binding + migration forCustomSanitizeAgentdocs/chat-agents.md— DocumentedsanitizeMessageForPersistencein Storage Management section, updated the context-vs-storage table.changeset/sanitize-message-hook.md— Minor changeset for@cloudflare/ai-chatTest plan
input.file_textandoutput.contentare truncated, short fields preservedproviderExecuted) are not truncatedCustomSanitizeAgentoverride is called and transforms outputnpm run checkpasses (sherif, exports, oxfmt, oxlint, typecheck)Made with Cursor