Skip to content

add: codex api support#1243

Open
cynicalight wants to merge 1 commit into
claude-code-best:mainfrom
cynicalight:main
Open

add: codex api support#1243
cynicalight wants to merge 1 commit into
claude-code-best:mainfrom
cynicalight:main

Conversation

@cynicalight
Copy link
Copy Markdown

@cynicalight cynicalight commented May 19, 2026

增加了对于 codex api 格式的支持(/v1/responses)

使用:

  1. /provider codex 切换成 codex 格式
  2. /login 选择 codex
image image

正常设置即可

Summary by CodeRabbit

  • New Features

    • Added Codex API provider as a new configuration option alongside existing providers.
    • Enabled OAuth login flow and authentication modes for Codex API.
    • Added model selection, mapping, and resolution for Codex.
    • Extended provider settings and environment variable management for Codex configuration.
  • Tests

    • Added comprehensive test coverage for Codex API client and model resolution.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

This PR adds complete Codex Responses API provider support by implementing model mapping, a streaming HTTP client, query orchestration, provider routing, settings schema updates, model selection helpers, and user-facing CLI/OAuth configuration flows, enabling users to switch between Anthropic, OpenAI, and Codex providers via environment variables or CLI command.

Changes

Codex Provider Integration

Layer / File(s) Summary
Core Model Resolution Library
packages/@ant/model-provider/src/providers/codex/modelMapping.ts, packages/@ant/model-provider/src/providers/codex/__tests__/modelMapping.test.ts, packages/@ant/model-provider/src/index.ts
Introduces resolveCodexModel to map Anthropic model names to Codex equivalents via DEFAULT_MODEL_MAP, DEFAULT_FAMILY_MAP, and env-var overrides (CODEX_MODEL, CODEX_DEFAULT_{FAMILY}_MODEL, etc.) with family detection and model-name cleanup. Tests verify env-driven defaults and non-override behavior.
Codex Responses API Client
src/services/api/codex/client.ts, src/services/api/codex/__tests__/client.test.ts, src/services/api/openai/responsesAdapter.ts
Implements createCodexResponsesStream with URL normalization (CODEX_RESPONSES_URL or CODEX_BASE_URL), SSE streaming, optional Bearer auth, and ChatGPT auth-mode routing. Exports ResponsesRequest type and parseSSE generator from responsesAdapter for shared use. Test cases cover native requests, /v1/responses path deduplication, and ChatGPT account-id header injection.
Codex Query Adapter and Orchestration
src/services/api/codex/index.ts
Implements queryModelCodex async generator that resolves Codex model, normalizes Anthropic messages/tools to OpenAI format, streams via createCodexResponsesStream, tracks TTFT, assembles assistant messages, updates token usage, records Langfuse observations with cost, yields normalized stream events, and converts errors into api_error messages.
Provider Type System and Dispatch
src/utils/model/providers.ts, src/services/api/claude.ts, src/utils/model/__tests__/providers.test.ts
Extends APIProvider union and getAPIProvider to support 'codex' from modelType setting or CLAUDE_CODE_USE_CODEX env var. Wires Codex adapter into queryModel dispatcher. Tests verify provider selection by type and env var.
Settings Schema and Environment Management
src/utils/settings/types.ts, src/utils/managedEnvConstants.ts
Updates SettingsSchema.modelType enum to include 'codex'. Extends PROVIDER_MANAGED_ENV_VARS with Codex provider keys (auth mode, API key, URLs, model). Adds Codex default model env vars to SAFE_ENV_VARS for pre-dialog application.
Model Selection and Default Resolution
src/utils/model/model.ts, src/utils/model/chatgptModels.ts, src/utils/model/configs.ts, src/utils/model/__tests__/codexModelOptions.test.ts
Adds codex provider branches to getSmallFastModel, getDefaultOpusModel, getDefaultSonnetModel, getDefaultHaikuModel resolving to CODEX_MODEL or CODEX_SMALL_FAST_MODEL with fallbacks. Parameterizes isChatGPTAuthMode to check provider-specific auth-mode env vars. Adds codex mappings to all 12 CLAUDE model configs. Tests verify model option inclusion and default selection.
Model Picker and Options Construction
src/utils/model/modelOptions.ts
Extends custom Sonnet/Opus/Haiku option helpers to include codex provider branch using codex-specific default/name/description env vars. Adds getChatGPTCodexModelOptions logic to append custom options from CODEX_MODEL. Refactors getModelOptionsBase with local provider variable and early-return for codex, updates auth-mode check parameterization.
Provider Command and CLI Configuration
src/commands/provider.ts
Extends /provider command to support codex via CLAUDE_CODE_USE_CODEX mapping. Adds 'codex' to validProviders. Implements dedicated validation block checking CODEX_API_KEY or allowing via CODEX_AUTH_MODE=chatgpt. Routes codex to settings.json-backed provider path. Cleans up conflicting env vars. Updates description and argumentHint to include codex.
OAuth Flow and Device-Login Setup
src/components/ConsoleOAuthFlow.tsx
Extends OAuthStatus with codex_api variant tracking baseUrl, apiKey, model, activeField. Adds login-method option for "Codex Responses API". Initializes codex_api status from CODEX_RESPONSES_URL/CODEX_BASE_URL, CODEX_API_KEY, CODEX_MODEL. Implements full form with base URL/API key/model inputs, regex validation for /v1/responses path, settings persistence, and env-var updates. Threads currentModelType prop to allow ChatGPT device-login to set either OPENAI_AUTH_MODE or CODEX_AUTH_MODE. Updates effect dependencies.
Logout Handling and Status Display
src/commands/logout/logout.tsx, src/utils/status.tsx
Extends clearChatGPTSettingsAuthMode to delete CODEX_AUTH_MODE, compute OpenAI/Codex compatibility from env vars, conditionally clear incompatible modelType, and set both auth modes to undefined. Adds codex: 'Codex API' label to provider status display.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🐰 A code-hopper's delight, I declare!
Codex streaming comes to light,
With models mapped and routes just right,
OAuth flows complete the sight,
Three providers dance in the night! 🌙

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.23% 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 PR title 'add: codex api support' directly and accurately summarizes the main change—adding Codex API support throughout the codebase.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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/codex/index.ts`:
- Around line 105-107: Replace the loose any types: change contentBlocks from
Record<number, any> to a safer type (e.g., Record<number, unknown> or
Map<number, unknown> depending on how it's used) and give partialMessage a
concrete type (for example AssistantMessage | undefined or unknown or a defined
PartialAssistantMessage interface) instead of any; update any downstream code
that accesses contentBlocks or partialMessage to narrow/cast the unknown safely
(using type guards or explicit mapping) so the compiler knows the actual shape
when using symbols contentBlocks and partialMessage.
- Around line 191-192: Replace the unsafe "as any" casts by giving `usage` a
proper type that matches what `calculateUSDCost` and `addToTotalSessionCost`
expect; update the `usage` variable declaration (or the function signatures) to
use that concrete type (e.g., `Usage`, `OpenAIUsage`, or your internal
`ModelUsage`), import/define that type and then call
`calculateUSDCost(codexModel, usage)` and `addToTotalSessionCost(costUSD, usage,
options.model)` without `as any`; if only one function needs a different shape,
add a small adapter/mapper function (e.g., `toExpectedUsage(usage)`) to convert
the current `usage` to the required type rather than casting.
- Around line 117-185: The loop over adaptedStream uses (event as any)
everywhere; define a discriminated union for the stream events (e.g.,
MessageStartEvent | ContentBlockStartEvent | ContentBlockDeltaEvent |
ContentBlockStopEvent | MessageDeltaEvent | MessageStopEvent), update the
for-await signature to use that union, and replace all (event as any).X with
strongly typed access (event.message, event.index, event.delta, event.usage,
etc.). Add minimal type-guard helpers where needed (e.g.,
isContentBlockDelta(event): event is ContentBlockDeltaEvent) to narrow variants
in switch cases, and if you must coerce due to upstream types use the approved
double-assertion (as unknown as YourEventType) only at the stream boundary; keep
rest of code references (partialMessage, contentBlocks, updateOpenAIUsage,
normalizeContentFromAPI, AssistantMessage, randomUUID) unchanged.

In `@src/utils/managedEnvConstants.ts`:
- Around line 83-101: PROVIDER_MANAGED_ENV_VARS is missing the new flag
CLAUDE_CODE_USE_CODEX which getAPIProvider() uses to decide Codex routing,
allowing settings-sourced env to override host-managed routing; add the string
'CLAUDE_CODE_USE_CODEX' to the PROVIDER_MANAGED_ENV_VARS array in
src/utils/managedEnvConstants.ts so host-managed mode will treat that key as
provider-managed and prevent settings from forcing Codex selection in
getAPIProvider().

In `@src/utils/model/__tests__/codexModelOptions.test.ts`:
- Around line 36-39: The test "uses CODEX_MODEL as the default model when no
explicit model is selected" is not environment-isolated; modify it to save and
restore any affected env vars (at minimum OPENAI_AUTH_MODE and CODEX_AUTH_MODE)
or explicitly clear them for the test, then restore originals after the test
finishes; keep the existing process.env.CLAUDE_CODE_USE_CODEX and
process.env.CODEX_MODEL assignments but wrap them with backing up original
values (e.g., const prev = process.env.OPENAI_AUTH_MODE;
process.env.OPENAI_AUTH_MODE = ''; ... ) and restore
(process.env.OPENAI_AUTH_MODE = prev) in a finally or afterEach so the test does
not depend on ambient runner environment.
🪄 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

Run ID: 8e226cfa-5d7d-4d6d-a96a-9376807b5ccc

📥 Commits

Reviewing files that changed from the base of the PR and between ea399f1 and 0553caa.

📒 Files selected for processing (21)
  • packages/@ant/model-provider/src/index.ts
  • packages/@ant/model-provider/src/providers/codex/__tests__/modelMapping.test.ts
  • packages/@ant/model-provider/src/providers/codex/modelMapping.ts
  • src/commands/logout/logout.tsx
  • src/commands/provider.ts
  • src/components/ConsoleOAuthFlow.tsx
  • src/services/api/claude.ts
  • src/services/api/codex/__tests__/client.test.ts
  • src/services/api/codex/client.ts
  • src/services/api/codex/index.ts
  • src/services/api/openai/responsesAdapter.ts
  • src/utils/managedEnvConstants.ts
  • src/utils/model/__tests__/codexModelOptions.test.ts
  • src/utils/model/__tests__/providers.test.ts
  • src/utils/model/chatgptModels.ts
  • src/utils/model/configs.ts
  • src/utils/model/model.ts
  • src/utils/model/modelOptions.ts
  • src/utils/model/providers.ts
  • src/utils/settings/types.ts
  • src/utils/status.tsx

Comment on lines +105 to +107
const contentBlocks: Record<number, any> = {}
const collectedMessages: AssistantMessage[] = []
let partialMessage: any
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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Avoid as any in production code.

Variables contentBlocks and partialMessage use any typing. Per coding guidelines, production code should use specific types or Record<string, unknown> for objects with unknown structure.

-    const contentBlocks: Record<number, any> = {}
+    const contentBlocks: Record<number, Record<string, unknown>> = {}
     const collectedMessages: AssistantMessage[] = []
-    let partialMessage: any
+    let partialMessage: Record<string, unknown> | undefined
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const contentBlocks: Record<number, any> = {}
const collectedMessages: AssistantMessage[] = []
let partialMessage: any
const contentBlocks: Record<number, Record<string, unknown>> = {}
const collectedMessages: AssistantMessage[] = []
let partialMessage: Record<string, unknown> | undefined
🤖 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/codex/index.ts` around lines 105 - 107, Replace the loose
any types: change contentBlocks from Record<number, any> to a safer type (e.g.,
Record<number, unknown> or Map<number, unknown> depending on how it's used) and
give partialMessage a concrete type (for example AssistantMessage | undefined or
unknown or a defined PartialAssistantMessage interface) instead of any; update
any downstream code that accesses contentBlocks or partialMessage to narrow/cast
the unknown safely (using type guards or explicit mapping) so the compiler knows
the actual shape when using symbols contentBlocks and partialMessage.

Comment on lines +117 to +185
for await (const event of adaptedStream) {
switch (event.type) {
case 'message_start': {
partialMessage = (event as any).message
ttftMs = Date.now() - start
if ((event as any).message?.usage) {
usage = updateOpenAIUsage(usage, (event as any).message.usage)
}
break
}
case 'content_block_start': {
const idx = (event as any).index
const cb = (event as any).content_block
if (cb.type === 'tool_use') {
contentBlocks[idx] = { ...cb, input: '' }
} else if (cb.type === 'text') {
contentBlocks[idx] = { ...cb, text: '' }
} else if (cb.type === 'thinking') {
contentBlocks[idx] = { ...cb, thinking: '', signature: '' }
} else {
contentBlocks[idx] = { ...cb }
}
break
}
case 'content_block_delta': {
const idx = (event as any).index
const delta = (event as any).delta
const block = contentBlocks[idx]
if (!block) break
if (delta.type === 'text_delta') {
block.text = (block.text || '') + delta.text
} else if (delta.type === 'input_json_delta') {
block.input = (block.input || '') + delta.partial_json
} else if (delta.type === 'thinking_delta') {
block.thinking = (block.thinking || '') + delta.thinking
} else if (delta.type === 'signature_delta') {
block.signature = delta.signature
}
break
}
case 'content_block_stop': {
const idx = (event as any).index
const block = contentBlocks[idx]
if (!block || !partialMessage) break

const m: AssistantMessage = {
message: {
...partialMessage,
content: normalizeContentFromAPI([block], tools, options.agentId),
},
requestId: undefined,
type: 'assistant',
uuid: randomUUID(),
timestamp: new Date().toISOString(),
}
collectedMessages.push(m)
yield m
break
}
case 'message_delta': {
const deltaUsage = (event as any).usage
if (deltaUsage) {
usage = updateOpenAIUsage(usage, deltaUsage)
}
break
}
case 'message_stop':
break
}
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.

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Replace as any with typed event handling.

The event loop uses (event as any) repeatedly to access event properties. This violates the coding guideline prohibiting as any in production code. Define a discriminated union type or use type guards for the stream events.

♻️ Suggested approach
+// Define or import proper event types
+type StreamEventWithIndex = { type: string; index?: number; content_block?: Record<string, unknown>; delta?: Record<string, unknown>; message?: Record<string, unknown>; usage?: Record<string, unknown> }

     for await (const event of adaptedStream) {
+      const typedEvent = event as StreamEventWithIndex
       switch (event.type) {
         case 'message_start': {
-          partialMessage = (event as any).message
+          partialMessage = typedEvent.message
           ttftMs = Date.now() - start
-          if ((event as any).message?.usage) {
-            usage = updateOpenAIUsage(usage, (event as any).message.usage)
+          if (typedEvent.message?.usage) {
+            usage = updateOpenAIUsage(usage, typedEvent.message.usage as typeof usage)
           }
           break
         }
         case 'content_block_start': {
-          const idx = (event as any).index
-          const cb = (event as any).content_block
+          const idx = typedEvent.index ?? 0
+          const cb = typedEvent.content_block ?? {}
           // ... rest of the block
         }
         // ... similar changes for other cases

As per coding guidelines: "Prohibit as any type assertions in production code; in test files, as any is permitted for mock data. Use as unknown as SpecificType double assertion or interface supplementation when type mismatches occur"

🤖 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/codex/index.ts` around lines 117 - 185, The loop over
adaptedStream uses (event as any) everywhere; define a discriminated union for
the stream events (e.g., MessageStartEvent | ContentBlockStartEvent |
ContentBlockDeltaEvent | ContentBlockStopEvent | MessageDeltaEvent |
MessageStopEvent), update the for-await signature to use that union, and replace
all (event as any).X with strongly typed access (event.message, event.index,
event.delta, event.usage, etc.). Add minimal type-guard helpers where needed
(e.g., isContentBlockDelta(event): event is ContentBlockDeltaEvent) to narrow
variants in switch cases, and if you must coerce due to upstream types use the
approved double-assertion (as unknown as YourEventType) only at the stream
boundary; keep rest of code references (partialMessage, contentBlocks,
updateOpenAIUsage, normalizeContentFromAPI, AssistantMessage, randomUUID)
unchanged.

Comment on lines +191 to +192
const costUSD = calculateUSDCost(codexModel, usage as any)
addToTotalSessionCost(costUSD, usage as any, options.model)
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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Avoid as any for usage object.

The usage as any casts should use proper typing.

-        const costUSD = calculateUSDCost(codexModel, usage as any)
-        addToTotalSessionCost(costUSD, usage as any, options.model)
+        const costUSD = calculateUSDCost(codexModel, usage as unknown as Parameters<typeof calculateUSDCost>[1])
+        addToTotalSessionCost(costUSD, usage as unknown as Parameters<typeof addToTotalSessionCost>[1], options.model)

Alternatively, define the usage type to match what these functions expect.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const costUSD = calculateUSDCost(codexModel, usage as any)
addToTotalSessionCost(costUSD, usage as any, options.model)
const costUSD = calculateUSDCost(codexModel, usage as unknown as Parameters<typeof calculateUSDCost>[1])
addToTotalSessionCost(costUSD, usage as unknown as Parameters<typeof addToTotalSessionCost>[1], options.model)
🤖 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/codex/index.ts` around lines 191 - 192, Replace the unsafe
"as any" casts by giving `usage` a proper type that matches what
`calculateUSDCost` and `addToTotalSessionCost` expect; update the `usage`
variable declaration (or the function signatures) to use that concrete type
(e.g., `Usage`, `OpenAIUsage`, or your internal `ModelUsage`), import/define
that type and then call `calculateUSDCost(codexModel, usage)` and
`addToTotalSessionCost(costUSD, usage, options.model)` without `as any`; if only
one function needs a different shape, add a small adapter/mapper function (e.g.,
`toExpectedUsage(usage)`) to convert the current `usage` to the required type
rather than casting.

Comment on lines +83 to +101
// Codex provider specific
'CODEX_AUTH_MODE',
'CODEX_API_KEY',
'CODEX_BASE_URL',
'CODEX_RESPONSES_URL',
'CODEX_MODEL',
'CODEX_DEFAULT_HAIKU_MODEL',
'CODEX_DEFAULT_HAIKU_MODEL_DESCRIPTION',
'CODEX_DEFAULT_HAIKU_MODEL_NAME',
'CODEX_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES',
'CODEX_DEFAULT_OPUS_MODEL',
'CODEX_DEFAULT_OPUS_MODEL_DESCRIPTION',
'CODEX_DEFAULT_OPUS_MODEL_NAME',
'CODEX_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES',
'CODEX_DEFAULT_SONNET_MODEL',
'CODEX_DEFAULT_SONNET_MODEL_DESCRIPTION',
'CODEX_DEFAULT_SONNET_MODEL_NAME',
'CODEX_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES',
'CODEX_SMALL_FAST_MODEL',
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add CLAUDE_CODE_USE_CODEX to provider-managed routing env keys.

getAPIProvider() now routes on CLAUDE_CODE_USE_CODEX, but this key is not in PROVIDER_MANAGED_ENV_VARS. In host-managed mode, that lets settings-sourced env still force Codex selection and bypass host routing intent.

Suggested patch
 const PROVIDER_MANAGED_ENV_VARS = new Set([
   // The flag itself — settings can't unset it once the host set it
   'CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST',
   // Provider selection
   'CLAUDE_CODE_USE_BEDROCK',
   'CLAUDE_CODE_USE_VERTEX',
   'CLAUDE_CODE_USE_FOUNDRY',
   'CLAUDE_CODE_USE_GEMINI',
+  'CLAUDE_CODE_USE_CODEX',
🤖 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/utils/managedEnvConstants.ts` around lines 83 - 101,
PROVIDER_MANAGED_ENV_VARS is missing the new flag CLAUDE_CODE_USE_CODEX which
getAPIProvider() uses to decide Codex routing, allowing settings-sourced env to
override host-managed routing; add the string 'CLAUDE_CODE_USE_CODEX' to the
PROVIDER_MANAGED_ENV_VARS array in src/utils/managedEnvConstants.ts so
host-managed mode will treat that key as provider-managed and prevent settings
from forcing Codex selection in getAPIProvider().

Comment on lines +36 to +39
test('uses CODEX_MODEL as the default model when no explicit model is selected', () => {
process.env.CLAUDE_CODE_USE_CODEX = '1'
process.env.CODEX_MODEL = 'deepseek-v4-pro[1m]'

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make this test env-isolated like the first one.

Line 36-39 sets Codex env, but unlike Line 27-28 it doesn’t clear OPENAI_AUTH_MODE / CODEX_AUTH_MODE. This can make behavior depend on ambient runner env.

Proposed patch
   test('uses CODEX_MODEL as the default model when no explicit model is selected', () => {
     process.env.CLAUDE_CODE_USE_CODEX = '1'
     process.env.CODEX_MODEL = 'deepseek-v4-pro[1m]'
+    delete process.env.OPENAI_AUTH_MODE
+    delete process.env.CODEX_AUTH_MODE
 
     expect(getDefaultSonnetModel()).toBe('deepseek-v4-pro[1m]')
   })
🤖 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/utils/model/__tests__/codexModelOptions.test.ts` around lines 36 - 39,
The test "uses CODEX_MODEL as the default model when no explicit model is
selected" is not environment-isolated; modify it to save and restore any
affected env vars (at minimum OPENAI_AUTH_MODE and CODEX_AUTH_MODE) or
explicitly clear them for the test, then restore originals after the test
finishes; keep the existing process.env.CLAUDE_CODE_USE_CODEX and
process.env.CODEX_MODEL assignments but wrap them with backing up original
values (e.g., const prev = process.env.OPENAI_AUTH_MODE;
process.env.OPENAI_AUTH_MODE = ''; ... ) and restore
(process.env.OPENAI_AUTH_MODE = prev) in a finally or afterEach so the test does
not depend on ambient runner environment.

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.

1 participant