fix: remove tool call ID truncation and improve DeepSeek reasoning handling
The 40-character truncation of tool call IDs in helper.go caused collisions when models (like deepseek-v4-flash) generated longer IDs, leading to "Duplicate value for 'tool_call_id'" errors. Removed the limit to allow full unique IDs. DeepSeek: updated reasoning_content injection to use an empty string instead of a space, better matching provider expectations for history. Improved API error reporting across all providers by capturing raw body content when response parsing fails or returns empty strings.
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -38,6 +40,17 @@ func (p *OpenAIProvider) ChatCompletion(ctx context.Context, req *models.Unified
|
||||
|
||||
body := BuildOpenAIBody(req, messagesJSON, false)
|
||||
|
||||
// Debug message sequence
|
||||
for i, m := range messagesJSON {
|
||||
mMap, _ := m.(map[string]interface{})
|
||||
role, _ := mMap["role"].(string)
|
||||
hasToolCalls := false
|
||||
if tc, ok := mMap["tool_calls"]; ok && tc != nil {
|
||||
hasToolCalls = true
|
||||
}
|
||||
log.Printf("[DEBUG] OpenAI Msg[%d]: role=%s, hasToolCalls=%v", i, role, hasToolCalls)
|
||||
}
|
||||
|
||||
// Transition: Newer models require max_completion_tokens
|
||||
if strings.HasPrefix(req.Model, "o1-") || strings.HasPrefix(req.Model, "o3-") || strings.Contains(req.Model, "gpt-5") {
|
||||
if maxTokens, ok := body["max_tokens"]; ok {
|
||||
@@ -57,7 +70,14 @@ func (p *OpenAIProvider) ChatCompletion(ctx context.Context, req *models.Unified
|
||||
}
|
||||
|
||||
if !resp.IsSuccess() {
|
||||
return nil, fmt.Errorf("OpenAI API error (%d): %s", resp.StatusCode(), resp.String())
|
||||
msg := resp.String()
|
||||
if msg == "" {
|
||||
if body, err := io.ReadAll(resp.RawBody()); err == nil {
|
||||
msg = string(body)
|
||||
}
|
||||
}
|
||||
log.Printf("OpenAI API Error (%d): %s", resp.StatusCode(), msg)
|
||||
return nil, fmt.Errorf("OpenAI API error (%d): %s", resp.StatusCode(), msg)
|
||||
}
|
||||
|
||||
var respJSON map[string]interface{}
|
||||
@@ -104,7 +124,13 @@ func (p *OpenAIProvider) ImageGeneration(ctx context.Context, req *models.ImageG
|
||||
}
|
||||
|
||||
if !resp.IsSuccess() {
|
||||
return nil, fmt.Errorf("OpenAI image API error (%d): %s", resp.StatusCode(), resp.String())
|
||||
msg := resp.String()
|
||||
if msg == "" {
|
||||
if body, err := io.ReadAll(resp.RawBody()); err == nil {
|
||||
msg = string(body)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("OpenAI image API error (%d): %s", resp.StatusCode(), msg)
|
||||
}
|
||||
|
||||
var result models.ImageGenerationResponse
|
||||
@@ -123,6 +149,17 @@ func (p *OpenAIProvider) ChatCompletionStream(ctx context.Context, req *models.U
|
||||
|
||||
body := BuildOpenAIBody(req, messagesJSON, true)
|
||||
|
||||
// Debug message sequence
|
||||
for i, m := range messagesJSON {
|
||||
mMap, _ := m.(map[string]interface{})
|
||||
role, _ := mMap["role"].(string)
|
||||
hasToolCalls := false
|
||||
if tc, ok := mMap["tool_calls"]; ok && tc != nil {
|
||||
hasToolCalls = true
|
||||
}
|
||||
log.Printf("[DEBUG] OpenAI Stream Msg[%d]: role=%s, hasToolCalls=%v", i, role, hasToolCalls)
|
||||
}
|
||||
|
||||
// Transition: Newer models require max_completion_tokens
|
||||
if strings.HasPrefix(req.Model, "o1-") || strings.HasPrefix(req.Model, "o3-") || strings.Contains(req.Model, "gpt-5") {
|
||||
if maxTokens, ok := body["max_tokens"]; ok {
|
||||
@@ -143,7 +180,14 @@ func (p *OpenAIProvider) ChatCompletionStream(ctx context.Context, req *models.U
|
||||
}
|
||||
|
||||
if !resp.IsSuccess() {
|
||||
return nil, fmt.Errorf("OpenAI API error (%d): %s", resp.StatusCode(), resp.String())
|
||||
msg := resp.String()
|
||||
if msg == "" {
|
||||
if body, err := io.ReadAll(resp.RawBody()); err == nil {
|
||||
msg = string(body)
|
||||
}
|
||||
}
|
||||
log.Printf("OpenAI API Error (%d): %s", resp.StatusCode(), msg)
|
||||
return nil, fmt.Errorf("OpenAI API error (%d): %s", resp.StatusCode(), msg)
|
||||
}
|
||||
|
||||
ch := make(chan *models.ChatCompletionStreamResponse)
|
||||
|
||||
Reference in New Issue
Block a user