Skip to content

添加openAI compatible的原生response api格式支持 - #1328

Open
gtlab2023 wants to merge 5 commits into
claude-code-best:mainfrom
gtlab2023:main
Open

添加openAI compatible的原生response api格式支持#1328
gtlab2023 wants to merge 5 commits into
claude-code-best:mainfrom
gtlab2023:main

Conversation

@gtlab2023

@gtlab2023 gtlab2023 commented Aug 2, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features

    • Added support for OpenAI’s Responses API using API-key authentication.
    • Added configurable selection between Responses API and Chat Completions.
    • Preserved ChatGPT OAuth routing with defined precedence.
    • Added prompt-cache support where available.
  • Bug Fixes

    • Improved errors for unsuccessful API responses and incomplete streams.
  • Documentation

    • Added design and implementation documentation for Responses API support.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds configurable OpenAI upstream modes, API-key Responses API streaming, routing precedence, incomplete-stream validation, focused tests, design documentation, and dependency updates.

Changes

OpenAI Responses API

Layer / File(s) Summary
Upstream mode contract
src/services/api/openai/upstreamApiMode.ts, src/services/api/openai/__tests__/upstreamApiMode.test.ts, docs/superpowers/specs/..., docs/superpowers/plans/...
Adds chat_completions and responses modes. Empty values default to Chat Completions. Unsupported values throw errors.
Responses SSE transport
src/services/api/openai/responsesAdapter.ts, src/services/api/openai/__tests__/responsesAdapter.test.ts
Adds API-key Responses requests with Bearer authentication, proxy support, optional prompt-cache keys, SSE parsing, and HTTP error handling.
Routing and stream validation
src/services/api/openai/index.ts, src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts
Prioritizes ChatGPT authentication, then configured Responses mode, then Chat Completions. Streams without terminal messages or assistant content now produce an API error.

Dependency updates

Layer / File(s) Summary
Package versions and overrides
package.json
Updates runtime and development dependency versions and adds package overrides.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant queryModelOpenAI
  participant ChatGPTAuthentication
  participant OpenAIResponsesAPI
  participant ChatCompletionsAPI
  ChatGPTAuthentication->>queryModelOpenAI: Return authentication state
  alt ChatGPT authentication is active
    queryModelOpenAI->>ChatGPTAuthentication: Request ChatGPT Responses stream
  else Responses mode is configured
    queryModelOpenAI->>OpenAIResponsesAPI: POST API-key Responses request
  else Default mode
    queryModelOpenAI->>ChatCompletionsAPI: Request Chat Completions stream
  end
  queryModelOpenAI->>queryModelOpenAI: Validate terminal message or assistant content
Loading

Possibly related PRs

Suggested reviewers: davidshawa

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding native OpenAI Responses API support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/services/api/openai/__tests__/upstreamApiMode.test.ts (1)

2-2: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the required source import path.

Line 2 imports a src module through a relative .js path. Use the src/* alias and the required TypeScript extension for this test import.

Proposed change
-import { getUpstreamApiMode } from '../upstreamApiMode.js'
+import { getUpstreamApiMode } from 'src/services/api/openai/upstreamApiMode.ts'

As per coding guidelines, use the src/* path alias for imports from src, and include the .ts extension where the project testing path rules require it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/api/openai/__tests__/upstreamApiMode.test.ts` at line 2, Update
the test import for getUpstreamApiMode to use the project’s src/* path alias and
the required .ts extension instead of the relative .js path, leaving the
imported symbol unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts`:
- Around line 424-472: Rename
src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts to
queryModelOpenAI.test.ts so normal test discovery includes the routing and
incomplete-stream tests. Update
docs/superpowers/specs/2026-08-02-openai-responses-api-design.md lines 65-69 to
use the renamed file in the verification command and remove the manual-discovery
exception. Update docs/superpowers/plans/2026-08-02-openai-responses-api.md
lines 166-169 and every reference there to the new test filename; no other test
behavior changes are needed.

In `@src/services/api/openai/responsesAdapter.ts`:
- Around line 512-530: The manual request in createOpenAIResponsesStream must
reuse the shared OpenAI request configuration applied by getOpenAIClient,
including organization and project headers plus API_TIMEOUT_MS handling. Update
the Responses fetch setup to apply the same headers, options, and timeout
behavior as the Chat Completions transport, while preserving existing proxy and
abort-signal behavior, and add regression tests covering organization, project,
and timeout configuration.

---

Nitpick comments:
In `@src/services/api/openai/__tests__/upstreamApiMode.test.ts`:
- Line 2: Update the test import for getUpstreamApiMode to use the project’s
src/* path alias and the required .ts extension instead of the relative .js
path, leaving the imported symbol unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b07321a4-bf20-4cf6-aeca-dc557a9cd386

📥 Commits

Reviewing files that changed from the base of the PR and between 987e550 and 7dd3f4b.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • docs/superpowers/plans/2026-08-02-openai-responses-api.md
  • docs/superpowers/specs/2026-08-02-openai-responses-api-design.md
  • package.json
  • src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts
  • src/services/api/openai/__tests__/responsesAdapter.test.ts
  • src/services/api/openai/__tests__/upstreamApiMode.test.ts
  • src/services/api/openai/index.ts
  • src/services/api/openai/responsesAdapter.ts
  • src/services/api/openai/upstreamApiMode.ts

Comment on lines +424 to +472
beforeEach(() => {
_lastCreateArgs = null
_isChatGPTAuthEnabled = false
_chatCompletionsCreateCalls = 0
_chatGPTResponsesCalls = 0
_openAIResponsesCalls = 0
})

describe('queryModelOpenAI — upstream API routing', () => {
test('uses API-key Responses transport when UPSTREAM_API_MODEL is responses', async () => {
await runQueryModel([], { UPSTREAM_API_MODEL: 'responses' })

expect(_openAIResponsesCalls).toBe(1)
expect(_chatCompletionsCreateCalls).toBe(0)
expect(_chatGPTResponsesCalls).toBe(0)
})

test('prefers ChatGPT Responses transport over UPSTREAM_API_MODEL', async () => {
_isChatGPTAuthEnabled = true

await runQueryModel([], { UPSTREAM_API_MODEL: 'responses' })

expect(_chatGPTResponsesCalls).toBe(1)
expect(_openAIResponsesCalls).toBe(0)
expect(_chatCompletionsCreateCalls).toBe(0)
})

test('keeps Chat Completions as the default transport', async () => {
await runQueryModel([], { UPSTREAM_API_MODEL: undefined })

expect(_chatCompletionsCreateCalls).toBe(1)
expect(_openAIResponsesCalls).toBe(0)
expect(_chatGPTResponsesCalls).toBe(0)
})

test('surfaces an invalid upstream API mode as an API error', async () => {
const { assistantMessages } = await runQueryModel([], {
UPSTREAM_API_MODEL: 'completion',
})

expect(assistantMessages).toHaveLength(1)
expect(assistantMessages[0]?.message.content).toEqual([
{
type: 'text',
text: expect.stringContaining('Invalid UPSTREAM_API_MODEL: completion'),
},
])
})
})

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Rename the isolated routing test for normal test discovery.

The added routing and incomplete-stream tests are in a file without the required .test.ts suffix. The verification record confirms that this requires an explicit command.

  • src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts#L424-L472: rename the file to the required queryModelOpenAI.test.ts convention.
  • docs/superpowers/specs/2026-08-02-openai-responses-api-design.md#L65-L69: update the verification command and remove the manual-discovery exception.
  • docs/superpowers/plans/2026-08-02-openai-responses-api.md#L166-L169: update the planned test filename and all references to it.

As per coding guidelines, use bun:test, place unit tests under src/**/__tests__/, and name them <module>.test.ts.

📍 Affects 3 files
  • src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts#L424-L472 (this comment)
  • docs/superpowers/specs/2026-08-02-openai-responses-api-design.md#L65-L69
  • docs/superpowers/plans/2026-08-02-openai-responses-api.md#L166-L169
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts` around lines
424 - 472, Rename src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts
to queryModelOpenAI.test.ts so normal test discovery includes the routing and
incomplete-stream tests. Update
docs/superpowers/specs/2026-08-02-openai-responses-api-design.md lines 65-69 to
use the renamed file in the verification command and remove the manual-discovery
exception. Update docs/superpowers/plans/2026-08-02-openai-responses-api.md
lines 166-169 and every reference there to the new test filename; no other test
behavior changes are needed.

Source: Coding guidelines

Comment on lines +512 to +530
export async function createOpenAIResponsesStream(params: {
request: ResponsesRequest
signal: AbortSignal
fetchOverride?: typeof fetch
}): Promise<AsyncIterable<Record<string, unknown>>> {
const fetchFn = params.fetchOverride ?? (globalThis.fetch as typeof fetch)
const baseUrl = (
process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1'
).replace(/\/+$/, '')
const response = await fetchFn(`${baseUrl}/responses`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY || ''}`,
'Content-Type': 'application/json',
Accept: 'text/event-stream',
},
body: JSON.stringify(params.request),
signal: params.signal,
...getProxyFetchOptions({ forAnthropicAPI: false }),

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)responsesAdapter\.ts$|(^|/)openai.*\.ts$|src/services/api/openai' || true

echo "== target outline =="
ast-grep outline src/services/api/openai/responsesAdapter.ts --view expanded || true

echo "== target relevant lines =="
sed -n '1,80p;460,560p' src/services/api/openai/responsesAdapter.ts

echo "== getOpenAIClient occurrences =="
rg -n "getOpenAIClient|OPENAI_ORG_ID|OPENAI_PROJECT_ID|API_TIMEOUT_MS|responsesAdapter|createOpenAIResponsesStream|responses" src -S

echo "== proxy fetch options =="
rg -n "getProxyFetchOptions|forAnthropicAPI" src/services -S || true

Repository: claude-code-best/claude-code

Length of output: 27466


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== openai client =="
sed -n '1,90p' src/services/api/openai/client.ts

echo "== openai index relevant call locations =="
sed -n '320,420p' src/services/api/openai/index.ts

echo "== openai shared timeout/headers helper usage =="
rg -n "API_TIMEOUT_MS|timeout:|fetchOptions|Authorization|OpenAI" src/services/api/client.ts src/services/api/openai/client.ts src/services/api/client.ts || true

echo "== responsesAdapter tests around fetch args =="
sed -n '175,245p' src/services/api/openai/__tests__/responsesAdapter.test.ts

echo "== isolated queryModel env test around responses =="
sed -n '420,450p' src/services/api/openai/__tests__/queryModelOpenAI.isolated.ts

Repository: claude-code-best/claude-code

Length of output: 13100


Apply the shared OpenAI request config to Responses requests.

createOpenAIResponsesStream() builds a manual fetch request, so it omits OPENAI_ORG_ID, OPENAI_PROJECT_ID, and API_TIMEOUT_MS that the Chat Completions transport applies through getOpenAIClient(). Ensure API-key Responses requests pass the same headers/options/timeout as the SDK path, and add regression tests for organization, project, and timeout behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/api/openai/responsesAdapter.ts` around lines 512 - 530, The
manual request in createOpenAIResponsesStream must reuse the shared OpenAI
request configuration applied by getOpenAIClient, including organization and
project headers plus API_TIMEOUT_MS handling. Update the Responses fetch setup
to apply the same headers, options, and timeout behavior as the Chat Completions
transport, while preserving existing proxy and abort-signal behavior, and add
regression tests covering organization, project, and timeout configuration.

@claude-code-best

Copy link
Copy Markdown
Owner

请问有经过测试吗

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