diff --git a/components/chat-input.tsx b/components/chat-input.tsx index fd67c84..774b6f2 100644 --- a/components/chat-input.tsx +++ b/components/chat-input.tsx @@ -162,6 +162,7 @@ interface ChatInputProps { models?: FlattenedModel[] selectedModelId?: string onModelSelect?: (modelId: string | undefined) => void + showUnvalidatedModels?: boolean onConfigureModels?: () => void } @@ -183,6 +184,7 @@ export function ChatInput({ models = [], selectedModelId, onModelSelect = () => {}, + showUnvalidatedModels = false, onConfigureModels = () => {}, }: ChatInputProps) { const dict = useDictionary() @@ -482,6 +484,7 @@ export function ChatInput({ onSelect={onModelSelect} onConfigure={onConfigureModels} disabled={isDisabled} + showUnvalidatedModels={showUnvalidatedModels} />
diff --git a/components/chat-panel.tsx b/components/chat-panel.tsx index ef7e8ef..086037e 100644 --- a/components/chat-panel.tsx +++ b/components/chat-panel.tsx @@ -1071,6 +1071,7 @@ export default function ChatPanel({ models={modelConfig.models} selectedModelId={modelConfig.selectedModelId} onModelSelect={modelConfig.setSelectedModelId} + showUnvalidatedModels={modelConfig.showUnvalidatedModels} onConfigureModels={() => setShowModelConfigDialog(true)} /> diff --git a/components/model-config-dialog.tsx b/components/model-config-dialog.tsx index 7c4534d..88ade22 100644 --- a/components/model-config-dialog.tsx +++ b/components/model-config-dialog.tsx @@ -50,6 +50,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" +import { Switch } from "@/components/ui/switch" import { useDictionary } from "@/hooks/use-dictionary" import type { UseModelConfigReturn } from "@/hooks/use-model-config" import { formatMessage } from "@/lib/i18n/utils" @@ -1447,10 +1448,23 @@ export function ModelConfigDialog({ {/* Footer */}
-

- - {dict.modelConfig.apiKeyStored} -

+
+
+ + +
+

+ + {dict.modelConfig.apiKeyStored} +

+
diff --git a/components/model-selector.tsx b/components/model-selector.tsx index 8153433..237474e 100644 --- a/components/model-selector.tsx +++ b/components/model-selector.tsx @@ -1,6 +1,13 @@ "use client" -import { Bot, Check, ChevronDown, Server, Settings2 } from "lucide-react" +import { + AlertTriangle, + Bot, + Check, + ChevronDown, + Server, + Settings2, +} from "lucide-react" import { useMemo, useState } from "react" import { ModelSelectorContent, @@ -26,6 +33,7 @@ interface ModelSelectorProps { onSelect: (modelId: string | undefined) => void onConfigure: () => void disabled?: boolean + showUnvalidatedModels?: boolean } // Map our provider names to models.dev logo names @@ -67,17 +75,20 @@ export function ModelSelector({ onSelect, onConfigure, disabled = false, + showUnvalidatedModels = false, }: ModelSelectorProps) { const dict = useDictionary() const [open, setOpen] = useState(false) - // Only show validated models in the selector - const validatedModels = useMemo( - () => models.filter((m) => m.validated === true), - [models], - ) + // Filter models based on showUnvalidatedModels setting + const displayModels = useMemo(() => { + if (showUnvalidatedModels) { + return models + } + return models.filter((m) => m.validated === true) + }, [models, showUnvalidatedModels]) const groupedModels = useMemo( - () => groupModelsByProvider(validatedModels), - [validatedModels], + () => groupModelsByProvider(displayModels), + [displayModels], ) // Find selected model for display @@ -126,7 +137,7 @@ export function ModelSelector({ /> - {validatedModels.length === 0 && models.length > 0 + {displayModels.length === 0 && models.length > 0 ? dict.modelConfig.noVerifiedModels : dict.modelConfig.noModelsFound} @@ -191,6 +202,16 @@ export function ModelSelector({ {model.modelId} + {model.validated !== true && ( + + + + )} ))} @@ -213,7 +234,9 @@ export function ModelSelector({ {/* Info text */}
- {dict.modelConfig.onlyVerifiedShown} + {showUnvalidatedModels + ? dict.modelConfig.allModelsShown + : dict.modelConfig.onlyVerifiedShown}
diff --git a/hooks/use-model-config.ts b/hooks/use-model-config.ts index 08c89c4..9904253 100644 --- a/hooks/use-model-config.ts +++ b/hooks/use-model-config.ts @@ -109,9 +109,11 @@ export interface UseModelConfigReturn { models: FlattenedModel[] selectedModel: FlattenedModel | undefined selectedModelId: string | undefined + showUnvalidatedModels: boolean // Actions setSelectedModelId: (modelId: string | undefined) => void + setShowUnvalidatedModels: (show: boolean) => void addProvider: (provider: ProviderName) => ProviderConfig updateProvider: ( providerId: string, @@ -160,6 +162,13 @@ export function useModelConfig(): UseModelConfigReturn { })) }, []) + const setShowUnvalidatedModels = useCallback((show: boolean) => { + setConfig((prev) => ({ + ...prev, + showUnvalidatedModels: show, + })) + }, []) + const addProvider = useCallback( (provider: ProviderName): ProviderConfig => { const newProvider = createProviderConfig(provider) @@ -278,7 +287,9 @@ export function useModelConfig(): UseModelConfigReturn { models, selectedModel, selectedModelId: config.selectedModelId, + showUnvalidatedModels: config.showUnvalidatedModels ?? false, setSelectedModelId, + setShowUnvalidatedModels, addProvider, updateProvider, deleteProvider, diff --git a/lib/i18n/dictionaries/en.json b/lib/i18n/dictionaries/en.json index 2d6b1fe..26557fe 100644 --- a/lib/i18n/dictionaries/en.json +++ b/lib/i18n/dictionaries/en.json @@ -243,6 +243,9 @@ "default": "Default", "serverDefault": "Server Default", "configureModels": "Configure Models...", - "onlyVerifiedShown": "Only verified models are shown" + "onlyVerifiedShown": "Only verified models are shown", + "showUnvalidatedModels": "Show unvalidated models", + "allModelsShown": "All models are shown (including unvalidated)", + "unvalidatedModelWarning": "This model has not been validated" } } diff --git a/lib/i18n/dictionaries/ja.json b/lib/i18n/dictionaries/ja.json index 6b86e4e..39bdac0 100644 --- a/lib/i18n/dictionaries/ja.json +++ b/lib/i18n/dictionaries/ja.json @@ -243,6 +243,9 @@ "default": "デフォルト", "serverDefault": "サーバーデフォルト", "configureModels": "モデルを設定...", - "onlyVerifiedShown": "検証済みのモデルのみ表示" + "onlyVerifiedShown": "検証済みのモデルのみ表示", + "showUnvalidatedModels": "未検証のモデルを表示", + "allModelsShown": "すべてのモデルを表示(未検証を含む)", + "unvalidatedModelWarning": "このモデルは検証されていません" } } diff --git a/lib/i18n/dictionaries/zh.json b/lib/i18n/dictionaries/zh.json index 7b3413c..b7868c4 100644 --- a/lib/i18n/dictionaries/zh.json +++ b/lib/i18n/dictionaries/zh.json @@ -243,6 +243,9 @@ "default": "默认", "serverDefault": "服务器默认", "configureModels": "配置模型...", - "onlyVerifiedShown": "仅显示已验证的模型" + "onlyVerifiedShown": "仅显示已验证的模型", + "showUnvalidatedModels": "显示未验证的模型", + "allModelsShown": "显示所有模型(包括未验证的)", + "unvalidatedModelWarning": "此模型尚未验证" } } diff --git a/lib/types/model-config.ts b/lib/types/model-config.ts index 38b3ba8..ad7fc25 100644 --- a/lib/types/model-config.ts +++ b/lib/types/model-config.ts @@ -40,6 +40,7 @@ export interface MultiModelConfig { version: 1 providers: ProviderConfig[] selectedModelId?: string // Currently selected model's UUID + showUnvalidatedModels?: boolean // Show models that haven't been validated } // Flattened model for dropdown display