Skip to content

fix(lite_llm): add JSON-tolerant tool call argument parsing with stri… - #6811

Open
Your7Maxx wants to merge 1 commit into
google:mainfrom
Your7Maxx:fix/json-tolerant-tool-call-parsing
Open

fix(lite_llm): add JSON-tolerant tool call argument parsing with stri…#6811
Your7Maxx wants to merge 1 commit into
google:mainfrom
Your7Maxx:fix/json-tolerant-tool-call-parsing

Conversation

@Your7Maxx

Copy link
Copy Markdown

…ct/non-strict modes

Lightweight models (e.g. DeepSeek V4 Flash) sometimes emit malformed JSON in tool call arguments — missing commas, unquoted keys, trailing garbage, or wrapped in markdown code fences. The existing _parse_tool_call_arguments had repair strategies (ast.literal_eval, unquoted-key quoting) but still raised json.JSONDecodeError as a last resort, and the only callsite in _message_to_generate_content_response did not catch it, causing a hard crash that terminated the entire agent pipeline.

Changes:

  1. Add a strict keyword parameter (default True) to _parse_tool_call_arguments. Existing callers keep the exception-raising behavior. The streaming _finalize_tool_call_response depends on the exception for truncation detection and is unaffected.
  2. Add two new repair strategies before the final fallback:
    • Strip markdown code fences (json ... ) and retry parsing
    • Extract the first balanced {…} block via JSONDecoder.raw_decode to tolerate trailing garbage text
  3. When strict=False (non-strict mode), log a warning and return {} instead of raising — this is used by _message_to_generate_content_response so the pipeline continues with default tool call arguments.
  4. Add 15 unit tests covering valid JSON, empty input, unquoted keys, markdown fences, trailing text, trailing commas, single quotes, nested objects, array values, escaped strings, and strict/non-strict error modes.

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

  • Closes: #issue_number
  • Related: #issue_number

2. Or, if no issue exists, describe the change:

If applicable, please follow the issue templates to provide as much detail as
possible.

Problem:
A clear and concise description of what the problem is.

Solution:
A clear and concise description of what you want to happen and why you choose
this solution.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.

Unit Tests:

Ran all 15 new unit tests and existing related tests:
tests/unittests/models/test_litellm.py::TestParseToolCallArguments 15/15 PASSED
tests/unittests/models/test_litellm.py -k "extract_json_from_deepseek_args or parse_tool_calls_from_text" 5/5 PASSED
All pre-existing test failures are unrelated to this change.

  • [✅] I have added or updated unit tests for my change.
  • [✅] All unit tests pass locally.

Please include a summary of passed pytest results.

Manual End-to-End (E2E) Tests:

Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix.

Checklist

  • [✅] I have read the CONTRIBUTING.md document.
  • [✅] I have performed a self-review of my own code.
  • [✅] I have commented my code, particularly in hard-to-understand areas.
  • [] I have added tests that prove my fix is effective or that my feature works.
  • [✅] New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

Add any other context or screenshots about the feature request here.

@google-cla

google-cla Bot commented Aug 19, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

…ct/non-strict modes

Lightweight models (e.g. DeepSeek V4 Flash) sometimes emit malformed JSON
in tool call arguments — missing commas, unquoted keys, trailing garbage,
or wrapped in markdown code fences. The existing `_parse_tool_call_arguments`
had repair strategies (ast.literal_eval, unquoted-key quoting) but still
raised `json.JSONDecodeError` as a last resort, and the only callsite in
`_message_to_generate_content_response` did not catch it, causing a hard
crash that terminated the entire agent pipeline.

Changes:
1. Add a `strict` keyword parameter (default True) to
   `_parse_tool_call_arguments`. Existing callers keep the exception-raising
   behavior. The streaming `_finalize_tool_call_response` depends on the
   exception for truncation detection and is unaffected.
2. Add two new repair strategies before the final fallback:
   - Strip markdown code fences (```json ... ```) and retry parsing
   - Extract the first balanced {…} block via `JSONDecoder.raw_decode`
     to tolerate trailing garbage text
3. When strict=False (non-strict mode), log a warning and return {} instead
   of raising — this is used by `_message_to_generate_content_response`
   so the pipeline continues with default tool call arguments.
4. Add 15 unit tests covering valid JSON, empty input, unquoted keys,
   markdown fences, trailing text, trailing commas, single quotes,
   nested objects, array values, escaped strings, and strict/non-strict
   error modes.
@Your7Maxx
Your7Maxx force-pushed the fix/json-tolerant-tool-call-parsing branch from fd116f0 to 734858f Compare August 19, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants