From 6b020f44588a72237dad4ef57bee0c213ea599af Mon Sep 17 00:00:00 2001 From: Klaus Date: Sat, 3 Jan 2026 16:49:08 +0800 Subject: [PATCH 1/2] Enhance response handling with reasoning content --- model/openai.go | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/model/openai.go b/model/openai.go index acc3be0..ce63361 100644 --- a/model/openai.go +++ b/model/openai.go @@ -530,6 +530,7 @@ func (m *openAIModel) generateStream(ctx context.Context, openaiReq *openAIReque scanner := bufio.NewScanner(httpResp.Body) var textBuffer strings.Builder + var reasoningBuffer strings.Builder var toolCalls []toolCall var usage *usage @@ -559,6 +560,24 @@ func (m *openAIModel) generateStream(ctx context.Context, openaiReq *openAIReque continue } + if delta.ReasoningContent != nil { + if text, ok := delta.ReasoningContent.(string); ok && text != "" { + reasoningBuffer.WriteString(text) + llmResp := &model.LLMResponse{ + Content: &genai.Content{ + Role: "model", + Parts: []*genai.Part{ + {Text: text, Thought: true}, + }, + }, + Partial: true, + } + if !yield(llmResp, nil) { + return + } + } + } + if delta.Content != nil { if text, ok := delta.Content.(string); ok && text != "" { textBuffer.WriteString(text) @@ -604,7 +623,7 @@ func (m *openAIModel) generateStream(ctx context.Context, openaiReq *openAIReque } if choice.FinishReason != "" { - finalResp := m.buildFinalResponse(textBuffer.String(), toolCalls, usage, choice.FinishReason) + finalResp := m.buildFinalResponse(textBuffer.String(), reasoningBuffer.String(), toolCalls, usage, choice.FinishReason) yield(finalResp, nil) return } @@ -616,7 +635,7 @@ func (m *openAIModel) generateStream(ctx context.Context, openaiReq *openAIReque } if textBuffer.Len() > 0 || len(toolCalls) > 0 { - finalResp := m.buildFinalResponse(textBuffer.String(), toolCalls, usage, "stop") + finalResp := m.buildFinalResponse(textBuffer.String(), reasoningBuffer.String(), toolCalls, usage, "stop") yield(finalResp, nil) } } @@ -732,9 +751,16 @@ func (m *openAIModel) convertResponse(resp *response) (*model.LLMResponse, error return llmResp, nil } -func (m *openAIModel) buildFinalResponse(text string, toolCalls []toolCall, usage *usage, finishReason string) *model.LLMResponse { +func (m *openAIModel) buildFinalResponse(text string, reasoningText string, toolCalls []toolCall, usage *usage, finishReason string) *model.LLMResponse { var parts []*genai.Part + if reasoningText != "" { + parts = append(parts, &genai.Part{ + Text: reasoningText, + Thought: true, + }) + } + if text != "" { parts = append(parts, genai.NewPartFromText(text)) } From 672d84ea84b8fde9cfa69a85ed293026b742d25c Mon Sep 17 00:00:00 2001 From: Klaus Date: Sat, 3 Jan 2026 16:49:47 +0800 Subject: [PATCH 2/2] Fix buildFinalResponse call in test cases --- model/openai_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/openai_test.go b/model/openai_test.go index 7fb8b5b..846a9fa 100644 --- a/model/openai_test.go +++ b/model/openai_test.go @@ -1268,7 +1268,7 @@ func TestBuildFinalResponse_EmptyToolCallFiltering(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - resp := m.buildFinalResponse("", tt.toolCalls, nil, "stop") + resp := m.buildFinalResponse("", "", tt.toolCalls, nil, "stop") var functionCalls []*genai.FunctionCall for _, part := range resp.Content.Parts {