feat(subagents): live child context window in subagent status - #271
Conversation
Children report provider usage once per response; publish it as a non-durable chat:subagent-context reading (tokens / model window) instead of a snapshot field, so strict snapshot parsers, revisions, durable writes and the Remote roster are unchanged. The subagents roster shows the percentage per active row and the detail pane shows used / window, reusing the #187 token formatting and 80% warning threshold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
ℹ️ Minor project-memory gap; no runtime issues found.
Reviewed changes I reviewed the commit adding live child context reporting to the desktop subagents panel.
- Usage transport. Child response usage is sent on the new non-durable
chat:subagent-contextnotification, leaving snapshots and durable writes unchanged. - Desktop display. A bounded renderer store filters to active runs; the roster and detail pane display the percentage and token counts with the 80% warning tone.
- Coverage and plan. Projector, parser, store, and rendering tests cover the new behavior, and the test registry and implementation plan are updated.
- Client scope. Remote, iOS, and Android remain unchanged, with live support documented as a follow-up.
ℹ️ The project-memory note is missing
The PR description claims .memory/subagent-live-context-window.md is included, but the file is absent from the branch diff and tracked tree. This leaves the implementation decisions and follow-ups out of the project memory required for changes of this kind.
Technical details
````markdown
Missing project-memory note
Affected sites
.memory/subagent-live-context-window.md— referenced in the PR description but absent from the branch.
Required outcome
- Add and commit a project-memory note covering the side-channel design and the documented follow-ups.
````
GPT Luna | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes I re-reviewed the delta since the prior pullfrog review (b254047): one commit, adding the project-memory note that review requested. No runtime code changed — git diff b254047..9516678 touches only the new .md file.
- Added
.memory/subagent-live-context-window.md. The note records the side-channel design, publish conditions, the 32 × 64 renderer bound, the 80% warning threshold, coverage locations, and the documented follow-ups. Every factual claim in it was verified against this diff:publishContextUsageskips finished runs and unknown windows and isolates observer throws; the store defaults are 32 chats × 64 runs with active-run gating; the threshold ispercent >= 80; and the store test is registered in thepackage.jsonscripts andscripts/ci-test-registry.json.
GLM Flash | 𝕏
# Conflicts: # .papercuts/troubleshooting.md # package.json # renderer/components/subagent-roster.tsx # scripts/ci-test-registry.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes I reviewed the delta since the prior Pullfrog review, including the upstream merge and its test-script conflict resolution.
- Merged upstream updates. Incorporated the upstream subagent roster/detail changes and preserved the union of both sides' entries in the root
testandtest:coveragescripts. - Recorded merge-train friction. Added papercut notes for workflow setup and cross-PR CI flakes.
GPT Luna | 𝕏
Hermes Review BotConfidence: 5 Engine: SummarySurfaces live child context-window usage in the subagents panel while child agents are running. Confidence Score: 5/5Fully traced the event pipeline from provider usage accounting in 📁 Important Files Changed
FindingsNo findings. 📊 Sequence DiagramsequenceDiagram
participant Child as Subagent Child Runtime
participant Projector as SubagentEventProjector
participant LLM as llm-client
participant Renderer as Preload & ContextUsageStore
participant UI as SubagentsPanel / Roster
Child->>Projector: usage(runId, assistantMessage)
Projector->>Projector: publishContextUsage(current, reportedTokens)
Projector->>LLM: onContextUsage(runId, usage)
LLM->>Renderer: sendGeneration("chat:subagent-context", payload)
Renderer->>Renderer: sharedStore.apply(payload)
Renderer->>UI: useSyncExternalStore listener trigger
UI->>UI: activeSubagentContextUsage(runs, readings)
UI->>UI: Render gauge & 80% warning tone
Machine-Readable Findings[]
|

Summary
While a child agent runs, the subagents panel now shows how full its context window is.
Context window: 84K / 200K tokens (42%).Source: pi-subagents #2448. This reuses the #187 context meter's
formatContextTokenCountand its 80% "approaching" threshold.Design
Figure.
tokensis the child's latest provider-reported usage total, the same number Pi treats as a response's context size.windowis the child model'scontextWindow. Nothing is published when the window is unknown or the provider reported nothing.Side channel, not a snapshot field. Readings go out on a new
chat:subagent-contextnotification, for these reasons:With the side channel, the snapshot, the revision and the durable writes all stay the same.
Changes
SubagentEventProjectoracceptscontextWindowandonContextUsage, and publishes on eachusage()call. It skips finished runs, and an observer that throws cannot break the run.llm-clientsends the readings throughsendGenerationonchat:subagent-context. That channel is allowlisted in the preload.renderer/shared/subagent-context-usage.tswith the types, strict parsers (safe run ids) and labels.renderer/lib/subagent-context-usage-store.ts: a bounded LRU (32 chats × 64 runs) exposed through auseSyncExternalStorehook.text-support-warning) and no borders.docs/plans/subagent-live-context-window-plan.mdand its row in the plan index,.memory/subagent-live-context-window.md, and papercuts.Tests
main/services/subagents/subagent-event-projector.test.ts(39 pass). Readings follow the latest response, including after the context shrinks. A zero report is skipped. The snapshot gains no field and no extra durable writes happen. Nothing is published after the run finishes or when there is no window. A throwing observer is isolated.renderer/lib/subagent-context-usage-store.test.ts: report conversion, labels and threshold, parser rejection, store reference stability and change notification, LRU eviction, and active-run gating.renderer/components/subagents-panel.test.tsx: the roster renders the percentage and spoken label on active rows, with the warning at 85% and nothing on done rows. The detail line renders when a reading exists.test,test:subagents,test:coverageandscripts/ci-test-registry.json.npm run type-check,npm run lint,npm run test:subagents(all pass),npm run test:ci:registry,main/handlers/ipc-contract.test.ts.Follow-ups
🤖 Generated with Claude Code