fix: repair malformed tool call args in streaming assembly before flagging as truncated
When the streaming path (chat completions) assembled tool call deltas and detected malformed JSON arguments, it set has_truncated_tool_args=True but passed the broken args through unchanged. This triggered the truncation handler which returned a partial result and killed the session (/new required). _many_ malformations are repairable: trailing commas, unclosed brackets, Python None, empty strings. _repair_tool_call_arguments() already existed for the pre-API-request path but wasn't called during streaming assembly. Now when JSON parsing fails during streaming assembly, we attempt repair via _repair_tool_call_arguments() before flagging as truncated. If repair succeeds (returns valid JSON), the tool call proceeds normally. Only truly unrepairable args fall through to the truncation handler. This prevents the most common session-killing failure mode for models like GLM-5.1 that produce trailing commas or unclosed brackets. Tests: 12 new streaming assembly repair tests, all 29 existing repair tests still passing.
This commit is contained in:
16
run_agent.py
16
run_agent.py
@@ -6073,11 +6073,25 @@ class AIAgent:
|
||||
for idx in sorted(tool_calls_acc):
|
||||
tc = tool_calls_acc[idx]
|
||||
arguments = tc["function"]["arguments"]
|
||||
tool_name = tc["function"]["name"] or "?"
|
||||
if arguments and arguments.strip():
|
||||
try:
|
||||
json.loads(arguments)
|
||||
except json.JSONDecodeError:
|
||||
has_truncated_tool_args = True
|
||||
# Attempt repair before flagging as truncated.
|
||||
# Models like GLM-5.1 via Ollama produce trailing
|
||||
# commas, unclosed brackets, Python None, etc.
|
||||
# Without repair, these hit the truncation handler
|
||||
# and kill the session. _repair_tool_call_arguments
|
||||
# returns "{}" for unrepairable args, which is far
|
||||
# better than a crashed session.
|
||||
repaired = _repair_tool_call_arguments(arguments, tool_name)
|
||||
if repaired != "{}":
|
||||
# Successfully repaired — use the fixed args
|
||||
arguments = repaired
|
||||
else:
|
||||
# Unrepairable — flag for truncation handling
|
||||
has_truncated_tool_args = True
|
||||
mock_tool_calls.append(SimpleNamespace(
|
||||
id=tc["id"],
|
||||
type=tc["type"],
|
||||
|
||||
Reference in New Issue
Block a user