Skip to content

Add support for vLLM's new reasoning field#6988

Open
AntoineToussaint wants to merge 4 commits intomainfrom
support-vllm-reasoning-field
Open

Add support for vLLM's new reasoning field#6988
AntoineToussaint wants to merge 4 commits intomainfrom
support-vllm-reasoning-field

Conversation

@AntoineToussaint
Copy link
Member

@AntoineToussaint AntoineToussaint commented Mar 18, 2026

Summary

  • vLLM >=0.8 renamed reasoning_content to reasoning in chat completion responses (commit), but sends both fields simultaneously (typically one null)
  • #[serde(alias)] can't handle duplicate keys, so we use custom Deserialize impls with intermediate Raw structs that accept both fields and merge them, preferring reasoning_content
  • Applies to both non-streaming (OpenAIResponseMessage) and streaming (OpenAIDelta) response types

Closes #6653

Test plan

  • New unit tests verify deserialization with reasoning only, reasoning_content only, both null, both set, and one null + one set
  • Existing vLLM and OpenAI unit tests pass
  • cargo clippy clean

🤖 Generated with Claude Code

Copy link
Member

@GabrielBianconi GabrielBianconi left a comment

Choose a reason for hiding this comment

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

We need to handle sending it back to the model in multi-turn conversations. This means we need to know the right one to send back.

We might need a more holistic solution here, e.g. default to the new one and make it configurable, or something like that.

We should also run E2E tests to confirm this works. We have a VLLM deployment; we might need to bump it to 0.8+.

AntoineToussaint and others added 3 commits March 20, 2026 15:26
vLLM >=0.8 renamed `reasoning_content` to `reasoning` in chat
completion responses. Add `#[serde(alias = "reasoning")]` to
`OpenAIResponseMessage` and `OpenAIDelta` so both field names are
accepted, maintaining compatibility with all OpenAI-compatible
providers.

Closes #6653

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ning_content`

vLLM >=0.8 sends both `reasoning` and `reasoning_content` in responses
(typically one null). Using `#[serde(alias)]` fails with a duplicate
field error in this case. Replace with custom Deserialize impls that
accept both fields and merge them, preferring `reasoning_content`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AntoineToussaint AntoineToussaint force-pushed the support-vllm-reasoning-field branch from c357acd to d67a978 Compare March 20, 2026 19:26
vLLM >=0.8 renamed `reasoning_content` to `reasoning` in both
requests and responses. The previous commits handle deserialization
(accepting both field names), but we also need to send the correct
field name back when constructing assistant messages for multi-turn
conversations.

Add `ReasoningFieldName` enum and `reasoning_field_name` config to
`OpenAIMessagesConfig`, so each provider can choose which field name
to serialize. vLLM defaults to `reasoning`; all other providers
default to `reasoning_content`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AntoineToussaint
Copy link
Member Author

Addressed the multi-turn serialization concern:

  • Added ReasoningFieldName enum to OpenAIMessagesConfig so each provider controls which field name (reasoning vs reasoning_content) is serialized in assistant messages for multi-turn requests
  • vLLM defaults to reasoning; all other providers default to reasoning_content
  • Added test verifying vLLM path serializes as "reasoning" and not "reasoning_content"

Still TODO: E2E tests with a vLLM >=0.8 deployment to confirm end-to-end behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for new vLLM reasoning field

2 participants