Skip to content

[BUG] anthropic_messages provider ignores SystemParts, breaks Anthropic prompt caching #2191

Description

@whtiehack

Quick Summary

anthropic_messages provider sends system as a flat string, ignoring SystemParts content blocks, which defeats Anthropic prompt caching.

Environment & Tools

  • PicoClaw Version: latest main
  • Go Version: go 1.25
  • AI Model & Provider: Anthropic Claude via anthropic_messages provider
  • Operating System: macOS
  • Channels: WeCom

📸 Steps to Reproduce

  1. Configure anthropic_messages as provider
  2. Send a message to the agent
  3. Observe the HTTP request — system field is a flat string instead of content blocks array

❌ Actual Behavior

anthropic_messages provider reads msg.Content (concatenated fallback string) instead of msg.SystemParts, resulting in:

  • system is a string instead of content blocks array
  • No cache_control markers on static blocks
  • Dynamic context (## Current Time) mixed in the same string causes the entire system prompt prefix to change every minute, defeating Anthropic prompt caching

provider.go L176-L281:

var systemPrompt string
// ...
case "system":
    systemPrompt = msg.Content  // ← ignores msg.SystemParts
// ...
result["system"] = systemPrompt  // ← flat string, no cache_control

✅ Expected Behavior

Same behavior as the SDK-based anthropic provider — output system as a content blocks array with cache_control: ephemeral on static blocks.

💬 Additional Context

The anthropic (SDK) provider correctly uses SystemParts with per-block cache_control: ephemeral. Fix submitted in PR #2192.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions