getsentry / getsentry/sentry

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

Open
#121,777 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Product Area: Explore Spans
Dominant language
Python
Stars
44.8k
Forks
4.9k
Avg merge
21h 23m
Merged PRs (30d)
607

Description

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/

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with useConversation.tsx around L304 and useAITrace.tsx around L99-L109 to compare node ordering, then inspect aiSpanTimeline.tsx around L66-L95 for indentation. Reproduce with an agent that delegates to subagents and compare the conversation Agent Timeline with the trace drawer; done means nested agents and their child spans remain grouped at the correct depth.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.