Skip to content

fix: omit synthesized reasoning items in Chat→Responses translation (#224) - #231

Merged
diegosouzapw merged 1 commit into
mainfrom
fix/issue-224-reasoning-ids
Mar 6, 2026
Merged

diegosouzapw merged 1 commit into
mainfrom
fix/issue-224-reasoning-ids

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Summary

When OmniRoute translates Chat Completions history to OpenAI Responses API input, it was generating synthetic reasoning items with IDs like reasoning_15. The Responses API requires server-generated rs_* IDs, causing 400 Invalid Request errors.

Fix

Removed reasoning item synthesis entirely from openaiToOpenAIResponsesRequest(). Since valid rs_* IDs can only be generated server-side, these items are now omitted during translation. Reasoning content is non-essential for the request flow.

Changes

  • open-sse/translator/request/openai-responses.ts: Removed reasoning_content and thinking block synthesis in Chat→Responses translation

Closes #224

Copilot AI review requested due to automatic review settings March 6, 2026 21:49
@diegosouzapw
diegosouzapw merged commit 3f5096c into main Mar 6, 2026
4 checks passed
@diegosouzapw
diegosouzapw deleted the fix/issue-224-reasoning-ids branch March 6, 2026 21:49
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical compatibility issue in OmniRoute's translation layer, specifically when converting Chat Completions to the OpenAI Responses API format. By ceasing the client-side generation of reasoning items, which previously led to 400 Invalid Request errors due to incorrect ID formats, the system now correctly aligns with the Responses API's requirement for server-generated IDs. This change ensures robust and error-free communication with Responses-compatible upstreams.

Highlights

  • API Compatibility Fix: Resolved 400 Invalid Request errors by preventing the client-side synthesis of reasoning items (e.g., reasoning_15) when translating Chat Completions history to OpenAI Responses API input, as the Responses API mandates server-generated rs_* IDs.
  • Translation Logic Simplification: Removed the code responsible for generating reasoning_content and thinking blocks within the openaiToOpenAIResponsesRequest() function, streamlining the translation process by omitting non-essential reasoning content that caused API rejections.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • open-sse/translator/request/openai-responses.ts
    • Removed the logic that added reasoning_content from msg.reasoning_content to the input array.
    • Removed the loop that processed thinking or redacted_thinking blocks from msg.content and added them as reasoning items.
    • Added comments explaining the rationale for skipping these items due to OpenAI Responses API's rs_* ID requirement.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@kilo-code-bot

kilo-code-bot Bot commented Mar 6, 2026

Copy link
Copy Markdown

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
open-sse/translator/request/openai-responses.ts 294 Stale comment - The comment says "Reasoning already moved above" but the reasoning code was removed (not moved). This comment is now misleading. Consider updating it to explain that thinking blocks are intentionally skipped due to the rs_* ID constraint mentioned in the comments above (lines 278-282).
Other Observations (not in diff)

The issue at line 294 is in unchanged code that exists after the diff hunk. The diff covers lines 275-285, but the stale comment is at line 294 (outside the diff range). This code was not modified in this PR but became incorrect after the reasoning logic was removed.

Files Reviewed (1 file)
  • open-sse/translator/request/openai-responses.ts - 1 issue

Review Notes:

The PR correctly addresses issue #224 by removing client-side reasoning synthesis that was causing 400 errors from the OpenAI Responses API. The changes are logically sound - the reasoning content is now properly skipped rather than incorrectly synthesized with invalid IDs. The only issue is a stale comment that references code that no longer exists.

@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 addresses a bug causing 400 Invalid Request errors by removing the client-side synthesis of reasoning items when translating Chat Completions to the OpenAI Responses API format. The change is correct and effectively resolves the issue. As a minor point of improvement for maintainability, the removal of this logic has made a comment on line 294 (// Reasoning already moved above) outdated. While this line is outside the current diff, I recommend updating it to reflect that thinking blocks are now skipped, not moved.

Copilot AI 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.

Pull request overview

This PR fixes an interoperability bug in OmniRoute’s Chat Completions → OpenAI Responses request translation by stopping the synthesis of client-generated “reasoning” items, which can produce invalid IDs and trigger upstream 400 Invalid Request errors.

Changes:

  • Removed synthesis of type: "reasoning" items from reasoning_content and thinking/redacted_thinking blocks during Chat→Responses translation.
  • Added inline comments explaining why reasoning/thinking content is omitted for Responses-compatible upstreams.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +278 to 283
// Skip reasoning_content — OpenAI Responses API requires server-generated
// rs_* IDs for reasoning items. Synthesizing client-side IDs (e.g. reasoning_N)
// causes 400 errors from Responses-compatible upstreams. (#224)

// Handle thinking blocks in array content
if (Array.isArray(msg.content)) {
for (const blockValue of msg.content) {
const block = toRecord(blockValue);
if (block.type === "thinking" || block.type === "redacted_thinking") {
input.push({
type: "reasoning",
id: `reasoning_${input.length}`,
summary: [
{ type: "summary_text", text: toString(block.thinking || block.data, "...") },
],
});
}
}
}
// Skip thinking blocks in array content — same rs_* ID constraint applies

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

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

The new behavior omits reasoning items entirely, but there’s still an in-function comment later in the assistant content loop that says thinking blocks were “moved above”. After this change that’s no longer true (they’re omitted), so please update/remove that stale comment to match the new behavior and avoid future confusion.

Copilot uses AI. Check for mistakes.
Comment on lines +278 to +282
// Skip reasoning_content — OpenAI Responses API requires server-generated
// rs_* IDs for reasoning items. Synthesizing client-side IDs (e.g. reasoning_N)
// causes 400 errors from Responses-compatible upstreams. (#224)

// Handle thinking blocks in array content
if (Array.isArray(msg.content)) {
for (const blockValue of msg.content) {
const block = toRecord(blockValue);
if (block.type === "thinking" || block.type === "redacted_thinking") {
input.push({
type: "reasoning",
id: `reasoning_${input.length}`,
summary: [
{ type: "summary_text", text: toString(block.thinking || block.data, "...") },
],
});
}
}
}
// Skip thinking blocks in array content — same rs_* ID constraint applies

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

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

This change fixes a specific interoperability bug (synthetic reasoning_* IDs causing 400s). Please add a unit test that exercises Chat→Responses translation with (a) assistant reasoning_content and (b) assistant array content containing thinking/redacted_thinking blocks, and asserts that no reasoning items are emitted and no synthetic IDs appear in result.input.

Copilot uses AI. Check for mistakes.
diegosouzapw added a commit that referenced this pull request Mar 7, 2026
fix: omit synthesized reasoning items in Chat→Responses translation (#224)
diegosouzapw added a commit that referenced this pull request May 14, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts #224 and #231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md documenting how to handle future
  occurrences (verify callchain → verify test coverage → dismiss with
  reference, do NOT duplicate the pattern inline).
- Extend CLAUDE.md Hard Rule #14 with the precedent so the next
  engineer doesn't try to "fix" the false positive by weakening the
  shared sanitizer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diegosouzapw added a commit that referenced this pull request May 14, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts #224 and #231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md
- Extend CLAUDE.md Hard Rule #14 with the precedent

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts cheaper-inference#224 and cheaper-inference#231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md
- Extend CLAUDE.md Hard Rule cheaper-inference#14 with the precedent

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts cheaper-inference#224 and cheaper-inference#231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md documenting how to handle future
  occurrences (verify callchain → verify test coverage → dismiss with
  reference, do NOT duplicate the pattern inline).
- Extend CLAUDE.md Hard Rule cheaper-inference#14 with the precedent so the next
  engineer doesn't try to "fix" the false positive by weakening the
  shared sanitizer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts cheaper-inference#224 and cheaper-inference#231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md
- Extend CLAUDE.md Hard Rule cheaper-inference#14 with the precedent

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts cheaper-inference#224 and cheaper-inference#231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md documenting how to handle future
  occurrences (verify callchain → verify test coverage → dismiss with
  reference, do NOT duplicate the pattern inline).
- Extend CLAUDE.md Hard Rule cheaper-inference#14 with the precedent so the next
  engineer doesn't try to "fix" the false positive by weakening the
  shared sanitizer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…224-reasoning-ids

fix: omit synthesized reasoning items in Chat→Responses translation (cheaper-inference#224)
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts cheaper-inference#224 and cheaper-inference#231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md
- Extend CLAUDE.md Hard Rule cheaper-inference#14 with the precedent

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…precedent

CodeQL js/stack-trace-exposure does not recognize sanitizers reached
through a custom helper indirection — flagging callsites like
open-sse/utils/error.ts::errorResponse and
open-sse/executors/cursor.ts::buildErrorResponse even though both route
through sanitizeErrorMessage().

Record the dismissal precedent (alerts cheaper-inference#224 and cheaper-inference#231, May 2026):
- Add a "Known CodeQL limitation" section in
  docs/security/ERROR_SANITIZATION.md documenting how to handle future
  occurrences (verify callchain → verify test coverage → dismiss with
  reference, do NOT duplicate the pattern inline).
- Extend CLAUDE.md Hard Rule cheaper-inference#14 with the precedent so the next
  engineer doesn't try to "fix" the false positive by weakening the
  shared sanitizer.

Co-Authored-By: Claude Opus 4.7 (1M context) <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.

Bug: Chat→Responses translation creates invalid synthetic reasoning IDs (reasoning_*)

2 participants