diff --git a/src/models.ts b/src/models.ts index d929edaf..4616261f 100644 --- a/src/models.ts +++ b/src/models.ts @@ -621,6 +621,7 @@ const SHORT_NAMES: Record = { 'gpt-5.4-nano': 'GPT-5.4 Nano', 'gpt-5.4-mini': 'GPT-5.4 Mini', 'gpt-5.4': 'GPT-5.4', + 'gpt-5.3-codex-spark': 'GPT-5.3 Codex Spark', 'gpt-5.3-codex': 'GPT-5.3 Codex', 'gpt-5.3': 'GPT-5.3', 'gpt-5.2-pro': 'GPT-5.2 Pro', diff --git a/src/providers/codex.ts b/src/providers/codex.ts index e41a58b2..8cadf0d8 100644 --- a/src/providers/codex.ts +++ b/src/providers/codex.ts @@ -16,6 +16,7 @@ const modelDisplayNames: Record = { 'gpt-5.5': 'GPT-5.5', 'gpt-5.4-mini': 'GPT-5.4 Mini', 'gpt-5.4': 'GPT-5.4', + 'gpt-5.3-codex-spark': 'GPT-5.3 Codex Spark', 'gpt-5.3-codex': 'GPT-5.3 Codex', 'gpt-5.2-low': 'GPT-5.2 Low', 'gpt-5.2': 'GPT-5.2', diff --git a/tests/models.test.ts b/tests/models.test.ts index 2943f2e3..29fe3b72 100644 --- a/tests/models.test.ts +++ b/tests/models.test.ts @@ -51,6 +51,18 @@ describe('getShortModelName', () => { expect(getShortModelName('gpt-5.4-mini')).toBe('GPT-5.4 Mini') }) + // Regression for #461: spark is a distinct variant, not a reasoning suffix. + it('maps gpt-5.3-codex-spark to its own label (not GPT-5.3 Codex)', () => { + const name = getShortModelName('gpt-5.3-codex-spark') + expect(name).not.toBe('GPT-5.3 Codex') + expect(name).toBe('GPT-5.3 Codex Spark') + }) + + it('maps gpt-5.3-codex reasoning suffixes to the base label', () => { + expect(getShortModelName('gpt-5.3-codex-high')).toBe('GPT-5.3 Codex') + expect(getShortModelName('gpt-5.3-codex-low')).toBe('GPT-5.3 Codex') + }) + it('maps claude-opus-4-6 with date suffix', () => { expect(getShortModelName('claude-opus-4-6-20260205')).toBe('Opus 4.6') }) diff --git a/tests/providers/codex.test.ts b/tests/providers/codex.test.ts index 2b7fb962..958139f8 100644 --- a/tests/providers/codex.test.ts +++ b/tests/providers/codex.test.ts @@ -105,6 +105,21 @@ async function writeSession(dir: string, date: string, filename: string, lines: return filePath } +describe('codex provider - model display names', () => { + it('maps gpt-5.3-codex-spark to its own label', () => { + const provider = createCodexProvider(tmpDir) + const name = provider.modelDisplayName('gpt-5.3-codex-spark') + expect(name).not.toBe('GPT-5.3 Codex') + expect(name).toBe('GPT-5.3 Codex Spark') + }) + + it('maps gpt-5.3-codex reasoning suffixes to the base label', () => { + const provider = createCodexProvider(tmpDir) + expect(provider.modelDisplayName('gpt-5.3-codex-high')).toBe('GPT-5.3 Codex') + expect(provider.modelDisplayName('gpt-5.3-codex-low')).toBe('GPT-5.3 Codex') + }) +}) + describe('codex provider - session discovery', () => { it('discovers sessions in YYYY/MM/DD structure', async () => { await writeSession(tmpDir, '2026-04-14', 'rollout-abc123.jsonl', [