Skip to content

merge reasoning and content messages for openai chat completions#331

Merged
Ken Jiang (knjiang) merged 5 commits into
mainfrom
07-02-merge_reasoning_and_content_messages_for_openai_chat_completions
Jul 2, 2026
Merged

merge reasoning and content messages for openai chat completions#331
Ken Jiang (knjiang) merged 5 commits into
mainfrom
07-02-merge_reasoning_and_content_messages_for_openai_chat_completions

Conversation

@knjiang

@knjiang Ken Jiang (knjiang) commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Fix non-streaming Chat Completions responses transformed from OpenAI Responses when the upstream output contains
reasoning before visible text.

Previously, Responses output[] items were converted into separate Chat Completions choices, so a reasoning item could
become choices[0] while the visible text landed in choices[1]. For Chat Completions, choices are completion
alternatives, not ordered response parts. With the default n = 1, OpenAI-compatible callers expect the generated
assistant message at choices[0].message.content, so this produced silently empty outputs.

This change merges a leading reasoning-only assistant message into the following assistant message when serializing a
universal response back to Chat Completions. The transformed response now returns one choice containing both
message.reasoning and message.content.

Also added a regression test for Responses reasoning followed by message output, and updated payload transform
snapshots.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@knjiang Ken Jiang (knjiang) marked this pull request as ready for review July 2, 2026 13:53

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9cd829a8bc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".


let choices: Vec<Value> = resp
.messages
let response_messages = merge_reasoning_response_messages(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve choice boundaries when merging reasoning

When this Chat Completions adapter is the target for a response whose universal messages are alternatives rather than ordered parts (for example, Google candidates, where GoogleAdapter::response_to_universal pushes one Message per candidate), this unconditional merge crosses choice boundaries. A first candidate containing only thought/reasoning followed by a second candidate with visible text is serialized as one Chat Completions choice, changing n/candidate semantics and moving another alternative's answer into choices[0]. Gate this merge to Responses-origin output items or preserve source grouping before merging.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

gonna move the merge to responses side

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c3a251a44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +127 to +129
merged.push(Message::Assistant {
content: AssistantContent::Array(combined_parts),
id: next_id.or(reasoning_id),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve both Responses item IDs when merging

When a Responses response has separate reasoning and message output items and a caller parses it through response_to_universal before emitting Responses again, this merged message can carry only next_id; the Responses serializer then assigns that single ID to the first regenerated output item (the reasoning item) and gives the visible message a placeholder. That drops or reassigns the original rs_*/msg_* item IDs, so follow-up item_reference requests can point at the wrong output item.

Useful? React with 👍 / 👎.

@knjiang Ken Jiang (knjiang) merged commit 2b5468d into main Jul 2, 2026
8 checks passed
paultancre-bt added a commit that referenced this pull request Jul 9, 2026
Main's reasoning/content merge for OpenAI chat completions (#331) changed
the chat-completions → responses transform; refresh the case snapshot to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants