Skip to content

Commit fbdda35

Browse files
Connoropolousclaude
andcommitted
fix(codex): skip model fallback when user has ChatGPT subscription
Check `codex login status` before the model availability check. If the user is logged in via ChatGPT subscription, gpt-5.3-codex is accessible natively and no fallback is needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 977c619 commit fbdda35

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

packages/codex-runner/src/CodexRunner.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,10 @@ export class CodexRunner extends EventEmitter implements IAgentRunner {
486486
/**
487487
* Check if the configured model is accessible via the OpenAI API.
488488
* If not, swap to the fallback model before starting the session.
489+
*
490+
* Skipped when:
491+
* - No OPENAI_API_KEY is set (Codex-native auth handles model access)
492+
* - The user has a ChatGPT subscription (`codex login status` reports "Logged in using ChatGPT")
489493
*/
490494
private async resolveModelWithFallback(): Promise<void> {
491495
const model = this.config.model;
@@ -495,6 +499,8 @@ export class CodexRunner extends EventEmitter implements IAgentRunner {
495499
const apiKey = process.env.OPENAI_API_KEY;
496500
if (!apiKey) return;
497501

502+
if (await this.hasCodexSubscription()) return;
503+
498504
const baseUrl = (
499505
process.env.OPENAI_BASE_URL ||
500506
process.env.OPENAI_API_BASE ||
@@ -522,6 +528,26 @@ export class CodexRunner extends EventEmitter implements IAgentRunner {
522528
}
523529
}
524530

531+
/**
532+
* Check if the user has a ChatGPT/Codex subscription by running `codex login status`.
533+
* Returns true when the output contains "Logged in using ChatGPT",
534+
* meaning the user has native Codex auth and can access gpt-5.3-codex.
535+
*/
536+
private async hasCodexSubscription(): Promise<boolean> {
537+
const codexBin = this.config.codexPath || "codex";
538+
try {
539+
const { execFile } = await import("node:child_process");
540+
const { promisify } = await import("node:util");
541+
const execFileAsync = promisify(execFile);
542+
const { stdout } = await execFileAsync(codexBin, ["login", "status"], {
543+
timeout: 5_000,
544+
});
545+
return /logged in using chatgpt/i.test(stdout);
546+
} catch {
547+
return false;
548+
}
549+
}
550+
525551
private createCodexClient(): Codex {
526552
const codexHome = this.resolveCodexHome();
527553
const envOverride = this.buildEnvOverride(codexHome);

0 commit comments

Comments
 (0)