From 5e78a24d63fdbaa7942d44d0417d01d83a7784b7 Mon Sep 17 00:00:00 2001 From: Yufeng He <40085740+he-yufeng@users.noreply.github.com> Date: Fri, 3 Apr 2026 16:32:49 +0800 Subject: [PATCH] fix: satisfy Google Gemini's function_response requirements to avoid 400 Invalid argument errors (#7216) Gemini API requires function_response to be a google.protobuf.Struct (JSON object). When tool results are plain text strings, the API returns 400 Invalid argument. Detect non-JSON tool content for Gemini models and wrap it in {"result": content} before sending. Fixes #7134 --- astrbot/core/provider/sources/openai_source.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/astrbot/core/provider/sources/openai_source.py b/astrbot/core/provider/sources/openai_source.py index d81185344..9c7c61fae 100644 --- a/astrbot/core/provider/sources/openai_source.py +++ b/astrbot/core/provider/sources/openai_source.py @@ -863,6 +863,9 @@ class ProviderOpenAIOfficial(Provider): def _finally_convert_payload(self, payloads: dict) -> None: """Finally convert the payload. Such as think part conversion, tool inject.""" + model = payloads.get("model", "").lower() + is_gemini = "gemini" in model + for message in payloads.get("messages", []): if message.get("role") == "assistant" and isinstance( message.get("content"), list @@ -879,6 +882,18 @@ class ProviderOpenAIOfficial(Provider): if reasoning_content: message["reasoning_content"] = reasoning_content + # Gemini 的 function_response 要求 google.protobuf.Struct(即 JSON 对象), + # 纯文本会触发 400 Invalid argument,需要包一层 JSON。 + if is_gemini and message.get("role") == "tool": + content = message.get("content", "") + if isinstance(content, str): + try: + json.loads(content) + except (json.JSONDecodeError, ValueError): + message["content"] = json.dumps( + {"result": content}, ensure_ascii=False + ) + async def _handle_api_error( self, e: Exception,