From 5d014b375b9633776453d44859d396b5d525966c Mon Sep 17 00:00:00 2001 From: 777genius Date: Sun, 19 Apr 2026 22:29:26 +0300 Subject: [PATCH] fix(runtime): tighten codex native-only phase 4 truth --- src/main/services/runtime/providerModelProbe.ts | 2 +- .../runtime/ProviderRuntimeBackendSelector.tsx | 4 ++++ .../runtime/ProviderRuntimeSettingsDialog.tsx | 2 +- .../team/dialogs/providerPrepareDiagnostics.ts | 2 +- src/renderer/utils/teamModelCatalog.ts | 4 ++-- .../CliProviderModelAvailabilityService.test.ts | 2 +- .../team/TeamProvisioningServicePrepare.test.ts | 2 +- .../runtime/ProviderRuntimeSettingsDialog.test.ts | 2 +- .../team/TeamModelSelectorDisabledState.test.ts | 6 +++--- .../dialogs/ProvisioningProviderStatusList.test.ts | 8 ++++---- .../team/dialogs/providerPrepareDiagnostics.test.ts | 12 ++++++------ .../team/dialogs/provisioningModelIssues.test.ts | 8 ++++---- 12 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/main/services/runtime/providerModelProbe.ts b/src/main/services/runtime/providerModelProbe.ts index 0a4b4f7b..f706539c 100644 --- a/src/main/services/runtime/providerModelProbe.ts +++ b/src/main/services/runtime/providerModelProbe.ts @@ -62,7 +62,7 @@ export function normalizeProviderModelProbeFailureReason(message: string): strin if ( /The '[^']+' model is not supported when using Codex with a ChatGPT account\./i.test(trimmed) ) { - return 'Not available with Codex ChatGPT subscription'; + return 'Not available on this Codex native runtime'; } if (/The requested model is not available for your account\./i.test(trimmed)) { return 'Not available for this account'; diff --git a/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx b/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx index 3a75c4c9..ffd4b966 100644 --- a/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx +++ b/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx @@ -116,6 +116,10 @@ export const ProviderRuntimeBackendSelector = ({ return null; } + if (provider.providerId === 'codex' && options.length === 1) { + return null; + } + const selectedBackendId = provider.selectedBackendId ?? options[0]?.id ?? ''; const selectedOption = options.find((option) => option.id === selectedBackendId) ?? options[0]; const resolvedOption = options.find((option) => option.id === provider.resolvedBackendId) ?? null; diff --git a/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx b/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx index fe75f3dd..d40e3661 100644 --- a/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +++ b/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx @@ -78,7 +78,7 @@ const API_KEY_PROVIDER_CONFIG: Record< }, codex: { envVarName: 'OPENAI_API_KEY', - name: 'OpenAI API Key', + name: 'Codex API Key', title: 'API key', description: 'Codex native requires API-key credentials. Save OPENAI_API_KEY here and the app will mirror it into the native CODEX_API_KEY environment when launching Codex.', diff --git a/src/renderer/components/team/dialogs/providerPrepareDiagnostics.ts b/src/renderer/components/team/dialogs/providerPrepareDiagnostics.ts index 626c5476..f1e47d6a 100644 --- a/src/renderer/components/team/dialogs/providerPrepareDiagnostics.ts +++ b/src/renderer/components/team/dialogs/providerPrepareDiagnostics.ts @@ -149,7 +149,7 @@ function normalizeModelReason(rawReason: string | null | undefined): string | nu if ( /The '[^']+' model is not supported when using Codex with a ChatGPT account\./i.test(trimmed) ) { - return 'Not available with Codex ChatGPT subscription'; + return 'Not available on this Codex native runtime'; } if (/The requested model is not available for your account\./i.test(trimmed)) { return 'Not available for this account'; diff --git a/src/renderer/utils/teamModelCatalog.ts b/src/renderer/utils/teamModelCatalog.ts index 5ac8d7b8..ad89fb92 100644 --- a/src/renderer/utils/teamModelCatalog.ts +++ b/src/renderer/utils/teamModelCatalog.ts @@ -28,9 +28,9 @@ export const TEAM_MODEL_UI_DISABLED_BADGE_LABEL = 'Disabled'; export const GPT_5_1_CODEX_MINI_UI_DISABLED_REASON = 'Temporarily disabled for team agents - this model has been less reliable with task and reply tool contracts.'; export const GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON = - 'Temporarily disabled for team agents when using Codex ChatGPT subscription - this model has been observed returning "Not available with Codex ChatGPT subscription".'; + 'Temporarily disabled for team agents - this model is not currently available on the Codex native runtime.'; export const GPT_5_2_CODEX_UI_DISABLED_REASON = - 'Temporarily disabled for team agents - this model has been observed returning "Not available with Codex ChatGPT subscription".'; + 'Temporarily disabled for team agents - this model is not currently available on the Codex native runtime.'; export const GPT_5_3_CODEX_SPARK_UI_DISABLED_REASON = 'Temporarily disabled for team agents - this model has been less reliable with bootstrap, task, and reply tool contracts.'; diff --git a/test/main/services/runtime/CliProviderModelAvailabilityService.test.ts b/test/main/services/runtime/CliProviderModelAvailabilityService.test.ts index 578fad06..552941f5 100644 --- a/test/main/services/runtime/CliProviderModelAvailabilityService.test.ts +++ b/test/main/services/runtime/CliProviderModelAvailabilityService.test.ts @@ -96,7 +96,7 @@ describe('CliProviderModelAvailabilityService', () => { expect.objectContaining({ modelId: 'gpt-5.4', status: 'unavailable', - reason: 'Not available with Codex ChatGPT subscription', + reason: 'Not available on this Codex native runtime', }), ], }) diff --git a/test/main/services/team/TeamProvisioningServicePrepare.test.ts b/test/main/services/team/TeamProvisioningServicePrepare.test.ts index 9f30a0a9..1cfb0a4a 100644 --- a/test/main/services/team/TeamProvisioningServicePrepare.test.ts +++ b/test/main/services/team/TeamProvisioningServicePrepare.test.ts @@ -402,7 +402,7 @@ describe('TeamProvisioningService prepare/auth behavior', () => { expect(result.ready).toBe(false); expect(result.message).toContain('Selected model gpt-5.2-codex is unavailable.'); - expect(result.message).toContain('Not available with Codex ChatGPT subscription'); + expect(result.message).toContain('Not available on this Codex native runtime'); }); it('keeps timed out Codex model verification as a warning with a clean generic reason', async () => { diff --git a/test/renderer/components/runtime/ProviderRuntimeSettingsDialog.test.ts b/test/renderer/components/runtime/ProviderRuntimeSettingsDialog.test.ts index 9995f624..10d68b2d 100644 --- a/test/renderer/components/runtime/ProviderRuntimeSettingsDialog.test.ts +++ b/test/renderer/components/runtime/ProviderRuntimeSettingsDialog.test.ts @@ -505,7 +505,7 @@ describe('ProviderRuntimeSettingsDialog', () => { id: 'key-1', envVarName: 'OPENAI_API_KEY', scope: 'user', - name: 'OpenAI API Key', + name: 'Codex API Key', maskedValue: 'sk-proj-...1234', createdAt: Date.now(), }, diff --git a/test/renderer/components/team/TeamModelSelectorDisabledState.test.ts b/test/renderer/components/team/TeamModelSelectorDisabledState.test.ts index 449ad5c0..47efb9ee 100644 --- a/test/renderer/components/team/TeamModelSelectorDisabledState.test.ts +++ b/test/renderer/components/team/TeamModelSelectorDisabledState.test.ts @@ -243,7 +243,7 @@ describe('TeamModelSelector disabled Codex models', () => { expect(disabledButton?.getAttribute('aria-disabled')).toBe('true'); expect(disabledButton?.textContent).toContain('Disabled'); expect(disabledButton?.getAttribute('title')).toContain( - 'Not available with Codex ChatGPT subscription' + 'Temporarily disabled for team agents - this model is not currently available on the Codex native runtime.' ); await act(async () => { @@ -391,7 +391,7 @@ describe('TeamModelSelector disabled Codex models', () => { value: 'gpt-5.2-codex', onValueChange: () => undefined, modelIssueReasonByValue: { - 'gpt-5.2-codex': 'Not available with Codex ChatGPT subscription', + 'gpt-5.2-codex': 'Not available on this Codex native runtime', }, }) ); @@ -404,7 +404,7 @@ describe('TeamModelSelector disabled Codex models', () => { ); expect(issueButton?.className).toContain('border-red-500/40'); expect(issueButton?.getAttribute('title')).toBe( - 'Not available with Codex ChatGPT subscription' + 'Not available on this Codex native runtime' ); await act(async () => { diff --git a/test/renderer/components/team/dialogs/ProvisioningProviderStatusList.test.ts b/test/renderer/components/team/dialogs/ProvisioningProviderStatusList.test.ts index a4a8065e..1fd0adbd 100644 --- a/test/renderer/components/team/dialogs/ProvisioningProviderStatusList.test.ts +++ b/test/renderer/components/team/dialogs/ProvisioningProviderStatusList.test.ts @@ -54,7 +54,7 @@ describe('ProvisioningProviderStatusList', () => { backendSummary: 'Codex native', details: [ '5.4 Mini - verified', - '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription', + '5.1 Codex Max - unavailable - Not available on this Codex native runtime', ], }, ], @@ -68,7 +68,7 @@ describe('ProvisioningProviderStatusList', () => { ); expect(host.textContent).toContain('5.4 Mini - verified'); expect(host.textContent).toContain( - '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription' + '5.1 Codex Max - unavailable - Not available on this Codex native runtime' ); const detailLines = Array.from(host.querySelectorAll('p')); @@ -90,11 +90,11 @@ describe('ProvisioningProviderStatusList', () => { details: [ '5.2 - verified', '5.3 Codex - check failed - Model verification timed out', - '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription', + '5.1 Codex Max - unavailable - Not available on this Codex native runtime', ], }, ]) - ).toBe('5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription'); + ).toBe('5.1 Codex Max - unavailable - Not available on this Codex native runtime'); }); it('summarizes timed out model verification separately from hard failures', async () => { diff --git a/test/renderer/components/team/dialogs/providerPrepareDiagnostics.test.ts b/test/renderer/components/team/dialogs/providerPrepareDiagnostics.test.ts index 65feb589..a313626d 100644 --- a/test/renderer/components/team/dialogs/providerPrepareDiagnostics.test.ts +++ b/test/renderer/components/team/dialogs/providerPrepareDiagnostics.test.ts @@ -35,7 +35,7 @@ describe('runProviderPrepareDiagnostics', () => { }, 'gpt-5.2-codex': { status: 'failed', - line: '5.2 Codex - unavailable - Not available with Codex ChatGPT subscription', + line: '5.2 Codex - unavailable - Not available on this Codex native runtime', warningLine: null, }, }) @@ -47,7 +47,7 @@ describe('runProviderPrepareDiagnostics', () => { }, 'gpt-5.2-codex': { status: 'failed', - line: '5.2 Codex - unavailable - Not available with Codex ChatGPT subscription', + line: '5.2 Codex - unavailable - Not available on this Codex native runtime', warningLine: null, }, }); @@ -129,14 +129,14 @@ describe('runProviderPrepareDiagnostics', () => { expect(result.status).toBe('failed'); expect(result.details).toEqual([ '5.4 - verified', - '5.2 Codex - unavailable - Not available with Codex ChatGPT subscription', + '5.2 Codex - unavailable - Not available on this Codex native runtime', ]); expect(progressUpdates.at(-1)).toEqual({ completedCount: 2, totalCount: 2, details: [ '5.4 - verified', - '5.2 Codex - unavailable - Not available with Codex ChatGPT subscription', + '5.2 Codex - unavailable - Not available on this Codex native runtime', ], }); expect(prepareProvisioning).toHaveBeenCalledTimes(2); @@ -173,7 +173,7 @@ describe('runProviderPrepareDiagnostics', () => { expect(result.status).toBe('failed'); expect(result.details).toEqual([ - '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription', + '5.1 Codex Max - unavailable - Not available on this Codex native runtime', ]); }); @@ -357,7 +357,7 @@ describe('runProviderPrepareDiagnostics', () => { expect(result.details).toEqual([ '5.2 - verified', '5.4 Mini - verified', - '5.2 Codex - unavailable - Not available with Codex ChatGPT subscription', + '5.2 Codex - unavailable - Not available on this Codex native runtime', ]); expect(prepareProvisioning).toHaveBeenCalledTimes(2); expect(prepareProvisioning).toHaveBeenNthCalledWith( diff --git a/test/renderer/components/team/dialogs/provisioningModelIssues.test.ts b/test/renderer/components/team/dialogs/provisioningModelIssues.test.ts index 69399be0..6b15a3a9 100644 --- a/test/renderer/components/team/dialogs/provisioningModelIssues.test.ts +++ b/test/renderer/components/team/dialogs/provisioningModelIssues.test.ts @@ -12,7 +12,7 @@ describe('getProvisioningModelIssue', () => { status: 'failed', details: [ '5.4 Mini - verified', - '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription', + '5.1 Codex Max - unavailable - Not available on this Codex native runtime', ], }, ], @@ -23,8 +23,8 @@ describe('getProvisioningModelIssue', () => { providerId: 'codex', modelId: 'gpt-5.1-codex-max', kind: 'unavailable', - reason: 'Not available with Codex ChatGPT subscription', - detail: '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription', + reason: 'Not available on this Codex native runtime', + detail: '5.1 Codex Max - unavailable - Not available on this Codex native runtime', }); }); @@ -37,7 +37,7 @@ describe('getProvisioningModelIssue', () => { status: 'failed', details: [ '5.4 Mini - verified', - '5.1 Codex Max - unavailable - Not available with Codex ChatGPT subscription', + '5.1 Codex Max - unavailable - Not available on this Codex native runtime', ], }, ],