Skip to content

Conversation Agent Timeline draws nested agents as siblings; trace AI Spans tab does not #121777

Description

@sergical

What is wrong

In a conversation's Agent Timeline, an agent that is called by another agent is drawn at the same level as its caller, and its child spans are not next to it. The trace drawer's AI Spans tab draws the same spans correctly.

Agent Activity (Explore) Agent Timeline (Conversation)
Image Image

A review agent calls two subagents. The spans form this tree:

invoke_agent ReviewLead
├─ execute_tool read_diff
├─ invoke_agent correctness-reviewer
│   └─ chat claude-haiku-4.5
├─ execute_tool mcp__sentry__search_issues
└─ invoke_agent style-reviewer
    └─ chat claude-haiku-4.5

The Agent Timeline draws both subagents next to each other, then both chat rows below them. correctness-reviewer looks like it made no model call, and the lead's mcp__sentry__search_issues call looks like it belongs to style-reviewer.

The span data is correct. The parent span links form the tree above.

Why

Both views render with the same component, AiSpanTimeline. They differ in how the node list is ordered.

The trace drawer walks the trace tree, so the array is in depth-first order — an agent is always followed by its own descendants (useAITrace.tsx#L99-L109):

const flattenedNodes = tree.root.findAllChildren<AITraceSpanNode>();

The conversation view sorts by start time instead (useConversation.tsx#L304):

transformedNodes.sort((a, b) => (a.startTimestamp ?? 0) - (b.startTimestamp ?? 0));

Parallel subagents start at nearly the same moment, so their rows sort together and each subagent's children are separated from it.

Indentation cannot recover the grouping, because it is a boolean (aiSpanTimeline.tsx#L66-L95):

const shouldIndent = aiRunNode && aiRunNode !== node;
<TimelineRow indent={shouldIndent ? 1 : 0}  />

Every span whose gen_ai.operation.type is agent gets indent 0, and everything else gets 1. A row cannot show which agent it belongs to, or how deep it is.

Proposed fix

  1. Order the conversation's nodes depth-first from the root, as the trace drawer does, instead of by start time. This alone fixes the reported case.
  2. Pass the number of agent ancestors as indent instead of 0 or 1. This is needed for agents nested more than one level deep, in either view.

findParent already returns the true parent, so no new span data is needed.

Reproduce

Run any agent that delegates to a subagent, then compare the conversation's Agent Timeline with the same trace's AI Spans tab. Example conversation: https://sentry-developer-experience.sentry.io/explore/agents/conversations/conv_01KZS2YRTJ52HADYA8F9P1BKSB/

Metadata

Metadata

Assignees

Projects

Status
Waiting for: Support

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions