From d989f93144204a3f6cab4485984bb9a65a3b9c30 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 30 Sep 2026 00:40:12 -0700 Subject: [PATCH] feat(ui): add agent traces section with setup card fallback --- .../TraceView/AgentTracesSection.tsx | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 ui/litellm-dashboard/src/components/view_logs/TraceView/AgentTracesSection.tsx diff --git a/ui/litellm-dashboard/src/components/view_logs/TraceView/AgentTracesSection.tsx b/ui/litellm-dashboard/src/components/view_logs/TraceView/AgentTracesSection.tsx new file mode 100644 index 00000000000..3e9eb82d4fe --- /dev/null +++ b/ui/litellm-dashboard/src/components/view_logs/TraceView/AgentTracesSection.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { useState } from "react"; + +import { Button } from "@/components/ui/button"; +import { ButtonGroup } from "@/components/ui/button-group"; + +import { AgentTracesTable } from "./AgentTracesTable"; +import { TraceDrawer } from "./TraceDrawer"; +import { TracingSetupCard } from "./TracingSetupCard"; +import { useAgentTraces } from "./useAgentTraces"; + +export type LogsView = "all" | "traces" | "llm"; + +const VIEWS: { id: LogsView; label: string }[] = [ + { id: "all", label: "All" }, + { id: "traces", label: "Agent traces" }, + { id: "llm", label: "LLM requests" }, +]; + +export function LogsViewSwitch({ value, onChange }: { value: LogsView; onChange: (view: LogsView) => void }) { + return ( + + {VIEWS.map((view) => ( + + ))} + + ); +} + +interface AgentTracesSectionProps { + view: LogsView; + accessToken: string; + isActive: boolean; + startTime: string; + endTime: string; + isCustomDate: boolean; + isLiveTail: boolean; + /** Open the request-log drawer for a LiteLLM request id (from a span's LiteLLM request card). */ + onOpenRequestLog: (requestId: string) => void; +} + +/** + * Agent trace rows for the Logs page. In "Agent traces" it is the whole list (or the + * setup card on 501); in "All" the current trace page sits above the request logs. + */ +export function AgentTracesSection({ + view, + accessToken, + isActive, + startTime, + endTime, + isCustomDate, + isLiveTail, + onOpenRequestLog, +}: AgentTracesSectionProps) { + const [openTrace, setOpenTrace] = useState<{ traceId: string; spanId: string | null } | null>(null); + const traces = useAgentTraces({ + accessToken, + startTime, + endTime, + isCustomDate, + isLiveTail, + enabled: isActive && view !== "llm", + }); + + if (view === "llm") return null; + + const handleOpenRequestLog = (requestId: string) => { + setOpenTrace(null); + onOpenRequestLog(requestId); + }; + + return ( + <> + {view === "traces" && traces.notEnabledDetail !== null && } + {traces.notEnabledDetail === null && ( + setOpenTrace({ traceId, spanId: spanId ?? null })} + compact={view === "all"} + /> + )} + setOpenTrace(null)} + onOpenRequestLog={handleOpenRequestLog} + /> + + ); +}