+
+ {justSaved && (
+
+ )}
{dirtyCount > 0
? `${dirtyCount} unsaved ${dirtyCount === 1 ? "change" : "changes"}`
: saveMessage}
diff --git a/components/model-config-dialog.tsx b/components/model-config-dialog.tsx
index d381761..9a3cb58 100644
--- a/components/model-config-dialog.tsx
+++ b/components/model-config-dialog.tsx
@@ -5,7 +5,6 @@ import {
Check,
ChevronRight,
Clock,
- Cloud,
Eye,
EyeOff,
Key,
@@ -21,6 +20,7 @@ import {
Zap,
} from "lucide-react"
import { useCallback, useEffect, useRef, useState } from "react"
+import { ProviderLogo } from "@/components/provider-logo"
import {
AlertDialog,
AlertDialogAction,
@@ -54,11 +54,7 @@ import { useDictionary } from "@/hooks/use-dictionary"
import type { UseModelConfigReturn } from "@/hooks/use-model-config"
import { formatMessage } from "@/lib/i18n/utils"
import type { ProviderConfig, ProviderName } from "@/lib/types/model-config"
-import {
- PROVIDER_INFO,
- PROVIDER_LOGO_MAP,
- SUGGESTED_MODELS,
-} from "@/lib/types/model-config"
+import { PROVIDER_INFO, SUGGESTED_MODELS } from "@/lib/types/model-config"
import { cn } from "@/lib/utils"
interface ModelConfigDialogProps {
@@ -69,38 +65,6 @@ interface ModelConfigDialogProps {
type ValidationStatus = "idle" | "validating" | "success" | "error"
-// Provider logo component
-function ProviderLogo({
- provider,
- className,
-}: {
- provider: ProviderName
- className?: string
-}) {
- // Use Lucide icons for providers without models.dev logos
- if (provider === "bedrock") {
- return
- }
- if (provider === "sglang") {
- return
- }
- if (provider === "doubao") {
- return
- }
-
- const logoName = PROVIDER_LOGO_MAP[provider] || provider
- return (
- // biome-ignore lint/performance/noImgElement: External URL from models.dev
-
- )
-}
-
// Configuration section with title and optional action
function ConfigSection({
title,
diff --git a/components/provider-logo.tsx b/components/provider-logo.tsx
new file mode 100644
index 0000000..0b04b0c
--- /dev/null
+++ b/components/provider-logo.tsx
@@ -0,0 +1,36 @@
+import { Cloud, Server, Sparkles } from "lucide-react"
+import { PROVIDER_LOGO_MAP, type ProviderName } from "@/lib/types/model-config"
+import { cn } from "@/lib/utils"
+
+// Provider logo from models.dev, with Lucide fallbacks for providers
+// that have no logo there
+export function ProviderLogo({
+ provider,
+ className,
+}: {
+ provider: ProviderName
+ className?: string
+}) {
+ if (provider === "bedrock") {
+ return
+ }
+ if (provider === "sglang") {
+ return
+ }
+ if (provider === "doubao") {
+ return
+ }
+
+ const logoName = PROVIDER_LOGO_MAP[provider] || provider
+ return (
+ // biome-ignore lint/performance/noImgElement: External URL from models.dev
+
+ )
+}
diff --git a/lib/admin/settings-registry.ts b/lib/admin/settings-registry.ts
index 59d127f..75ef165 100644
--- a/lib/admin/settings-registry.ts
+++ b/lib/admin/settings-registry.ts
@@ -76,6 +76,30 @@ export const SETTING_GROUPS: SettingGroup[] = [
},
]
+// Provider name for each subgroup in the providers group (for logos)
+export const SUBGROUP_PROVIDERS: Record = {
+ "AWS Bedrock": "bedrock",
+ OpenAI: "openai",
+ Anthropic: "anthropic",
+ Google: "google",
+ "Vertex AI": "vertexai",
+ "Azure OpenAI": "azure",
+ Ollama: "ollama",
+ OpenRouter: "openrouter",
+ DeepSeek: "deepseek",
+ SiliconFlow: "siliconflow",
+ SGLang: "sglang",
+ "Vercel AI Gateway": "gateway",
+ Doubao: "doubao",
+ ModelScope: "modelscope",
+ GLM: "glm",
+ Qwen: "qwen",
+ Kimi: "kimi",
+ Qiniu: "qiniu",
+ MiniMax: "minimax",
+ Novita: "novita",
+}
+
const PROVIDER_OPTIONS = [
"bedrock",
"openai",