Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,12 @@ export const de: Record<TKey, string> = {
"models.nativeHint": "Passthrough-Modelle verwenden die unter Anbieter gewählte Pool- oder Direkt-Option. Ausblenden entfernt sie aus der Codex-Auswahl (Katalogeintrag bleibt, Reaktivierung stellt exakt wieder her). Ein hier hinzugefügtes Modell wird als gerouteter `openai/<model>`-Selektor registriert, nicht als neue reine Passthrough-ID.",
"models.active": "{active}/{total} sichtbar",
"models.workspace.providers": "Anbieter",
"models.workspace.frontierRoutes": "Frontier-Routen",
"models.workspace.addProvider": "Anbieter hinzufügen",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "Alle Anbieter",
"models.workspace.mainAria": "Modelldetails",
"models.allOn": "Alle an",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,12 @@ export const en = {
"models.nativeHint": "Passthrough models use the Pool or Direct account option selected on Providers. Toggling one off hides it from the Codex picker (the catalog entry is kept, so re-enabling restores it exactly). Adding a model here registers a routed `openai/<model>` selector, not a new bare passthrough id.",
"models.active": "{active}/{total} visible",
"models.workspace.providers": "Providers",
"models.workspace.frontierRoutes": "Frontier routes",
"models.workspace.addProvider": "Add provider",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "All providers",
"models.workspace.mainAria": "Model details",
"models.allOn": "All on",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,12 @@ export const fr: Record<TKey, string> = {
"models.nativeHint": "Les modèles en accès direct utilisent l’option de compte Groupe ou Direct sélectionnée dans Fournisseurs. La désactivation d’un modèle le masque dans le sélecteur Codex (son entrée de catalogue est conservée afin que sa réactivation la restaure à l’identique). Ajouter un modèle ici enregistre un sélecteur routé `openai/<model>`, et non un nouvel identifiant passthrough brut.",
"models.active": "{active}/{total} visibles",
"models.workspace.providers": "Fournisseurs",
"models.workspace.frontierRoutes": "Modèles de pointe",
"models.workspace.addProvider": "Ajouter un fournisseur",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "Tous les fournisseurs",
"models.workspace.mainAria": "Détails du modèle",
"models.allOn": "Tout activer",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ export const ja: Record<TKey, string> = {
"models.nativeHint": "パススルーモデルはプロバイダーで選択したプールまたはダイレクトアカウントオプションを使用します。一つオフにすると Codex ピッカーから隠します(カタログエントリは保持されるので、再有効化で正確に復元されます)。 ここでモデルを追加すると、bare passthrough id ではなくルーティングされた `openai/<model>` セレクタとして登録されます。",
"models.active": "{active}/{total} 表示中",
"models.workspace.providers": "プロバイダー",
"models.workspace.frontierRoutes": "最先端モデル",
"models.workspace.addProvider": "プロバイダーを追加",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "すべてのプロバイダー",
"models.workspace.mainAria": "モデルの詳細",
"models.allOn": "すべてオン",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,12 @@ export const ko: Record<TKey, string> = {
"models.nativeHint": "프로바이더에서 선택한 풀 또는 직접 계정 옵션으로 서빙되는 passthrough 모델입니다. 끄면 Codex 선택기에서 숨겨지고, 카탈로그 항목은 유지되므로 다시 켜면 그대로 복원됩니다. 여기서 모델을 추가하면 bare passthrough id가 아니라 라우팅된 `openai/<model>` selector로 등록됩니다.",
"models.active": "{active}/{total} 표시",
"models.workspace.providers": "프로바이더",
"models.workspace.frontierRoutes": "프런티어 모델",
"models.workspace.addProvider": "프로바이더 추가",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "모든 프로바이더",
"models.workspace.mainAria": "모델 세부정보",
"models.allOn": "모두 켜기",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ export const ru: Record<TKey, string> = {
"models.nativeHint": "Модели сквозного проброса используют режим аккаунта (пул или прямое подключение), выбранный на странице «Провайдеры». Отключение модели скрывает её из селектора Codex (запись в каталоге сохраняется, поэтому при повторном включении она восстанавливается в точности). Добавление модели здесь регистрирует маршрутизируемый селектор `openai/<model>`, а не новый «голый» passthrough-идентификатор.",
"models.active": "{active}/{total} видимо",
"models.workspace.providers": "Провайдеры",
"models.workspace.frontierRoutes": "Передовые модели",
"models.workspace.addProvider": "Добавить провайдера",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "Все провайдеры",
"models.workspace.mainAria": "Сведения о моделях",
"models.allOn": "Все вкл.",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,12 @@ export const tr: Record<TKey, string> = {
"models.nativeHint": "Doğrudan geçiş modelleri Sağlayıcılar bölümünde seçilen Havuz veya Doğrudan seçeneğini kullanır. Buradan model eklemek, yeni bir düz passthrough kimliği değil, yönlendirilmiş bir `openai/<model>` seçici kaydeder.",
"models.active": "{active}/{total} görünür",
"models.workspace.providers": "Sağlayıcılar",
"models.workspace.frontierRoutes": "Öncü modeller",
"models.workspace.addProvider": "Sağlayıcı ekle",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "Tüm sağlayıcılar",
"models.workspace.mainAria": "Model detayları",
"models.allOn": "Tümünü aç",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ export const zhTW: Record<TKey, string> = {
"models.nativeHint": "Passthrough 模型使用在供應商頁面選擇的帳號池或直連選項。關閉後會從 Codex 選擇器中隱藏(目錄條目保留,重新開啟即可完整恢復)。 在此新增模型會註冊為路由的 `openai/<model>` 選擇器,而非新的裸 passthrough id。",
"models.active": "{active}/{total} 已啟用",
"models.workspace.providers": "供應商",
"models.workspace.frontierRoutes": "前沿模型",
"models.workspace.addProvider": "新增供應商",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "所有供應商",
"models.workspace.mainAria": "模型詳細資料",
"models.allOn": "全部開啟",
Expand Down
6 changes: 6 additions & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ export const zh: Record<TKey, string> = {
"models.nativeHint": "Passthrough 模型使用在提供方页面选择的账户池或直连选项。关闭后会从 Codex 选择器中隐藏(目录条目保留,重新开启即可完整恢复)。 在此添加模型将注册为路由的 `openai/<model>` 选择器,而不是新的裸 passthrough id。",
"models.active": "{active}/{total} 可见",
"models.workspace.providers": "提供方",
"models.workspace.frontierRoutes": "前沿模型",
"models.workspace.addProvider": "添加提供方",
"models.workspace.xaiGrok": "xAI Grok",
"models.workspace.cursorGrok": "Cursor Grok",
"models.workspace.opus5": "Claude Opus 5",
"models.workspace.fable5": "Claude Fable 5",
"models.workspace.allProviders": "所有提供方",
"models.workspace.mainAria": "模型详情",
"models.allOn": "全部开启",
Expand Down
63 changes: 63 additions & 0 deletions gui/src/pages/Models.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { readSessionListCache, writeSessionListCache } from "../session-list-cac
import { setClientResourceData } from "../client-resource";
import { createBoundedFetch } from "../bounded-fetch";
import { startVisibilityPoll } from "../visibility-poll";
import { navigateHash } from "../hash-routing";
import { useDataSurface } from "../data-surface";
import { DataSurfaceSkeleton } from "../components/data-surface";
import ErrorBoundary from "../components/ErrorBoundary";
Expand Down Expand Up @@ -68,6 +69,7 @@ import {
import { EmptyProviderHint } from "./models-provider-hints";
import { shadowCallModelOptions } from "./dashboard-shared";
import { shadowSourceModelBadge, shadowSourceModelLabel } from "./shadow-call-source";
import { buildFrontierRouteShortcuts } from "./frontier-route-shortcuts";

type CachedModelsPage = {
models: ModelRow[];
Expand Down Expand Up @@ -1313,6 +1315,28 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string;
? groups.filter(group => group.provider === selectedProvider)
: groups;

const frontierShortcuts = useMemo(
() => buildFrontierRouteShortcuts(models, new Set(groups.map(group => group.provider))),
[groups, models],
);

const focusFrontierRoute = (provider: string, query: string, providerConfigured: boolean) => {
if (!providerConfigured) {
navigateHash("providers");
return;
}
setSelectedProvider(provider);
setSearch(previous => ({ ...previous, [provider]: query }));
setLimit(previous => ({ ...previous, [provider]: PAGE }));
setCollapsed(previous => {
if (!previous.has(provider)) return previous;
const next = new Set(previous);
next.delete(provider);
writeCollapsedProviders(next);
return next;
});
};

const controlsBlock = (
<>
<div className="models-control-top-row">
Expand Down Expand Up @@ -1859,6 +1883,45 @@ export default function Models({ apiBase, restartEpoch = 0 }: { apiBase: string;
<span className="models-workspace-rail-title">{t("models.workspace.providers")}</span>
<span className="models-workspace-rail-count">{groups.length}</span>
</div>
<div className="models-frontier-shortcuts" role="group" aria-label={t("models.workspace.frontierRoutes")}>
<span className="models-frontier-shortcuts-title">{t("models.workspace.frontierRoutes")}</span>
<div className="models-frontier-shortcuts-list">
{frontierShortcuts.map(shortcut => {
const selected = shortcut.providerConfigured
&& selectedProvider === shortcut.provider
&& (search[shortcut.provider] ?? "") === shortcut.query;
const label = shortcut.id === "xai-grok"
? t("models.workspace.xaiGrok")
: shortcut.id === "cursor-grok"
? t("models.workspace.cursorGrok")
: shortcut.id === "opus-5"
? t("models.workspace.opus5")
: t("models.workspace.fable5");
return (
<button
key={shortcut.id}
type="button"
className={`models-frontier-shortcut${selected ? " models-frontier-shortcut--selected" : ""}`}
aria-pressed={selected}
onClick={() => focusFrontierRoute(
shortcut.provider,
shortcut.query,
shortcut.providerConfigured,
)}
>
<span className="models-frontier-shortcut-name">{label}</span>
<span className="models-frontier-shortcut-meta">
{shortcut.route
? formatNamespacedModelId(shortcut.route, t)
: shortcut.providerConfigured
? providerDisplaySlug(shortcut.provider)
: t("models.workspace.addProvider")}
</span>
</button>
);
})}
</div>
</div>
<div className="models-workspace-rail-list">
<button
type="button"
Expand Down
87 changes: 87 additions & 0 deletions gui/src/pages/frontier-route-shortcuts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import type { ModelRow } from "./models-shared";

export type FrontierRouteShortcutId = "xai-grok" | "cursor-grok" | "opus-5" | "fable-5";

export interface FrontierRouteShortcut {
id: FrontierRouteShortcutId;
provider: string;
query: string;
route: string | null;
providerConfigured: boolean;
}

interface ShortcutDefinition {
id: FrontierRouteShortcutId;
providers: readonly string[];
query: string;
matches: (model: ModelRow) => boolean;
}

const SHORTCUTS: readonly ShortcutDefinition[] = [
{
id: "xai-grok",
providers: ["xai"],
query: "grok-",
matches: model => model.provider === "xai" && /^grok-\d/.test(model.id),
},
{
id: "cursor-grok",
providers: ["cursor"],
query: "grok-",
matches: model => model.provider === "cursor" && /^grok-\d/.test(model.id),
},
{
id: "opus-5",
providers: ["anthropic", "cursor", "kiro"],
query: "claude-opus-5",
matches: model => model.id === "claude-opus-5",
},
{
id: "fable-5",
providers: ["anthropic", "cursor", "kiro"],
query: "claude-fable-5",
matches: model => model.id === "claude-fable-5",
},
] as const;

function compareCandidates(
providers: readonly string[],
left: ModelRow,
right: ModelRow,
): number {
const providerOrder = providers.indexOf(left.provider) - providers.indexOf(right.provider);
if (providerOrder !== 0) return providerOrder;
const leftFast = left.id.endsWith("-fast");
const rightFast = right.id.endsWith("-fast");
if (leftFast !== rightFast) return leftFast ? 1 : -1;
return right.id.localeCompare(left.id, undefined, { numeric: true, sensitivity: "base" });
}

/**
* Resolve the four focused frontend shortcuts against the catalog that is actually loaded.
* Provider preference is deterministic, but never hides an available Cursor/Kiro Claude route
* merely because the direct Anthropic provider is absent.
*/
export function buildFrontierRouteShortcuts(
models: readonly ModelRow[],
configuredProviders: ReadonlySet<string>,
): FrontierRouteShortcut[] {
return SHORTCUTS.map(definition => {
const candidates = models
.filter(definition.matches)
.filter(model => definition.providers.includes(model.provider))
.toSorted((left, right) => compareCandidates(definition.providers, left, right));
const candidate = candidates[0];
const provider = candidate?.provider
?? definition.providers.find(configured => configuredProviders.has(configured))
?? definition.providers[0];

return {
id: definition.id,
provider,
query: definition.query,
route: candidate?.namespaced ?? null,
providerConfigured: configuredProviders.has(provider),
};
});
}
82 changes: 80 additions & 2 deletions gui/src/styles-models-workspace.css
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,84 @@
font-variant-numeric: tabular-nums;
}

.models-frontier-shortcuts {
display: flex;
flex-direction: column;
gap: var(--space-1);
padding-bottom: var(--space-3);
border-bottom: 1px solid var(--border);
}

.models-frontier-shortcuts-title {
color: var(--muted);
font-size: var(--text-caption);
font-weight: var(--weight-medium);
}

.models-frontier-shortcuts-list {
display: flex;
flex-direction: column;
gap: 2px;
}

.models-frontier-shortcut {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: var(--space-2);
width: 100%;
min-height: 36px;
appearance: none;
background: transparent;
border: 1px solid transparent;
border-radius: var(--radius-sm);
padding: var(--space-1) var(--space-2);
color: inherit;
cursor: pointer;
font: inherit;
text-align: left;
transition: background-color 120ms ease, border-color 120ms ease;
}

.models-frontier-shortcut:hover {
background: var(--hover);
}

.models-frontier-shortcut:active {
background: var(--raised);
}

.models-frontier-shortcut:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 1px;
}

.models-frontier-shortcut--selected {
background: var(--accent-soft);
border-color: var(--border);
}

.models-frontier-shortcut-name,
.models-frontier-shortcut-meta {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.models-frontier-shortcut-name {
color: var(--text);
font-size: var(--text-control);
font-weight: var(--weight-medium);
}

.models-frontier-shortcut-meta {
max-width: 8.5rem;
color: var(--faint);
font-family: var(--mono);
font-size: 10px;
}

.models-workspace-rail-list {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -102,11 +180,11 @@
}

.models-workspace-rail-row:hover {
background: var(--surface-2);
background: var(--hover);
}

.models-workspace-rail-row--selected {
background: var(--surface-2);
background: var(--accent-soft);
box-shadow: inset 0 0 0 1px var(--border);
}

Expand Down
Loading
Loading