Skip to content

Conversation

@ayushag-nv
Copy link
Contributor

@ayushag-nv ayushag-nv commented Aug 19, 2025

Overview:

  • PR adds mistral and phi4 tool calling parsers.
  • Expands test suite for testing new lines in tool parsing

Details:

Where should the reviewer start?

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

  • closes GitHub issue: #xxx

Summary by CodeRabbit

  • New Features

    • Added support for Mistral and Phi-4 tool-calling formats, enabling seamless parsing of their outputs.
  • Bug Fixes

    • Improved reliability of tool-call JSON parsing with stricter extraction and smarter fallbacks, reducing malformed or missed parses, including better handling of wrapped arrays and whitespace.
  • Tests

    • Expanded test coverage to validate single/multiple calls, nested arguments, and varied start-token scenarios across supported parsers.

@ayushag-nv ayushag-nv self-assigned this Aug 19, 2025
@ayushag-nv ayushag-nv requested a review from a team as a code owner August 19, 2025 00:12
@copy-pr-bot
Copy link

copy-pr-bot bot commented Aug 19, 2025

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

Walkthrough

Adds stricter JSON extraction and fallback handling in the tool-calling JSON parser, introduces two new model-specific parser configurations (mistral, phi4), and wires them into detection. Also adds a debug print for parsed JSON.

Changes

Cohort / File(s) Summary
JSON parsing tweaks
lib/llm/src/postprocessor/tool_calling/json_parser.rs
Tightened candidate extraction to segments starting with '{', search for last '}', trim candidates, validate via serde_json, and adjust fallback to return input with start token stripped; added debug print of final JSON.
Parser configurations and routing
lib/llm/src/postprocessor/tool_calling/parsers.rs
Added ToolCallConfig::mistral() and ::phi4() with JSON format and specific start tokens; integrated into detect_and_parse_tool_call mapping; no changes to existing parser semantics.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Detector as detect_and_parse_tool_call
  participant Config as ToolCallConfig
  participant JSONP as JsonParser

  Client->>Detector: parse(input, parser="mistral"/"phi4"/...)
  Detector->>Config: select config by parser key
  Config-->>Detector: ToolCallConfig (start/end tokens, Json)
  Detector->>JSONP: try_tool_call_parse_json(input, config)
  JSONP->>JSONP: extract '{...}' segments, trim, validate
  JSONP-->>Detector: parsed tool calls or stripped fallback
  Detector-->>Client: result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

In curly braces, truths now dwell,
I sniff the JSON—parsèd well.
Mistral winds and phi4’s tune,
Start tokens hum a tidy rune.
Hop, trim, validate—no stall,
Debug prints guide my nightly crawl.
Thump! Tool calls for one and all.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/llm/src/postprocessor/tool_calling/json_parser.rs (1)

77-81: Clarify intent and consider array segments for single-token cases

The comment says “brace/bracket,” but the code only searches for '}'. If an array follows the start token (e.g., “[{...}, ...]”), this branch is skipped and we fall back. That’s OK for many cases, but we’ll miss multiple calls if there are several “single-token” segments each starting with '['.

  • Update the comment for accuracy.
  • Optional: also handle s.starts_with('[') by cutting at the last ']' and attempting to parse it as a JSON array.

Example minimal comment fix within this block:

-            // Trim trailing non-JSON by cutting at the last closing brace/bracket
+            // Trim trailing non-JSON by cutting at the last closing brace

If you want to also handle arrays here (optional), I can provide a patch that safely parses '[' segments and merges/normalizes them. Let me know.

lib/llm/src/postprocessor/tool_calling/parsers.rs (4)

103-112: Mistral config looks good; consider adding a brief doc comment

Configuration is straightforward and consistent with how the single-token handler expects the start token. A short doc comment helps future maintainers.

+    /// Default configuration for Mistral tool calls.
+    /// Models may emit a `[TOOL_CALLS]` prefix followed by a JSON array.
     pub fn mistral() -> Self {

561-579: Test name nit: missing underscore

Minor nit: “with_start_tokenwith_new_lines” -> “with_start_token_with_new_lines”.

-    fn test_mistralai_mistral_7b_instruct_v03_single_with_start_tokenwith_new_lines() {
+    fn test_mistralai_mistral_7b_instruct_v03_single_with_start_token_with_new_lines() {

841-857: Test name nit: says “multiple” but input contains a single call

The name “..._multiple_with_new_lines” is misleading here; the input has one call.

-    fn test_detect_and_parse_tool_call_default_parser_llama3_json_without_python_tag_multiple_with_new_lines(
+    fn test_detect_and_parse_tool_call_default_parser_llama3_json_without_python_tag_with_new_lines(

157-181: Optional: avoid per-call HashMap allocation in detect_and_parse_tool_call

Constructing the parser map on every call is small but avoidable. Consider a static Lazy or a direct match on the parser string.

Happy to draft a small refactor using once_cell::sync::Lazy if you want.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0376e72 and 63b4179.

📒 Files selected for processing (2)
  • lib/llm/src/postprocessor/tool_calling/json_parser.rs (2 hunks)
  • lib/llm/src/postprocessor/tool_calling/parsers.rs (9 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
lib/llm/src/postprocessor/tool_calling/parsers.rs (1)
lib/llm/src/protocols/openai/chat_completions/aggregator.rs (1)
  • default (67-69)
🪛 GitHub Actions: Pre Merge Validation of (ai-dynamo/dynamo/refs/pull/2510/merge) by ayushag-nv.
lib/llm/src/postprocessor/tool_calling/parsers.rs

[error] 1-1: Pre-commit trailing-whitespace check failed; file modified by hook. Trailing whitespace detected and fixed by the 'trailing-whitespace' hook.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build and Test - dynamo
  • GitHub Check: pre-merge-rust (lib/bindings/python)
  • GitHub Check: pre-merge-rust (lib/runtime/examples)
  • GitHub Check: pre-merge-rust (.)
🔇 Additional comments (14)
lib/llm/src/postprocessor/tool_calling/parsers.rs (14)

114-123: phi4 config is appropriate; relies on single-token array handling

Using "functools" (without the '[') is a good choice because the array fallback needs the '[' to remain. With the proposed json_parser fallback fix (strip from first occurrence), this will also work when the token isn’t at position 0.

Consider adding a test where the response contains a short preface before “functools[...]” to exercise this path.


167-169: Wiring new parsers into detection map looks correct

Both "mistral" and "phi4" are added alongside existing parsers. Behavior remains backward compatible.


332-360: Great newline-tolerance coverage for nemotron_deci

This test strengthens confidence in the regex extractor with multi-line arrays inside tags.


413-438: Hermes multi-call with newlines: solid coverage

Confirms the end-token with leading newline is matched and multiple tool_call blocks are handled.


483-507: Mistral simple with newlines: good

Validates that plain arrays (no start token present) still parse under the Mistral config.


509-524: Mistral multiple calls (no start token): good

Confirms vector parsing path.


526-547: Mistral multiple with newlines: good

Exercises pretty-printed arrays.


597-622: Mistral with start token, multiple and newlines: good

Validates that a prefixed array parses as multiple calls.


635-648: Default llama3_json with newlines: good

Covers the plain JSON object path under the default-detected parser.


662-676: llama3_json with python tag + newlines: good

Covers the single-token without end-token flow for objects.


677-696: llama3_json multiple python tags + newlines: good

Confirms multiple single-token segments are aggregated.


822-840: Default parser with python tag + newlines: good

Validates detection default path handles the python tag.


870-924: phi4 tests are thorough; add a prefaced variant to harden further

The coverage for single, multiple, nested, and parameters-vs-arguments is great. Add one case with a natural-language preface before “functools[...]” to ensure robustness when the token isn’t at position 0. This will be fully supported after the json_parser fallback fix.

Would you like me to add a test like:

  • input: "Tool calls:\nfunctools[ { ... }, { ... } ]"
  • parser: Some("phi4")
  • expectation: parse both calls

332-360: Note on trailing whitespace pre-commit failure

CI flagged and auto-fixed trailing whitespace. Locally running pre-commit hooks before pushing will avoid future CI churn.

If you don’t have pre-commit set up locally:

  • Install: pip install pre-commit
  • Init: pre-commit install
  • Run: pre-commit run -a

Also applies to: 413-438, 483-507, 526-547, 561-579, 597-622, 635-648, 662-676, 677-696, 822-840, 841-857

@ayushag-nv ayushag-nv enabled auto-merge (squash) August 19, 2025 15:12
@ayushag-nv ayushag-nv merged commit 1ed877f into main Aug 19, 2025
10 checks passed
@ayushag-nv ayushag-nv deleted the ayushag/mistral_nd_phi4_parsers branch August 19, 2025 15:36
@coderabbitai coderabbitai bot mentioned this pull request Aug 19, 2025
hhzhang16 pushed a commit that referenced this pull request Aug 27, 2025
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants