mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
fix(model_tools): log warnings for failed JSON-array coercion
When _coerce_json fails to parse a string as JSON or parses to the wrong type, log a clear WARNING instead of silently returning the original value. When coerce_tool_args wraps a bare string into a single-element list AND the string looks like a JSON array (starts with '['), warn that the model likely emitted a JSON-encoded string instead of a native array. This improves diagnostics for the open-weight model output drift described in #21933 (JSON-array-as-string), as well as any other tool whose array-typed argument arrives stringified through handle_function_call. Note: delegate_task does NOT go through coerce_tool_args (it is in _AGENT_LOOP_TOOLS and dispatched directly from run_agent.py with raw function_args from json.loads). The actual delegate_task fix for #21933 is the previous commit. These logging changes apply to all other array-typed arguments coerced via the shared pipeline. Salvaged from PR #22092.
This commit is contained in:
parent
326ca754ad
commit
7330183d08
1 changed files with 21 additions and 1 deletions
|
|
@ -550,6 +550,16 @@ def coerce_tool_args(tool_name: str, args: Dict[str, Any]) -> Dict[str, Any]:
|
|||
# nullable "null" → None).
|
||||
args[key] = coerced
|
||||
continue
|
||||
# If the string looks like a JSON array but _coerce_value
|
||||
# failed to parse it, warn clearly instead of silently wrapping.
|
||||
if value.strip().startswith("["):
|
||||
logger.warning(
|
||||
"coerce_tool_args: %s.%s looks like a JSON array string "
|
||||
"but could not be parsed — model may have emitted a "
|
||||
"JSON-encoded string instead of a native array. "
|
||||
"Falling back to single-element list.",
|
||||
tool_name, key,
|
||||
)
|
||||
args[key] = [value]
|
||||
logger.info(
|
||||
"coerce_tool_args: wrapped bare string in list for %s.%s",
|
||||
|
|
@ -637,7 +647,12 @@ def _coerce_json(value: str, expected_python_type: type):
|
|||
"""
|
||||
try:
|
||||
parsed = json.loads(value)
|
||||
except (ValueError, TypeError):
|
||||
except (ValueError, TypeError) as exc:
|
||||
logger.warning(
|
||||
"coerce_tool_args: failed to parse string as JSON for expected type %s: %s",
|
||||
expected_python_type.__name__,
|
||||
exc,
|
||||
)
|
||||
return value
|
||||
if isinstance(parsed, expected_python_type):
|
||||
logger.debug(
|
||||
|
|
@ -645,6 +660,11 @@ def _coerce_json(value: str, expected_python_type: type):
|
|||
expected_python_type.__name__,
|
||||
)
|
||||
return parsed
|
||||
logger.warning(
|
||||
"coerce_tool_args: JSON-parsed value is %s, expected %s — skipping coercion",
|
||||
type(parsed).__name__,
|
||||
expected_python_type.__name__,
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue