fix: tool definition does not pass back to gemini properly, causing repeated tool calls.

fixes: #8789
fixes: #8773
fixes: #7111
fixes: #6402
fixes: #7684
This commit is contained in:
Soulter
2026-06-17 10:03:03 +08:00
parent 4f5075e608
commit 92fc2b592e

View File

@@ -349,12 +349,6 @@ class ProviderGoogleGenAI(Provider):
contents.append(content_cls(parts=part))
gemini_contents: list[types.Content] = []
native_tool_enabled = any(
[
self.provider_config.get("gm_native_coderunner", False),
self.provider_config.get("gm_native_search", False),
],
)
for message in payloads["messages"]:
role, content = message["role"], message.get("content")
@@ -377,11 +371,10 @@ class ProviderGoogleGenAI(Provider):
append_or_extend(gemini_contents, parts, types.UserContent)
elif role == "assistant":
parts = []
if isinstance(content, str):
parts = [types.Part.from_text(text=content)]
append_or_extend(gemini_contents, parts, types.ModelContent)
parts.append(types.Part.from_text(text=content))
elif isinstance(content, list):
parts = []
thinking_signature = None
text = ""
for part in content:
@@ -400,16 +393,25 @@ class ProviderGoogleGenAI(Provider):
exc_info=True,
)
thinking_signature = None
parts.append(
types.Part(
text=text,
thought_signature=thinking_signature,
)
)
append_or_extend(gemini_contents, parts, types.ModelContent)
elif not native_tool_enabled and "tool_calls" in message:
parts = []
if not text and thinking_signature and "tool_calls" in message and any(
tool.get("extra_content", {}).get("google", {}).get(
"thought_signature"
)
for tool in message["tool_calls"]
):
# If the main content is empty but tool calls have thought signatures,
# skip adding an empty text part to deduplicate the thinking signature in the main content and tool calls.
pass
else:
parts.append(
types.Part(
text=text,
thought_signature=thinking_signature,
)
)
if "tool_calls" in message:
for tool in message["tool_calls"]:
part = types.Part.from_function_call(
name=tool["function"]["name"],
@@ -427,17 +429,13 @@ class ProviderGoogleGenAI(Provider):
if ts_bs64:
part.thought_signature = base64.b64decode(ts_bs64)
parts.append(part)
append_or_extend(gemini_contents, parts, types.ModelContent)
else:
logger.warning("assistant 角色的消息内容为空,已添加空格占位")
if native_tool_enabled and "tool_calls" in message:
logger.warning(
"检测到启用Gemini原生工具且上下文中存在函数调用建议使用 /reset 重置上下文",
)
parts = [types.Part.from_text(text=" ")]
append_or_extend(gemini_contents, parts, types.ModelContent)
elif role == "tool" and not native_tool_enabled:
if not parts:
parts = [types.Part.from_text(text=" ")]
append_or_extend(gemini_contents, parts, types.ModelContent)
elif role == "tool":
func_name = message.get("name", message["tool_call_id"])
part = types.Part.from_function_response(
name=func_name,