/* ┌──────────────────────────────────────────────────────────────────────────────┐ │ @author: Davidson Gomes │ │ @file: /app/agents/forms/ConfigurationTab.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 { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Agent } from "@/types/agent"; import { MCPServer } from "@/types/mcpServer"; import { Check, Copy, Eye, EyeOff, Plus, Server, Settings, X, } from "lucide-react"; import { ParallelAgentConfig } from "../config/ParallelAgentConfig"; import { SequentialAgentConfig } from "../config/SequentialAgentConfig"; import { ApiKey } from "@/services/agentService"; import { LoopAgentConfig } from "../config/LoopAgentConfig copy"; import { A2AAgentConfig } from "../config/A2AAgentConfig"; import { TaskAgentConfig } from "../config/TaskAgentConfig"; import { useState } from "react"; import { MCPDialog } from "../dialogs/MCPDialog"; import { CustomMCPDialog } from "../dialogs/CustomMCPDialog"; import { AgentToolDialog } from "../dialogs/AgentToolDialog"; import { CustomToolDialog } from "../dialogs/CustomToolDialog"; import { useToast } from "@/hooks/use-toast"; interface ConfigurationTabProps { values: Partial; onChange: (values: Partial) => void; agents: Agent[]; availableMCPs: MCPServer[]; apiKeys: ApiKey[]; availableModels: any[]; getAgentNameById: (id: string) => string; onOpenApiKeysDialog: () => void; onConfigureMCP: (mcpConfig: any) => void; onRemoveMCP: (mcpId: string) => void; onConfigureCustomMCP: (customMCP: any) => void; onRemoveCustomMCP: (url: string) => void; onOpenMCPDialog: (mcpConfig?: any) => void; onOpenCustomMCPDialog: (customMCP?: any) => void; clientId: string; } export function ConfigurationTab({ values, onChange, agents, availableMCPs, apiKeys, availableModels, getAgentNameById, onOpenApiKeysDialog, onConfigureMCP, onRemoveMCP, onConfigureCustomMCP, onRemoveCustomMCP, onOpenMCPDialog, onOpenCustomMCPDialog, clientId, }: ConfigurationTabProps) { const [agentToolDialogOpen, setAgentToolDialogOpen] = useState(false); const [customToolDialogOpen, setCustomToolDialogOpen] = useState(false); const [editingCustomTool, setEditingCustomTool] = useState(null); const [showApiKey, setShowApiKey] = useState(false); const [copied, setCopied] = useState(false); const [copiedCardUrl, setCopiedCardUrl] = useState(false); const { toast } = useToast(); const handleAddAgentTool = (tool: { id: string }) => { const updatedAgentTools = [...(values.config?.agent_tools || [])]; if (!updatedAgentTools.includes(tool.id)) { updatedAgentTools.push(tool.id); onChange({ ...values, config: { ...(values.config || {}), agent_tools: updatedAgentTools, }, }); } }; const handleRemoveAgentTool = (id: string) => { onChange({ ...values, config: { ...(values.config || {}), agent_tools: (values.config?.agent_tools || []).filter( (toolId) => toolId !== id ), }, }); }; // Custom Tools handlers const handleAddCustomTool = (tool: any) => { const updatedTools = [...(values.config?.custom_tools?.http_tools || [])]; updatedTools.push(tool); onChange({ ...values, config: { ...(values.config || {}), custom_tools: { ...(values.config?.custom_tools || { http_tools: [] }), http_tools: updatedTools, }, }, }); }; const handleEditCustomTool = (tool: any, idx: number) => { setEditingCustomTool({ ...tool, idx }); setCustomToolDialogOpen(true); }; const handleSaveEditCustomTool = (tool: any) => { const updatedTools = [...(values.config?.custom_tools?.http_tools || [])]; if (editingCustomTool && typeof editingCustomTool.idx === "number") { updatedTools[editingCustomTool.idx] = tool; } onChange({ ...values, config: { ...(values.config || {}), custom_tools: { ...(values.config?.custom_tools || { http_tools: [] }), http_tools: updatedTools, }, }, }); setEditingCustomTool(null); }; const handleRemoveCustomTool = (idx: number) => { const updatedTools = [...(values.config?.custom_tools?.http_tools || [])]; updatedTools.splice(idx, 1); onChange({ ...values, config: { ...(values.config || {}), custom_tools: { ...(values.config?.custom_tools || { http_tools: [] }), http_tools: updatedTools, }, }, }); }; const apiKeyField = (

Credentials

onChange({ ...values, config: { ...(values.config || {}), api_key: e.target.value, }, }) } autoComplete="off" />
); if (values.type === "llm") { return (
{apiKeyField}

MCP Servers

Configure the MCP servers that this agent can use.

{values.config?.mcp_servers && values.config.mcp_servers.length > 0 ? (
{values.config.mcp_servers.map((mcpConfig) => { const mcpServer = availableMCPs.find( (mcp) => mcp.id === mcpConfig.id ); return (

{mcpServer?.name || mcpConfig.id}

{mcpServer?.description?.substring(0, 100)} ...

{mcpConfig.tools && mcpConfig.tools.length > 0 && (
{mcpConfig.tools.map((toolId) => ( {toolId} ))}
)}
); })}
) : (

No MCP servers configured

Add MCP servers for this agent

)}

Custom MCPs

Configure custom MCPs with URL and HTTP headers.

{values.config?.custom_mcp_servers && values.config.custom_mcp_servers.length > 0 ? (
{values.config.custom_mcp_servers.map((customMCP) => (

{customMCP.url}

{Object.keys(customMCP.headers || {}).length > 0 ? `${ Object.keys(customMCP.headers || {}).length } headers configured` : "No headers configured"}

))}
) : (

No custom MCPs configured

Add custom MCPs for this agent

)}

Agent Tools

Configure other agents as tools for this agent.

{values.config?.agent_tools && values.config.agent_tools.length > 0 ? (
{values.config.agent_tools.map((toolId) => { const agent = agents.find((a) => a.id === toolId); return (

{agent?.name || toolId}

{agent?.description || "No description"}

); })}
) : (

No agent tools configured

Add agent tools for this agent

)}

Custom Tools (HTTP Tools)

Configure HTTP tools for this agent.

{values.config?.custom_tools?.http_tools && values.config.custom_tools.http_tools.length > 0 ? (
{values.config.custom_tools.http_tools.map((tool, idx) => (

{tool.name}

{tool.method} {tool.endpoint}

{tool.description}

))}
) : (

No custom tools configured

Add HTTP tools for this agent

)}
{ setCustomToolDialogOpen(open); if (!open) setEditingCustomTool(null); }} onSave={ editingCustomTool ? handleSaveEditCustomTool : handleAddCustomTool } initialTool={editingCustomTool} /> {agentToolDialogOpen && ( )}
); } if (values.type === "a2a") { return (
{apiKeyField}
); } if (values.type === "sequential") { return (
{apiKeyField}
); } if (values.type === "parallel") { return (
{apiKeyField}
); } if (values.type === "loop") { return (
{apiKeyField}
); } if (values.type === "task") { return (
{apiKeyField}
); } return (
{apiKeyField}

Configure the sub-agents in the "Sub-Agents" tab

); }