fix: normalize incomplete tool requests at extraction layer

When LLMs output valid JSON with tool_name but missing/malformed tool_args, json_parse_dirty() returned the incomplete dict as-is, causing ValueError crashes in validate_tool_request().

Root cause fix: normalize tool requests in json_parse_dirty() before returning them:

- Missing tool_args -> defaults to {}

- tool_args as string -> converts to dict

- tool_args as non-dict -> defaults to {}

- tool key -> normalized to tool_name

Non-tool requests are left untouched.

Related: #1458, #1466
This commit is contained in:
Greg DeYoung 2026-04-09 21:41:29 +00:00
parent b5e110ad0d
commit 2c5a13bba7

View file

@ -13,6 +13,16 @@ def json_parse_dirty(json: str) -> dict[str, Any] | None:
try:
data = DirtyJson.parse_string(ext_json)
if isinstance(data, dict):
# Normalize: if it looks like a tool request, ensure required fields exist
if "tool_name" in data or "tool" in data:
# Normalize tool_name (some models use "tool" instead of "tool_name")
if "tool" in data and "tool_name" not in data:
data["tool_name"] = data.pop("tool")
# Normalize tool_args — default to empty dict if missing or not a dict
if "tool_args" not in data:
data["tool_args"] = data.get("args", {})
if not isinstance(data.get("tool_args"), dict):
data["tool_args"] = {}
return data
except Exception:
# If parsing fails, return None instead of crashing