"use client"; import type { Session } from "next-auth"; import { startTransition, useEffect, useMemo, useOptimistic, useState, } from "react"; import useSWR from "swr"; import { saveChatModelAsCookie } from "@/app/(chat)/actions"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { cn } from "@/lib/utils"; import { CheckCircleFillIcon, ChevronDownIcon } from "@/components/icons"; import { getImageModelCreditDiscountLabel } from "@/lib/ai/image-model-pricing"; // 从 API 获取的动态模型类型 type DynamicModel = { id: string; modelId: string; displayName: string; description: string | null; supportsVision: boolean; supportsImageGen: boolean; isDefault: boolean; providerName: string; providerType: string; imageGenConfig?: { creditDiscountRate?: number | null; } | null; }; const fetcher = (url: string) => fetch(url).then((res) => res.json()); export function ModelSelector({ session, selectedModelId, className, }: { session: Session; selectedModelId: string; } & React.ComponentProps) { const [open, setOpen] = useState(false); const [optimisticModelId, setOptimisticModelId] = useOptimistic(selectedModelId); // 获取动态配置的模型 const { data: dynamicModelsData, error: modelsError } = useSWR<{ models: DynamicModel[]; defaultModelId: string | null; }>("/api/models", fetcher); const dynamicModels = dynamicModelsData?.models ?? []; const defaultDynamicModelId = dynamicModelsData?.defaultModelId; // 新增:手动添加 Auto 选项 const autoModel: DynamicModel = { id: "auto", modelId: "auto", displayName: "Agent模式", description: "AI 自动识别意图,为您选择最佳模型", supportsVision: true, supportsImageGen: true, isDefault: false, providerName: "System", providerType: "system", }; // 将 Auto 放在列表最前面 const displayModels = [autoModel, ...dynamicModels]; // 调试日志 useEffect(() => { if (modelsError) { console.error("[ModelSelector] Failed to load models:", modelsError); } if (dynamicModelsData) { console.log("[ModelSelector] Loaded models:", dynamicModelsData); } }, [dynamicModelsData, modelsError]); // 如果当前选中的模型 ID 不存在,且有动态默认模型,则切换到默认模型 useEffect(() => { if (dynamicModels.length > 0 && defaultDynamicModelId) { const currentExists = dynamicModels.some((m) => m.id === optimisticModelId); if (!currentExists) { startTransition(() => { setOptimisticModelId(defaultDynamicModelId); saveChatModelAsCookie(defaultDynamicModelId); }); } } }, [ dynamicModels, defaultDynamicModelId, optimisticModelId, setOptimisticModelId, ]); // 查找当前选中的模型(仅从数据库配置的模型中查找) const selectedModel = useMemo(() => { // 在动态模型中查找 const dynamicModel = displayModels.find((m) => m.id === optimisticModelId); if (dynamicModel) { return { name: dynamicModel.displayName, description: dynamicModel.description, }; } // 默认显示第一个可用模型 if (displayModels.length > 0) { return { name: displayModels[0].displayName, description: displayModels[0].description, }; } return { name: "未配置模型", description: null }; }, [optimisticModelId, displayModels]); // 数据加载中 if (!dynamicModelsData && !modelsError) { return ( ); } // 数据加载完成,但没有配置任何模型 if (dynamicModelsData && displayModels.length === 0) { return ( ); } // 数据加载失败 if (modelsError) { return ( ); } return ( {/* 系统设置中配置的模型 */} {displayModels.map((model) => ( { setOpen(false); startTransition(() => { setOptimisticModelId(model.id); saveChatModelAsCookie(model.id); }); }} > ))} ); }