Repository navigation
Conversation
|
👋 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. 🚀 |
…frontend The chat-completions and tokenize routes rejected empty user content (`""` or `[]`) with a 400, while the Python frontend renders it as an empty turn. Drop the content checks and keep only the non-empty messages check, so both frontends accept the same requests. Co-authored-by: Trae Agent <noreply@trae.ai> Signed-off-by: xin.li <xin.li@daocloud.io>
0aca866 to
4090c81
Compare
Overview
The Rust frontend rejects empty user message content on
/v1/chat/completions/renderand/tokenizewith400 BadRequestError: message content cannot be empty, while the Python frontend renders it as a normal (empty) turn. This PR drops the Rust-only content check so both frontends accept the same requests.Fixes #64433 (second bug, see #62741 below for the first one).
Claims
POST /v1/chat/completions/renderaccepts{"role": "user", "content": ""}and{"role": "user", "content": []}and returns200with non-emptytoken_ids.POST /tokenizeaccepts the same two payloads and returns200with non-emptytokens.messages: []is still rejected with400(messages cannot be empty); only the content check is removed.Validation
Reproducer (unit/route level, no server or GPU needed):
Other checks:
cargo fmt --checkpasses.validate_messages()helper, so the change is exercised through the public HTTP entry points (/v1/chat/completions/render,/tokenize), not a test-only path..buildkite/test_areas/rust_frontend_cargo.yamlruns the wholerust/workspace test suite on anyrust/change, so the new tests run in CI.Details
Root cause.
validate_messages()inrust/src/server/src/routes/openai/utils/types.rsis shared by the chat-completions render path and the/tokenizechat form. It was introduced in #44222 together with/tokenizeand added auser-message content check (Text("")/Parts([])→ 400) that has no counterpart in the Python frontend (vllm/renderers/), which accepts empty content and renders an empty turn. Empty content is legal in the OpenAI schema, so the Rust frontend was stricter than both Python and the API spec.Design. Minimal fix: delete the content loop, keep the
messagesnon-empty check (both frontends still require at least one message). Net −8 lines in production code (low complexity, no new abstractions, no behaviour change outside these two routes); the only two call sites areroutes/openai/chat_completions/types.rsandroutes/openai/tokenize/types.rs.Tests.
tokenize_chat_empty_message_content_returns_400asserted the old (incorrect) behaviour and is replaced bytokenize_chat_accepts_empty_message_content; a newrender_chat_accepts_empty_message_contentcovers the render route. Both assert200plus a non-empty token list for""and[], so a regression that silently produces an empty prompt is also caught.Tradeoffs / limitations. Empty turns are now tokenized (a few template control tokens) instead of rejected — same cost profile as Python. Validation was done at the route level; no local GPU/Python environment was available to run a side-by-side end-to-end comparison against the Python frontend, so the parity claim is based on the Python renderer's code path (no empty-content rejection there) rather than a live diff of responses.
Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.