[Bugfix][Parser] Coerce nested strings in decoded XML arguments - #55574
Dreamer-HIT wants to merge 1 commit into
Conversation
Apply properties/items recursion to strings inside decoded XML argument containers. Preserve their native JSON scalars and keep the existing native-container entry points unchanged. Extend Qwen3 parser coverage for nested numeric, boolean and nullable strings in streaming and non-streaming output, plus native scalar and string controls. Addresses the independent recursion gap discussed under PR vllm-project#50933; does not implement schema reference resolution for issue vllm-project#46924. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: JIE <daijiehit@foxmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe parser now preserves native scalar types while coercing nested string values inside decoded containers. Qwen3 tests cover object, array, streaming, boolean, null, numeric, and schema-kind combinations. ChangesScalar Coercion
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to Decoded tool-call containers now coerce nested string values according to inline schemas while retaining native JSON scalar types. Nested, streaming, and scalar-preservation coverage is present, with no identified merge-blocking risk. 🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
Full details: Linked Issues checkExplanation The pull request fixes inline decoded-container recursion, but linked issue Resolution Implement root-schema $ref/$defs resolution or consistent dereferencing, preserve structured nested output for referenced schemas, and add regression tests. Alternatively, link this pull request to an issue that covers the inline-schema recursion fix.
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
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. Comment |
|
👋 Hi! Thank you for contributing to the vLLM project. 💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment Once the PR is approved or has the If you have any questions, please reach out to us on Slack at https://slack.vllm.ai. Agent GuidelinesIMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban. 🚀 |
Purpose
The XML tool parser decodes an object or array parameter from a string, but
ParserEngine._coerce_valueimmediately returns that container without applyingthe existing
properties/itemsrecursion. For an inline schema declaring anarray of integers,
<parameter=limits>["10", "20", "30"]</parameter>thereforeproduces string elements. Nested numeric, boolean and nullable fields have the
same problem, including in streaming responses. Clients expecting the declared
argument types can reject these tool calls.
After a string successfully converts to a dict or list, recurse through its
properties/itemsand coerce nested strings. An internalcoerce_native_scalarsflag keeps the decoded container's existing JSONnumbers, booleans and nulls unchanged. Without that distinction, the existing
fallback to
stringfor untyped schemas would turn{"n": 1}into{"n": "1"}underproperties: {n: {}}, introducing a regression.Existing native scalar coercion remains enabled by default for native JSON
input. Stringified container children in such input also gain the new
recursion. String conversion, union precedence and best-effort failure behavior
are unchanged.
This is a nested-string correction, not full schema normalization: a decoded
native
1still remains1even if its schema requestsstring, as it didbefore. No JSON Schema keyword support is added.
Extend the existing Qwen3 parser tests to cover both native JSON values and
string values requiring nested conversion. The existing string-array guard
continues to ensure that values such as
"42"stay strings when requested.Add native scalar preservation cases for objects and arrays with empty,
description-only,
const, and explicit string schemas.Duplicate-work check
This is the independent recursion bug explicitly identified and deferred by
the author of #50933 in this comment,
while investigating #46924. It reproduces with inline schemas and does not
implement the
$ref/$defsresolution in #50933. #54964 fixes a separateHermes/Granite outer-arguments double-encoding problem. This PR does not claim
to close #46924.
Read #46924 and its comments and searched open PRs for
46924 in:body,nested coercion,XML recursive, and_coerce_valuebefore preparing thischange.
Checked the actual patches of #53729, #51577 and #49318 as well. #53729 changes
adjacent coercion statements for schemas without concrete types but retains
the string-to-container early return. This change avoids depending on its
type-inference changes by preserving decoded native scalars. #51577
migrates Llama JSON parsing and still delegates string coercion to this method.
#49318 adds Kimi argument conversion and tests native nested objects, without
changing this string-to-container path.
Test Plan and Results
Environment: WSL Ubuntu 24.04, Python 3.12.14, PyTorch 2.13.0+cu132. Python source
base:
569adb5a9780f9c02d22a6b29826acf711512356. Parser tests use CPU and theexisting mock-tokenizer fixtures; they exercise the public streaming and
non-streaming parser entry points.
already had the expected JSON types, so they did not catch the missing step.
Failures cover numeric object fields, numeric array items, and boolean/null
fields in an array of objects in non-streaming and streaming responses.
including 24 native-scalar preservation cases.
Model smoke check: Qwen2.5-0.5B-Instruct at revision
7ae557604adf67be50417f59c2c2f167def9a775, FP16 on an RTX 4060 Laptop 8 GB,eager TRITON_ATTN, max model length/batched tokens 1024, max sequences 2,
memory utilization 0.55, prefix caching off, seed 0, temperature 0,
256 output-token limit. V1 model runner and PyTorch sampling were selected
for WSL compatibility.
Generated seven XML calls and replayed each exact text and generated token-ID
sequence through the public
ParserEngine.parsebefore and after the change.The baseline restores both
_coerce_valueand_coerce_dictfrom the sourcebase above. No generated output was edited or replaced.
containing quoted numbers, and an object with
min_stars: "125".native-scalar object with empty/const schemas stayed correct.
the boolean/null array, and an untyped array where the model emitted
"1"instead of the requested native
1. One intended native-integer controlalso emitted quoted numbers and therefore became a fix witness instead.
This is a targeted shared-parser smoke check using prompted Qwen2.5 outputs,
not a Qwen3-Coder evaluation or a general accuracy/throughput benchmark.
Boolean/null coercion and native-array preservation are covered by the unit
tests above.
Runtime provenance: imported this checkout via explicit
PYTHONPATH, withofficial cu130 native artifacts for the exact source base above. An editable
packaging pass was stopped after artifact extraction because WSL file scans
were slow; existing package registration was retained. New and old dependency
requirements matched, and the actual source/extension import paths and CUDA
availability were verified before the smoke run.
Applicable pre-commit hooks and the additional Python 3.12 mypy hook passed
on both changed files:
The unused
actionlinthook was excluded because no workflow YAML changedand its Go environment bootstrap previously timed out on this host.
All applicable commit hooks and the DCO sign-off hook passed during creation
of the final commit. The separate final Python 3.12 mypy run also exited 0.
AI assistance: Codex assisted with issue triage, diagnosis, implementation,
regression tests and local validation. Commits include AI attribution and DCO
sign-off.