feat(subagents): the delegation tree had no data source at all - #19
Merged
Conversation
Delegating produced one row and nothing else: `/agents` said "No
subagents this turn" for the whole session, the busy line never showed a
delegation, and spawn history stayed empty. The bridge emitted no subagent
events — the word does not appear in it — so every surface the TUI already
ships for delegation was drawing an empty list.
The harness publishes the whole lifecycle. `subagent/start` and
`subagent/end` carry the child's session id and terminal outcome, and the
child's own session log rides the same bus: its `subagent/descriptor`
names the delegation, its `tool/call`s are its work, its
`assistant/message`s carry its usage. Translating those gives the tree
everything it draws.
Correlation is keyed on the child's session id, never on arrival order.
The harness's own guidance tells a model to start independent delegations
together in one message, so pairing a child with its call by order would
attribute one delegation's work to another the moment two run at once. A
session the bridge was never told is a child is ignored outright, so a
sibling top-level session on the same bus cannot leak into this
transcript.
The row the tree hangs from also had to be recognizable. Both the inline
tree and the `(/agents to monitor)` hint tested `label.startsWith('Delegate
Task')` — upstream's tool name, which the harness does not use. That
vocabulary now lives with the rest of it in domain/toolBrief, covering
Agent/Task/Delegate Task and the harness's subagent/subagent_fork.
Live capture, `/agents` while a child works:
Spawn tree d1 · 1 agent · 1 tool · ⚡1 █ · inherit×1
#1 ● List the sources
depth · 0 · running
tools · 1 (subtree 1)
▾ Tool calls (1)
· Bash(sleep 20 && ls -1 src | head -3)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Delegating produced one row and nothing else.
/agentssaid "No subagents this turn" for the whole session, the busy line never showed a delegation, spawn history stayed empty. The bridge emitted no subagent events — the word does not appear in it — so every delegation surface the TUI already ships was drawing an empty list.Live capture,
/agentsopened while a child is working:Where the data comes from
The harness publishes the whole lifecycle, and the instrumented run confirms every edge:
subagent/start/subagent/end— the child's session id and its terminal outcomesubagent/descriptornames the delegation, itstool/calls are its work, itsassistant/messages carry its usageCorrelation is by child session id, never arrival order
The harness's own guidance tells a model to "start independent delegations together in one assistant message", so pairing a child with its call by order would attribute one delegation's work to another the moment two run at once. The child's id appears on both lifecycle edges and on every event its session emits, so nothing is guessed.
A session the bridge was never told is a child is ignored outright — a sibling top-level session on the same bus cannot leak into this transcript. There is a test for exactly that.
The row the tree hangs from
Both the inline tree and the
(/agents to monitor)hint testedlabel.startsWith('Delegate Task')— upstream's tool name, which the harness does not use. That vocabulary now lives with the rest of it indomain/toolBrief, covering Agent / Task / Delegate Task and the harness'ssubagent/subagent_fork.Test
npm run typecheck,npm test— 150 files / 1935 passingnode scripts/verify-boundary.mjssubagent_workinggallery scenario + a--liveflag, so the tree can be captured mid-flight@deepseek-ai/dsh-subagentis added as a type-only devDependency, the same waydsh-plan-modealready is — it activates the lifecycleEventsand thesubagent/descriptorsession-event augmentation.🤖 Generated with Claude Code