fix(agent): recognize OpenAI Responses API tool-call shape in native tool loop

is_tool_call_list() and extract_tool_call_info() only recognized
Chat-Completions-style ({"function": {...}}), Anthropic-style
({"name", "input"}), and Gemini-style tool-call shapes. The Responses
API's function_call output items are flat dicts shaped
{"id", "name", "arguments"} with no nested "function" key and no
"input" key, so they matched none of the checks.

This caused is_tool_call_list() to misclassify a genuine tool call as
a plain text answer, so the native tool loop returned the raw
tool-call list as the agent's final output instead of executing the
tool. Even after recognizing the shape, extract_tool_call_info() would
have passed an empty arguments dict, since it only read "input" for
the dict fallback.

Verified against LLM(api="responses") with tools attached: the agent
now correctly executes the tool with the parsed arguments instead of
returning the unexecuted tool-call JSON as its answer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
theCyberTech
2026-07-11 18:12:20 +08:00
parent 289686ab49
commit 37087b7e1d

View File

@@ -1228,7 +1228,14 @@ def extract_tool_call_info(
)
func_info = tool_call.get("function", {})
func_name = func_info.get("name", "") or tool_call.get("name", "")
func_args = func_info.get("arguments") or tool_call.get("input") or {}
# OpenAI Responses API function_call items are flat dicts using
# "arguments" (not "input") with no nested "function" key.
func_args = (
func_info.get("arguments")
or tool_call.get("arguments")
or tool_call.get("input")
or {}
)
return call_id, sanitize_tool_name(func_name), func_args
return None
@@ -1260,6 +1267,13 @@ def is_tool_call_list(response: list[Any]) -> bool:
# Bedrock-style
if isinstance(first_item, dict) and "name" in first_item and "input" in first_item:
return True
# OpenAI Responses API-style (flat dict, no nested "function" key)
if (
isinstance(first_item, dict)
and "name" in first_item
and "arguments" in first_item
):
return True
# Gemini-style
if hasattr(first_item, "function_call") and first_item.function_call:
return True