Agent Tree
ProThe shape of a multi-agent run: who handed work to whom, what each agent is on, where the run is stuck and what it has cost so far.
Batch of 50 invoices
- Needs youInvoice runWaiting on the supplier checkLead5m 12s$0.08
- RunningCaptureReading invoice 32 of 50OCR4m 58s$0.40
- DoneSplit pagesSplit 50 PDFs into 74 pages47s$0.04
- RunningLine itemsExtracting lines from invoice 324m 10s$0.21
- Done
- Needs youGuardBank details changed for one supplierPolicy4m 00s$0.12
- DoneDuplicatesNo duplicate invoices39s$0.03
- Needs youSupplier checkApprove the new IBAN from Papelería Tramuntana3m 20s$0.05
- Done
- RunningMatcherMatching invoices to purchase orders3-way match3m 00s$0.18
- RunningPO lookupFound 30 purchase orders3m 00s$0.06
- Running
- Running
Installation#
Usage#
The tree draws what you give it and fetches nothing. Keep your run in state, from polling, a socket or a stream, and render one node per agent, nesting the agents each one started.
The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.
Have a license? Unlock it here
Anatomy#
import {
AgentTree,
AgentTreeHeader,
AgentTreeTitle,
AgentTreeSummary,
AgentTreeCount,
AgentTreeContent,
AgentTreeNode,
AgentTreeNodeCard,
AgentTreeNodeHead,
AgentTreeNodeMark,
AgentTreeNodeName,
AgentTreeNodeKind,
AgentTreeNodeStatus,
AgentTreeNodeTask,
AgentTreeNodeMeta,
AgentTreeNodeSources,
AgentTreeNodeElapsed,
AgentTreeNodeCost,
AgentTreeChildren,
} from "@/components/ui/agent-tree"Org chart#
With layout="org" the agents hang below the one that started them, joined by lines. When the tree is wider than its container it scrolls inside itself instead of pushing the page.
Customer ledger migration
- RunningLedger moveMoving the customer ledger to the new clusterLead19m 00s$0.64
- RunningSchemaMapping 14 tables, 9 doneMapping13m 40s$0.91
- DoneColumnsWidened 6 amount columnsTypes4m 20s$0.07
- RunningIndexesRebuilding the invoice indexTuning5m 00s$0.05
- Done
- Needs youBackfillApprove writing 2.1M rowsWrites10m 10s$0.33
- IdleVerifyStarts after the backfillChecks0s
- Running
Layout#
The default, auto, works out how wide the org chart would be and uses it only while it fits. Narrow the window and the same run turns into an indented outline with guide lines, so a sidebar or a phone never scrolls sideways.
Support triage
- RunningTriage120 tickets, 84 sortedLead9m 00s$0.22
- DoneClassifierTagged 120 tickets3m 40s$0.09
- RunningRefundsDrafting 12 refund repliesDrafts5m 00s$0.31
- RunningOrder lookupReading order #204182m 00s$0.04
- Running
- FailedEscalationsLost access to the on-call rota2m 30s$0.11
- Done
Outline#
The outline fits a side panel. The guide line leaves each parent from under its mark, and compact density tightens the cards for a dense app shell.
- RunningTriage120 tickets, 84 sortedLead9m 00s$0.22
- DoneClassifierTagged 120 tickets3m 40s$0.09
- RunningRefundsDrafting 12 refund repliesDrafts5m 00s$0.31
- RunningOrder lookupReading order #204182m 00s$0.04
- Running
- FailedEscalationsLost access to the on-call rota2m 30s$0.11
- Done
Folding#
A folded branch keeps reporting: its toggle rolls up the state of every agent under it, so a sub-agent that needs you still shows. Click the toggle, or press Left and Right on a focused agent.
- RunningLedger moveMoving the customer ledger to the new clusterLead19m 00s$0.64
- RunningSchemaMapping 14 tables, 9 doneMapping13m 40s$0.91
- DoneColumnsWidened 6 amount columnsTypes4m 20s$0.07
- RunningIndexesRebuilding the invoice indexTuning5m 00s$0.05
- Done
- Needs youBackfillApprove writing 2.1M rowsWrites10m 10s$0.33
- IdleVerifyStarts after the backfillChecks0s
- Running
States#
The same five states as Agent Monitor. Only a running agent pings and only one that needs you blinks and turns its card amber, so the eye goes where it is needed.
- RunningCaptureReading invoice 32 of 50
- Needs youSupplier checkApprove the new IBAN
- FailedBank feedThe bank refused the token
- IdleReconcileStarts after the match
- DoneDuplicatesNo duplicate invoices
API reference#
AgentTree
The run and the context every part reads. It counts the agents it holds, so the summary and the folded branches add themselves up. Every part accepts className, merged last.
| Prop | Type | Default | Description |
|---|---|---|---|
| layout | "auto" | "org" | "outline" | "auto" | org hangs agents below the one that started them, outline indents them in a column, and auto uses org only while it fits the container. |
| value | string | - | The selected agent, when you control it. Setting value, defaultValue or onValueChange makes the cards selectable. |
| defaultValue | string | - | The agent selected on the first render. |
| onValueChange | (value: string) => void | - | An agent was picked with a click, Enter or Space. |
| now | number | - | The current time in epoch milliseconds. Pass it when your runtime owns the clock; otherwise running timers share one internal clock. |
| formatCost | (value: number) => string | $0.00 | Formats every cost, on the cards and in the summary. |
| labels | Partial<AgentTreeLabels> | - | Replaces the status names and the summary words, to translate them. |
| variant | "card" | "plain" | "card" | A framed surface, or no chrome for a full page. |
| density | "comfortable" | "compact" | - | Card padding and spacing. Reads DensityProvider when unset. |
AgentTreeSummary
Agents, running, needing you, failed and the total cost, counted from the nodes. The figures roll when they change. Children replace the counts, for instance with your own AgentTreeCounts.
| Prop | Type | Default | Description |
|---|---|---|---|
| cost | boolean | true | Shows the total of every AgentTreeNodeCost. |
AgentTreeCount
One figure of the summary. Children replace the label.
| Prop | Type | Default | Description |
|---|---|---|---|
| count* | number | - | The figure, in tabular numerals. |
| status | "working" | "waiting" | "idle" | "done" | "failed" | - | Adds the status dot and its default label. |
AgentTreeContent
The tree itself (role="tree") and the box layout="auto" measures. In org it scrolls sideways inside itself rather than overflow the page. Arrow keys move between agents, Right opens a branch and Left folds it. Name it with aria-label.
AgentTreeNode
One agent (role="treeitem"). Holds its AgentTreeNodeCard and, when it started others, an AgentTreeChildren.
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | string | - | A unique id within the tree. |
| status | "working" | "waiting" | "idle" | "done" | "failed" | "idle" | Tones the card and its mark, and is read out by a screen reader. |
| defaultOpen | boolean | true | Whether its branch starts open. |
| open | boolean | - | The branch state, when you control it. |
| onOpenChange | (open: boolean) => void | - | The branch was folded or opened. |
AgentTreeNodeCard
The card of an agent. A node with children grows a fold toggle on its lower edge, showing the count when open and a roll-up such as "1 needs you, 2 running" when folded.
AgentTreeNodeMark
A square for the agent's icon, with a status dot on its corner. A running agent gets a ring.
AgentTreeNodeStatus
The status as a word. Needs you and Failed turn into a tinted badge so they stand out. Children replace the label.
AgentTreeNodeTask
The one line that says what the agent is on. A new task slides in where the old one was.
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | string | - | The current task. |
AgentTreeNodeElapsed
How long the agent has run, in tabular numerals.
| Prop | Type | Default | Description |
|---|---|---|---|
| since | number | - | Start time in epoch milliseconds. Ticks until until is set. |
| until | number | - | Stops the timer at this time. |
| value | number | - | A duration in milliseconds you already have, in place of since. |
AgentTreeNodeCost
What the agent has cost so far, formatted by formatCost. It also feeds the summary total.
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | number | - | The amount. |
AgentTreeNodeSources
A row of small icons for the tools or sources the agent is using.