Decode raw tool arguments with consistent diagnostics.
(*, tool_name: str, input_json: str)
| 1573 | |
| 1574 | |
| 1575 | def _parse_function_tool_json_input(*, tool_name: str, input_json: str) -> dict[str, Any]: |
| 1576 | """Decode raw tool arguments with consistent diagnostics.""" |
| 1577 | json_decode_error: Exception | None = None |
| 1578 | try: |
| 1579 | parsed = json.loads(input_json) if input_json else {} |
| 1580 | except Exception as exc: |
| 1581 | json_decode_error = exc |
| 1582 | |
| 1583 | if json_decode_error is not None: |
| 1584 | base_message = f"Invalid JSON input for tool {tool_name}" |
| 1585 | if _debug.DONT_LOG_TOOL_DATA: |
| 1586 | logger.debug(base_message) |
| 1587 | # Raise outside the ``except`` block so the JSONDecodeError, which |
| 1588 | # carries the raw payload in ``.doc``, is not attached as the |
| 1589 | # ``__context__`` of the redacted ModelBehaviorError. |
| 1590 | raise ModelBehaviorError(base_message) |
| 1591 | detailed_message = f"{base_message}: {input_json}" |
| 1592 | logger.debug(detailed_message) |
| 1593 | raise ModelBehaviorError(detailed_message) from json_decode_error |
| 1594 | |
| 1595 | if not isinstance(parsed, dict): |
| 1596 | raise ModelBehaviorError(f"Invalid JSON input for tool {tool_name}: expected a JSON object") |
| 1597 | |
| 1598 | return parsed |
| 1599 | |
| 1600 | |
| 1601 | def _log_function_tool_invocation(*, tool_name: str, input_json: str) -> None: |
no test coverage detected