From 3cad6b9d7fc5668b1c7cc9995ddfba5291512d0f Mon Sep 17 00:00:00 2001 From: CaIon Date: Thu, 16 Apr 2026 17:44:38 +0800 Subject: [PATCH] fix(claude): improve handling of empty string content in OpenAI to Claude message conversion --- relay/channel/claude/relay-claude.go | 30 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/relay/channel/claude/relay-claude.go b/relay/channel/claude/relay-claude.go index 3968a268..e7f351b7 100644 --- a/relay/channel/claude/relay-claude.go +++ b/relay/channel/claude/relay-claude.go @@ -258,7 +258,7 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe formatMessages = formatMessages[:len(formatMessages)-1] } } - if fmtMessage.Content == nil { + if fmtMessage.Content == nil || (fmtMessage.IsStringContent() && fmtMessage.StringContent() == "") { fmtMessage.SetStringContent("...") } formatMessages = append(formatMessages, fmtMessage) @@ -274,14 +274,16 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe if message.Role == "system" { // 根据Claude API规范,system字段使用数组格式更有通用性 if message.IsStringContent() { - systemMessages = append(systemMessages, dto.ClaudeMediaMessage{ - Type: "text", - Text: common.GetPointer[string](message.StringContent()), - }) + if text := message.StringContent(); text != "" { + systemMessages = append(systemMessages, dto.ClaudeMediaMessage{ + Type: "text", + Text: common.GetPointer[string](text), + }) + } } else { // 支持复合内容的system消息(虽然不常见,但需要考虑完整性) for _, ctx := range message.ParseContent() { - if ctx.Type == "text" { + if ctx.Type == "text" && ctx.Text != "" { systemMessages = append(systemMessages, dto.ClaudeMediaMessage{ Type: "text", Text: common.GetPointer[string](ctx.Text), @@ -339,16 +341,22 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe } } } else if message.IsStringContent() && message.ToolCalls == nil { - claudeMessage.Content = message.StringContent() + text := message.StringContent() + if text == "" { + text = "..." + } + claudeMessage.Content = text } else { claudeMediaMessages := make([]dto.ClaudeMediaMessage, 0) for _, mediaMessage := range message.ParseContent() { switch mediaMessage.Type { case "text": - claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{ - Type: "text", - Text: common.GetPointer[string](mediaMessage.Text), - }) + if mediaMessage.Text != "" { + claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{ + Type: "text", + Text: common.GetPointer[string](mediaMessage.Text), + }) + } default: source := mediaMessage.ToFileSource() if source == nil {