The tree view

The shape of a run — every call named with its status, decisions marked where they happened, redrawn in place as it grows.

4 min read
8 sections
Edit this page

The transcript reads like a colleague talking: prose is the content, work is a quiet receipt underneath. That is right when you are reading the answer.

Sometimes you want the opposite — the shape of the run:

text
Agent started

├─ Understanding request
│  Read the inbox, check the guest list, then save.

├─ Tool group: Read 2 files
│  ├─ read_file                                     completed   4ms
│  └─ read_file                                     completed   6ms

├─ Decision
│  Guest was not found. Create a new RSVP record.

├─ Approval required
│  Used Slack #events                               comms.send

└─ Final answer
   RSVP successfully recorded.

15,470 tokens · claude-opus-5

Same rows, same grouping, same verbs as the transcript — only the shape changes.

What it looks like

agent.run_live(prompt, style="tree") Live
Agent started
│
├─ Understanding request
│  Read the inbox, check the guest list, then save.
│
├─ Tool group: Read 2 files
│  ├─ read_file                                     completed   4ms
│  └─ read_file                                     completed   6ms
│
├─ Decision
│  Guest was not found. Create a new RSVP record.
│
├─ Approval required
│  Used Slack #events                               comms.send
│
└─ Final answer
   RSVP successfully recorded.
15,470 tokens · claude-opus-5

On a terminal this redraws in place: the trunk stays open — ├─ working… — until the run ends, and the finished tree replaces the draft exactly once.


Two ways to get one

python
# Live, in a terminal — redraws in place as the run proceeds
agent.run_live("Process the latest RSVP", style="tree")

# A finished run, as text
from shipit_agent.narrate import render_tree
print(render_tree(result.events, model="claude-opus-5"))

In a notebook, watch(agent, prompt, shape="tree") draws it in the live panel.


Live behaviour

On a terminal the tree redraws in place: the shape grows downward, statuses flip from running to completed where they stand, and the trunk stays open until the run ends:

text
├─ Tool group: Reading guests.csv
│  └─ read_file                                     running

├─ working…

Drawing the final corner early would claim the agent had finished. When the run closes, the draft is erased and the finished tree is written once, so your scrollback holds one clean copy rather than every intermediate frame.

Piped output never animates — it gets a single buffered write with no escape codes, so > run.txt is clean.

python
TreeRenderer(live=True)    # force in-place updates
TreeRenderer(live=False)   # force one buffered write

The row labels

LabelWhat it is
Understanding requestThe opening prose, before any tool ran — what the agent intends
DecisionProse between tool groups, or an agent_decision event
ObservedAn agent_observation event — what the tools returned
Tool groupA run of calls, each named with its status and duration
DelegatedA sub-agent's work, attributed to it
Approval requiredA queued side-effecting call
Connection neededThe agent asking you to connect something
ArtifactA file the run produced
Final answerThe last prose in the run

The deep tree

detail=True opens every call — what it was called with, and the first lines of what came back:

python
print(render_tree(result.events, detail=True, output_lines=6))
text
├─ Tool group: Searched for def summarize
│  └─ grep_files                                    completed  204ms
│     ↳ pattern='def summarize', path='shipit_agent'
│       shipit_agent/narrate/verbs.py:589:def summarize(name: str, …

output_lines=None shows every line, at the cost of the tree's compactness.


Alignment

Statuses sit at a fixed column, and nesting is accounted for — a row two levels deep starts further right, so without that the column would drift and the fixed column would be pointless. Colour never shifts it either: padding is computed on visible width, ignoring ANSI escapes.

On a terminal that cannot encode │├└─, the tree falls back to |+- rather than raising.


When to reach for it

  • Debugging — a tool that fired twice is obvious in a tree and invisible in prose.
  • Explaining — "here is what the agent did" pastes cleanly into a PR or a ticket.
  • Long autonomous runs — the live tree is a progress display that does not scroll away.

See also