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 && (