Skip to content

Conversation

@ibetitsmike
Copy link
Contributor

Summary

This PR fixes the Anthropic cache strategy to properly cache system prompts, tool definitions, and conversation messages according to the Vercel AI SDK documentation.

Problem

The current implementation only cached conversation messages but missed two critical components:

  • System prompts (which rarely change and should always be cached)
  • Tool definitions (which are static per model and should always be cached)

Solution

1. Enhanced Cache Strategy Module

  • Added createCachedSystemMessage() to convert system prompts to cached messages
  • Added applyCacheControlToTools() to cache tool definitions
  • Added supportsAnthropicCache() helper for cleaner code

2. StreamManager Integration

  • System messages are now converted to cached messages at the start of the message array
  • Tool definitions are cached when passed to streamText()
  • Messages continue to be cached up to the second-to-last message

3. Comprehensive Testing

  • Added unit tests for all cache strategy functions (13 tests, all passing)
  • Added integration tests to verify end-to-end functionality

Impact

This change significantly reduces token usage and costs when using Anthropic models by:

  • System prompts: Cached across all conversations (rarely change)
  • Tool definitions: Cached for all tool calls (static schemas)
  • Message history: Cached up to current message (reused context)

Implementation Details

Uses the proper providerOptions structure as documented:

providerOptions: {
  anthropic: {
    cacheControl: {
      type: "ephemeral"
    }
  }
}

Testing

  • ✅ Unit tests: bun test src/common/utils/ai/cacheStrategy.test.ts
  • ✅ Type checking: make typecheck
  • ✅ Build: make build

Generated with mux

…nd tools

- Add cache control for system messages by converting them to cached messages
- Implement tool definition caching for Anthropic models
- Improve message caching to use proper providerOptions structure
- Add comprehensive unit tests for cache strategy functions
- Add integration tests to verify end-to-end functionality

This significantly reduces token usage and costs when using Anthropic models by:
- Caching system prompts that rarely change
- Caching static tool definitions
- Properly caching conversation history up to the current message

Follows Vercel AI SDK documentation for Anthropic cache control using
providerOptions with { anthropic: { cacheControl: { type: 'ephemeral' } } }
…thropic

When converting system message to cached message for Anthropic models,
the system parameter must be undefined (not empty string) to avoid API error:
'system: text content blocks must be non-empty'

This ensures the AI SDK doesn't send an empty system block to Anthropic.
- Add 8 new tests in streamManager.test.ts covering:
  - System message caching
  - Tool definition caching
  - Message caching at correct positions
  - Non-Anthropic model behavior
  - System parameter handling (undefined vs string)
  - Cache control structure validation
- Add integration test for empty system message handling
- All tests pass without requiring API keys
- Tests verify correct providerOptions structure sent to AI SDK
- Close previous test block before adding new describe block
- Remove duplicate closing braces
- All tests now pass successfully
- Replace async functions without await with Promise.resolve()
- Fix type assertions to use recommended pattern (as unknown as T)
- Remove streamManager cache tests (duplicated in cacheStrategy.test.ts)
- Run prettier formatting on all modified files
- All static checks now pass
@ibetitsmike ibetitsmike added this pull request to the merge queue Nov 21, 2025
Merged via the queue into main with commit ed2b285 Nov 21, 2025
14 checks passed
@ibetitsmike ibetitsmike deleted the anthropic-cache-strategy branch November 21, 2025 19:18
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.

1 participant