diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/components/agent-detail.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/components/agent-detail.tsx new file mode 100644 index 00000000000..76d7d9477fc --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/components/agent-detail.tsx @@ -0,0 +1,123 @@ +"use client"; + +/** + * AgentDetail — /agents/{agent_id} landing view. + * + * Renders the Agent's identity card, a settings hand-off link to + * /settings/cloud-agents/ (G's territory), and the SessionList for + * this agent. + New Session opens the create dialog. + */ +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { Card, Empty, Tag, Typography, Button, Space, message } from "antd"; +import dayjs from "dayjs"; +import SessionList from "@/app/(dashboard)/agents/components/session-list"; +import NewSessionDialog from "@/app/(dashboard)/agents/components/new-session-dialog"; +import { getCloudAgent, listCloudSessions } from "@/lib/cloud-agents-client"; +import type { CloudAgent, CloudAgentSession } from "@/types/cloud-agents"; + +const { Title, Paragraph, Text } = Typography; + +interface AgentDetailProps { + agentId: string; + accessToken: string | null; +} + +export default function AgentDetail({ agentId, accessToken }: AgentDetailProps) { + const router = useRouter(); + const [agent, setAgent] = useState(null); + const [sessions, setSessions] = useState([]); + const [loading, setLoading] = useState(true); + const [showNewSession, setShowNewSession] = useState(false); + + useEffect(() => { + if (!accessToken) return; + let cancelled = false; + setLoading(true); + Promise.all([getCloudAgent(accessToken, agentId), listCloudSessions(accessToken, agentId)]) + .then(([a, s]) => { + if (cancelled) return; + setAgent(a); + setSessions(s); + }) + .catch((e: unknown) => { + if (!cancelled) { + const msg = e instanceof Error ? e.message : String(e); + message.error(`Failed to load agent: ${msg}`); + } + }) + .finally(() => { + if (!cancelled) setLoading(false); + }); + return () => { + cancelled = true; + }; + }, [accessToken, agentId]); + + return ( +
+ +
+
+ + ← All agents + + + {agent?.name ?? "Agent"} + + + {agent?.model && {agent.model}} + {agent?.last_activity_at && ( + + Last activity {dayjs(agent.last_activity_at).fromNow?.() ?? agent.last_activity_at} + + )} + +
+ + + + + + +
+ + {agent?.system_prompt && ( + + System prompt + {agent.system_prompt} + + )} + + + {sessions.length === 0 && !loading ? ( + + ) : ( +
+ setShowNewSession(true)} + /> +
+ )} +
+
+ + setShowNewSession(false)} + onCreated={(s) => { + setShowNewSession(false); + router.push(`/agents/${agentId}/sessions/${s.session_id}`); + }} + /> +
+ ); +}