"use client"; import { BotIcon, SettingsIcon, XIcon } from "lucide-react"; import { useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Dialog, DialogContent, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { PromptInputButton } from "@/components/ai-elements/prompt-input"; import { AgentManageDialog } from "@/components/workspace/agents/agent-manage-dialog"; import { Tooltip } from "@/components/workspace/tooltip"; import { useAgentSelector, useAgentsPaginated } from "@/core/agents"; import type { Agent } from "@/core/agents"; import { getStoredAuth } from "@/core/auth"; import { desensitize } from "@/lib/desensitize"; import { cn } from "@/lib/utils"; interface AgentSelectorProps { selectedAgentId: string | null; onAgentChange: (agentId: string | null) => void; disabled?: boolean; /** 紧凑模式(CM 参考图):触发器改为灰底胶囊 + 主色机器人图标。 */ compact?: boolean; /** 图标模式:用于 iframe 等底栏场景,仅显示机器人图标和可选清空按钮。 */ triggerVariant?: "default" | "icon"; iconButtonClassName?: string; iconActiveClassName?: string; } /** * Homepage agent picker — shows the admin-curated selector list. * * - Non-admins see a read-only dropdown. * - Admins also see a "管理 Agent 列表" entry that opens the management dialog. * * Selecting an agent flips this chip to a coloured pill with a ✕ to clear. * The actual handoff to ``AgentChatPage`` happens in ``ChatPage`` on submit. */ export function AgentSelector({ selectedAgentId, onAgentChange, disabled, compact = false, triggerVariant = "default", iconButtonClassName, iconActiveClassName, }: AgentSelectorProps) { const [open, setOpen] = useState(false); const [manageOpen, setManageOpen] = useState(false); const { agents, isLoading } = useAgentSelector(); // 弹窗列表只展示管理弹窗里配置的 agent(agents);但「已选中 agent」的名称解析要更宽—— // 侧边栏「常用智能体」可以选中未配置进管理弹窗的 agent(如用户自己的智能体), // 这些 agent 也要能在胶囊上显示名称,故额外用「我的 / 广场」列表兜底解析(缓存与侧边栏共享)。 const { agents: mineAgents } = useAgentsPaginated({ scope: "mine", page: 1, pageSize: 20 }); const { agents: squareAgents } = useAgentsPaginated({ scope: "square", page: 1, pageSize: 20 }); const isAdmin = useMemo(() => getStoredAuth()?.system_role === "admin", []); const selectedAgent = useMemo(() => { if (!selectedAgentId) return null; return ( [...agents, ...mineAgents, ...squareAgents].find( (a) => a.id === selectedAgentId, ) ?? null ); }, [agents, mineAgents, squareAgents, selectedAgentId]); const handleSelect = (agent: Agent) => { onAgentChange(agent.id); setOpen(false); }; const handleClear = (e: React.MouseEvent) => { e.stopPropagation(); onAgentChange(null); }; const triggerLabel = selectedAgent ? desensitize(selectedAgent.name) : "选择 Agent"; const iconTooltipLabel = selectedAgent ? triggerLabel : "未选择"; const iconMode = triggerVariant === "icon"; return ( <> {iconMode ? (
) : ( {triggerLabel} {selectedAgent && ( { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onAgentChange(null); } }} > )} )} 选择 Agent {isLoading ? "加载中…" : "没有找到匹配的 agent"} {agents.length > 0 && ( {agents.map((agent) => ( handleSelect(agent)} className={cn( "flex w-full min-w-0 items-start gap-2 overflow-hidden", agent.id === selectedAgentId && "bg-accent", )} >
{desensitize(agent.name)} {agent.description && ( {desensitize(agent.description)} )}
))}
)} {!isLoading && agents.length === 0 && (
{isAdmin ? "还没有配置任何 agent。点击下方 “管理” 添加几个。" : "管理员还没有配置可选的 agent。"}
)}
{isAdmin && (
)}
{isAdmin && ( )} ); }