From 2c5a13bba7da026af5b2ee891764e6eefbe317c9 Mon Sep 17 00:00:00 2001 From: Greg DeYoung Date: Thu, 9 Apr 2026 21:41:29 +0000 Subject: [PATCH] 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 --- helpers/extract_tools.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/helpers/extract_tools.py b/helpers/extract_tools.py index d939cc534..2b92c3aed 100644 --- a/helpers/extract_tools.py +++ b/helpers/extract_tools.py @@ -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