mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 20:40:52 +08:00
Add reasoning/thinking configuration handling for Claude and OpenAI translators
- Implemented `thinkingConfig` handling to allow reasoning effort configuration in request generation. - Added support for reasoning content deltas (`thinking_delta`) in response processing. - Enhanced reasoning-related token budget mappings for various reasoning levels. - Improved response handling logic to ensure proper reasoning content inclusion.
This commit is contained in:
@@ -89,6 +89,17 @@ func ConvertGeminiRequestToClaude(modelName string, inputRawJSON []byte, stream
|
|||||||
out, _ = sjson.Set(out, "stop_sequences", stopSequences)
|
out, _ = sjson.Set(out, "stop_sequences", stopSequences)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Include thoughts configuration for reasoning process visibility
|
||||||
|
if thinkingConfig := genConfig.Get("thinkingConfig"); thinkingConfig.Exists() && thinkingConfig.IsObject() {
|
||||||
|
if includeThoughts := thinkingConfig.Get("include_thoughts"); includeThoughts.Exists() {
|
||||||
|
if includeThoughts.Type == gjson.True {
|
||||||
|
out, _ = sjson.Set(out, "thinking.type", "enabled")
|
||||||
|
if thinkingBudget := thinkingConfig.Get("thinkingBudget"); thinkingBudget.Exists() {
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", thinkingBudget.Int())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// System instruction conversion to Claude Code format
|
// System instruction conversion to Claude Code format
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ func ConvertClaudeResponseToGemini(_ context.Context, modelName string, original
|
|||||||
}
|
}
|
||||||
case "thinking_delta":
|
case "thinking_delta":
|
||||||
// Thinking/reasoning content delta for models with reasoning capabilities
|
// Thinking/reasoning content delta for models with reasoning capabilities
|
||||||
if text := delta.Get("text"); text.Exists() && text.String() != "" {
|
if text := delta.Get("thinking"); text.Exists() && text.String() != "" {
|
||||||
thinkingPart := `{"thought":true,"text":""}`
|
thinkingPart := `{"thought":true,"text":""}`
|
||||||
thinkingPart, _ = sjson.Set(thinkingPart, "text", text.String())
|
thinkingPart, _ = sjson.Set(thinkingPart, "text", text.String())
|
||||||
template, _ = sjson.SetRaw(template, "candidates.0.content.parts.-1", thinkingPart)
|
template, _ = sjson.SetRaw(template, "candidates.0.content.parts.-1", thinkingPart)
|
||||||
@@ -411,7 +411,7 @@ func ConvertClaudeResponseToGeminiNonStream(_ context.Context, modelName string,
|
|||||||
}
|
}
|
||||||
case "thinking_delta":
|
case "thinking_delta":
|
||||||
// Process reasoning/thinking content
|
// Process reasoning/thinking content
|
||||||
if text := delta.Get("text"); text.Exists() && text.String() != "" {
|
if text := delta.Get("thinking"); text.Exists() && text.String() != "" {
|
||||||
partJSON := `{"thought":true,"text":""}`
|
partJSON := `{"thought":true,"text":""}`
|
||||||
partJSON, _ = sjson.Set(partJSON, "text", text.String())
|
partJSON, _ = sjson.Set(partJSON, "text", text.String())
|
||||||
part := gjson.Parse(partJSON).Value().(map[string]interface{})
|
part := gjson.Parse(partJSON).Value().(map[string]interface{})
|
||||||
|
|||||||
@@ -41,6 +41,21 @@ func ConvertOpenAIRequestToClaude(modelName string, inputRawJSON []byte, stream
|
|||||||
|
|
||||||
root := gjson.ParseBytes(rawJSON)
|
root := gjson.ParseBytes(rawJSON)
|
||||||
|
|
||||||
|
if v := root.Get("reasoning_effort"); v.Exists() {
|
||||||
|
out, _ = sjson.Set(out, "thinking.type", "enabled")
|
||||||
|
|
||||||
|
switch v.String() {
|
||||||
|
case "none":
|
||||||
|
out, _ = sjson.Set(out, "thinking.type", "disabled")
|
||||||
|
case "low":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 1024)
|
||||||
|
case "medium":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 8192)
|
||||||
|
case "high":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 24576)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper for generating tool call IDs in the form: toolu_<alphanum>
|
// Helper for generating tool call IDs in the form: toolu_<alphanum>
|
||||||
// This ensures unique identifiers for tool calls in the Claude Code format
|
// This ensures unique identifiers for tool calls in the Claude Code format
|
||||||
genToolCallID := func() string {
|
genToolCallID := func() string {
|
||||||
|
|||||||
@@ -128,10 +128,11 @@ func ConvertClaudeResponseToOpenAI(_ context.Context, modelName string, original
|
|||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []string{template}
|
return []string{}
|
||||||
|
|
||||||
case "content_block_delta":
|
case "content_block_delta":
|
||||||
// Handle content delta (text, tool use arguments, or reasoning content)
|
// Handle content delta (text, tool use arguments, or reasoning content)
|
||||||
|
hasContent := false
|
||||||
if delta := root.Get("delta"); delta.Exists() {
|
if delta := root.Get("delta"); delta.Exists() {
|
||||||
deltaType := delta.Get("type").String()
|
deltaType := delta.Get("type").String()
|
||||||
|
|
||||||
@@ -140,8 +141,14 @@ func ConvertClaudeResponseToOpenAI(_ context.Context, modelName string, original
|
|||||||
// Text content delta - send incremental text updates
|
// Text content delta - send incremental text updates
|
||||||
if text := delta.Get("text"); text.Exists() {
|
if text := delta.Get("text"); text.Exists() {
|
||||||
template, _ = sjson.Set(template, "choices.0.delta.content", text.String())
|
template, _ = sjson.Set(template, "choices.0.delta.content", text.String())
|
||||||
|
hasContent = true
|
||||||
|
}
|
||||||
|
case "thinking_delta":
|
||||||
|
// Accumulate reasoning/thinking content
|
||||||
|
if thinking := delta.Get("thinking"); thinking.Exists() {
|
||||||
|
template, _ = sjson.Set(template, "choices.0.delta.reasoning_content", thinking.String())
|
||||||
|
hasContent = true
|
||||||
}
|
}
|
||||||
|
|
||||||
case "input_json_delta":
|
case "input_json_delta":
|
||||||
// Tool use input delta - accumulate arguments for tool calls
|
// Tool use input delta - accumulate arguments for tool calls
|
||||||
if partialJSON := delta.Get("partial_json"); partialJSON.Exists() {
|
if partialJSON := delta.Get("partial_json"); partialJSON.Exists() {
|
||||||
@@ -156,7 +163,11 @@ func ConvertClaudeResponseToOpenAI(_ context.Context, modelName string, original
|
|||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []string{template}
|
if hasContent {
|
||||||
|
return []string{template}
|
||||||
|
} else {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
case "content_block_stop":
|
case "content_block_stop":
|
||||||
// End of content block - output complete tool call if it's a tool_use block
|
// End of content block - output complete tool call if it's a tool_use block
|
||||||
|
|||||||
@@ -28,6 +28,23 @@ func ConvertOpenAIResponsesRequestToClaude(modelName string, inputRawJSON []byte
|
|||||||
|
|
||||||
root := gjson.ParseBytes(rawJSON)
|
root := gjson.ParseBytes(rawJSON)
|
||||||
|
|
||||||
|
if v := root.Get("reasoning.effort"); v.Exists() {
|
||||||
|
out, _ = sjson.Set(out, "thinking.type", "enabled")
|
||||||
|
|
||||||
|
switch v.String() {
|
||||||
|
case "none":
|
||||||
|
out, _ = sjson.Set(out, "thinking.type", "disabled")
|
||||||
|
case "minimal":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 1024)
|
||||||
|
case "low":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 4096)
|
||||||
|
case "medium":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 8192)
|
||||||
|
case "high":
|
||||||
|
out, _ = sjson.Set(out, "thinking.budget_tokens", 24576)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper for generating tool call IDs when missing
|
// Helper for generating tool call IDs when missing
|
||||||
genToolCallID := func() string {
|
genToolCallID := func() string {
|
||||||
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
|||||||
Reference in New Issue
Block a user