Skip to content

[Frontend][Responses API] Fold developer-role input messages into system instructions - #43590

Merged
sfeng33 merged 5 commits into
vllm-project:mainfrom
chaunceyjiang:fix/responses-fold-developer-into-instruction
Jun 3, 2026
Merged

[Frontend][Responses API] Fold developer-role input messages into system instructions#43590
sfeng33 merged 5 commits into
vllm-project:mainfrom
chaunceyjiang:fix/responses-fold-developer-into-instruction

Conversation

@chaunceyjiang

@chaunceyjiang chaunceyjiang commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Co-authored-by: kdcyberdude kdsingh.cyberdude@gmail.com
Co-Authored-By: Ben Browning bbrownin@redhat.com
Signed-off-by: chaunceyjiang chaunceyjiang@gmail.com

Purpose

OpenAI's Responses API allows role: "developer" items in the input array. Clients such as Codex send developer messages for harness / policy text. vLLM's non-harmony path previously forwarded those items into the chat template, which only accepts standard roles and returned Unexpected message role.

fix #42475
fix #42407

Test Plan

Test Result


Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

…tructions

Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>

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

Copy link
Copy Markdown
Contributor

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 introduces message normalization for chat templates, mapping 'developer' roles to 'system' and merging multiple system messages into a single entry at the start of the message list. It also adds comprehensive unit tests for these scenarios. Feedback indicates that the normalization logic is currently too restrictive because it checks for a 'type' field that standard OpenAI messages lack, which may cause them to be skipped. Additionally, the text extraction logic should be updated to support the standard 'text' content part type to ensure compatibility with standard chat messages.

Comment thread vllm/entrypoints/openai/responses/utils.py Outdated
Comment thread vllm/entrypoints/openai/responses/utils.py Outdated
@chaunceyjiang

Copy link
Copy Markdown
Collaborator Author

I’m not sure whether we need a command-line flag to enable or disable this feature, since dsv4 pro already supports the developer role.

Comment on lines +152 to +155
1. Maps the "developer" role to "system" because most HF chat templates
do not recognize "developer".
2. Merges all system messages into a single message so that chat
templates (which typically expect at most one) do not receive multiples.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While I am pretty sure that item 1 is safe to go for most models that vllm supports, item 2 may surprise some users:

there is no all-agreed semantics for a system message appearing in the middle of chat message array - some models simply ignore it entirely, some models raise, some models even allow multiple system messages by nature. With item 2 merged, some models that rely on this trait silently generate a wildly different result or performance degrade.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

c.f. item 1 type approach also appears in bbrowning@fb34cd1#diff-8e595bc43c5d519d4b6dbfdeab1c72f4eac44a220759c99af944b8de506f6118, and I also find this approach nonviolent in our internal fork.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

+1, I think the fix should live in vllm/renderers/hf.py inside safe_apply_chat_template() rather than in responses/utils.py. That function is the shared bottleneck for both the Chat Completion API and the Responses API on the HF template path, and the developer role issue affects both.

Normalizing in safe_apply_chat_template() also avoids interfering with renderers that handle developer natively (DeepSeek V32/V4 have their own render_messages and never call this function, same for Mistral and Harmony).

Additionally, merging all system messages into one seems unnecessary — most HF Jinja2 templates iterate over messages and handle multiple system messages fine.

cc @bbrowning

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@cjackal An important context to the PR you linked above is in my own testing with Qwen 3.6 I had to follow it up with 0fe00a3 to get that model working with Codex CLI.

So, for some models, we're going to need some logic to optionally (by config) or intelligently (by chat template introspection) collapse system roles into a single one. Because that was on my own fork not yet opened here, I did the easy thing that was to collapse.

I do agree your concerns are valid with regards to collapsing or not having impacts for some models.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@bbrowning @cjackal @sfeng33

Based on @bbrowning's code, I reworked the implementation and submitted an updated version. I also tested it locally, and it works correctly. Additionally, it does not affect DSV4.

@chaunceyjiang chaunceyjiang changed the title [Frontend][Responses API] Fold developer-role input messages into instructions [Frontend][Responses API] Move developer-to-system conversion into HF renderer Jun 1, 2026
… renderer

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-Authored-By: Ben Browning <bbrownin@redhat.com>

@bbrowning bbrowning left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm approving this, as I think it's the safe default for the state of our open weight models today that don't support a developer message natively.

As pointed out in a comment thread above, collapsing all the system messages into 1 may not always be the right thing to do. However, in anecdotal testing of Nemotron 3 Super models (which explicitly support more than 1 system message), a system message appearing after a user message seems to send the model in a weird direction and it feels like I'm getting worse trajectories in agentic coding sessions after that. It was likely only trained for multiple system messages that all come before the first user message.

Given that we only trigger that collapsing for models that don't natively support developer message roles, I think it's a pretty safe assumption that those models also weren't trained in system messages that come after user messages in a conversation. This leads me to believing collapsing is the right thing to do in this situation, so approving this.

If we find future open weight models that don't support developer message but are trained for multiple system messages, including ones that come after user messages, then we can figure out something smarter to do here for those models. It's just as likely that more models will standardize on supporting developer role natively for those kind of mid-conversation steering adjustments, in which case our consolidation logic wouldn't apply and the right thing would just happen.

@sfeng33 sfeng33 added the ready ONLY add when PR is ready to merge/full CI is needed label Jun 2, 2026
@sfeng33
sfeng33 enabled auto-merge (squash) June 2, 2026 17:57
Comment thread vllm/renderers/hf.py
"does not define one."
)

if any(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Am I missing something? Doesn't seem you "moved" anything, you only added this logic without removing it from the original place

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Oh, sorry, the PR title was indeed incorrect. I've revised the title

@chaunceyjiang chaunceyjiang changed the title [Frontend][Responses API] Move developer-to-system conversion into HF renderer [Frontend][Responses API] Fold developer-role input messages into instructions Jun 3, 2026
@sfeng33
sfeng33 merged commit 27f1d34 into vllm-project:main Jun 3, 2026
43 checks passed
@chaunceyjiang chaunceyjiang changed the title [Frontend][Responses API] Fold developer-role input messages into instructions [Frontend][Responses API] Fold developer-role input messages into system instructions Jun 4, 2026
mvanhorn pushed a commit to mvanhorn/vllm that referenced this pull request Jun 4, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
JisoLya pushed a commit to JisoLya/vllm that referenced this pull request Jun 5, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
Signed-off-by: JisoLya <523420504@qq.com>
knight0528 pushed a commit to knight0528/vllm that referenced this pull request Jun 8, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
waqahmed-amd-fi pushed a commit to waqahmed-amd-fi/vllm that referenced this pull request Jun 10, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
Signed-off-by: Waqar Ahmed <waqar.ahmed@amd.com>
Saddss pushed a commit to Saddss/vllm that referenced this pull request Jun 14, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
divineearthly pushed a commit to divineearthly/vllm that referenced this pull request Jun 19, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
Signed-off-by: divineearthly <divineearthly@gmail.com>
nkzhenhua pushed a commit to nkzhenhua/vllm that referenced this pull request Jun 24, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
philippesic pushed a commit to philippesic/vllm-semantic-cache that referenced this pull request Jul 19, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
plasticchris pushed a commit to plasticchris/vllm that referenced this pull request Jul 20, 2026
… renderer (vllm-project#43590)

Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Co-authored-by: kdcyberdude <kdsingh.cyberdude@gmail.com>
Co-authored-by: Ben Browning <bbrownin@redhat.com>
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Doc]: Integration Issue: Qwen3.6-27B-FP8 with Codex via vLLM Server [Doc]: which version of vllm supports codex ?

5 participants