fix(TOOLS-STREAMING-PARSER): a parenthesized Gemma-4 tool call does not parse, in both gemma4 surfaces
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 423
- Forks
- 53
- Avg merge
- 20h 26m
- Merged PRs (30d)
- 310
Description
Row: TOOLS-STREAMING-PARSER (.agents/engine-matrix.md:165) for the engine config, and TOOLS-PARSER-BREADTH (.agents/engine-matrix.md:166) for the text-seam copy. Both resolved by line number before filing.
Found by wave PORTQ-7 (#2717) re-deriving PORT-NOW entry [246], upstream 9c8e90eb26 vllm#53657. Nothing was executed.
What is missing
A Gemma-4 tool call written with parentheses — call:name(a:1)<tool_call|> — is not parsed. Upstream added an OPEN_PAREN terminal, two TOOL_NAME transitions, and an unbalanced-trailing-paren strip. This tree carries the exact pre-commit state in two places.
Engine config, src/vllm/parser/engine/configs.cpp:
- the terminal map at
:820-824is{THINK_START, THINK_END, TOOL_START, TOOL_END, CALL_PREFIX, OPEN_BRACE}— noOPEN_PAREN; - the transition table at
:829-843holds exactly the eleven pre-commit entries, and jumps straight from{{S::TOOL_NAME, "OPEN_BRACE"}, ...}at:839to{{S::TOOL_ARGS, "TOOL_END"}, ...}at:840. Both transitions the commit adds are absent; - the converter at
:800-804isif (!text.empty() && text.back() == '}') text.pop_back();— theendswith(")") and count("(") < count(")")arm is not there.
Text seam, src/vllm/entrypoints/openai/tool_parsers/gemma4.cpp:256, is the identical single-condition strip, under a comment at :252 that names _gemma4_arg_converter.
Both sites are the claim's full enumeration, not a sample: gemma4_arg_converter has exactly two implementations in this tree (configs.cpp:800, gemma4.cpp:256) and one config (configs.cpp:811). functiongemma is a different wire format and structural_tags.cpp carries no gemma4 mapping.
grep -rn "OPEN_PAREN" src/ include/ tests/ returns rc 1 with no hits; the positive control OPEN_BRACE through the identical probe form and scope returns 2 (configs.cpp:823, :839).
The commit is the whole distance
git show 5559679229:vllm/parser/gemma4.py:285-380 is character-for-character this tree's shape — same six terminals, same eleven transitions, same one-condition strip — and include/vllm/parser/gemma4.h:1 records the port as "@ 555967922". Not a pre-pin hole.
The second transition is a separate fix and must not be dropped
{S::TOOL_NAME, "TOOL_END"} -> CONTENT/{TOOL_CALL_END} is what keeps a call with no arguments at all from wedging in TOOL_NAME. It is independent of the paren handling, and reading the change as "add paren support" loses it.
Size
~12-16 product lines across two files. Tests must be authored, not ported: git show --stat 9c8e90eb26 lists one file and ships no test, so there is no upstream case to mirror. Budget ~60-100 test lines covering call:name(a:1)<tool_call|>, a balanced paren inside a delimited string (which must not be stripped), and the bare no-arguments call:name<tool_call|>, in both tests/vllm/parser/engine/ and tests/vllm/entrypoints/openai/tool_parsers/test_gemma4*.
Not to be confused with
d29dc3ab87 vllm#52430, the other in-range touch of gemma4.py, which flips the enable_thinking default and touches neither the converter nor the transitions. PORTQ-5 read it as entry [192]; it is a disjoint gap.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the converter and transition definitions in src/vllm/parser/engine/configs.cpp and the matching converter in src/vllm/entrypoints/openai/tool_parsers/gemma4.cpp. Run the parser tests under tests/vllm/parser/engine/ and tests/vllm/entrypoints/openai/tool_parsers/test_gemma4* before adding cases for parenthesized arguments, balanced parentheses in strings, and bare calls. Done means all cases pass in both Gemma-4 surfaces.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100