feat(tui): subagent spawn observability overlay
Adds a live + post-hoc audit surface for recursive delegate_task fan-out. None of cc/oc/oclaw tackle nested subagent trees inside an Ink overlay; this ships a view-switched dashboard that handles arbitrary depth + width. Python - delegate_tool: every subagent event now carries subagent_id, parent_id, depth, model, tool_count; subagent.complete also ships input/output/ reasoning tokens, cost, api_calls, files_read/files_written, and a tail of tool-call outputs - delegate_tool: new subagent.spawn_requested event + _active_subagents registry so the overlay can kill a branch by id and pause new spawns - tui_gateway: new RPCs delegation.status, delegation.pause, subagent.interrupt, spawn_tree.save/list/load (disk under \$HERMES_HOME/spawn-trees/<session>/<ts>.json) TUI - /agents overlay: full-width list mode (gantt strip + row picker) and Enter-to-drill full-width scrollable detail mode; inverse+amber selection, heat-coloured branch markers, wall-clock gantt with tick ruler, per-branch rollups - Detail pane: collapsible accordions (Budget, Files, Tool calls, Output, Progress, Summary); open-state persists across agents + mode switches via a shared atom - /replay [N|last|list|load <path>] for in-memory + disk history; /replay-diff <a> <b> for side-by-side tree comparison - Status-bar SpawnHud warns as depth/concurrency approaches caps; overlay auto-follows the just-finished turn onto history[1] - Theme: bump DARK dim #B8860B → #CC9B1F for readable secondary text globally; keep LIGHT untouched Tests: +29 new subagentTree unit tests; 215/215 passing.
This commit is contained in:
@@ -12,16 +12,72 @@ export interface ActivityItem {
|
||||
}
|
||||
|
||||
export interface SubagentProgress {
|
||||
apiCalls?: number
|
||||
costUsd?: number
|
||||
depth: number
|
||||
durationSeconds?: number
|
||||
filesRead?: string[]
|
||||
filesWritten?: string[]
|
||||
goal: string
|
||||
id: string
|
||||
index: number
|
||||
inputTokens?: number
|
||||
iteration?: number
|
||||
model?: string
|
||||
notes: string[]
|
||||
status: 'completed' | 'failed' | 'interrupted' | 'running'
|
||||
outputTail?: SubagentOutputEntry[]
|
||||
outputTokens?: number
|
||||
parentId: null | string
|
||||
reasoningTokens?: number
|
||||
startedAt?: number
|
||||
status: 'completed' | 'failed' | 'interrupted' | 'queued' | 'running'
|
||||
summary?: string
|
||||
taskCount: number
|
||||
thinking: string[]
|
||||
toolCount: number
|
||||
tools: string[]
|
||||
toolsets?: string[]
|
||||
}
|
||||
|
||||
export interface SubagentOutputEntry {
|
||||
isError: boolean
|
||||
preview: string
|
||||
tool: string
|
||||
}
|
||||
|
||||
export interface SubagentNode {
|
||||
aggregate: SubagentAggregate
|
||||
children: SubagentNode[]
|
||||
item: SubagentProgress
|
||||
}
|
||||
|
||||
export interface SubagentAggregate {
|
||||
activeCount: number
|
||||
costUsd: number
|
||||
descendantCount: number
|
||||
filesTouched: number
|
||||
hotness: number
|
||||
inputTokens: number
|
||||
maxDepthFromHere: number
|
||||
outputTokens: number
|
||||
totalDuration: number
|
||||
totalTools: number
|
||||
}
|
||||
|
||||
export interface DelegationStatus {
|
||||
active: {
|
||||
depth?: number
|
||||
goal?: string
|
||||
model?: null | string
|
||||
parent_id?: null | string
|
||||
started_at?: number
|
||||
status?: string
|
||||
subagent_id?: string
|
||||
tool_count?: number
|
||||
}[]
|
||||
max_concurrent_children?: number
|
||||
max_spawn_depth?: number
|
||||
paused: boolean
|
||||
}
|
||||
|
||||
export interface ApprovalReq {
|
||||
|
||||
Reference in New Issue
Block a user