From cd163d5886601ef3a434bec9e981e5ff101586bd Mon Sep 17 00:00:00 2001 From: moe-berri Date: Tue, 6 Oct 2026 11:55:17 -0700 Subject: [PATCH] style(lens): format native actor conversation handling --- .../detail/conversation/conversation.test.ts | 23 +++++++++++++++---- .../detail/conversation/conversation.ts | 19 ++++++++++----- .../src/components/lens/traces/utils.ts | 3 ++- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.test.ts b/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.test.ts index b9c88927dae..43369905fbf 100644 --- a/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.test.ts +++ b/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.test.ts @@ -616,11 +616,18 @@ describe("coding sessions", () => { }); }); - it("keeps explicit native actors separate across workflow branches and background resumes", () => { const span = (id: string, actor: string, parentActor: string | null, offset: number): Span => ({ - ...root, span_id: id, name: "claude_code.llm_request", type: "llm", framework: "claude-code", - parent_span_id: "root", actor_id: actor, parent_actor_id: parentActor, agent: "general-purpose", start_offset_ms: offset, + ...root, + span_id: id, + name: "claude_code.llm_request", + type: "llm", + framework: "claude-code", + parent_span_id: "root", + actor_id: actor, + parent_actor_id: parentActor, + agent: "general-purpose", + start_offset_ms: offset, }); const spans = [ { ...root, framework: "claude-code", actor_id: "root-actor", parent_actor_id: null, agent: "claude-code" }, @@ -635,6 +642,12 @@ it("keeps explicit native actors separate across workflow branches and backgroun const groups = groupConversation(items, spans); const branches = groups.filter((group) => group.kind === "branch"); expect(branches.map((group) => group.id)).toEqual(["actor-one", "actor-two"]); - expect(branches[0].children.map((group) => group.kind === "branch" ? group.id : group.item.span.span_id)).toEqual(["first", "actor-three", "resumed"]); - expect(items.filter((item) => ["first", "resumed"].includes(item.span.span_id)).map((item) => item.agentName)).toEqual(["general-purpose (1)", "general-purpose (1)"]); + expect(branches[0].children.map((group) => (group.kind === "branch" ? group.id : group.item.span.span_id))).toEqual([ + "first", + "actor-three", + "resumed", + ]); + expect( + items.filter((item) => ["first", "resumed"].includes(item.span.span_id)).map((item) => item.agentName), + ).toEqual(["general-purpose (1)", "general-purpose (1)"]); }); diff --git a/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.ts b/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.ts index 67edfe862d2..945ed273a35 100644 --- a/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.ts +++ b/ui/litellm-dashboard/src/components/lens/traces/detail/conversation/conversation.ts @@ -223,7 +223,10 @@ function conversationBranch(span: Span, byId: ReadonlyMap): string } function agentIdentity(span: Span, details: ReadonlyMap): string { - return span.actor_id || (isNativeAgent(span) ? span.span_id : details.get(span.span_id)?.attributes["gen_ai.agent.id"] || span.span_id); + return ( + span.actor_id || + (isNativeAgent(span) ? span.span_id : details.get(span.span_id)?.attributes["gen_ai.agent.id"] || span.span_id) + ); } function agentLabels(agents: readonly Span[], details: ReadonlyMap): ReadonlyMap { @@ -327,7 +330,9 @@ export function buildConversation( }; if (combined.length || item.showError) items.push(item); } - const byBranch = new Map([...spans].sort((a, b) => b.start_offset_ms - a.start_offset_ms).map((span) => [branch(span), span])); + const byBranch = new Map( + [...spans].sort((a, b) => b.start_offset_ms - a.start_offset_ms).map((span) => [branch(span), span]), + ); const agents = [...new Set(conversationSteps(spans).map(branch))].flatMap((id) => { const span = byId.get(id) ?? byBranch.get(id); return span ? [span] : []; @@ -342,9 +347,10 @@ export function buildConversation( .map((item) => ({ ...item, agentId: actor(branch(item.span)), - agentName: item.span.framework === "claude-code" && item.span.actor_id === null - ? "Unassigned" - : labels.get(actor(branch(item.span))) || item.span.agent, + agentName: + item.span.framework === "claude-code" && item.span.actor_id === null + ? "Unassigned" + : labels.get(actor(branch(item.span))) || item.span.agent, branchId: branch(item.span), parentBranchId: (() => { if (item.span.actor_id) return item.span.parent_actor_id || undefined; @@ -367,7 +373,8 @@ export function groupConversation(items: readonly ConversationItem[], spans: rea const parentById = new Map( conversationSteps(spans).flatMap((span) => { if (span.actor_id) return [[span.actor_id, span.parent_actor_id || undefined] as const]; - if (span.framework === "claude-code" && span.actor_id === null) return [[conversationBranch(span, byId), undefined] as const]; + if (span.framework === "claude-code" && span.actor_id === null) + return [[conversationBranch(span, byId), undefined] as const]; const branch = byId.get(conversationBranch(span, byId)); if (!branch) return []; const parent = branch.parent_span_id ? byId.get(branch.parent_span_id) : undefined; diff --git a/ui/litellm-dashboard/src/components/lens/traces/utils.ts b/ui/litellm-dashboard/src/components/lens/traces/utils.ts index 760b5f64bab..3bebfae07f5 100644 --- a/ui/litellm-dashboard/src/components/lens/traces/utils.ts +++ b/ui/litellm-dashboard/src/components/lens/traces/utils.ts @@ -113,7 +113,8 @@ export function errorSource(span: Span): ErrorSource | null { type GroupOrSpan = Span | { group: Span[] }; -const groupKey = (span: Pick): string => `${span.actor_id ?? span.agent}|${span.name}|${span.type}`; +const groupKey = (span: Pick): string => + `${span.actor_id ?? span.agent}|${span.name}|${span.type}`; /** Siblings sharing agent + name + type fold into one group once there are enough of them (or enough failures). */ function groupChildren(children: readonly Span[]): GroupOrSpan[] {