Skip to content

Conversation

@DevonPeroutky
Copy link
Contributor

@DevonPeroutky DevonPeroutky commented Aug 12, 2025

Issue

The XLAM Tool Parser Documentation states it supports the following formats:

Direct JSON arrays: Output strings that are JSON arrays starting with [ and ending with ]
Thinking tags: Using <think>...</think> tags containing JSON arrays
Code blocks: JSON in code blocks (json ...)
Tool calls tags: Using [TOOL_CALLS] or <tool_call>...</tool_call> tags

However, the <tool_call>...</tool_call> tag format is broken/not-supported in streaming mode. The only output format that is supported in streaming mode is "Direct JSON arrays".

Additionally, none of the formats support any preamble before the tool call. Example:

Sure, I can help with that! <tool_call>...</tool_call>

This PR fix that as well for all formats.

Proposed Plan

This PR adds support for the <tool_call>...</tool_call> tag output format in streaming mode for the XLAM Tool Parser, while maintaining the existing functionality for every other output format.

Test Plan

I've added additional unit test cases for both synchronous and steaming-mode, to verify all possible XLAM formats are parsed correctly. The existing tests should catch any possible regressions.

Test Results

Local

=============================================================================================================== test session starts ================================================================================================================
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_no_tools PASSED                                                                                                                                                             [  7%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls[parallel_tool_calls] PASSED                                                                                                                                                 [ 14%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls[single_tool_with_think_tag] PASSED                                                                                                                                          [ 21%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls[single_tool_with_json_code_block] PASSED                                                                                                                                    [ 28%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls[single_tool_with_tool_calls_tag] PASSED                                                                                                                                     [ 35%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls[single_tool_with_tool_call_xml_tags] PASSED                                                                                                                                 [ 42%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_list_structure[list_structured_tool_call] PASSED                                                                                                                            [ 50%]
tests/tool_use/test_xlam_tool_parser.py::test_preprocess_model_output PASSED                                                                                                                                                                 [ 57%]
tests/tool_use/test_xlam_tool_parser.py::test_streaming_with_list_structure PASSED                                                                                                                                                           [ 64%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_streaming_incremental[parallel_tool_calls] PASSED                                                                                                                           [ 71%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_streaming_incremental[single_tool_with_think_tag] PASSED                                                                                                                    [ 78%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_streaming_incremental[single_tool_with_json_code_block] PASSED                                                                                                              [ 85%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_streaming_incremental[single_tool_with_tool_calls_tag] PASSED                                                                                                               [ 92%]
tests/tool_use/test_xlam_tool_parser.py::test_extract_tool_calls_streaming_incremental[single_tool_with_tool_call_xml_tags] PASSED                                                                                                           [100%]

================================================================================================================= warnings summary =================================================================================================================
<frozen importlib._bootstrap>:488
  <frozen importlib._bootstrap>:488: DeprecationWarning: builtin type SwigPyPacked has no __module__ attribute

<frozen importlib._bootstrap>:488
  <frozen importlib._bootstrap>:488: DeprecationWarning: builtin type SwigPyObject has no __module__ attribute

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
========================================================================================================== 14 passed, 2 warnings in 2.14s ====

BuildKite

TBD

@DevonPeroutky DevonPeroutky requested a review from aarnphm as a code owner August 12, 2025 22:57
@github-actions
Copy link

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

Just a reminder: PRs would not trigger full CI run by default. Instead, it would only run fastcheck CI which starts running only a small and essential subset of CI tests to quickly catch errors. You can run other CI tests on top of those by going to your fastcheck build on Buildkite UI (linked in the PR checks section) and unblock them. If you do not have permission to unblock, ping simon-mo or khluu to add you in our Buildkite org.

Once the PR is approved and ready to go, your PR reviewer(s) can run CI to test the changes comprehensively before merging.

To run CI, PR reviewers can either: Add ready label to the PR or enable auto-merge.

🚀

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly adds support for the <tool_call> format in streaming mode by leveraging the existing preprocess_model_output method. The changes to the parser logic are sound. The accompanying tests have been updated, but the new streaming test is confusing and could be improved for clarity and correctness. I've provided a suggestion to refactor the test to be more straightforward and representative of a streaming scenario.

@DevonPeroutky
Copy link
Contributor Author

@simon-mo or @khluu , could I get access to the buildkite so I can unblock the relevant tests for this? Thanks 🙏

@DevonPeroutky DevonPeroutky marked this pull request as ready for review August 12, 2025 23:16
@DevonPeroutky DevonPeroutky force-pushed the fix-xlam-stream-parser branch from b394d10 to 2c12b4d Compare August 14, 2025 21:25
@DevonPeroutky
Copy link
Contributor Author

@aarnphm Is there anything else you need from me? Or do I just sit tight?

@aarnphm
Copy link
Collaborator

aarnphm commented Aug 26, 2025

@aarnphm Is there anything else you need from me? Or do I just sit tight?

Can u check the CI failure here?

@aarnphm aarnphm enabled auto-merge (squash) August 26, 2025 22:52
@github-actions github-actions bot added the ready ONLY add when PR is ready to merge/full CI is needed label Aug 26, 2025
…ming mode with the XLAM tool parser

Signed-off-by: Devon Peroutky <devon@kindo.ai>
auto-merge was automatically disabled August 28, 2025 02:22

Head branch was pushed to by a user without write access

@DevonPeroutky DevonPeroutky force-pushed the fix-xlam-stream-parser branch 2 times, most recently from 0e2a07f to d199a97 Compare August 28, 2025 02:30
Signed-off-by: Devon Peroutky <devon@kindo.ai>
@DevonPeroutky DevonPeroutky force-pushed the fix-xlam-stream-parser branch from d199a97 to ec50893 Compare August 28, 2025 04:29
…ling

Signed-off-by: Devon Peroutky <devon@kindo.ai>
@DevonPeroutky DevonPeroutky force-pushed the fix-xlam-stream-parser branch from ec50893 to 26f11d8 Compare August 28, 2025 04:31
@DevonPeroutky
Copy link
Contributor Author

@aarnphm

All the tests are passing now! I modified the implementation slightly since you first approved it, FYI. However, I've add a lot more comprehensive tests for each possible XLAM format to account for the changes.

@DevonPeroutky DevonPeroutky requested a review from aarnphm August 28, 2025 21:05
Copy link
Member

@DarkLight1337 DarkLight1337 left a comment

Choose a reason for hiding this comment

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

Thanks and sorry for the delay

@DarkLight1337 DarkLight1337 merged commit 422e793 into vllm-project:main Sep 1, 2025
39 checks passed
didier-durand pushed a commit to didier-durand/vllm that referenced this pull request Sep 1, 2025
…LAM Tool Parser (vllm-project#22769)

Signed-off-by: Devon Peroutky <devon@kindo.ai>
eicherseiji pushed a commit to eicherseiji/vllm that referenced this pull request Sep 9, 2025
…LAM Tool Parser (vllm-project#22769)

Signed-off-by: Devon Peroutky <devon@kindo.ai>
FeiDaLI pushed a commit to FeiDaLI/vllm that referenced this pull request Sep 25, 2025
…LAM Tool Parser (vllm-project#22769)

Signed-off-by: Devon Peroutky <devon@kindo.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend ready ONLY add when PR is ready to merge/full CI is needed tool-calling

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants