feat: Refactor model handling & reasoning effort across navigation, typeahead, OpenAI/Codex providers, API shim, configs, and UI (adds EffortPicker, new mappings/options, unique suggestion IDs, effort utilities; removes deprecated aliases; defaults Codex to gpt-5.4; improves selection logic and status display)

This commit is contained in:
Meet Patel
2026-04-02 17:17:14 +05:30
parent 9f48bb4431
commit 8f50f17674
15 changed files with 612 additions and 139 deletions

View File

@@ -268,20 +268,65 @@ function getOpusPlanOption(): ModelOption {
function getCodexPlanOption(): ModelOption {
return {
value: 'codexplan',
label: 'Codex Plan',
value: 'gpt-5.4',
label: 'gpt-5.4',
description: 'GPT-5.4 on the Codex backend with high reasoning',
}
}
function getCodexSparkOption(): ModelOption {
return {
value: 'codexspark',
label: 'Codex Spark',
value: 'gpt-5.3-codex-spark',
label: 'gpt-5.3-codex-spark',
description: 'GPT-5.3 Codex Spark on the Codex backend for fast tool loops',
}
}
function getCodexModelOptions(): ModelOption[] {
return [
{
value: 'gpt-5.4',
label: 'gpt-5.4',
description: 'GPT-5.4 with high reasoning',
},
{
value: 'gpt-5.3-codex',
label: 'gpt-5.3-codex',
description: 'GPT-5.3 Codex with high reasoning',
},
{
value: 'gpt-5.3-codex-spark',
label: 'gpt-5.3-codex-spark',
description: 'GPT-5.3 Codex Spark for fast tool loops',
},
{
value: 'codexspark',
label: 'codexspark',
description: 'GPT-5.3 Codex Spark alias for fast tool loops',
},
{
value: 'gpt-5.2-codex',
label: 'gpt-5.2-codex',
description: 'GPT-5.2 Codex with high reasoning',
},
{
value: 'gpt-5.1-codex-max',
label: 'gpt-5.1-codex-max',
description: 'GPT-5.1 Codex Max for deep reasoning',
},
{
value: 'gpt-5.1-codex-mini',
label: 'gpt-5.1-codex-mini',
description: 'GPT-5.1 Codex Mini - faster, cheaper',
},
{
value: 'gpt-5.4-mini',
label: 'gpt-5.4-mini',
description: 'GPT-5.4 Mini - faster, cheaper',
},
]
}
// @[MODEL LAUNCH]: Update the model picker lists below to include/reorder options for the new model.
// Each user tier (ant, Max/Team Premium, Pro/Team Standard/Enterprise, PAYG 1P, PAYG 3P) has its own list.
function getModelOptionsBase(fastMode = false): ModelOption[] {
@@ -360,8 +405,9 @@ function getModelOptionsBase(fastMode = false): ModelOption[] {
// PAYG 3P: Default (Sonnet 4.5) + Sonnet (3P custom) or Sonnet 4.6/1M + Opus (3P custom) or Opus 4.1/Opus 4.6/Opus1M + Haiku + Opus 4.1
const payg3pOptions = [getDefaultOptionForUser(fastMode)]
if (getAPIProvider() === 'openai') {
payg3pOptions.push(getCodexPlanOption(), getCodexSparkOption())
// Add Codex models for openai and codex providers
if (getAPIProvider() === 'openai' || getAPIProvider() === 'codex') {
payg3pOptions.push(...getCodexModelOptions())
}
const customSonnet = getCustomSonnetOption()
@@ -517,9 +563,9 @@ export function getModelOptions(fastMode = false): ModelOption[] {
return filterModelOptionsByAllowlist(options)
} else if (customModel === 'opusplan') {
return filterModelOptionsByAllowlist([...options, getOpusPlanOption()])
} else if (customModel === 'codexplan') {
} else if (customModel === 'gpt-5.4') {
return filterModelOptionsByAllowlist([...options, getCodexPlanOption()])
} else if (customModel === 'codexspark') {
} else if (customModel === 'gpt-5.3-codex-spark') {
return filterModelOptionsByAllowlist([...options, getCodexSparkOption()])
} else if (customModel === 'opus' && getAPIProvider() === 'firstParty') {
return filterModelOptionsByAllowlist([
@@ -554,11 +600,23 @@ export function getModelOptions(fastMode = false): ModelOption[] {
*/
function filterModelOptionsByAllowlist(options: ModelOption[]): ModelOption[] {
const settings = getSettings_DEPRECATED() || {}
if (!settings.availableModels) {
return options // No restrictions
}
return options.filter(
const filtered = !settings.availableModels
? options // No restrictions
: options.filter(
opt =>
opt.value === null || (opt.value !== null && isModelAllowed(opt.value)),
)
// Select state uses option values as identity keys. If two entries share the
// same value (e.g. provider-specific aliases collapsing to one model ID),
// navigation/focus can become inconsistent and appear as duplicate rendering.
const seen = new Set<string>()
return filtered.filter(opt => {
const key = String(opt.value)
if (seen.has(key)) {
return false
}
seen.add(key)
return true
})
}