Repository navigation
feats: repair the thinking of claude to openrouter convert #3120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -34,16 +34,30 @@ func ClaudeToOpenAIRequest(claudeRequest dto.ClaudeRequest, info *relaycommon.Re | |||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| isOpenRouter := info.ChannelType == constant.ChannelTypeOpenRouter | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if claudeRequest.Thinking != nil && claudeRequest.Thinking.Type == "enabled" { | ||||||||||||||||||||||||||||
| if claudeRequest.Thinking != nil && (claudeRequest.Thinking.Type == "enabled" || claudeRequest.Thinking.Type == "adaptive") { | ||||||||||||||||||||||||||||
| if isOpenRouter { | ||||||||||||||||||||||||||||
| reasoning := openrouter.RequestReasoning{ | ||||||||||||||||||||||||||||
| MaxTokens: claudeRequest.Thinking.GetBudgetTokens(), | ||||||||||||||||||||||||||||
| if effort := claudeRequest.GetEfforts(); effort != "" { | ||||||||||||||||||||||||||||
| effortBytes, _ := json.Marshal(effort) | ||||||||||||||||||||||||||||
| openAIRequest.Verbosity = effortBytes | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| reasoningJSON, err := json.Marshal(reasoning) | ||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||
| return nil, fmt.Errorf("failed to marshal reasoning: %w", err) | ||||||||||||||||||||||||||||
| if claudeRequest.Thinking != nil { | ||||||||||||||||||||||||||||
| var reasoning openrouter.RequestReasoning | ||||||||||||||||||||||||||||
| if claudeRequest.Thinking.Type == "enabled" { | ||||||||||||||||||||||||||||
| reasoning = openrouter.RequestReasoning{ | ||||||||||||||||||||||||||||
| Enabled: true, | ||||||||||||||||||||||||||||
| MaxTokens: claudeRequest.Thinking.GetBudgetTokens(), | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, find and examine the service/convert.go file around lines 45-49
fd convert.go | grep -E "service|convert"Repository: QuantumNous/new-api Length of output: 81 🏁 Script executed: # Get the actual code at lines 45-49 in service/convert.go
find . -path "*service/convert.go" -type f | head -1 | xargs head -60 | tail -20Repository: QuantumNous/new-api Length of output: 709 🏁 Script executed: # Search for GetBudgetTokens method implementation
rg "GetBudgetTokens" -A 5 -B 2Repository: QuantumNous/new-api Length of output: 710 🏁 Script executed: # Look at relay/channel/openai/adaptor.go around lines 296-298
find . -path "*relay/channel/openai/adaptor.go" -type f | xargs sed -n '290,305p'Repository: QuantumNous/new-api Length of output: 521 🏁 Script executed: # Search for the Thinking struct definition to understand BudgetTokens type
rg "type.*Thinking\s*struct" -A 20 | head -50Repository: QuantumNous/new-api Length of output: 2180 Add nil validation for At Lines [45-49], Proposed fix if claudeRequest.Thinking.Type == "enabled" {
+ if claudeRequest.Thinking.BudgetTokens == nil {
+ return nil, fmt.Errorf("BudgetTokens is nil when thinking is enabled")
+ }
reasoning = openrouter.RequestReasoning{
Enabled: true,
MaxTokens: claudeRequest.Thinking.GetBudgetTokens(),
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| } else if claudeRequest.Thinking.Type == "adaptive" { | ||||||||||||||||||||||||||||
| reasoning = openrouter.RequestReasoning{ | ||||||||||||||||||||||||||||
| Enabled: true, | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| reasoningJSON, err := json.Marshal(reasoning) | ||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Check if the file exists and read the relevant section
if [ -f "service/convert.go" ]; then
echo "=== Lines 35-60 of service/convert.go ==="
sed -n '35,60p' service/convert.go
else
echo "File not found: service/convert.go"
fiRepository: QuantumNous/new-api Length of output: 1069 🏁 Script executed: # Verify common.Marshal wrapper function exists
echo "=== Checking for common.Marshal in common/json.go ==="
if [ -f "common/json.go" ]; then
rg -A 5 "func (.*)?Marshal\(" common/json.go | head -40
else
echo "File common/json.go not found"
fiRepository: QuantumNous/new-api Length of output: 263 🏁 Script executed: # Check all json.Marshal and json.Unmarshal usage in service/convert.go
echo "=== All json.Marshal and json.Unmarshal calls in service/convert.go ==="
rg "(json\.Marshal|json\.Unmarshal)" service/convert.go -nRepository: QuantumNous/new-api Length of output: 448 🏁 Script executed: # Check for json imports in service/convert.go
echo "=== Imports in service/convert.go ==="
head -30 service/convert.go | grep -E "^import|^\\s+\".*\""Repository: QuantumNous/new-api Length of output: 399 Replace direct Lines 40 and 55 use Proposed fix if effort := claudeRequest.GetEfforts(); effort != "" {
- effortBytes, _ := json.Marshal(effort)
+ effortBytes, err := common.Marshal(effort)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal effort: %w", err)
+ }
openAIRequest.Verbosity = effortBytes
}- reasoningJSON, err := json.Marshal(reasoning)
+ reasoningJSON, err := common.Marshal(reasoning)
if err != nil {
return nil, fmt.Errorf("failed to marshal reasoning: %w", err)
}Per the coding guideline for 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| return nil, fmt.Errorf("failed to marshal reasoning: %w", err) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| openAIRequest.Reasoning = reasoningJSON | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| openAIRequest.Reasoning = reasoningJSON | ||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||
| thinkingSuffix := "-thinking" | ||||||||||||||||||||||||||||
| if strings.HasSuffix(info.OriginModelName, thinkingSuffix) && | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: QuantumNous/new-api
Length of output: 121
🏁 Script executed:
Repository: QuantumNous/new-api
Length of output: 1351
🏁 Script executed:
Repository: QuantumNous/new-api
Length of output: 484
🏁 Script executed:
Repository: QuantumNous/new-api
Length of output: 207
🏁 Script executed:
Repository: QuantumNous/new-api
Length of output: 507
🏁 Script executed:
# Check imports at the top of dto/claude.go head -50 dto/claude.goRepository: QuantumNous/new-api
Length of output: 1534
🏁 Script executed:
# Check what JSON wrapper functions are available in common/json.go cat common/json.goRepository: QuantumNous/new-api
Length of output: 817
Use
common.UnmarshalinGetEffortsinstead ofjson.Unmarshal.Line 419 directly calls
json.Unmarshalin business code. This violates the project guideline requiring all JSON marshal/unmarshal operations to use wrapper functions fromcommon/json.go.Proposed fix
func (c *ClaudeRequest) GetEfforts() string { - var OutputConfig OutputConfigForEffort - if err := json.Unmarshal(c.OutputConfig, &OutputConfig); err == nil { - effort := OutputConfig.Effort - return effort - } - return "" + if len(c.OutputConfig) == 0 { + return "" + } + var outputConfig OutputConfigForEffort + if err := common.Unmarshal(c.OutputConfig, &outputConfig); err != nil { + return "" + } + return outputConfig.Effort }📝 Committable suggestion
🤖 Prompt for AI Agents