diff --git a/ui/src/components/cliproxy/provider-model-selector.tsx b/ui/src/components/cliproxy/provider-model-selector.tsx index 37ba59c8..405c9f19 100644 --- a/ui/src/components/cliproxy/provider-model-selector.tsx +++ b/ui/src/components/cliproxy/provider-model-selector.tsx @@ -21,19 +21,13 @@ import { Skeleton } from '@/components/ui/skeleton'; import type { CliproxyProviderRoutingHints } from '@/lib/api-client'; import type { CodexEffort, CodexServiceTier } from '@/lib/codex-effort'; import { - applyCodexEffortSuffix, getCodexEffortDisplay, getCodexEffortVariants, - getSelectableCodexEfforts, parseCodexEffort, parseCodexServiceTier, - stripCodexEffortSuffix, } from '@/lib/codex-effort'; -import { - findCatalogModel, - getResolvedCatalogModels, - getSupplementalCatalogModels, -} from '@/lib/model-catalogs'; +import { getResolvedCatalogModels, getSupplementalCatalogModels } from '@/lib/model-catalogs'; +import { getReasoningAdapter } from '@/lib/reasoning-control'; import { cn } from '@/lib/utils'; /** Model entry from catalog */ @@ -61,6 +55,8 @@ export interface ModelEntry { codexEfforts?: CodexEffort[]; /** Additional Codex service-tier suffixes supported by this model in the dashboard UI. */ codexServiceTiers?: CodexServiceTier[]; + /** Reasoning-level suffixes this model supports via paren syntax in the dashboard UI. */ + reasoningLevels?: string[]; } /** Provider catalog */ @@ -575,22 +571,21 @@ export function FlexibleModelSelector({ } : null; const hasAvailableModels = recommendedOptions.length + allModelOptions.length > 0; - const currentEffort = isCodexProvider ? parseCodexEffort(value) : undefined; - const baseModelId = isCodexProvider - ? stripCodexEffortSuffix(normalizeModelValue(value, routing)) - : ''; - const selectedCatalogModel = - isCodexProvider && baseModelId && catalog - ? findCatalogModel(catalog.provider, baseModelId, catalog) - : undefined; - const selectableEfforts = getSelectableCodexEfforts( - selectedCatalogModel?.codexMaxEffort, - selectedCatalogModel?.codexEfforts - ); - const effortOptions = - currentEffort && !selectableEfforts.includes(currentEffort) - ? [...selectableEfforts, currentEffort] - : selectableEfforts; + const reasoningAdapter = getReasoningAdapter(catalog?.provider); + const currentReasoningLevel = reasoningAdapter?.parse(value); + const selectableReasoningLevels = + reasoningAdapter && catalog + ? reasoningAdapter.getOptions( + reasoningAdapter.strip(normalizeModelValue(value, routing)), + catalog + ) + : null; + const reasoningOptions = + selectableReasoningLevels && + currentReasoningLevel && + !selectableReasoningLevels.includes(currentReasoningLevel) + ? [...selectableReasoningLevels, currentReasoningLevel] + : selectableReasoningLevels; return (
@@ -683,16 +678,11 @@ export function FlexibleModelSelector({ ...allModelOptions, ]} /> - {isCodexProvider && ( + {reasoningAdapter && reasoningOptions && (