Skip to content

Commit 9cdef93

Browse files
committed
fix: initialize contentBlocks with an empty slice and improve content handling in ConvertOpenAIResponseToClaudeNonStream
1 parent 3dd0844 commit 9cdef93

File tree

1 file changed

+74
-64
lines changed

1 file changed

+74
-64
lines changed

internal/translator/openai/claude/openai_claude_response.go

Lines changed: 74 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ func ConvertOpenAIResponseToClaudeNonStream(_ context.Context, _ string, origina
466466
},
467467
}
468468

469-
var contentBlocks []interface{}
469+
contentBlocks := make([]interface{}, 0)
470470
hasToolCall := false
471471

472472
if choices := root.Get("choices"); choices.Exists() && choices.IsArray() && len(choices.Array()) > 0 {
@@ -477,80 +477,90 @@ func ConvertOpenAIResponseToClaudeNonStream(_ context.Context, _ string, origina
477477
}
478478

479479
if message := choice.Get("message"); message.Exists() {
480-
if contentArray := message.Get("content"); contentArray.Exists() && contentArray.IsArray() {
481-
var textBuilder strings.Builder
482-
var thinkingBuilder strings.Builder
483-
484-
flushText := func() {
485-
if textBuilder.Len() == 0 {
486-
return
480+
if contentResult := message.Get("content"); contentResult.Exists() {
481+
if contentResult.IsArray() {
482+
var textBuilder strings.Builder
483+
var thinkingBuilder strings.Builder
484+
485+
flushText := func() {
486+
if textBuilder.Len() == 0 {
487+
return
488+
}
489+
contentBlocks = append(contentBlocks, map[string]interface{}{
490+
"type": "text",
491+
"text": textBuilder.String(),
492+
})
493+
textBuilder.Reset()
487494
}
488-
contentBlocks = append(contentBlocks, map[string]interface{}{
489-
"type": "text",
490-
"text": textBuilder.String(),
491-
})
492-
textBuilder.Reset()
493-
}
494495

495-
flushThinking := func() {
496-
if thinkingBuilder.Len() == 0 {
497-
return
496+
flushThinking := func() {
497+
if thinkingBuilder.Len() == 0 {
498+
return
499+
}
500+
contentBlocks = append(contentBlocks, map[string]interface{}{
501+
"type": "thinking",
502+
"thinking": thinkingBuilder.String(),
503+
})
504+
thinkingBuilder.Reset()
498505
}
499-
contentBlocks = append(contentBlocks, map[string]interface{}{
500-
"type": "thinking",
501-
"thinking": thinkingBuilder.String(),
502-
})
503-
thinkingBuilder.Reset()
504-
}
505506

506-
for _, item := range contentArray.Array() {
507-
typeStr := item.Get("type").String()
508-
switch typeStr {
509-
case "text":
510-
flushThinking()
511-
textBuilder.WriteString(item.Get("text").String())
512-
case "tool_calls":
513-
flushThinking()
514-
flushText()
515-
toolCalls := item.Get("tool_calls")
516-
if toolCalls.IsArray() {
517-
toolCalls.ForEach(func(_, tc gjson.Result) bool {
518-
hasToolCall = true
519-
toolUse := map[string]interface{}{
520-
"type": "tool_use",
521-
"id": tc.Get("id").String(),
522-
"name": tc.Get("function.name").String(),
523-
}
524-
525-
argsStr := util.FixJSON(tc.Get("function.arguments").String())
526-
if argsStr != "" {
527-
var parsed interface{}
528-
if err := json.Unmarshal([]byte(argsStr), &parsed); err == nil {
529-
toolUse["input"] = parsed
507+
for _, item := range contentResult.Array() {
508+
typeStr := item.Get("type").String()
509+
switch typeStr {
510+
case "text":
511+
flushThinking()
512+
textBuilder.WriteString(item.Get("text").String())
513+
case "tool_calls":
514+
flushThinking()
515+
flushText()
516+
toolCalls := item.Get("tool_calls")
517+
if toolCalls.IsArray() {
518+
toolCalls.ForEach(func(_, tc gjson.Result) bool {
519+
hasToolCall = true
520+
toolUse := map[string]interface{}{
521+
"type": "tool_use",
522+
"id": tc.Get("id").String(),
523+
"name": tc.Get("function.name").String(),
524+
}
525+
526+
argsStr := util.FixJSON(tc.Get("function.arguments").String())
527+
if argsStr != "" {
528+
var parsed interface{}
529+
if err := json.Unmarshal([]byte(argsStr), &parsed); err == nil {
530+
toolUse["input"] = parsed
531+
} else {
532+
toolUse["input"] = map[string]interface{}{}
533+
}
530534
} else {
531535
toolUse["input"] = map[string]interface{}{}
532536
}
533-
} else {
534-
toolUse["input"] = map[string]interface{}{}
535-
}
536537

537-
contentBlocks = append(contentBlocks, toolUse)
538-
return true
539-
})
540-
}
541-
case "reasoning":
542-
flushText()
543-
if thinking := item.Get("text"); thinking.Exists() {
544-
thinkingBuilder.WriteString(thinking.String())
538+
contentBlocks = append(contentBlocks, toolUse)
539+
return true
540+
})
541+
}
542+
case "reasoning":
543+
flushText()
544+
if thinking := item.Get("text"); thinking.Exists() {
545+
thinkingBuilder.WriteString(thinking.String())
546+
}
547+
default:
548+
flushThinking()
549+
flushText()
545550
}
546-
default:
547-
flushThinking()
548-
flushText()
549551
}
550-
}
551552

552-
flushThinking()
553-
flushText()
553+
flushThinking()
554+
flushText()
555+
} else if contentResult.Type == gjson.String {
556+
textContent := contentResult.String()
557+
if textContent != "" {
558+
contentBlocks = append(contentBlocks, map[string]interface{}{
559+
"type": "text",
560+
"text": textContent,
561+
})
562+
}
563+
}
554564
}
555565

556566
if toolCalls := message.Get("tool_calls"); toolCalls.Exists() && toolCalls.IsArray() {

0 commit comments

Comments
 (0)