mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-11-21 15:36:49 +08:00
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:
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
@@ -128,6 +129,40 @@ func getAndValidateAnthropicRequest(c *gin.Context) (*anthropic.Request, error)
|
|||||||
anthropicRequest.MaxTokens = 4096 // default max tokens
|
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
|
return anthropicRequest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +196,7 @@ func estimateAnthropicTokens(request *anthropic.Request) int {
|
|||||||
|
|
||||||
// Count tokens in messages
|
// Count tokens in messages
|
||||||
for _, message := range request.Messages {
|
for _, message := range request.Messages {
|
||||||
for _, content := range message.Content {
|
for _, content := range message.Content.ToContentArray() {
|
||||||
if content.Type == "text" {
|
if content.Type == "text" {
|
||||||
totalTokens += len(content.Text) / CHARS_PER_TOKEN
|
totalTokens += len(content.Text) / CHARS_PER_TOKEN
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user