Skip to content

Commit 5e78a24

Browse files
authored
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
1 parent 6a7b622 commit 5e78a24

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

astrbot/core/provider/sources/openai_source.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,9 @@ async def _prepare_chat_payload(
863863

864864
def _finally_convert_payload(self, payloads: dict) -> None:
865865
"""Finally convert the payload. Such as think part conversion, tool inject."""
866+
model = payloads.get("model", "").lower()
867+
is_gemini = "gemini" in model
868+
866869
for message in payloads.get("messages", []):
867870
if message.get("role") == "assistant" and isinstance(
868871
message.get("content"), list
@@ -879,6 +882,18 @@ def _finally_convert_payload(self, payloads: dict) -> None:
879882
if reasoning_content:
880883
message["reasoning_content"] = reasoning_content
881884

885+
# Gemini 的 function_response 要求 google.protobuf.Struct(即 JSON 对象),
886+
# 纯文本会触发 400 Invalid argument,需要包一层 JSON。
887+
if is_gemini and message.get("role") == "tool":
888+
content = message.get("content", "")
889+
if isinstance(content, str):
890+
try:
891+
json.loads(content)
892+
except (json.JSONDecodeError, ValueError):
893+
message["content"] = json.dumps(
894+
{"result": content}, ensure_ascii=False
895+
)
896+
882897
async def _handle_api_error(
883898
self,
884899
e: Exception,

0 commit comments

Comments
 (0)