Skip to content

Commit 960bc21

Browse files
authored
fix: resolve EmptyModelOutputError and enhance tool fallback robustness (#7375)
Improve robustness of tool call handling in OpenAI completions and agent tool loop by avoiding premature filtering and surfacing clearer errors when tools are missing. * Refactor tool call argument handling in openai_source.py * Improve error logging for missing tools Log available tools when a specified tool is not found.
1 parent 1199b70 commit 960bc21

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

astrbot/core/agent/runners/tool_loop_agent_runner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,16 +924,18 @@ def _append_tool_call_result(tool_call_id: str, content: str) -> None:
924924
# in 'skills_like' mode, raw.func_tool is light schema, does not have handler
925925
# so we need to get the tool from the raw tool set
926926
func_tool = self._skill_like_raw_tool_set.get_tool(func_tool_name)
927+
available_tools = self._skill_like_raw_tool_set.names()
927928
else:
928929
func_tool = req.func_tool.get_tool(func_tool_name)
930+
available_tools = req.func_tool.names()
929931

930932
logger.info(f"使用工具:{func_tool_name},参数:{func_tool_args}")
931933

932934
if not func_tool:
933935
logger.warning(f"未找到指定的工具: {func_tool_name},将跳过。")
934936
_append_tool_call_result(
935937
func_tool_id,
936-
f"error: Tool {func_tool_name} not found.",
938+
f"error: Tool {func_tool_name} not found. Available tools are: {', '.join(available_tools)}",
937939
)
938940
continue
939941

astrbot/core/provider/sources/openai_source.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -854,24 +854,26 @@ async def _parse_openai_completion(
854854
# 工具集未提供
855855
# Should be unreachable
856856
raise Exception("工具集未提供")
857-
for tool in tools.func_list:
858-
if (
859-
tool_call.type == "function"
860-
and tool.name == tool_call.function.name
861-
):
862-
# workaround for #1454
863-
if isinstance(tool_call.function.arguments, str):
857+
858+
if tool_call.type == "function":
859+
# workaround for #1454
860+
if isinstance(tool_call.function.arguments, str):
861+
try:
864862
args = json.loads(tool_call.function.arguments)
865-
else:
866-
args = tool_call.function.arguments
867-
args_ls.append(args)
868-
func_name_ls.append(tool_call.function.name)
869-
tool_call_ids.append(tool_call.id)
870-
871-
# gemini-2.5 / gemini-3 series extra_content handling
872-
extra_content = getattr(tool_call, "extra_content", None)
873-
if extra_content is not None:
874-
tool_call_extra_content_dict[tool_call.id] = extra_content
863+
except json.JSONDecodeError as e:
864+
logger.error(f"解析参数失败: {e}")
865+
args = {}
866+
else:
867+
args = tool_call.function.arguments
868+
args_ls.append(args)
869+
func_name_ls.append(tool_call.function.name)
870+
tool_call_ids.append(tool_call.id)
871+
872+
# gemini-2.5 / gemini-3 series extra_content handling
873+
extra_content = getattr(tool_call, "extra_content", None)
874+
if extra_content is not None:
875+
tool_call_extra_content_dict[tool_call.id] = extra_content
876+
875877
llm_response.role = "tool"
876878
llm_response.tools_call_args = args_ls
877879
llm_response.tools_call_name = func_name_ls

0 commit comments

Comments
 (0)