From 51d407f25c1dce39f195156baa7787e0ec06e06f Mon Sep 17 00:00:00 2001 From: x3M3x Date: Thu, 3 Sep 2026 21:34:21 +0400 Subject: [PATCH 1/7] feat(models): add main picker ordering controls --- .../mobile-auth-model-picker-order.png | Bin 0 -> 76459 bytes .../src/content/docs/guides/model-ordering.md | 5 ++ gui/src/i18n/de.ts | 12 +++ gui/src/i18n/en.ts | 12 +++ gui/src/i18n/fr.ts | 12 +++ gui/src/i18n/ja.ts | 12 +++ gui/src/i18n/ko.ts | 12 +++ gui/src/i18n/ru.ts | 12 +++ gui/src/i18n/tr.ts | 12 +++ gui/src/i18n/zh-TW.ts | 12 +++ gui/src/i18n/zh.ts | 12 +++ gui/src/model-picker-order.ts | 64 ++++++++++++++++ gui/src/pages/Models.tsx | 71 +++++++++++++++++- gui/tests/model-picker-order.test.ts | 29 +++++++ .../management/agent-settings-routes.ts | 62 ++++++++++++--- tests/subagent-roster-retention.test.ts | 33 ++++++++ 16 files changed, 360 insertions(+), 12 deletions(-) create mode 100644 docs-site/public/pr-screenshots/mobile-auth-model-picker-order.png create mode 100644 gui/src/model-picker-order.ts create mode 100644 gui/tests/model-picker-order.test.ts diff --git a/docs-site/public/pr-screenshots/mobile-auth-model-picker-order.png b/docs-site/public/pr-screenshots/mobile-auth-model-picker-order.png new file mode 100644 index 0000000000000000000000000000000000000000..dadc79aabc7b024eee53a03d3a1fc7761ad68702 GIT binary patch literal 76459 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%0DXx?LMRP%X=BuXGHJ{3_M%9CdC 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%0Dr@cnZa9> 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ⅇ5YI_Pmn3n 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 z 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⪻>gZ((DwdwCyKbEkNhP}4L=>Dpw{Q|eA9lErx($sdN`G?0Es z$vE{WI$bNlm0zIRpHUVgzg%ArV_X0afsvMsW7W>j+_@bmM8B%XG?e3yqX}q|S*Bzx zX?J0{S?ga6r8Afw>` literal 0 HcmV?d00001 diff --git a/docs-site/src/content/docs/guides/model-ordering.md b/docs-site/src/content/docs/guides/model-ordering.md index 696f631a58..9df6e511ee 100644 --- a/docs-site/src/content/docs/guides/model-ordering.md +++ b/docs-site/src/content/docs/guides/model-ordering.md @@ -130,6 +130,11 @@ featured block: } ``` +The dashboard's **Models** page can write this setting for all currently visible routed models. +Choose **Default** to keep the normal provider/model order, **A–Z** to sort by model id, +**Provider** to group by provider, or **Most used** to rank by all recorded request history. The +dashboard fetches usage only when you apply the Most used order. + Listed routed rows appear in the configured order. A routed row omitted from the array keeps its normal priority, so it remains ahead of the `modelPickerOrder` display band; list every routed row whose relative position you want to control. A row also present in `subagentModels` keeps its diff --git a/gui/src/i18n/de.ts b/gui/src/i18n/de.ts index 94ce7e9103..5090c937e2 100644 --- a/gui/src/i18n/de.ts +++ b/gui/src/i18n/de.ts @@ -2246,6 +2246,18 @@ export const de: Record = { "claudeDesktop.effort.supported": "effort", "claudeDesktop.effort.displayOnly": "effort (nur Anzeige)", "sub.settings": "Einstellungen", + "models.pickerOrder.title": "Reihenfolge der Modellauswahl", + "models.pickerOrder.hint": "Ordnet weitergeleitete Modelle in der Hauptauswahl von Codex. Dies ändert weder hervorgehobene Subagent-Modelle noch Fallback-Routing.", + "models.pickerOrder.label": "Weitergeleitete Modelle sortieren", + "models.pickerOrder.default": "Standard", + "models.pickerOrder.alphabetical": "A–Z nach Modell", + "models.pickerOrder.provider": "Nach Anbieter", + "models.pickerOrder.mostUsed": "Am häufigsten verwendet", + "models.pickerOrder.custom": "Benutzerdefinierte Reihenfolge (Konfiguration)", + "models.pickerOrder.apply": "Anwenden", + "models.pickerOrder.applying": "Wird angewendet…", + "models.pickerOrder.saved": "Reihenfolge der Modellauswahl gespeichert. Gilt für neue Codex-Sitzungen.", + "models.pickerOrder.usageFailed": "Modellnutzung konnte nicht geladen werden", "sub.sections": "Subagent-Abschnitte", "sub.delegation.model": "Zuerst aufgerufenes Modell", "sub.delegation.modelHint": "Das Modell, zu dem Codex zuerst greift, wenn es Arbeit übergibt. Oben steht, wen es überhaupt aufrufen darf; hier wählst du den Ersten davon.", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index 917aba8e2b..ea24c6bd0d 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -623,6 +623,18 @@ export const en = { "sub.models": "Models", "sub.search": "Search models (native gpt + routed)…", "sub.settings": "Settings", + "models.pickerOrder.title": "Model picker order", + "models.pickerOrder.hint": "Controls Codex's main picker only. It does not change subagent models or fallback routing.", + "models.pickerOrder.label": "Order routed models", + "models.pickerOrder.default": "Default (provider, then model)", + "models.pickerOrder.alphabetical": "A–Z by model name", + "models.pickerOrder.provider": "Group by provider", + "models.pickerOrder.mostUsed": "Most used", + "models.pickerOrder.custom": "Custom order (config)", + "models.pickerOrder.apply": "Apply", + "models.pickerOrder.applying": "Applying…", + "models.pickerOrder.saved": "Model picker order saved. Applies to new Codex sessions.", + "models.pickerOrder.usageFailed": "Failed to load model usage", "sub.sections": "Subagent sections", "sub.delegation.model": "Model to call first", "sub.delegation.modelHint": "The model Codex reaches for first when it hands off work. Featured above is the list it may call; this is the one it calls first.", diff --git a/gui/src/i18n/fr.ts b/gui/src/i18n/fr.ts index c7ad8b6ee5..4f822eb183 100644 --- a/gui/src/i18n/fr.ts +++ b/gui/src/i18n/fr.ts @@ -606,6 +606,18 @@ export const fr: Record = { "sub.models": "Modèles", "sub.search": "Rechercher des modèles (gpt natifs + routés)…", "sub.settings": "Paramètres", + "models.pickerOrder.title": "Ordre du sélecteur de modèles", + "models.pickerOrder.hint": "Trie les modèles routés dans le sélecteur principal de Codex. Cela ne modifie ni les modèles de sous-agent mis en avant ni le routage de secours.", + "models.pickerOrder.label": "Trier les modèles routés", + "models.pickerOrder.default": "Par défaut", + "models.pickerOrder.alphabetical": "A–Z par modèle", + "models.pickerOrder.provider": "Par fournisseur", + "models.pickerOrder.mostUsed": "Les plus utilisés", + "models.pickerOrder.custom": "Ordre personnalisé (configuration)", + "models.pickerOrder.apply": "Appliquer", + "models.pickerOrder.applying": "Application…", + "models.pickerOrder.saved": "Ordre du sélecteur de modèles enregistré. S'applique aux nouvelles sessions Codex.", + "models.pickerOrder.usageFailed": "Échec du chargement de l'utilisation des modèles", "sub.sections": "Sections des sous-agents", "sub.delegation.model": "Modèle à appeler en premier", "sub.delegation.modelHint": "Le modèle que Codex sollicite en premier lorsqu’il délègue une tâche. La liste À la une ci-dessus contient les modèles qu’il peut appeler ; celui-ci est appelé en premier.", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index c26bfc7902..f418eeaaec 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -2267,6 +2267,18 @@ export const ja: Record = { "pws.tokenInput": "Input", "pws.tokenOutput": "Output", "sub.settings": "設定", + "models.pickerOrder.title": "モデルピッカーの順序", + "models.pickerOrder.hint": "Codex のメインピッカーでルーティング済みモデルを並べ替えます。注目のサブエージェントモデルやフォールバックルーティングは変更しません。", + "models.pickerOrder.label": "ルーティング済みモデルの順序", + "models.pickerOrder.default": "デフォルト", + "models.pickerOrder.alphabetical": "モデル名で A–Z", + "models.pickerOrder.provider": "プロバイダー別", + "models.pickerOrder.mostUsed": "最も使用", + "models.pickerOrder.custom": "カスタム順序(設定)", + "models.pickerOrder.apply": "適用", + "models.pickerOrder.applying": "適用中…", + "models.pickerOrder.saved": "モデルピッカーの順序を保存しました。新しい Codex セッションに適用されます。", + "models.pickerOrder.usageFailed": "モデル使用状況を読み込めませんでした", "sub.sections": "サブエージェントのセクション", "sub.delegation.model": "最初に呼ぶモデル", "sub.delegation.modelHint": "Codex が作業を任せるとき、最初に呼ぶモデルです。上のおすすめが呼べる候補で、ここで選んだものがその中の第一候補になります。", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index 709bfeb3ca..bc09ad202f 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -609,6 +609,18 @@ export const ko: Record = { "sub.models": "모델", "sub.search": "모델 검색(네이티브 gpt + 라우팅)…", "sub.settings": "설정", + "models.pickerOrder.title": "모델 선택기 순서", + "models.pickerOrder.hint": "Codex 기본 선택기에서 라우팅된 모델을 정렬합니다. 주요 하위 에이전트 모델이나 폴백 라우팅은 변경하지 않습니다.", + "models.pickerOrder.label": "라우팅된 모델 순서", + "models.pickerOrder.default": "기본값", + "models.pickerOrder.alphabetical": "모델별 A–Z", + "models.pickerOrder.provider": "공급자별", + "models.pickerOrder.mostUsed": "가장 많이 사용됨", + "models.pickerOrder.custom": "사용자 지정 순서(구성)", + "models.pickerOrder.apply": "적용", + "models.pickerOrder.applying": "적용 중…", + "models.pickerOrder.saved": "모델 선택기 순서를 저장했습니다. 새 Codex 세션에 적용됩니다.", + "models.pickerOrder.usageFailed": "모델 사용량을 불러오지 못했습니다", "sub.sections": "서브에이전트 구역", "sub.delegation.model": "먼저 부를 모델", "sub.delegation.modelHint": "Codex가 일을 나눠 맡길 때 가장 먼저 부를 모델입니다. 위 추천 목록이 부를 수 있는 후보라면, 여기서 고른 모델이 그중 1순위가 됩니다.", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index bc699216e9..f170e2e7e2 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -2267,6 +2267,18 @@ export const ru: Record = { "cws.err.invalidWeight": "Каждый вес round-robin должен быть целым числом от 1 до 10000.", "cws.err.noEnabledTarget": "Хотя бы одна цель должна использовать включённого провайдера.", "sub.settings": "Настройки", + "models.pickerOrder.title": "Порядок выбора моделей", + "models.pickerOrder.hint": "Сортирует маршрутизируемые модели в главном списке Codex. Это не меняет избранные модели субагентов или маршрутизацию резервного выбора.", + "models.pickerOrder.label": "Сортировать маршрутизируемые модели", + "models.pickerOrder.default": "По умолчанию", + "models.pickerOrder.alphabetical": "A–Z по модели", + "models.pickerOrder.provider": "По провайдеру", + "models.pickerOrder.mostUsed": "Чаще всего используемые", + "models.pickerOrder.custom": "Пользовательский порядок (конфигурация)", + "models.pickerOrder.apply": "Применить", + "models.pickerOrder.applying": "Применение…", + "models.pickerOrder.saved": "Порядок выбора моделей сохранён. Применяется к новым сеансам Codex.", + "models.pickerOrder.usageFailed": "Не удалось загрузить использование моделей", "sub.sections": "Разделы подагентов", "sub.delegation.model": "Модель, которую вызывать первой", "sub.delegation.modelHint": "Модель, к которой Codex обращается первой, когда передаёт работу. Список выше — кого он вообще может вызвать, а здесь выбирается первый в очереди.", diff --git a/gui/src/i18n/tr.ts b/gui/src/i18n/tr.ts index 622ebb3c19..f1365ef1ce 100644 --- a/gui/src/i18n/tr.ts +++ b/gui/src/i18n/tr.ts @@ -614,6 +614,18 @@ export const tr: Record = { "sub.models": "Modeller", "sub.search": "Modellerde ara…", "sub.settings": "Ayarlar", + "models.pickerOrder.title": "Model seçici sırası", + "models.pickerOrder.hint": "Codex'in ana seçicisindeki yönlendirilmiş modelleri sıralar. Öne çıkan alt ajan modellerini veya geri dönüş yönlendirmesini değiştirmez.", + "models.pickerOrder.label": "Yönlendirilmiş modelleri sırala", + "models.pickerOrder.default": "Varsayılan", + "models.pickerOrder.alphabetical": "Modele göre A–Z", + "models.pickerOrder.provider": "Sağlayıcıya göre", + "models.pickerOrder.mostUsed": "En çok kullanılan", + "models.pickerOrder.custom": "Özel sıra (yapılandırma)", + "models.pickerOrder.apply": "Uygula", + "models.pickerOrder.applying": "Uygulanıyor…", + "models.pickerOrder.saved": "Model seçici sırası kaydedildi. Yeni Codex oturumlarına uygulanır.", + "models.pickerOrder.usageFailed": "Model kullanımı yüklenemedi", "sub.sections": "Alt ajan bölümleri", "sub.delegation.model": "İlk çağrılacak model", "sub.delegation.modelHint": "Codex'in iş devrederken ilk ulaştığı model.", diff --git a/gui/src/i18n/zh-TW.ts b/gui/src/i18n/zh-TW.ts index f5f94c4e31..34272c9ad2 100644 --- a/gui/src/i18n/zh-TW.ts +++ b/gui/src/i18n/zh-TW.ts @@ -1843,6 +1843,18 @@ export const zhTW: Record = { "dash.syncModelsHint": "根據已連接的供應商重寫 Codex 的模型目錄。", "dash.syncRun": "立即同步", "sub.settings": "設定", + "models.pickerOrder.title": "模型選擇器排序", + "models.pickerOrder.hint": "為 Codex 主選擇器中的已路由模型排序。這不會變更精選子代理模型或後備路由。", + "models.pickerOrder.label": "排序已路由模型", + "models.pickerOrder.default": "預設", + "models.pickerOrder.alphabetical": "依模型 A–Z", + "models.pickerOrder.provider": "依提供者", + "models.pickerOrder.mostUsed": "最常使用", + "models.pickerOrder.custom": "自訂順序(設定)", + "models.pickerOrder.apply": "套用", + "models.pickerOrder.applying": "正在套用…", + "models.pickerOrder.saved": "模型選擇器排序已儲存。會套用到新的 Codex 工作階段。", + "models.pickerOrder.usageFailed": "無法載入模型使用情況", "sub.sections": "子代理分區", "sub.delegation.model": "優先調用的模型", "sub.delegation.modelHint": "Codex 分派工作時最先調用的模型。上面的推薦是可調用的名單,這裡選的是其中第一順位。", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index c1a4ceaa25..37bd11cbd8 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -2266,6 +2266,18 @@ export const zh: Record = { "claudeDesktop.effort.supported": "effort", "claudeDesktop.effort.displayOnly": "effort (仅显示)", "sub.settings": "设置", + "models.pickerOrder.title": "模型选择器排序", + "models.pickerOrder.hint": "对 Codex 主选择器中的已路由模型排序。这不会更改精选子代理模型或回退路由。", + "models.pickerOrder.label": "排序已路由模型", + "models.pickerOrder.default": "默认", + "models.pickerOrder.alphabetical": "按模型 A–Z", + "models.pickerOrder.provider": "按提供商", + "models.pickerOrder.mostUsed": "最常使用", + "models.pickerOrder.custom": "自定义顺序(配置)", + "models.pickerOrder.apply": "应用", + "models.pickerOrder.applying": "正在应用…", + "models.pickerOrder.saved": "模型选择器排序已保存。将应用于新的 Codex 会话。", + "models.pickerOrder.usageFailed": "无法加载模型使用情况", "sub.sections": "子代理分区", "sub.delegation.model": "优先调用的模型", "sub.delegation.modelHint": "Codex 分派工作时最先调用的模型。上面的推荐是可调用的名单,这里选的是其中第一顺位。", diff --git a/gui/src/model-picker-order.ts b/gui/src/model-picker-order.ts new file mode 100644 index 0000000000..62d8b5b034 --- /dev/null +++ b/gui/src/model-picker-order.ts @@ -0,0 +1,64 @@ +export type ModelPickerOrderMode = "default" | "alphabetical" | "provider" | "most-used" | "custom"; + +export interface ModelPickerUsage { + provider: string; + model: string; + resolvedModel?: string; + requests: number; +} + +function providerAndModel(slug: string): [string, string] { + const slash = slug.indexOf("/"); + return slash < 0 ? ["", slug] : [slug.slice(0, slash), slug.slice(slash + 1)]; +} + +function compareProviderAndModel(a: string, b: string): number { + const [aProvider, aModel] = providerAndModel(a); + const [bProvider, bModel] = providerAndModel(b); + return aProvider.localeCompare(bProvider) || aModel.localeCompare(bModel); +} + +function usageBySlug(usage: readonly ModelPickerUsage[], models: readonly string[]): Map { + const requests = new Map(); + const pickerModels = new Set(models); + for (const row of usage) { + const slug = row.model.includes("/") ? row.model : `${row.provider}/${row.model}`; + const resolved = row.resolvedModel + ? (row.resolvedModel.includes("/") ? row.resolvedModel : `${row.provider}/${row.resolvedModel}`) + : undefined; + const target = pickerModels.has(slug) ? slug : resolved && pickerModels.has(resolved) ? resolved : undefined; + if (target) requests.set(target, (requests.get(target) ?? 0) + row.requests); + } + return requests; +} + +export function modelPickerOrder( + mode: Exclude, + models: readonly string[], + usage: readonly ModelPickerUsage[] = [], +): string[] | null { + if (mode === "default") return null; + const unique = [...new Set(models)]; + if (mode === "alphabetical") { + return unique.toSorted((a, b) => { + const [, aModel] = providerAndModel(a); + const [, bModel] = providerAndModel(b); + return aModel.localeCompare(bModel) || compareProviderAndModel(a, b); + }); + } + if (mode === "provider") return unique.toSorted(compareProviderAndModel); + + const requests = usageBySlug(usage, unique); + return unique.toSorted((a, b) => (requests.get(b) ?? 0) - (requests.get(a) ?? 0) || compareProviderAndModel(a, b)); +} + +export function modelPickerOrderMode(models: readonly string[], saved: readonly string[]): ModelPickerOrderMode { + if (saved.length === 0) return "default"; + const normalized = [...new Set(saved)]; + if (normalized.length !== models.length || normalized.some(model => !models.includes(model))) return "custom"; + for (const mode of ["alphabetical", "provider"] as const) { + const expected = modelPickerOrder(mode, models); + if (expected?.every((model, index) => model === normalized[index])) return mode; + } + return "custom"; +} diff --git a/gui/src/pages/Models.tsx b/gui/src/pages/Models.tsx index 4c00641422..08bd8b89d2 100644 --- a/gui/src/pages/Models.tsx +++ b/gui/src/pages/Models.tsx @@ -68,6 +68,7 @@ import { import { EmptyProviderHint } from "./models-provider-hints"; import { shadowCallModelOptions } from "./dashboard-shared"; import { shadowSourceModelBadge, shadowSourceModelLabel } from "./shadow-call-source"; +import { modelPickerOrder, modelPickerOrderMode, type ModelPickerOrderMode, type ModelPickerUsage } from "../model-picker-order"; type CachedModelsPage = { models: ModelRow[]; @@ -76,8 +77,12 @@ type CachedModelsPage = { disabled: string[]; contextCaps: Record; contextCapValue: number; + pickerAvailable?: string[]; + pickerOrder?: string[]; }; +type PickerOrderResponse = { pickerAvailable?: string[]; pickerOrder?: string[] }; + /** One subtitle per tab: only one panel is visible, so only one description applies. */ const SUBTITLE_TKEY: Record = { catalog: "models.subtitle", @@ -214,6 +219,9 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string; const [limit, setLimit] = useState>({}); const [contextCaps, setContextCaps] = useState>(() => cached?.contextCaps ?? {}); const [contextCapValue, setContextCapValue] = useState(() => cached?.contextCapValue ?? 350_000); + const [pickerAvailable, setPickerAvailable] = useState(() => cached?.pickerAvailable ?? []); + const [pickerMode, setPickerMode] = useState(() => modelPickerOrderMode(cached?.pickerAvailable ?? [], cached?.pickerOrder ?? [])); + const [pickerBusy, setPickerBusy] = useState(false); const [customCap, setCustomCap] = useState(""); const [showCustom, setShowCustom] = useState(false); const [providerCapCustomOpen, setProviderCapCustomOpen] = useState>({}); @@ -399,18 +407,20 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string; }, [apiBase]); const fetchCatalog = useCallback(async (signal: AbortSignal): Promise => { - const [modelsRes, capsRes, providersRes, selectionData] = await Promise.all([ + const [modelsRes, capsRes, providersRes, selectionData, pickerRes] = await Promise.all([ // Every request carries the resource signal, so leaving the catalog tab cancels // the work rather than only discarding its result. fetch(`${apiBase}/api/models`, { signal }), fetch(`${apiBase}/api/provider-context-caps`, { signal }), fetch(`${apiBase}/api/providers`, { signal }), fetchSelectedModels(apiBase, fetch, signal), + fetch(`${apiBase}/api/subagent-models`, { signal }), ]); - const [data, capsData, providerData] = await Promise.all([ + const [data, capsData, providerData, pickerData] = await Promise.all([ readJsonOrThrow(modelsRes), readJsonOrThrow(capsRes), readJsonOrThrow(providersRes), + readJsonIfOk(pickerRes), ]); if (data === undefined || capsData === undefined || providerData === undefined) { throw new Error("models payload missing"); @@ -428,6 +438,8 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string; disabled: [...nextDisabled], contextCaps: capsData.caps ?? {}, contextCapValue: nextCapValue, + pickerAvailable: pickerData?.pickerAvailable ?? [], + pickerOrder: pickerData?.pickerOrder ?? [], } satisfies CachedModelsPage; writeSessionListCache(cacheKey, next); return next; @@ -446,6 +458,8 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string; setSelectedModels(next.selectedModels); setContextCapValue(next.contextCapValue); setContextCaps(next.contextCaps); + setPickerAvailable(next.pickerAvailable ?? []); + setPickerMode(modelPickerOrderMode(next.pickerAvailable ?? [], next.pickerOrder ?? [])); }, []); const catalogResource = useDataSurface( @@ -1586,6 +1600,38 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string; ? groups.filter(group => group.provider === selectedProvider) : groups; + const savePickerOrder = async () => { + if (pickerBusy || pickerMode === "custom") return; + setPickerBusy(true); + try { + let usage: ModelPickerUsage[] = []; + if (pickerMode === "most-used") { + const usageResponse = await fetch(`${apiBase}/api/usage?range=all&surface=all`); + const usageData = await readJsonOrThrow<{ models?: ModelPickerUsage[] }>(usageResponse, t("models.pickerOrder.usageFailed")); + usage = usageData?.models ?? []; + } + const order = modelPickerOrder(pickerMode, pickerAvailable, usage); + const response = await fetch(`${apiBase}/api/subagent-models`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ pickerOrder: order }), + }); + const data = await readJsonOrThrow<{ pickerOrder?: string[] }>(response, t("models.saveFailed")); + const saved = data?.pickerOrder ?? order ?? []; + const next = catalogState.data ?? cached; + if (next) { + const updated = { ...next, pickerAvailable, pickerOrder: saved }; + writeSessionListCache(cacheKey, updated); + setClientResourceData(cacheKey, updated); + } + publishFeedback(true, t("models.pickerOrder.saved")); + } catch (error) { + publishFeedback(false, error instanceof Error && error.message ? error.message : t("models.networkError")); + } finally { + setPickerBusy(false); + } + }; + const controlsBlock = ( <>
@@ -1713,6 +1759,27 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string; {t("models.setAllHint", { value: fmtK(contextCapValue) })}
+
+ {t("models.pickerOrder.label")} +