@@ -391,12 +391,36 @@ func convertMessages(req *model.InternalLLMRequest) []anthropicModel.MessagePara
391391 }
392392
393393 converted := convertSingleMessage (msg , req .Messages , processedIndexes )
394- messages = append (messages , converted ... )
394+ for _ , convertedMsg := range converted {
395+ // Anthropic API 要求消息角色必须交替出现(user/assistant/user/assistant)。
396+ // 当 OpenAI 格式的多个连续 tool 消息被各自转换为独立的 user 消息时,
397+ // 会产生连续的同角色消息,需要合并以避免 "Improperly formed request" 错误。
398+ if n := len (messages ); n > 0 && messages [n - 1 ].Role == convertedMsg .Role {
399+ last := & messages [n - 1 ]
400+ last .Content = anthropicModel.MessageContent {
401+ MultipleContent : append (contentToBlocks (last .Content ), contentToBlocks (convertedMsg .Content )... ),
402+ }
403+ } else {
404+ messages = append (messages , convertedMsg )
405+ }
406+ }
395407 }
396408
397409 return messages
398410}
399411
412+ // contentToBlocks 将 MessageContent 统一展开为 MessageContentBlock 切片。
413+ func contentToBlocks (c anthropicModel.MessageContent ) []anthropicModel.MessageContentBlock {
414+ if len (c .MultipleContent ) > 0 {
415+ // 返回副本,避免后续 append 污染原 slice
416+ return append ([]anthropicModel.MessageContentBlock (nil ), c .MultipleContent ... )
417+ }
418+ if c .Content != nil && * c .Content != "" {
419+ return []anthropicModel.MessageContentBlock {{Type : "text" , Text : c .Content }}
420+ }
421+ return nil
422+ }
423+
400424func convertSingleMessage (msg model.Message , allMessages []model.Message , processedIndexes map [int ]bool ) []anthropicModel.MessageParam {
401425 switch msg .Role {
402426 case "tool" :
@@ -449,14 +473,7 @@ func convertToolMessage(msg model.Message, allMessages []model.Message, processe
449473 // original Anthropic request may also include additional user content alongside tool_result.
450474 if userMsg := findUserMessageByIndex (allMessages , * msg .MessageIndex ); userMsg != nil {
451475 userContent := buildMessageContent (* userMsg )
452- if len (userContent .MultipleContent ) > 0 {
453- contentBlocks = append (contentBlocks , userContent .MultipleContent ... )
454- } else if userContent .Content != nil && * userContent .Content != "" {
455- contentBlocks = append (contentBlocks , anthropicModel.MessageContentBlock {
456- Type : "text" ,
457- Text : userContent .Content ,
458- })
459- }
476+ contentBlocks = append (contentBlocks , contentToBlocks (userContent )... )
460477 }
461478
462479 processedIndexes [* msg .MessageIndex ] = true
0 commit comments