diff --git a/.github/instructions/project-structure.instructions.md b/.github/instructions/project-structure.instructions.md index b12d68cf..995f8402 100644 --- a/.github/instructions/project-structure.instructions.md +++ b/.github/instructions/project-structure.instructions.md @@ -59,7 +59,6 @@ applyTo: '**/*' │ │ │ └── helpers/ # JSON column helpers, backups │ │ ├── localDb.js # Backward-compat shim → re-exports @/lib/db/index.js │ │ ├── usageDb.js # Usage + log persistence (~/.9router/usage.json, log.txt) -│ │ ├── disabledModelsDb.js # Disabled models DB │ │ ├── requestDetailsDb.js # Request detail logging DB │ │ ├── oauth/ # OAuth flow helpers │ │ ├── headroom/ # Headroom token compression diff --git a/public/providers/ag.png b/public/providers/ag.png new file mode 100644 index 00000000..ce40c20f Binary files /dev/null and b/public/providers/ag.png differ diff --git a/public/providers/cf.png b/public/providers/cf.png new file mode 100644 index 00000000..2ec56991 Binary files /dev/null and b/public/providers/cf.png differ diff --git a/public/providers/cx.png b/public/providers/cx.png new file mode 100644 index 00000000..12df8bb1 Binary files /dev/null and b/public/providers/cx.png differ diff --git a/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.js b/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.js index b18a3048..47636dd5 100644 --- a/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.js +++ b/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.js @@ -165,7 +165,7 @@ export default function BasicChatPageClient() { const providerMap = new Map(); for (const model of modelsData.models || []) { - if (model.disabled || !model.fullModel) continue; + if (!model.fullModel) continue; const providerId = model.provider?.id || model.providerAlias; const providerName = model.provider?.name || humanize(providerId); diff --git a/src/app/(dashboard)/dashboard/cli-tools/[toolId]/ToolDetailClient.js b/src/app/(dashboard)/dashboard/cli-tools/[toolId]/ToolDetailClient.js index cbbe8b54..fc13b01a 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/[toolId]/ToolDetailClient.js +++ b/src/app/(dashboard)/dashboard/cli-tools/[toolId]/ToolDetailClient.js @@ -45,7 +45,7 @@ export default function ToolDetailClient({ toolId, machineId }) { } if (modelsRes.ok) { const data = await modelsRes.json(); - setAvailableModels((data.models || []).filter((model) => !model.disabled)); + setAvailableModels(data.models || []); } if (configRes.ok) { const data = await configRes.json(); diff --git a/src/app/(dashboard)/dashboard/combos/page.js b/src/app/(dashboard)/dashboard/combos/page.js index bd88a6e8..b5c03d7f 100644 --- a/src/app/(dashboard)/dashboard/combos/page.js +++ b/src/app/(dashboard)/dashboard/combos/page.js @@ -54,10 +54,8 @@ export default function CombosPage() { } } - // The Models page is the source of truth for eligible models. Administrators - // can still see disabled rows there to manage them, but disabled models must - // not be added to new or edited combos because they cannot serve requests. - const selectableModels = connectedModels.filter((model) => !model.disabled); + // The Models page is the source of truth for eligible models. + const selectableModels = connectedModels; const handleCreate = async (data) => { try { diff --git a/src/app/(dashboard)/dashboard/mitm/MitmPageClient.js b/src/app/(dashboard)/dashboard/mitm/MitmPageClient.js index e3f5afb4..ca54992d 100644 --- a/src/app/(dashboard)/dashboard/mitm/MitmPageClient.js +++ b/src/app/(dashboard)/dashboard/mitm/MitmPageClient.js @@ -35,7 +35,7 @@ export default function MitmPageClient() { setConnections(connectionsData.connections || []); setApiKeys(keysData.keys || []); setModelAliases(aliasesData.aliases || {}); - setAvailableModels((modelsData.models || []).filter((model) => !model.disabled)); + setAvailableModels(modelsData.models || []); setCloudEnabled(settingsData.cloudEnabled || false); }).catch(() => {}); diff --git a/src/app/(dashboard)/dashboard/models/page.js b/src/app/(dashboard)/dashboard/models/page.js index 8fefb0c7..a4a96b06 100644 --- a/src/app/(dashboard)/dashboard/models/page.js +++ b/src/app/(dashboard)/dashboard/models/page.js @@ -3,16 +3,12 @@ import { useEffect, useMemo, useState } from "react"; import { Badge, - Button, Card, CardSkeleton, CapacityBadges, - Toggle, } from "@/shared/components"; import ProviderIcon from "@/shared/components/ProviderIcon"; import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard"; -import useUserStore from "@/store/userStore"; -import { useNotificationStore } from "@/store/notificationStore"; function groupModelsByProvider(models) { return models.reduce((groups, model) => { @@ -28,17 +24,9 @@ function groupModelsByProvider(models) { }, {}); } -function ProviderModelsCard({ group, canManage, onSetModelDisabled, onSetModelsDisabled, pendingIds }) { +function ProviderModelsCard({ group }) { const [expanded, setExpanded] = useState(true); const { copied, copy } = useCopyToClipboard(); - const isUpdatingGroup = group.models.some((model) => pendingIds.has(model.fullModel)); - const enabledCount = group.models.filter((model) => !model.disabled).length; - const disabledCount = group.models.length - enabledCount; - - const setAllModelsDisabled = (disabled) => { - const modelsToUpdate = group.models.filter((model) => model.disabled !== disabled); - if (modelsToUpdate.length > 0) onSetModelsDisabled(group.provider.alias, modelsToUpdate, disabled); - }; return ( @@ -72,38 +60,14 @@ function ProviderModelsCard({ group, canManage, onSetModelDisabled, onSetModelsD expand_more - {canManage ? ( -
- - -
- ) : null} {expanded ? (
- {group.models.map((model) => { - const isPending = pendingIds.has(model.fullModel); - return ( + {group.models.map((model) => (

@@ -130,19 +94,9 @@ function ProviderModelsCard({ group, canManage, onSetModelDisabled, onSetModelsD {model.alias !== model.model ? {model.alias} : null}

- {canManage ? ( - onSetModelDisabled(group.provider.alias, model, !enabled)} - className="shrink-0" - /> - ) : null}
- ); - })} + ))} ) : null}
@@ -150,18 +104,10 @@ function ProviderModelsCard({ group, canManage, onSetModelDisabled, onSetModelsD } export default function ModelsPage() { - const user = useUserStore((state) => state.user); - const fetchCurrentUser = useUserStore((state) => state.fetchCurrentUser); - const notify = useNotificationStore(); const [models, setModels] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [search, setSearch] = useState(""); - const [pendingIds, setPendingIds] = useState(new Set()); - - useEffect(() => { - if (!user) fetchCurrentUser(); - }, [fetchCurrentUser, user]); useEffect(() => { const loadModels = async () => { @@ -195,43 +141,6 @@ export default function ModelsPage() { .sort((a, b) => a.provider.name.localeCompare(b.provider.name)); }, [models, search]); - const setModelDisabled = async (providerAlias, model, disabled) => { - await setModelsDisabled(providerAlias, [model], disabled); - }; - - const setModelsDisabled = async (providerAlias, modelsToUpdate, disabled) => { - const ids = modelsToUpdate.map((model) => model.fullModel); - const modelIds = modelsToUpdate.map((model) => model.model); - if (ids.length === 0) return; - - setPendingIds((current) => new Set([...current, ...ids])); - setModels((current) => current.map((item) => ( - ids.includes(item.fullModel) ? { ...item, disabled } : item - ))); - - try { - const response = await fetch("/api/models/connected", { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ providerAlias, modelIds, disabled }), - }); - const data = await response.json(); - if (!response.ok) throw new Error(data.error || "Failed to update model"); - notify.success(`${modelIds.length} model${modelIds.length === 1 ? "" : "s"} ${disabled ? "disabled" : "enabled"}.`); - } catch (updateError) { - setModels((current) => current.map((item) => ( - ids.includes(item.fullModel) ? { ...item, disabled: !disabled } : item - ))); - notify.error(updateError.message); - } finally { - setPendingIds((current) => { - const next = new Set(current); - ids.forEach((id) => next.delete(id)); - return next; - }); - } - }; - if (loading) { return (
@@ -242,7 +151,6 @@ export default function ModelsPage() { } const providerCount = new Set(models.map((model) => model.providerAlias)).size; - const canManage = user?.role === "admin"; return (
@@ -253,9 +161,7 @@ export default function ModelsPage() { {models.length}

- {canManage - ? "Manage models available from connected providers." - : "Browse models currently available through connected providers."} + Browse models currently available through connected providers.