Compare commits

...

3 Commits

Author SHA1 Message Date
Soulter
b7df91dff0 fix: update docstring to clarify normalization of malformed tool call names 2026-07-05 10:52:40 +08:00
Weilong Liao
9ac0f374ba Update astrbot/core/agent/runners/tool_loop_agent_runner.py
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2026-07-05 10:50:57 +08:00
Soulter
037e789deb feat: add sanitation for malformed tool call names in ToolLoopAgentRunner
fixes: #8929
closes: #8911
2026-07-05 10:49:38 +08:00

View File

@@ -145,6 +145,7 @@ class ToolLoopAgentRunner(BaseAgentRunner[TContext]):
REPEATED_TOOL_NOTICE_L1_THRESHOLD = 3
REPEATED_TOOL_NOTICE_L2_THRESHOLD = 4
REPEATED_TOOL_NOTICE_L3_THRESHOLD = 5
MALFORMED_TOOL_NAME_PLACEHOLDER = "__malformed_tool_name__"
REPEATED_TOOL_NOTICE_L1_TEMPLATE = (
"\n\n[SYSTEM NOTICE] By the way, you have executed the same tool "
"`{tool_name}` {streak} times consecutively. Double-check whether another "
@@ -532,6 +533,7 @@ class ToolLoopAgentRunner(BaseAgentRunner[TContext]):
)
break
self._sanitize_malformed_tool_calls(resp)
yield resp
return
@@ -689,6 +691,22 @@ class ToolLoopAgentRunner(BaseAgentRunner[TContext]):
streak=streak,
)
def _sanitize_malformed_tool_calls(
self,
llm_resp: LLMResponse,
) -> None:
"""Normalize malformed tool call names.
Args:
llm_resp: The LLM response whose tool call lists should be sanitized.
"""
llm_resp.tools_call_name = [
self.MALFORMED_TOOL_NAME_PLACEHOLDER
if tool_name is None or tool_name.strip() == ""
else tool_name
for tool_name in llm_resp.tools_call_name
]
@override
async def step(self):
"""Process a single step of the agent.
@@ -1312,6 +1330,7 @@ class ToolLoopAgentRunner(BaseAgentRunner[TContext]):
)
if requery_resp:
llm_resp = requery_resp
self._sanitize_malformed_tool_calls(llm_resp)
# If the re-query still returns no tool calls, and also does not have a meaningful assistant reply,
# we consider it as a failure of the LLM to follow the tool-use instruction,
@@ -1339,6 +1358,7 @@ class ToolLoopAgentRunner(BaseAgentRunner[TContext]):
)
if repair_resp:
llm_resp = repair_resp
self._sanitize_malformed_tool_calls(llm_resp)
return llm_resp, subset