import { AudioLines, Check, Film, Flame, Image, MessageSquareText, Network, Settings2, Sparkles } from "lucide-react"; import { Button, Modal } from "antd"; import { useEffect, useState, type ReactNode } from "react"; import { ModelIcon } from "@/components/model-picker"; import { modelProtocolLabel, type ModelProtocol, type ModelProtocolDefinition, type ProtocolCapability } from "@/lib/model-protocols"; import { cn } from "@/lib/utils"; export type ModelCapabilityChoice = ProtocolCapability; const capabilityChoices: Array<{ value: ModelCapabilityChoice; label: string; description: string; icon: ReactNode; brands: string[]; }> = [ { value: "text", label: "文本", description: "对话与推理", icon: , brands: ["openai", "deepseek", "glm"] }, { value: "image", label: "图片", description: "生成与编辑", icon: , brands: ["openai", "gemini"] }, { value: "video", label: "视频", description: "生成与续写", icon: , brands: ["grok", "gemini"] }, { value: "audio", label: "音频", description: "语音与音效", icon: , brands: ["openai"] }, ]; type PickerDensity = "comfortable" | "compact"; export function CapabilityCardPicker({ value, onChange, density = "comfortable" }: { value?: ModelCapabilityChoice; onChange?: (value: ModelCapabilityChoice) => void; density?: PickerDensity }) { return (
{capabilityChoices.map((item) => { const selected = value === item.value; return ( ); })}
); } export function ProtocolCardPicker({ capability, value, onChange, density = "comfortable", protocols = [], }: { capability?: ModelCapabilityChoice; value?: ModelProtocol; onChange?: (value: ModelProtocol) => void; density?: PickerDensity; protocols?: ModelProtocolDefinition[]; }) { const availableProtocols = protocols.filter((item) => item.capability === capability && item.enabled !== false); return (
{availableProtocols.map((protocol) => { const selected = value === protocol.value; return ( ); })}
); } export function ModelCapabilityProtocolModal({ value, onChange, protocols = [], }: { value: { capability: ModelCapabilityChoice; protocol: ModelProtocol }; onChange: (value: { capability: ModelCapabilityChoice; protocol: ModelProtocol }) => void; protocols?: ModelProtocolDefinition[]; }) { const [open, setOpen] = useState(false); const [draft, setDraft] = useState(value); useEffect(() => { if (!open) setDraft(value); }, [open, value]); const updateCapability = (capability: ModelCapabilityChoice) => { const protocol = draft.protocol && protocols.some((item) => item.value === draft.protocol && item.capability === capability) ? draft.protocol : protocols.find((item) => item.capability === capability)?.value || ""; setDraft({ capability, protocol }); }; return ( <> setOpen(false)} okText="应用配置" cancelText="取消" onOk={() => { onChange(draft); setOpen(false); }} >
模型能力
请求协议
setDraft((current) => ({ ...current, protocol }))} />
); } function ProtocolBrandMark({ protocol, compact = false }: { protocol: ModelProtocolDefinition; compact?: boolean }) { const iconSize = compact ? "size-6" : "size-8"; const vendor = `${protocol.vendor || ""} ${protocol.label}`.toLowerCase(); if (vendor.includes("jimeng") || vendor.includes("即梦")) return ( ); if (vendor.includes("volcengine") || vendor.includes("火山方舟")) return ( ); if (vendor.includes("newapi") || vendor.includes("novita")) return ( ); const brand = vendor.includes("gemini") || vendor.includes("google") ? "gemini" : vendor.includes("grok") || vendor.includes("xai") ? "grok" : vendor.includes("openai") ? "openai" : "openai"; return ; } function BrandIconRow({ models, compact = false, className }: { models: string[]; compact?: boolean; className?: string }) { return ( ); } function modelBrandLabel(model: string) { const labels: Record = { openai: "OpenAI", deepseek: "DeepSeek", glm: "智谱 GLM", gemini: "Google Gemini", grok: "xAI Grok" }; return labels[model] || model; } function capabilityLabel(value: ModelCapabilityChoice) { return { text: "文本", image: "图片", video: "视频", audio: "音频" }[value]; }