Skip to content

fix:gemini to claude tool_use err#5041

Open
nekohy wants to merge 1 commit into
QuantumNous:mainfrom
nekohy:feat-gemini-claude-tool-use
Open

fix:gemini to claude tool_use err#5041
nekohy wants to merge 1 commit into
QuantumNous:mainfrom
nekohy:feat-gemini-claude-tool-use

Conversation

@nekohy
Copy link
Copy Markdown
Contributor

@nekohy nekohy commented May 22, 2026

📝 变更描述 / Description

修复Gemini转Claude接口的工具兼容问题

🚀 变更类型 / Type of change

  • [*] 🐛 Bug 修复 (Bug fix)

✅ 提交前检查项 / Checklist

  • [*] 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • [*] 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • [*] Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • [*] 变更理解: 我已理解这些更改的工作原理及可能影响。
  • [*] 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • [*] 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • [*] 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)
后:
image
前:
image

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of tool calls and response formatting in relay scenarios, ensuring correct stop message generation and response completion based on relay format configuration.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Walkthrough

The PR modifies Gemini relay handlers to detect tool calls in streamed responses and conditionally emit stop/final responses based on the target relay format. For Claude-format conversions, stop messages are suppressed and final responses return in stop form with computed usage tracking.

Changes

Gemini Tool-Call Relay Format Handling

Layer / File(s) Summary
Streaming tool-call detection and finishReason update
relay/channel/gemini/relay-gemini.go
The streaming callback now detects when a converted Gemini response represents a tool call, sets finishReason to tool_calls, and clears FinishReason on each choice for Claude-format conversions.
Format-aware stop-message and final-response completion
relay/channel/gemini/relay-gemini.go
Stop SSE messages are generated only when the relay format is not Claude. Final response handling returns a stop-form response with computed usage when Claude conversion is in progress and not yet complete.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • QuantumNous/new-api#2742: Both PRs modify tool-call finish-reason handling and format-specific streaming behavior in relay/channel/gemini/relay-gemini.go.
  • QuantumNous/new-api#1531: Overlapping Gemini tool-call finish-reason and Claude relay-format logic updates in the same handler functions.
  • QuantumNous/new-api#2397: Both PRs ensure correct tool-call finish-reason handling and proper stop signaling for Claude-converted tool-call responses.

Poem

A rabbit hops through relay streams so bright,
Detecting tool calls dancing left and right,
For Claude we pause, for others we emit,
Format-aware responses, perfectly fit! 🐰✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'fix:gemini to claude tool_use err' is partially related to the changeset—it mentions the Gemini-to-Claude conversion issue, but uses vague phrasing ('err') and lacks clarity about the specific technical fix being implemented. Improve clarity by using a more descriptive title like 'Fix Gemini to Claude tool call conversion in streaming' or 'Handle tool_calls properly in Gemini-to-Claude relay format'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@relay/channel/gemini/relay-gemini.go`:
- Around line 1342-1349: The Claude branch rebuilds streamed tool-calls with
fresh UUIDs because getResponseToolCall() is called each chunk and keyed by
tool.ID, causing reindexing and duplicate tool-use blocks; fix this by
persisting a stable ID per choice/tool across chunks (e.g., maintain a map keyed
by choice index and tool name or choice index+tool type) in relay-gemini.go and
use that stable ID when converting deltas for Claude instead of generating a new
UUID in getResponseToolCall(); update the logic around response.IsToolCall(),
response.Choices and tool.ID so the conversion reuses the stored ID for the same
logical tool call across chunks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: efac3ff4-57d6-4291-8d81-bc80cf78d1ae

📥 Commits

Reviewing files that changed from the base of the PR and between f2c7647 and dcf567c.

📒 Files selected for processing (1)
  • relay/channel/gemini/relay-gemini.go

Comment on lines +1342 to +1349
if response.IsToolCall() {
finishReason = constant.FinishReasonToolCalls
if info.RelayFormat == types.RelayFormatClaude {
for choiceIdx := range response.Choices {
response.Choices[choiceIdx].FinishReason = nil
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep streamed tool-call IDs stable across deltas.

This Claude branch relies on response.IsToolCall(), but the streamed tool calls are still rebuilt with a fresh UUID in getResponseToolCall() every chunk. Because the reindexing map below keys on tool.ID, one logical tool call never reuses its prior slot and gets emitted as multiple tool-use blocks as arguments stream in. Please persist a stable ID per choice/tool across chunks before converting these deltas for Claude.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/gemini/relay-gemini.go` around lines 1342 - 1349, The Claude
branch rebuilds streamed tool-calls with fresh UUIDs because
getResponseToolCall() is called each chunk and keyed by tool.ID, causing
reindexing and duplicate tool-use blocks; fix this by persisting a stable ID per
choice/tool across chunks (e.g., maintain a map keyed by choice index and tool
name or choice index+tool type) in relay-gemini.go and use that stable ID when
converting deltas for Claude instead of generating a new UUID in
getResponseToolCall(); update the logic around response.IsToolCall(),
response.Choices and tool.ID so the conversion reuses the stored ID for the same
logical tool call across chunks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant