/* ┌──────────────────────────────────────────────────────────────────────────────┐ │ @author: Davidson Gomes │ │ @file: /app/agents/forms/AgentForm.tsx │ │ Developed by: Davidson Gomes │ │ Creation date: May 13, 2025 │ │ Contact: contato@evolution-api.com │ ├──────────────────────────────────────────────────────────────────────────────┤ │ @copyright © Evolution API 2025. All rights reserved. │ │ Licensed under the Apache License, Version 2.0 │ │ │ │ You may not use this file except in compliance with the License. │ │ You may obtain a copy of the License at │ │ │ │ http://www.apache.org/licenses/LICENSE-2.0 │ │ │ │ Unless required by applicable law or agreed to in writing, software │ │ distributed under the License is distributed on an "AS IS" BASIS, │ │ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ │ See the License for the specific language governing permissions and │ │ limitations under the License. │ ├──────────────────────────────────────────────────────────────────────────────┤ │ @important │ │ For any future changes to the code in this file, it is recommended to │ │ include, together with the modification, the information of the developer │ │ who changed it and the date of modification. │ └──────────────────────────────────────────────────────────────────────────────┘ */ "use client"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Agent } from "@/types/agent"; import { ApiKey } from "@/services/agentService"; import { MCPServer } from "@/types/mcpServer"; import { useState, useEffect } from "react"; import { BasicInfoTab } from "./BasicInfoTab"; import { ConfigurationTab } from "./ConfigurationTab"; import { SubAgentsTab } from "./SubAgentsTab"; import { MCPDialog } from "../dialogs/MCPDialog"; import { CustomMCPDialog } from "../dialogs/CustomMCPDialog"; interface ModelOption { value: string; label: string; provider: string; } interface AgentFormProps { open: boolean; onOpenChange: (open: boolean) => void; initialValues: Partial; apiKeys: ApiKey[]; availableModels: ModelOption[]; availableMCPs: MCPServer[]; agents: Agent[]; onOpenApiKeysDialog: () => void; onOpenMCPDialog: (mcp?: any) => void; onOpenCustomMCPDialog: (customMCP?: any) => void; onSave: (values: Partial) => Promise; isLoading?: boolean; getAgentNameById: (id: string) => string; clientId: string; } export function AgentForm({ open, onOpenChange, initialValues, apiKeys, availableModels, availableMCPs, agents, onOpenApiKeysDialog, onOpenMCPDialog: externalOnOpenMCPDialog, onOpenCustomMCPDialog: externalOnOpenCustomMCPDialog, onSave, isLoading = false, getAgentNameById, clientId, }: AgentFormProps) { const [values, setValues] = useState>(initialValues); const [activeTab, setActiveTab] = useState("basic"); const [mcpDialogOpen, setMcpDialogOpen] = useState(false); const [selectedMCP, setSelectedMCP] = useState(null); const [customMcpDialogOpen, setCustomMcpDialogOpen] = useState(false); const [selectedCustomMCP, setSelectedCustomMCP] = useState(null); useEffect(() => { if (open) { setValues(initialValues); setActiveTab("basic"); } }, [open, initialValues]); const handleOpenMCPDialog = (mcpConfig: any = null) => { setSelectedMCP(mcpConfig); setMcpDialogOpen(true); }; const handleOpenCustomMCPDialog = (customMCP: any = null) => { setSelectedCustomMCP(customMCP); setCustomMcpDialogOpen(true); }; const handleConfigureMCP = (mcpConfig: any) => { handleOpenMCPDialog(mcpConfig); }; const handleRemoveMCP = (mcpId: string) => { setValues({ ...values, config: { ...values.config, mcp_servers: values.config?.mcp_servers?.filter((mcp) => mcp.id !== mcpId) || [], }, }); }; const handleConfigureCustomMCP = (customMCP: any) => { handleOpenCustomMCPDialog(customMCP); }; const handleRemoveCustomMCP = (url: string) => { setValues({ ...values, config: { ...values.config, custom_mcp_servers: values.config?.custom_mcp_servers?.filter( (customMCP) => customMCP.url !== url ) || [], }, }); }; const handleSaveMCP = (mcpConfig: any) => { const updatedMcpServers = [...(values.config?.mcp_servers || [])]; const existingIndex = updatedMcpServers.findIndex( (mcp) => mcp.id === mcpConfig.id ); if (existingIndex >= 0) { updatedMcpServers[existingIndex] = mcpConfig; } else { updatedMcpServers.push(mcpConfig); } setValues({ ...values, config: { ...(values.config || {}), mcp_servers: updatedMcpServers, }, }); }; const handleSaveCustomMCP = (customMCP: any) => { const updatedCustomMCPs = [...(values.config?.custom_mcp_servers || [])]; const existingIndex = updatedCustomMCPs.findIndex( (mcp) => mcp.url === customMCP.url ); if (existingIndex >= 0) { updatedCustomMCPs[existingIndex] = customMCP; } else { updatedCustomMCPs.push(customMCP); } setValues({ ...values, config: { ...(values.config || {}), custom_mcp_servers: updatedCustomMCPs, }, }); }; const handleSave = async () => { const finalValues = { ...values, client_id: clientId, name: values.name, }; await onSave(finalValues); }; return ( <> {initialValues.id ? "Edit Agent" : "New Agent"} {initialValues.id ? "Edit the existing agent information" : "Fill in the information to create a new agent"} Basic Information Configuration Sub-Agents {/* MCP Dialog */} selectedMCP?.id === m.id) || null } initialEnvs={selectedMCP?.envs || {}} initialTools={selectedMCP?.tools || []} clientId={clientId} /> {/* Custom MCP Dialog */} ); }