Skip to content

Conversation

@xunxiing
Copy link

@xunxiing xunxiing commented Jan 25, 2026


Modifications / 改动点

修复了 ProviderGoogleGenAI (Gemini) 适配器中导致工具调用无限循环的 Bug。

在构建 role == "tool" 的历史消息时,原代码错误地将 tool_call_id 当作了函数 name 传入,且没有显式绑定 idfunction_response 中。这导致 Gemini API 无法正确识别工具执行结果,从而让模型认为任务未完成并陷入死循环。

主要修改 (astrbot/core/provider/sources/gemini_source.py):

  1. 修正函数名映射:在 types.Part.from_function_response 中使用真实的函数名 (message.get("name")),而不是 ID。
  2. 显式绑定 ID:手动赋值 part.function_response.id = message["tool_call_id"],确保工具返回结果能正确匹配到对应的调用请求。
  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

Before Fix / 修复前:
(日志显示模型不断重复调用 chip_build,无法识别工具返回结果,陷入死循环。)
image

After Fix / 修复后:
image

(Gemini 正确识别了工具执行结果,并成功输出了最终总结文本,跳出了循环。)

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc. (Bug fix usually doesn't need this / 修复 Bug 通常不需要此项,可以不勾)
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jan 25, 2026
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 1 个问题

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `astrbot/core/provider/sources/gemini_source.py:385-387` </location>
<code_context>
-                ]
+                # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
+                # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
+                func_name = message.get("name", "unknown_tool")
+
+                # 2. 创建 Part,注意 name 参数必须是函数名
</code_context>

<issue_to_address>
**suggestion:** 建议将 `tool_call_id` 用作函数名的回退值,而不是使用泛化的字面量。

使用像 `"unknown_tool"` 这样的通用占位符,会让你在日志中更难将响应与其对应的工具调用关联起来。由于这里可以保证 `tool_call_id` 一定存在,并且之前也被用作函数名,因此使用 `message.get("name", message["tool_call_id"])` 可以在仍然优先使用显式 `name` 的同时,更好地保留可追踪性。

```suggestion
                # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
                # 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源
                func_name = message.get("name", message["tool_call_id"])
```
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的代码评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审质量。
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `astrbot/core/provider/sources/gemini_source.py:385-387` </location>
<code_context>
-                ]
+                # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
+                # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
+                func_name = message.get("name", "unknown_tool")
+
+                # 2. 创建 Part,注意 name 参数必须是函数名
</code_context>

<issue_to_address>
**suggestion:** Consider using `tool_call_id` as the fallback function name instead of a generic literal.

A generic placeholder like `"unknown_tool"` makes it harder to correlate responses with their originating tool calls, especially in logs. Since `tool_call_id` is guaranteed here and was previously used as the function name, using `message.get("name", message["tool_call_id"])` preserves traceability while still preferring an explicit `name` when present.

```suggestion
                # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
                # 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源
                func_name = message.get("name", message["tool_call_id"])
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +385 to +387
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
func_name = message.get("name", "unknown_tool")
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: 建议将 tool_call_id 用作函数名的回退值,而不是使用泛化的字面量。

使用像 "unknown_tool" 这样的通用占位符,会让你在日志中更难将响应与其对应的工具调用关联起来。由于这里可以保证 tool_call_id 一定存在,并且之前也被用作函数名,因此使用 message.get("name", message["tool_call_id"]) 可以在仍然优先使用显式 name 的同时,更好地保留可追踪性。

Suggested change
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
func_name = message.get("name", "unknown_tool")
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源
func_name = message.get("name", message["tool_call_id"])
Original comment in English

suggestion: Consider using tool_call_id as the fallback function name instead of a generic literal.

A generic placeholder like "unknown_tool" makes it harder to correlate responses with their originating tool calls, especially in logs. Since tool_call_id is guaranteed here and was previously used as the function name, using message.get("name", message["tool_call_id"]) preserves traceability while still preferring an explicit name when present.

Suggested change
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
func_name = message.get("name", "unknown_tool")
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源
func_name = message.get("name", message["tool_call_id"])

@dosubot dosubot bot added the area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. label Jan 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant