import { WorkflowToolKey } from "lib/ai/workflow/workflow.interface"; import { groupBy } from "lib/utils"; import { ChevronDownIcon, WrenchIcon } from "lucide-react"; import { useTranslations } from "next-intl"; import { ReactNode, useMemo, useState } from "react"; import { Button } from "ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "ui/command"; import { MCPIcon } from "ui/mcp-icon"; import { Popover, PopoverContent, PopoverTrigger } from "ui/popover"; export function WorkflowToolSelect({ tools, onChange, children, side, align, tool, }: { side?: "top" | "bottom" | "left" | "right"; align?: "start" | "end" | "center"; tools: WorkflowToolKey[]; onChange: (tool: WorkflowToolKey) => void; children?: ReactNode; tool?: WorkflowToolKey; }) { const t = useTranslations(); const [open, setOpen] = useState(false); const mcpToolsByServerId = useMemo(() => { const mcpTools = tools.filter((tool) => tool.type == "mcp-tool"); return Object.entries(groupBy(mcpTools, "serverId")).map( ([serverId, tools]) => { return { serverId, serverName: tools[0].serverName, tools, }; }, ); }, [tools]); const defaultTools = useMemo(() => { return tools.filter((tool) => tool.type == "app-tool"); }, [tools]); const selectedToolLabel = useMemo(() => { if (!tool) return ( <> {t("Common.selectTool")} ); if (tool.type == "mcp-tool") { return ( <> {tool.serverName}
{tool.id}
); } return ( <> {tool.id} ); }, [tool]); return ( {children || ( )} {t("Common.noResults")} {mcpToolsByServerId.map((mcpTools) => { return ( {mcpTools.tools.map((tool) => { return ( { onChange(tool); setOpen(false); }} className="cursor-pointer" > {tool.id} ); })} ); })} {defaultTools.map((tool) => { return ( { onChange(tool); setOpen(false); }} className="cursor-pointer" > {tool.id} ); })} ); }