fix: add provider prefixes to CLI models for clear separation

- Add 'codex-' prefix to all Codex CLI model IDs
- Add 'cursor-' prefix to Cursor CLI GPT model IDs
- Update provider-utils.ts to use prefix-based matching
- Update UI components to use prefixed model IDs
- Fix model routing to prevent Cursor picking up Codex models
This commit is contained in:
DhanushSantosh
2026-01-09 00:03:49 +05:30
parent 08ccf2632a
commit 7b4667eba9
13 changed files with 121 additions and 114 deletions

View File

@@ -45,8 +45,8 @@ export function ModelSelector({
// Switch to Cursor's default model (from global settings) // Switch to Cursor's default model (from global settings)
onModelSelect(`${PROVIDER_PREFIXES.cursor}${cursorDefaultModel}`); onModelSelect(`${PROVIDER_PREFIXES.cursor}${cursorDefaultModel}`);
} else if (provider === 'codex' && selectedProvider !== 'codex') { } else if (provider === 'codex' && selectedProvider !== 'codex') {
// Switch to Codex's default model (gpt-5.2-codex) // Switch to Codex's default model (codex-gpt-5.2-codex)
onModelSelect('gpt-5.2-codex'); onModelSelect('codex-gpt-5.2-codex');
} else if (provider === 'claude' && selectedProvider !== 'claude') { } else if (provider === 'claude' && selectedProvider !== 'claude') {
// Switch to Claude's default model // Switch to Claude's default model
onModelSelect('sonnet'); onModelSelect('sonnet');

View File

@@ -20,7 +20,7 @@ function getProfileModelDisplay(profile: AIProfile): string {
return modelConfig?.label || cursorModel; return modelConfig?.label || cursorModel;
} }
if (profile.provider === 'codex') { if (profile.provider === 'codex') {
return getCodexModelLabel(profile.codexModel || 'gpt-5.2-codex'); return getCodexModelLabel(profile.codexModel || 'codex-gpt-5.2-codex');
} }
// Claude // Claude
return profile.model || 'sonnet'; return profile.model || 'sonnet';

View File

@@ -26,7 +26,7 @@ function getProfileModelDisplay(profile: AIProfile): string {
return modelConfig?.label || cursorModel; return modelConfig?.label || cursorModel;
} }
if (profile.provider === 'codex') { if (profile.provider === 'codex') {
return getCodexModelLabel(profile.codexModel || 'gpt-5.2-codex'); return getCodexModelLabel(profile.codexModel || 'codex-gpt-5.2-codex');
} }
// Claude // Claude
return profile.model || 'sonnet'; return profile.model || 'sonnet';

View File

@@ -99,7 +99,7 @@ export function SortableProfileCard({ profile, onEdit, onDelete }: SortableProfi
profile.cursorModel || profile.cursorModel ||
'auto' 'auto'
: profile.provider === 'codex' : profile.provider === 'codex'
? getCodexModelLabel(profile.codexModel || 'gpt-5.2-codex') ? getCodexModelLabel(profile.codexModel || 'codex-gpt-5.2-codex')
: profile.model || 'sonnet'} : profile.model || 'sonnet'}
</span> </span>

View File

@@ -29,28 +29,28 @@ interface CodexModelInfo {
} }
const CODEX_MODEL_INFO: Record<CodexModelId, CodexModelInfo> = { const CODEX_MODEL_INFO: Record<CodexModelId, CodexModelInfo> = {
'gpt-5.2-codex': { 'codex-gpt-5.2-codex': {
id: 'gpt-5.2-codex', id: 'codex-gpt-5.2-codex',
label: 'GPT-5.2-Codex', label: 'GPT-5.2-Codex',
description: 'Most advanced agentic coding model for complex software engineering', description: 'Most advanced agentic coding model for complex software engineering',
}, },
'gpt-5.1-codex-max': { 'codex-gpt-5.1-codex-max': {
id: 'gpt-5.1-codex-max', id: 'codex-gpt-5.1-codex-max',
label: 'GPT-5.1-Codex-Max', label: 'GPT-5.1-Codex-Max',
description: 'Optimized for long-horizon, agentic coding tasks in Codex', description: 'Optimized for long-horizon, agentic coding tasks in Codex',
}, },
'gpt-5.1-codex-mini': { 'codex-gpt-5.1-codex-mini': {
id: 'gpt-5.1-codex-mini', id: 'codex-gpt-5.1-codex-mini',
label: 'GPT-5.1-Codex-Mini', label: 'GPT-5.1-Codex-Mini',
description: 'Smaller, more cost-effective version for faster workflows', description: 'Smaller, more cost-effective version for faster workflows',
}, },
'gpt-5.2': { 'codex-gpt-5.2': {
id: 'gpt-5.2', id: 'codex-gpt-5.2',
label: 'GPT-5.2', label: 'GPT-5.2',
description: 'Best general agentic model for tasks across industries and domains', description: 'Best general agentic model for tasks across industries and domains',
}, },
'gpt-5.1': { 'codex-gpt-5.1': {
id: 'gpt-5.1', id: 'codex-gpt-5.1',
label: 'GPT-5.1', label: 'GPT-5.1',
description: 'Great for coding and agentic tasks across domains', description: 'Great for coding and agentic tasks across domains',
}, },
@@ -162,16 +162,21 @@ export function CodexModelConfiguration({
function getModelDisplayName(modelId: string): string { function getModelDisplayName(modelId: string): string {
const displayNames: Record<string, string> = { const displayNames: Record<string, string> = {
'gpt-5.2-codex': 'GPT-5.2-Codex', 'codex-gpt-5.2-codex': 'GPT-5.2-Codex',
'gpt-5.1-codex-max': 'GPT-5.1-Codex-Max', 'codex-gpt-5.1-codex-max': 'GPT-5.1-Codex-Max',
'gpt-5.1-codex-mini': 'GPT-5.1-Codex-Mini', 'codex-gpt-5.1-codex-mini': 'GPT-5.1-Codex-Mini',
'gpt-5.2': 'GPT-5.2', 'codex-gpt-5.2': 'GPT-5.2',
'gpt-5.1': 'GPT-5.1', 'codex-gpt-5.1': 'GPT-5.1',
}; };
return displayNames[modelId] || modelId; return displayNames[modelId] || modelId;
} }
function supportsReasoningEffort(modelId: string): boolean { function supportsReasoningEffort(modelId: string): boolean {
const reasoningModels = ['gpt-5.2-codex', 'gpt-5.1-codex-max', 'gpt-5.2', 'gpt-5.1']; const reasoningModels = [
'codex-gpt-5.2-codex',
'codex-gpt-5.1-codex-max',
'codex-gpt-5.2',
'codex-gpt-5.1',
];
return reasoningModels.includes(modelId); return reasoningModels.includes(modelId);
} }

View File

@@ -39,11 +39,11 @@ export function formatModelName(model: string): string {
if (model.includes('haiku')) return 'Haiku 4.5'; if (model.includes('haiku')) return 'Haiku 4.5';
// Codex/GPT models - specific formatting // Codex/GPT models - specific formatting
if (model === 'gpt-5.2-codex') return 'GPT-5.2 Codex'; if (model === 'codex-gpt-5.2-codex') return 'GPT-5.2 Codex';
if (model === 'gpt-5.2') return 'GPT-5.2'; if (model === 'codex-gpt-5.2') return 'GPT-5.2';
if (model === 'gpt-5.1-codex-max') return 'GPT-5.1 Max'; if (model === 'codex-gpt-5.1-codex-max') return 'GPT-5.1 Max';
if (model === 'gpt-5.1-codex-mini') return 'GPT-5.1 Mini'; if (model === 'codex-gpt-5.1-codex-mini') return 'GPT-5.1 Mini';
if (model === 'gpt-5.1') return 'GPT-5.1'; if (model === 'codex-gpt-5.1') return 'GPT-5.1';
// Generic fallbacks for other GPT models // Generic fallbacks for other GPT models
if (model.startsWith('gpt-')) return model.toUpperCase(); if (model.startsWith('gpt-')) return model.toUpperCase();
if (model.match(/^o\d/)) return model.toUpperCase(); // o1, o3, etc. if (model.match(/^o\d/)) return model.toUpperCase(); // o1, o3, etc.

View File

@@ -59,14 +59,16 @@ export function getModelDisplayName(model: ModelAlias | string): string {
sonnet: 'Claude Sonnet', sonnet: 'Claude Sonnet',
opus: 'Claude Opus', opus: 'Claude Opus',
// Codex models // Codex models
'gpt-5.2': 'GPT-5.2', 'codex-gpt-5.2': 'GPT-5.2',
'gpt-5.1-codex-max': 'GPT-5.1 Codex Max', 'codex-gpt-5.1-codex-max': 'GPT-5.1 Codex Max',
'gpt-5.1-codex': 'GPT-5.1 Codex', 'codex-gpt-5.1-codex': 'GPT-5.1 Codex',
'gpt-5.1-codex-mini': 'GPT-5.1 Codex Mini', 'codex-gpt-5.1-codex-mini': 'GPT-5.1 Codex Mini',
'gpt-5.1': 'GPT-5.1', 'codex-gpt-5.1': 'GPT-5.1',
// Cursor models (common ones) // Cursor models (common ones)
'cursor-auto': 'Cursor Auto', 'cursor-auto': 'Cursor Auto',
'cursor-composer-1': 'Composer 1', 'cursor-composer-1': 'Composer 1',
'cursor-gpt-5.2': 'GPT-5.2',
'cursor-gpt-5.1': 'GPT-5.1',
}; };
return displayNames[model] || model; return displayNames[model] || model;
} }

View File

@@ -1161,7 +1161,7 @@ const initialState: AppState = {
enabledCursorModels: getAllCursorModelIds(), // All Cursor models enabled by default enabledCursorModels: getAllCursorModelIds(), // All Cursor models enabled by default
cursorDefaultModel: 'auto', // Default to auto selection cursorDefaultModel: 'auto', // Default to auto selection
enabledCodexModels: getAllCodexModelIds(), // All Codex models enabled by default enabledCodexModels: getAllCodexModelIds(), // All Codex models enabled by default
codexDefaultModel: 'gpt-5.2-codex', // Default to GPT-5.2-Codex codexDefaultModel: 'codex-gpt-5.2-codex', // Default to GPT-5.2-Codex
codexAutoLoadAgents: false, // Default to disabled (user must opt-in) codexAutoLoadAgents: false, // Default to disabled (user must opt-in)
codexSandboxMode: 'workspace-write', // Default to workspace-write for safety codexSandboxMode: 'workspace-write', // Default to workspace-write for safety
codexApprovalPolicy: 'on-request', // Default to on-request for balanced safety codexApprovalPolicy: 'on-request', // Default to on-request for balanced safety

View File

@@ -2,13 +2,15 @@
* Codex CLI Model IDs * Codex CLI Model IDs
* Based on OpenAI Codex CLI official models * Based on OpenAI Codex CLI official models
* Reference: https://developers.openai.com/codex/models/ * Reference: https://developers.openai.com/codex/models/
*
* IMPORTANT: All Codex models use 'codex-' prefix to distinguish from Cursor CLI models
*/ */
export type CodexModelId = export type CodexModelId =
| 'gpt-5.2-codex' | 'codex-gpt-5.2-codex'
| 'gpt-5.1-codex-max' | 'codex-gpt-5.1-codex-max'
| 'gpt-5.1-codex-mini' | 'codex-gpt-5.1-codex-mini'
| 'gpt-5.2' | 'codex-gpt-5.2'
| 'gpt-5.1'; | 'codex-gpt-5.1';
/** /**
* Codex model metadata * Codex model metadata
@@ -24,40 +26,41 @@ export interface CodexModelConfig {
/** /**
* Complete model map for Codex CLI * Complete model map for Codex CLI
* All keys use 'codex-' prefix to distinguish from Cursor CLI models
*/ */
export const CODEX_MODEL_CONFIG_MAP: Record<CodexModelId, CodexModelConfig> = { export const CODEX_MODEL_CONFIG_MAP: Record<CodexModelId, CodexModelConfig> = {
'gpt-5.2-codex': { 'codex-gpt-5.2-codex': {
id: 'gpt-5.2-codex', id: 'codex-gpt-5.2-codex',
label: 'GPT-5.2-Codex', label: 'GPT-5.2-Codex',
description: 'Most advanced agentic coding model for complex software engineering', description: 'Most advanced agentic coding model for complex software engineering',
hasThinking: true, hasThinking: true,
supportsVision: true, supportsVision: true,
}, },
'gpt-5.1-codex-max': { 'codex-gpt-5.1-codex-max': {
id: 'gpt-5.1-codex-max', id: 'codex-gpt-5.1-codex-max',
label: 'GPT-5.1-Codex-Max', label: 'GPT-5.1-Codex-Max',
description: 'Optimized for long-horizon, agentic coding tasks in Codex', description: 'Optimized for long-horizon, agentic coding tasks in Codex',
hasThinking: true, hasThinking: true,
supportsVision: true, supportsVision: true,
}, },
'gpt-5.1-codex-mini': { 'codex-gpt-5.1-codex-mini': {
id: 'gpt-5.1-codex-mini', id: 'codex-gpt-5.1-codex-mini',
label: 'GPT-5.1-Codex-Mini', label: 'GPT-5.1-Codex-Mini',
description: 'Smaller, more cost-effective version for faster workflows', description: 'Smaller, more cost-effective version for faster workflows',
hasThinking: false, hasThinking: false,
supportsVision: true, supportsVision: true,
}, },
'gpt-5.2': { 'codex-gpt-5.2': {
id: 'gpt-5.2', id: 'codex-gpt-5.2',
label: 'GPT-5.2', label: 'GPT-5.2 (Codex)',
description: 'Best general agentic model for tasks across industries and domains', description: 'Best general agentic model for tasks across industries and domains via Codex',
hasThinking: true, hasThinking: true,
supportsVision: true, supportsVision: true,
}, },
'gpt-5.1': { 'codex-gpt-5.1': {
id: 'gpt-5.1', id: 'codex-gpt-5.1',
label: 'GPT-5.1', label: 'GPT-5.1 (Codex)',
description: 'Great for coding and agentic tasks across domains', description: 'Great for coding and agentic tasks across domains via Codex',
hasThinking: true, hasThinking: true,
supportsVision: true, supportsVision: true,
}, },

View File

@@ -1,6 +1,8 @@
/** /**
* Cursor CLI Model IDs * Cursor CLI Model IDs
* Reference: https://cursor.com/docs * Reference: https://cursor.com/docs
*
* IMPORTANT: GPT models use 'cursor-' prefix to distinguish from Codex CLI models
*/ */
export type CursorModelId = export type CursorModelId =
| 'auto' // Auto-select best model | 'auto' // Auto-select best model
@@ -12,14 +14,14 @@ export type CursorModelId =
| 'opus-4.1' // Claude Opus 4.1 | 'opus-4.1' // Claude Opus 4.1
| 'gemini-3-pro' // Gemini 3 Pro | 'gemini-3-pro' // Gemini 3 Pro
| 'gemini-3-flash' // Gemini 3 Flash | 'gemini-3-flash' // Gemini 3 Flash
| 'gpt-5.2' // GPT-5.2 | 'cursor-gpt-5.2' // GPT-5.2 via Cursor
| 'gpt-5.1' // GPT-5.1 | 'cursor-gpt-5.1' // GPT-5.1 via Cursor
| 'gpt-5.2-high' // GPT-5.2 High | 'cursor-gpt-5.2-high' // GPT-5.2 High via Cursor
| 'gpt-5.1-high' // GPT-5.1 High | 'cursor-gpt-5.1-high' // GPT-5.1 High via Cursor
| 'gpt-5.1-codex' // GPT-5.1 Codex | 'cursor-gpt-5.1-codex' // GPT-5.1 Codex via Cursor
| 'gpt-5.1-codex-high' // GPT-5.1 Codex High | 'cursor-gpt-5.1-codex-high' // GPT-5.1 Codex High via Cursor
| 'gpt-5.1-codex-max' // GPT-5.1 Codex Max | 'cursor-gpt-5.1-codex-max' // GPT-5.1 Codex Max via Cursor
| 'gpt-5.1-codex-max-high' // GPT-5.1 Codex Max High | 'cursor-gpt-5.1-codex-max-high' // GPT-5.1 Codex Max High via Cursor
| 'grok'; // Grok | 'grok'; // Grok
/** /**
@@ -101,57 +103,57 @@ export const CURSOR_MODEL_MAP: Record<CursorModelId, CursorModelConfig> = {
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.2': { 'cursor-gpt-5.2': {
id: 'gpt-5.2', id: 'cursor-gpt-5.2',
label: 'GPT-5.2', label: 'GPT-5.2',
description: 'OpenAI GPT-5.2 via Cursor', description: 'OpenAI GPT-5.2 via Cursor',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.1': { 'cursor-gpt-5.1': {
id: 'gpt-5.1', id: 'cursor-gpt-5.1',
label: 'GPT-5.1', label: 'GPT-5.1',
description: 'OpenAI GPT-5.1 via Cursor', description: 'OpenAI GPT-5.1 via Cursor',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.2-high': { 'cursor-gpt-5.2-high': {
id: 'gpt-5.2-high', id: 'cursor-gpt-5.2-high',
label: 'GPT-5.2 High', label: 'GPT-5.2 High',
description: 'OpenAI GPT-5.2 with high compute', description: 'OpenAI GPT-5.2 with high compute',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.1-high': { 'cursor-gpt-5.1-high': {
id: 'gpt-5.1-high', id: 'cursor-gpt-5.1-high',
label: 'GPT-5.1 High', label: 'GPT-5.1 High',
description: 'OpenAI GPT-5.1 with high compute', description: 'OpenAI GPT-5.1 with high compute',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.1-codex': { 'cursor-gpt-5.1-codex': {
id: 'gpt-5.1-codex', id: 'cursor-gpt-5.1-codex',
label: 'GPT-5.1 Codex', label: 'GPT-5.1 Codex',
description: 'OpenAI GPT-5.1 Codex for code generation', description: 'OpenAI GPT-5.1 Codex for code generation',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.1-codex-high': { 'cursor-gpt-5.1-codex-high': {
id: 'gpt-5.1-codex-high', id: 'cursor-gpt-5.1-codex-high',
label: 'GPT-5.1 Codex High', label: 'GPT-5.1 Codex High',
description: 'OpenAI GPT-5.1 Codex with high compute', description: 'OpenAI GPT-5.1 Codex with high compute',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.1-codex-max': { 'cursor-gpt-5.1-codex-max': {
id: 'gpt-5.1-codex-max', id: 'cursor-gpt-5.1-codex-max',
label: 'GPT-5.1 Codex Max', label: 'GPT-5.1 Codex Max',
description: 'OpenAI GPT-5.1 Codex Max capacity', description: 'OpenAI GPT-5.1 Codex Max capacity',
hasThinking: false, hasThinking: false,
supportsVision: false, supportsVision: false,
}, },
'gpt-5.1-codex-max-high': { 'cursor-gpt-5.1-codex-max-high': {
id: 'gpt-5.1-codex-max-high', id: 'cursor-gpt-5.1-codex-max-high',
label: 'GPT-5.1 Codex Max High', label: 'GPT-5.1 Codex Max High',
description: 'OpenAI GPT-5.1 Codex Max with high compute', description: 'OpenAI GPT-5.1 Codex Max with high compute',
hasThinking: false, hasThinking: false,
@@ -224,14 +226,14 @@ export interface GroupedModel {
export const CURSOR_MODEL_GROUPS: GroupedModel[] = [ export const CURSOR_MODEL_GROUPS: GroupedModel[] = [
// GPT-5.2 group (compute levels) // GPT-5.2 group (compute levels)
{ {
baseId: 'gpt-5.2-group', baseId: 'cursor-gpt-5.2-group',
label: 'GPT-5.2', label: 'GPT-5.2',
description: 'OpenAI GPT-5.2 via Cursor', description: 'OpenAI GPT-5.2 via Cursor',
variantType: 'compute', variantType: 'compute',
variants: [ variants: [
{ id: 'gpt-5.2', label: 'Standard', description: 'Default compute level' }, { id: 'cursor-gpt-5.2', label: 'Standard', description: 'Default compute level' },
{ {
id: 'gpt-5.2-high', id: 'cursor-gpt-5.2-high',
label: 'High', label: 'High',
description: 'High compute level', description: 'High compute level',
badge: 'More tokens', badge: 'More tokens',
@@ -240,14 +242,14 @@ export const CURSOR_MODEL_GROUPS: GroupedModel[] = [
}, },
// GPT-5.1 group (compute levels) // GPT-5.1 group (compute levels)
{ {
baseId: 'gpt-5.1-group', baseId: 'cursor-gpt-5.1-group',
label: 'GPT-5.1', label: 'GPT-5.1',
description: 'OpenAI GPT-5.1 via Cursor', description: 'OpenAI GPT-5.1 via Cursor',
variantType: 'compute', variantType: 'compute',
variants: [ variants: [
{ id: 'gpt-5.1', label: 'Standard', description: 'Default compute level' }, { id: 'cursor-gpt-5.1', label: 'Standard', description: 'Default compute level' },
{ {
id: 'gpt-5.1-high', id: 'cursor-gpt-5.1-high',
label: 'High', label: 'High',
description: 'High compute level', description: 'High compute level',
badge: 'More tokens', badge: 'More tokens',
@@ -256,16 +258,26 @@ export const CURSOR_MODEL_GROUPS: GroupedModel[] = [
}, },
// GPT-5.1 Codex group (capacity + compute matrix) // GPT-5.1 Codex group (capacity + compute matrix)
{ {
baseId: 'gpt-5.1-codex-group', baseId: 'cursor-gpt-5.1-codex-group',
label: 'GPT-5.1 Codex', label: 'GPT-5.1 Codex',
description: 'OpenAI GPT-5.1 Codex for code generation', description: 'OpenAI GPT-5.1 Codex for code generation',
variantType: 'capacity', variantType: 'capacity',
variants: [ variants: [
{ id: 'gpt-5.1-codex', label: 'Standard', description: 'Default capacity' }, { id: 'cursor-gpt-5.1-codex', label: 'Standard', description: 'Default capacity' },
{ id: 'gpt-5.1-codex-high', label: 'High', description: 'High compute', badge: 'Compute' },
{ id: 'gpt-5.1-codex-max', label: 'Max', description: 'Maximum capacity', badge: 'Capacity' },
{ {
id: 'gpt-5.1-codex-max-high', id: 'cursor-gpt-5.1-codex-high',
label: 'High',
description: 'High compute',
badge: 'Compute',
},
{
id: 'cursor-gpt-5.1-codex-max',
label: 'Max',
description: 'Maximum capacity',
badge: 'Capacity',
},
{
id: 'cursor-gpt-5.1-codex-max-high',
label: 'Max High', label: 'Max High',
description: 'Max capacity + high compute', description: 'Max capacity + high compute',
badge: 'Premium', badge: 'Premium',

View File

@@ -11,21 +11,23 @@ export const CLAUDE_MODEL_MAP: Record<string, string> = {
* Codex/OpenAI model identifiers * Codex/OpenAI model identifiers
* Based on OpenAI Codex CLI official models * Based on OpenAI Codex CLI official models
* See: https://developers.openai.com/codex/models/ * See: https://developers.openai.com/codex/models/
*
* IMPORTANT: All Codex models use 'codex-' prefix to distinguish from Cursor CLI models
*/ */
export const CODEX_MODEL_MAP = { export const CODEX_MODEL_MAP = {
// Recommended Codex-specific models // Recommended Codex-specific models
/** Most advanced agentic coding model for complex software engineering (default for ChatGPT users) */ /** Most advanced agentic coding model for complex software engineering (default for ChatGPT users) */
gpt52Codex: 'gpt-5.2-codex', gpt52Codex: 'codex-gpt-5.2-codex',
/** Optimized for long-horizon, agentic coding tasks in Codex */ /** Optimized for long-horizon, agentic coding tasks in Codex */
gpt51CodexMax: 'gpt-5.1-codex-max', gpt51CodexMax: 'codex-gpt-5.1-codex-max',
/** Smaller, more cost-effective version for faster workflows */ /** Smaller, more cost-effective version for faster workflows */
gpt51CodexMini: 'gpt-5.1-codex-mini', gpt51CodexMini: 'codex-gpt-5.1-codex-mini',
// General-purpose GPT models (also available in Codex) // General-purpose GPT models (also available in Codex)
/** Best general agentic model for tasks across industries and domains */ /** Best general agentic model for tasks across industries and domains */
gpt52: 'gpt-5.2', gpt52: 'codex-gpt-5.2',
/** Great for coding and agentic tasks across domains */ /** Great for coding and agentic tasks across domains */
gpt51: 'gpt-5.1', gpt51: 'codex-gpt-5.1',
} as const; } as const;
export const CODEX_MODEL_IDS = Object.values(CODEX_MODEL_MAP); export const CODEX_MODEL_IDS = Object.values(CODEX_MODEL_MAP);

View File

@@ -15,7 +15,6 @@ import { CODEX_MODEL_CONFIG_MAP, type CodexModelId } from './codex-models.js';
export const PROVIDER_PREFIXES = { export const PROVIDER_PREFIXES = {
cursor: 'cursor-', cursor: 'cursor-',
codex: 'codex-', codex: 'codex-',
// Add new provider prefixes here
} as const; } as const;
/** /**
@@ -35,20 +34,6 @@ export function isCursorModel(model: string | undefined | null): boolean {
// Check if it's a bare Cursor model ID (excluding Codex-specific models) // Check if it's a bare Cursor model ID (excluding Codex-specific models)
// Codex-specific models should always route to Codex provider, not Cursor // Codex-specific models should always route to Codex provider, not Cursor
if (model in CURSOR_MODEL_MAP) { if (model in CURSOR_MODEL_MAP) {
// Exclude Codex-specific model IDs that are in Cursor's model map
// These models should be routed to Codex provider instead
// This includes all Codex model variants (standard, high, max, mini, etc.)
if (
model.startsWith('gpt-5.1-codex-') ||
model.startsWith('gpt-5.2-codex-') ||
// Also exclude bare Codex models that overlap with Cursor's OpenAI models
model === 'gpt-5.2' ||
model === 'gpt-5.1' ||
// Exclude all Codex models from CODEX_MODEL_CONFIG_MAP
model in CODEX_MODEL_CONFIG_MAP
) {
return false;
}
return true; return true;
} }
@@ -87,7 +72,7 @@ export function isCodexModel(model: string | undefined | null): boolean {
return true; return true;
} }
// Check if it's a gpt- model // Check if it's a gpt- model (bare gpt models go to Codex, not Cursor)
if (model.startsWith('gpt-')) { if (model.startsWith('gpt-')) {
return true; return true;
} }
@@ -98,8 +83,7 @@ export function isCodexModel(model: string | undefined | null): boolean {
} }
// Check if it's in the CODEX_MODEL_MAP // Check if it's in the CODEX_MODEL_MAP
const modelValues = Object.values(CODEX_MODEL_MAP); return model in CODEX_MODEL_MAP;
return modelValues.includes(model as CodexModelId);
} }
/** /**
@@ -198,9 +182,8 @@ export function normalizeModelString(model: string | undefined | null): string {
} }
// For Codex, bare gpt-* and o-series models are valid canonical forms // For Codex, bare gpt-* and o-series models are valid canonical forms
// Only add prefix if it's in CODEX_MODEL_MAP but doesn't have gpt-/o prefix // Check if it's in the CODEX_MODEL_MAP
const codexModelValues = Object.values(CODEX_MODEL_MAP); if (model in CODEX_MODEL_MAP) {
if (codexModelValues.includes(model as CodexModelId)) {
// If it already starts with gpt- or o, it's canonical // If it already starts with gpt- or o, it's canonical
if (model.startsWith('gpt-') || /^o\d/.test(model)) { if (model.startsWith('gpt-') || /^o\d/.test(model)) {
return model; return model;

View File

@@ -281,7 +281,7 @@ export function profileHasThinking(profile: AIProfile): boolean {
if (profile.provider === 'codex') { if (profile.provider === 'codex') {
// Codex models handle thinking internally (o-series models) // Codex models handle thinking internally (o-series models)
const model = profile.codexModel || 'gpt-5.2'; const model = profile.codexModel || 'codex-gpt-5.2';
return model.startsWith('o'); return model.startsWith('o');
} }
@@ -297,7 +297,7 @@ export function getProfileModelString(profile: AIProfile): string {
} }
if (profile.provider === 'codex') { if (profile.provider === 'codex') {
return `codex:${profile.codexModel || 'gpt-5.2'}`; return `codex:${profile.codexModel || 'codex-gpt-5.2'}`;
} }
// Claude // Claude