Skip to content

fix(translator): use string content for assistant messages in OpenAI format#2859

Open
ArcaneOrion wants to merge 1 commit into
router-for-me:devfrom
ArcaneOrion:fix/assistant-content-string-format
Open

fix(translator): use string content for assistant messages in OpenAI format#2859
ArcaneOrion wants to merge 1 commit into
router-for-me:devfrom
ArcaneOrion:fix/assistant-content-string-format

Conversation

@ArcaneOrion
Copy link
Copy Markdown

Problem

The Claude→OpenAI translator was outputting assistant message content as an array ([{"type":"text","text":"..."}]), but the OpenAI Chat Completions API spec requires assistant content
to be a string.

This caused some upstream providers (notably New API / One API based relay stations) to reject requests mid-stream with HTTP/2 INTERNAL_ERROR, resulting in unexpected EOF or stream error disconnections visible as 500 errors with "Headers were already written" warnings in the proxy log.

Fix

For assistant messages, extract text from content items and concatenate into a single string. Non-assistant roles (user, etc.) keep the array format since OpenAI allows array content for
user messages.

Testing

  • All 11 existing tests in internal/translator/openai/claude/ pass
  • All translator package tests pass (0 failures)

…format

  OpenAI spec requires assistant message content to be a string, not an array.
  The Claude-to-OpenAI translator was incorrectly preserving Claude's array
  format which caused some upstream providers to reject requests mid-stream.
@github-actions github-actions Bot changed the base branch from main to dev April 17, 2026 10:47
@github-actions
Copy link
Copy Markdown

This pull request targeted main.

The base branch has been automatically changed to dev.

Copy link
Copy Markdown

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

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: 373c8de4cb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

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

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

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +226 to +229
item := gjson.ParseBytes(contentItem)
if item.Get("type").String() == "text" {
textParts = append(textParts, item.Get("text").String())
}
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 assistant image blocks when flattening content

The new assistant-content conversion now keeps only type == "text" blocks and drops every other content block before building the OpenAI message string. For Claude histories that include assistant image blocks (or mixed text+image assistant content), this silently removes previously preserved context and sends an incomplete prompt upstream. This regression was introduced in ConvertClaudeRequestToOpenAI by filtering content items to text-only instead of preserving non-text blocks or handling them explicitly.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

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

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 updates the translation logic from Claude to OpenAI to ensure that assistant message content is formatted as a single string instead of an array, aligning with the OpenAI specification. Multiple text parts are now concatenated with newlines, and non-text items are excluded. The associated tests have been updated to reflect these changes. I have no feedback to provide.

Copy link
Copy Markdown
Collaborator

@luispater luispater left a comment

Choose a reason for hiding this comment

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

Summary

This PR updates the Claude→OpenAI translator to emit assistant content as a string (by concatenating text blocks) instead of an array, which should improve compatibility with OpenAI Chat Completions–style upstream relays that reject assistant content arrays.

Findings

  • No blocking issues found in the patch itself.
  • Non-blocking: please double-check the choice of "\n" as the join separator for multiple text blocks; it may introduce new newlines compared to the original Claude block boundaries. A small unit test for multiple adjacent text blocks (no tools) would lock in the expected behavior.

CI / Checks

  • pr-test-build passed.
  • translator-path-guard is failing (expected for translator-only changes, but may still be merge-gating depending on repo policy).

Test plan

  • Not run locally (reviewed via gh diff/checks only; no PR checkout).
  • Suggested: go test ./... (or at least the translator package tests) before merge.

This is an automated Codex review result and still requires manual verification by a human reviewer.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants