fix(anthropic): filter empty content messages to prevent API errors

- Add message content validation in getAndValidateAnthropicRequest
- Filter out messages with empty content to prevent 'all messages must have non-empty content' errors
- Support both text and non-text content validation (images, tool_use, tool_result)
- Add detailed logging for filtered messages
- Ensure at least one valid message remains after filtering

修复Anthropic协议空消息内容问题:
- 在getAndValidateAnthropicRequest中添加消息内容验证
- 过滤空内容消息以防止'all messages must have non-empty content'错误
- 支持文本和非文本内容验证(图片、工具调用、工具结果)
- 为被过滤的消息添加详细日志记录
- 确保过滤后至少保留一条有效消息
This commit is contained in:
Deadwalk
2025-09-29 16:51:55 +08:00
parent 290931b506
commit 7b9631408f

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"github.com/gin-gonic/gin"
@@ -128,6 +129,40 @@ func getAndValidateAnthropicRequest(c *gin.Context) (*anthropic.Request, error)
anthropicRequest.MaxTokens = 4096 // default max tokens
}
// Filter out messages with empty content to prevent API errors
var validMessages []anthropic.Message
ctx := c.Request.Context()
for i, message := range anthropicRequest.Messages {
hasContent := false
// Check if message has any non-empty content
for _, content := range message.Content.ToContentArray() {
if content.Type == "text" && strings.TrimSpace(content.Text) != "" {
hasContent = true
break
} else if content.Type != "text" && content.Type != "" {
// Non-text content (like images, tool_use, tool_result) is considered valid
hasContent = true
break
}
}
if hasContent {
validMessages = append(validMessages, message)
} else {
logger.Warnf(ctx, "Filtered out message at index %d with empty content (role: %s)", i, message.Role)
}
}
// Update the request with filtered messages
anthropicRequest.Messages = validMessages
// Ensure we still have at least one message after filtering
if len(anthropicRequest.Messages) == 0 {
return nil, fmt.Errorf("no valid messages found after filtering empty content")
}
return anthropicRequest, nil
}
@@ -161,7 +196,7 @@ func estimateAnthropicTokens(request *anthropic.Request) int {
// Count tokens in messages
for _, message := range request.Messages {
for _, content := range message.Content {
for _, content := range message.Content.ToContentArray() {
if content.Type == "text" {
totalTokens += len(content.Text) / CHARS_PER_TOKEN
}