fix(provider): anthropic_messages sends system as content blocks with cache_control
- Use SystemParts structured blocks when available, with per-block cache_control for Anthropic prompt caching support - Fall back to plain text block when SystemParts is absent - Output system as content blocks array instead of flat string - Update test expectation to match new array format
This commit is contained in:
parent
77b0c43392
commit
c85f572687
2 changed files with 28 additions and 9 deletions
|
|
@ -178,17 +178,34 @@ func buildRequestBody(
|
|||
}
|
||||
|
||||
// Process messages
|
||||
var systemPrompt string
|
||||
var systemBlocks []map[string]any
|
||||
var apiMessages []any
|
||||
|
||||
for _, msg := range messages {
|
||||
switch msg.Role {
|
||||
case "system":
|
||||
// Accumulate system messages
|
||||
if systemPrompt != "" {
|
||||
systemPrompt += "\n\n" + msg.Content
|
||||
// Prefer structured SystemParts for per-block cache_control.
|
||||
// This enables Anthropic prompt caching: static blocks keep a
|
||||
// stable prefix hash while dynamic parts (time, session) change.
|
||||
if len(msg.SystemParts) > 0 {
|
||||
for _, part := range msg.SystemParts {
|
||||
block := map[string]any{
|
||||
"type": "text",
|
||||
"text": part.Text,
|
||||
}
|
||||
if part.CacheControl != nil && part.CacheControl.Type != "" {
|
||||
block["cache_control"] = map[string]string{
|
||||
"type": part.CacheControl.Type,
|
||||
}
|
||||
}
|
||||
systemBlocks = append(systemBlocks, block)
|
||||
}
|
||||
} else {
|
||||
systemPrompt = msg.Content
|
||||
// Fallback: no structured parts, use plain text block.
|
||||
systemBlocks = append(systemBlocks, map[string]any{
|
||||
"type": "text",
|
||||
"text": msg.Content,
|
||||
})
|
||||
}
|
||||
|
||||
case "user":
|
||||
|
|
@ -280,9 +297,9 @@ func buildRequestBody(
|
|||
|
||||
result["messages"] = apiMessages
|
||||
|
||||
// Set system prompt if present
|
||||
if systemPrompt != "" {
|
||||
result["system"] = systemPrompt
|
||||
// Set system prompt if present (always as content blocks array for cache_control support)
|
||||
if len(systemBlocks) > 0 {
|
||||
result["system"] = systemBlocks
|
||||
}
|
||||
|
||||
// Add tools if present
|
||||
|
|
|
|||
|
|
@ -86,7 +86,9 @@ func TestBuildRequestBody(t *testing.T) {
|
|||
want: map[string]any{
|
||||
"model": "test-model",
|
||||
"max_tokens": int64(8192),
|
||||
"system": "You are a helpful assistant.",
|
||||
"system": []map[string]any{
|
||||
{"type": "text", "text": "You are a helpful assistant."},
|
||||
},
|
||||
"messages": []any{
|
||||
map[string]any{
|
||||
"role": "user",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue