diff --git a/ui/litellm-dashboard/src/components/agents/agent_info.tsx b/ui/litellm-dashboard/src/components/agents/agent_info.tsx index d543be8356a..44dfa91b2e4 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_info.tsx +++ b/ui/litellm-dashboard/src/components/agents/agent_info.tsx @@ -1,8 +1,11 @@ -import React, { useState, useEffect } from "react"; -import { Card, Title, Text, Button as TremorButton, Tab, TabGroup, TabList, TabPanel, TabPanels} from "@tremor/react"; -import { Form, Input, InputNumber, Button as AntButton, Spin, Descriptions, Divider } from "antd"; +import React, { useState, useEffect, useCallback } from "react"; +// eslint-disable-next-line litellm-ui/no-banned-ui-imports +import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@tremor/react"; +import { Form, Input, InputNumber, Descriptions } from "antd"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { ArrowLeft, Loader2 } from "lucide-react"; import MessageManager from "@/components/molecules/message_manager"; -import { ArrowLeftIcon } from "@heroicons/react/outline"; import { getAgentInfo, patchAgentCall, getAgentCreateMetadata, AgentCreateInfo } from "../networking"; import { Agent } from "./types"; import AgentFormFields from "./agent_form_fields"; @@ -44,31 +47,27 @@ const AgentInfoView: React.FC = ({ fetchMetadata(); }, []); - useEffect(() => { - fetchAgentInfo(); - }, [agentId, accessToken]); - - const fetchAgentInfo = async () => { + const fetchAgentInfo = useCallback(async () => { if (!accessToken) return; setIsLoading(true); try { const data = await getAgentInfo(accessToken, agentId); setAgent(data); - - // Detect agent type + const agentType = detectAgentType(data); setDetectedAgentType(agentType); - - // Parse form values based on agent type + if (agentType === "a2a") { form.setFieldsValue(parseAgentForForm(data)); } else { - const typeInfo = agentTypeMetadata.find(t => t.agent_type === agentType); + const typeInfo = agentTypeMetadata.find( + (t) => t.agent_type === agentType, + ); if (typeInfo) { form.setFieldsValue(parseDynamicAgentForForm(data, typeInfo)); } else { - form.setFieldsValue(parseAgentForForm(data)); + form.setFieldsValue(parseAgentForForm(data)); } } } catch (error) { @@ -77,30 +76,41 @@ const AgentInfoView: React.FC = ({ } finally { setIsLoading(false); } - }; + }, [accessToken, agentId, agentTypeMetadata, form]); + + useEffect(() => { + fetchAgentInfo(); + }, [fetchAgentInfo]); // Re-parse form when metadata is loaded useEffect(() => { if (agent && agentTypeMetadata.length > 0) { const agentType = detectAgentType(agent); if (agentType !== "a2a") { - const typeInfo = agentTypeMetadata.find(t => t.agent_type === agentType); + const typeInfo = agentTypeMetadata.find( + (t) => t.agent_type === agentType, + ); if (typeInfo) { form.setFieldsValue(parseDynamicAgentForForm(agent, typeInfo)); } } } - }, [agentTypeMetadata, agent]); + }, [agentTypeMetadata, agent, form]); - const selectedAgentTypeInfo = agentTypeMetadata.find(t => t.agent_type === detectedAgentType); + const selectedAgentTypeInfo = agentTypeMetadata.find( + (t) => t.agent_type === detectedAgentType, + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const handleUpdate = async (values: any) => { if (!accessToken || !agent) return; setIsSaving(true); try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any let updateData: any; - + + if (detectedAgentType === "a2a") { updateData = buildAgentDataFromForm(values, agent); } else if (selectedAgentTypeInfo) { @@ -127,7 +137,7 @@ const AgentInfoView: React.FC = ({ return (
- +
); @@ -137,9 +147,9 @@ const AgentInfoView: React.FC = ({ return (
Agent not found
- +
); } @@ -154,11 +164,14 @@ const AgentInfoView: React.FC = ({ return (
- + +

+ {agent.agent_name || "Unnamed Agent"} +

+ {agent.agent_id}
@@ -215,9 +228,9 @@ const AgentInfoView: React.FC = ({ agent.object_permission.mcp_access_groups?.length || (agent.object_permission.mcp_tool_permissions && Object.keys(agent.object_permission.mcp_tool_permissions).length > 0)) && ( -
- MCP Tool Permissions - +
+

MCP Tool Permissions

+ {agent.object_permission.mcp_servers && agent.object_permission.mcp_servers.length > 0 && ( {agent.object_permission.mcp_servers.join(", ")} @@ -250,35 +263,58 @@ const AgentInfoView: React.FC = ({ - {agent.agent_card_params?.skills && agent.agent_card_params.skills.length > 0 && ( -
- Skills - - {agent.agent_card_params.skills.map((skill: any, index: number) => ( - -
-
ID: {skill.id}
-
Description: {skill.description}
-
Tags: {Array.isArray(skill.tags) ? skill.tags.join(", ") : skill.tags}
- {skill.examples && skill.examples.length > 0 && ( -
Examples: {Array.isArray(skill.examples) ? skill.examples.join(", ") : skill.examples}
- )} -
-
- ))} -
-
- )} + {agent.agent_card_params?.skills && + agent.agent_card_params.skills.length > 0 && ( +
+

Skills

+ + {agent.agent_card_params.skills.map( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (skill: any, index: number) => ( + +
+
+ ID: {skill.id} +
+
+ Description: {skill.description} +
+
+ Tags:{" "} + {Array.isArray(skill.tags) + ? skill.tags.join(", ") + : skill.tags} +
+ {skill.examples && skill.examples.length > 0 && ( +
+ Examples:{" "} + {Array.isArray(skill.examples) + ? skill.examples.join(", ") + : skill.examples} +
+ )} +
+
+ ), + )} +
+
+ )} {/* Settings Panel (only for admins) */} {isAdmin && ( - +
- Agent Settings +

Agent Settings

{!isEditing && ( - setIsEditing(true)}>Edit Settings + )}
@@ -300,8 +336,8 @@ const AgentInfoView: React.FC = ({ )} - - Rate Limits +
+

Rate Limits

@@ -320,19 +356,26 @@ const AgentInfoView: React.FC = ({
- { - setIsEditing(false); - fetchAgentInfo(); - }}> + +
) : ( - Click "Edit Settings" to modify agent configuration. +

+ Click "Edit Settings" to modify agent + configuration. +

)}