Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,12 @@ func resolveStopReason(params *Params) string {
return "tool_use"
}

switch params.FinishReason {
case "MAX_TOKENS":
if params.FinishReason == "MAX_TOKENS" {
return "max_tokens"
case "STOP", "FINISH_REASON_UNSPECIFIED", "UNKNOWN":
return "end_turn"
}

return "end_turn"

}

// ConvertAntigravityResponseToClaudeNonStream converts a non-streaming Gemini CLI response to a non-streaming Claude response.
Expand Down Expand Up @@ -498,13 +496,8 @@ func ConvertAntigravityResponseToClaudeNonStream(_ context.Context, _ string, or
stopReason = "tool_use"
} else {
if finish := root.Get("response.candidates.0.finishReason"); finish.Exists() {
switch finish.String() {
case "MAX_TOKENS":
if finish.String() == "MAX_TOKENS" {
stopReason = "max_tokens"
case "STOP", "FINISH_REASON_UNSPECIFIED", "UNKNOWN":
stopReason = "end_turn"
default:
stopReason = "end_turn"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,17 @@ func ConvertAntigravityResponseToOpenAI(_ context.Context, _ string, originalReq
template, _ = sjson.Set(template, "id", responseIDResult.String())
}

// Extract and set the finish reason.
if finishReasonResult := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason"); finishReasonResult.Exists() {
template, _ = sjson.Set(template, "choices.0.finish_reason", strings.ToLower(finishReasonResult.String()))
template, _ = sjson.Set(template, "choices.0.native_finish_reason", strings.ToLower(finishReasonResult.String()))
// Extract the finish reason (set after payload processing).
finishReason := ""
if stopReasonResult := gjson.GetBytes(rawJSON, "response.stop_reason"); stopReasonResult.Exists() {
finishReason = stopReasonResult.String()
}
if finishReason == "" {
if finishReasonResult := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason"); finishReasonResult.Exists() {
finishReason = finishReasonResult.String()
}
}
finishReason = strings.ToLower(finishReason)

// Extract and set usage metadata (token counts).
if usageResult := gjson.GetBytes(rawJSON, "response.usageMetadata"); usageResult.Exists() {
Expand Down Expand Up @@ -198,6 +204,12 @@ func ConvertAntigravityResponseToOpenAI(_ context.Context, _ string, originalReq
if hasFunctionCall {
template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls")
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls")
} else if finishReason != "" && (*param).(*convertCliResponseToOpenAIChatParams).FunctionIndex == 0 {
// Only pass through specific finish reasons
if finishReason == "max_tokens" || finishReason == "stop" {
template, _ = sjson.Set(template, "choices.0.finish_reason", finishReason)
template, _ = sjson.Set(template, "choices.0.native_finish_reason", finishReason)
}
}

return []string{template}
Expand Down
8 changes: 6 additions & 2 deletions internal/translator/codex/claude/codex_claude_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,16 @@ func ConvertCodexResponseToClaude(_ context.Context, _ string, originalRequestRa
output = "event: content_block_stop\n"
output += fmt.Sprintf("data: %s\n\n", template)
} else if typeStr == "response.completed" {
template = `{"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":0,"output_tokens":0}}`
template = `{"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":0,"output_tokens":0}}`
p := (*param).(*bool)
if *p {
template, _ = sjson.Set(template, "delta.stop_reason", "tool_use")
} else {
template, _ = sjson.Set(template, "delta.stop_reason", "end_turn")
stopReason := rootResult.Get("response.stop_reason").String()
// Only pass through specific stop reasons
if stopReason == "max_tokens" || stopReason == "stop" || stopReason == "end_turn" {
template, _ = sjson.Set(template, "delta.stop_reason", stopReason)
}
}
template, _ = sjson.Set(template, "usage.input_tokens", rootResult.Get("response.usage.input_tokens").Int())
template, _ = sjson.Set(template, "usage.output_tokens", rootResult.Get("response.usage.output_tokens").Int())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
// Set tool_use stop reason if tools were used in this response
if usedTool {
template = `{"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":0,"output_tokens":0}}`
} else {
if finish := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason"); finish.Exists() {
if finish.String() == "MAX_TOKENS" {
template, _ = sjson.Set(template, "delta.stop_reason", "max_tokens")
}
}
}

// Include thinking tokens in output token count if present
Expand Down Expand Up @@ -352,13 +358,8 @@ func ConvertGeminiCLIResponseToClaudeNonStream(_ context.Context, _ string, orig
stopReason = "tool_use"
} else {
if finish := root.Get("response.candidates.0.finishReason"); finish.Exists() {
switch finish.String() {
case "MAX_TOKENS":
if finish.String() == "MAX_TOKENS" {
stopReason = "max_tokens"
case "STOP", "FINISH_REASON_UNSPECIFIED", "UNKNOWN":
stopReason = "end_turn"
default:
stopReason = "end_turn"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,17 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ
template, _ = sjson.Set(template, "id", responseIDResult.String())
}

// Extract and set the finish reason.
if finishReasonResult := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason"); finishReasonResult.Exists() {
template, _ = sjson.Set(template, "choices.0.finish_reason", strings.ToLower(finishReasonResult.String()))
template, _ = sjson.Set(template, "choices.0.native_finish_reason", strings.ToLower(finishReasonResult.String()))
// Extract the finish reason (set after payload processing).
finishReason := ""
if stopReasonResult := gjson.GetBytes(rawJSON, "response.stop_reason"); stopReasonResult.Exists() {
finishReason = stopReasonResult.String()
}
if finishReason == "" {
if finishReasonResult := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason"); finishReasonResult.Exists() {
finishReason = finishReasonResult.String()
}
}
finishReason = strings.ToLower(finishReason)

// Extract and set usage metadata (token counts).
if usageResult := gjson.GetBytes(rawJSON, "response.usageMetadata"); usageResult.Exists() {
Expand Down Expand Up @@ -187,6 +193,12 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ
if hasFunctionCall {
template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls")
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls")
} else if finishReason != "" && (*param).(*convertCliResponseToOpenAIChatParams).FunctionIndex == 0 {
// Only pass through specific finish reasons
if finishReason == "max_tokens" || finishReason == "stop" {
template, _ = sjson.Set(template, "choices.0.finish_reason", finishReason)
template, _ = sjson.Set(template, "choices.0.native_finish_reason", finishReason)
}
}

return []string{template}
Expand Down
13 changes: 7 additions & 6 deletions internal/translator/gemini/claude/gemini_claude_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ func ConvertGeminiResponseToClaude(_ context.Context, _ string, originalRequestR
template := `{"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":0,"output_tokens":0}}`
if usedTool {
template = `{"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":0,"output_tokens":0}}`
} else {
if finish := gjson.GetBytes(rawJSON, "candidates.0.finishReason"); finish.Exists() {
if finish.String() == "MAX_TOKENS" {
template, _ = sjson.Set(template, "delta.stop_reason", "max_tokens")
}
}
}

thoughtsTokenCount := usageResult.Get("thoughtsTokenCount").Int()
Expand Down Expand Up @@ -358,13 +364,8 @@ func ConvertGeminiResponseToClaudeNonStream(_ context.Context, _ string, origina
stopReason = "tool_use"
} else {
if finish := root.Get("candidates.0.finishReason"); finish.Exists() {
switch finish.String() {
case "MAX_TOKENS":
if finish.String() == "MAX_TOKENS" {
stopReason = "max_tokens"
case "STOP", "FINISH_REASON_UNSPECIFIED", "UNKNOWN":
stopReason = "end_turn"
default:
stopReason = "end_turn"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,17 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR
template, _ = sjson.Set(template, "id", responseIDResult.String())
}

// Extract and set the finish reason.
if finishReasonResult := gjson.GetBytes(rawJSON, "candidates.0.finishReason"); finishReasonResult.Exists() {
template, _ = sjson.Set(template, "choices.0.finish_reason", strings.ToLower(finishReasonResult.String()))
template, _ = sjson.Set(template, "choices.0.native_finish_reason", strings.ToLower(finishReasonResult.String()))
// Extract the finish reason (set after payload processing).
finishReason := ""
if stopReasonResult := gjson.GetBytes(rawJSON, "stop_reason"); stopReasonResult.Exists() {
finishReason = stopReasonResult.String()
}
if finishReason == "" {
if finishReasonResult := gjson.GetBytes(rawJSON, "candidates.0.finishReason"); finishReasonResult.Exists() {
finishReason = finishReasonResult.String()
}
}
finishReason = strings.ToLower(finishReason)

// Extract and set usage metadata (token counts).
if usageResult := gjson.GetBytes(rawJSON, "usageMetadata"); usageResult.Exists() {
Expand Down Expand Up @@ -199,6 +205,12 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR
if hasFunctionCall {
template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls")
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls")
} else if finishReason != "" && (*param).(*convertGeminiResponseToOpenAIChatParams).FunctionIndex == 0 {
// Only pass through specific finish reasons
if finishReason == "max_tokens" || finishReason == "stop" {
template, _ = sjson.Set(template, "choices.0.finish_reason", finishReason)
template, _ = sjson.Set(template, "choices.0.native_finish_reason", finishReason)
}
}

return []string{template}
Expand Down
Loading