Fix subagent activity, opening, and completion state - #334986
Fix subagent activity, opening, and completion state#334986Justin Chen (justschen) wants to merge 4 commits into
Conversation
Recover failed child subscriptions through chat catalog discovery, keep restored subagent pills observable, and gate opening on resolved child chats. Preserve completed tool labels and surface missing-chat errors instead of blank editable editors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Catalog correlation and restored nested/cross-client subagent availability remain incorrect in supported scenarios.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 1
New issues introduced by this change (3)
| Severity | Finding |
|---|---|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts — The catalog projection drops origin.chat and later matches only toolCallId. Tool-call ids are… |
|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts — This new live-invocation path does not recover restored subagents contributed by another client.… |
|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts — Hard-coding serialized subagents as unavailable leaves restored nested subagents permanently hidden… |
What changed in this PR
Fixes subagent lifecycle synchronization, availability, activity labels, and missing-chat handling.
Changes:
- Recovers child chats through catalog discovery and subscription retries.
- Gates opening on resolved availability and improves completion/activity UI.
- Adds regression coverage for restore, failure, and delayed-start scenarios.
| File | Description |
|---|---|
chatSubagentContentPart.test.ts |
Tests pill state, visibility, and labels. |
stateToProgressAdapter.test.ts |
Tests initial availability metadata. |
agentHostChatContribution.test.ts |
Tests recovery, restoration, and load errors. |
chatService.ts |
Adds subagent chat availability metadata. |
chatSubagentOpenChat.css |
Hides unavailable pill actions. |
chatSubagentOpenChat.ts |
Gates opening on chat availability. |
chatSubagentContentPart.ts |
Improves completed and serialized activity rendering. |
stateToProgressAdapter.ts |
Preserves observable subagent invocations and availability. |
agentHostSessionHandler.ts |
Adds catalog recovery and subscription-error handling. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Scope child discovery to the spawning chat, restore cross-client and nested subagent availability, and adopt completed client snapshots without duplicate pills. Keep cancelled tools from showing success labels and preserve synchronous setup for already-hydrated child chats. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Separate rich pill visibility from chat navigation readiness, preserve activity after the launch tool completes, and keep unavailable output accessible. Cover the actual toolbar lifecycle and add dark/light fixtures for pending, running, and unavailable child chats. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Screenshot ChangesBase: 1 insignificant change(s) omitted (≤20 px, Δ≤2). See CI logs for details. Added (6) |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Post-hydration child subscription failures can leave subagent pills stale and incorrectly openable.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 1
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts — This marks the child permanently available after the first snapshot, but the subscription can enter… |
|
src/vs/workbench/contrib/chat/common/chatService/chatService.ts — The existing chatResource contract still says the URI is present only for a separately openable… |
Issues resolved since last review (3)
| Severity | Finding |
|---|---|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts — Hard-coding serialized subagents as unavailable leaves restored nested subagents permanently hidden… View resolved comment |
|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts — This new live-invocation path does not recover restored subagents contributed by another client.… View resolved comment |
|
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts — The catalog projection drops origin.chat and later matches only toolCallId. Tool-call ids are… View resolved comment |
Observe child subscription failures throughout the observation lifetime, clear stale activity and availability, release the failed observer, and allow subsequent catalog recovery. Clarify prospective chat resources and legacy undefined availability semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>



Summary
Fix subagent pills losing their connection to the child chat: tool activity remains stuck at "Working on it...", completed background agents still look busy, and opening a subagent can either do nothing or produce an empty editable chat.
The pill and the "Background agent ... is complete" notification represent the same delegated agent. The notification was arriving through the parent chat while the pill's child-chat subscription had already failed. This is a client-side lifecycle and presentation problem, not evidence that the agent had stopped doing work.
Findings from the debug exports
Two locally inspected debug bundles covered the missing-activity, blank-editor, and stale-completion cases. Raw logs, transcripts, machine paths, and session identifiers are intentionally not attached.
Delayed startup strands the parent pill
The reviewer session showed the following sequence on September 7, 2026 (times below are UTC):
taskcalls returned their launch acknowledgments; the parent began subscribing to their prospective child-chat URIs.AHP_NOT_FOUNDafter the 15-second pre-spawn wait.chat/turnCompleteimmediately afterward.Four reviewers completed in the captured interval; the fifth was still active. Opening a child could establish a fresh, working subscription, explaining why its transcript contained real tool calls while the parent pill remained stale.
There were two holes in recovery:
Errorvalue asynchronously._observeSubagentSessiononly had a synchronoustry/catch, so it left the failed observation registered and the pill marked active.ChatToolCallContentChangedfor completed tools, so the later discovery block cannot wake a tool-only observer. The session's chat catalog does publish the real child, but the observer was not using that catalog for discovery.Other presentation and restore gaps
Errorvalue. Not-found suppression was also broad enough to hide missing-child failures, and missing child state could fall back to editable interactivity.Relevant history
This is a combination of lifecycle assumptions rather than a single rendering-only change:
9603ef1ea5f)d5dd3ab6966)dcfc4269938)908ab0dc0b8)Fixes
Recover and track the actual child chat
Errorvalues through the existing logging and observation cleanup.Keep opening and completion tied to real state
isChatAvailablemetadata for provider-resolved availability, separately from the prospective resource URI.Show accurate activity and load failures
No SDK dependency bump, generated protocol change, new setting, or telemetry change is included.
Review follow-up
Commit
042e0ebd701addresses the three PR review threads and the two findings from the additional three-agent review:(origin.chat, origin.toolCallId)so reused tool IDs cannot redirect a pill to a sibling's child.Commit
892e443ecd7corrects a follow-up regression where the availability guard hid the entire rich pill and a completed background launch fell back to the legacy text header. Presentation now remains rich while child navigation is pending. Tests use the real toolbar/action view together, and new dark/light component fixtures cover pending, running, and unavailable states.Commit
0ae69d43141handles child subscription errors throughout the observation lifetime, not only during initial hydration. A later error clears availability and activity, freezes timing, releases the failed observer, and permits catalog-driven recovery. The metadata contract now explicitly distinguishes prospective resources from readiness and documents legacy behavior when availability is undefined.Validation
npm run typecheck-clientpassed.git diff --checkpassed.Regression coverage includes:
The affected suites cover
AgentHostChatContribution,AgentHostClientTools,stateToProgressAdapter,ChatSubagentContentPart,OpenSubagentChatActionViewItem, and the collapsed subagent history renderer.Manual follow-up
The exact reported sequence has been reproduced in automated regression tests, and the rich-header components have been validated in the integrated browser. The changes have not been manually replayed against a live SDK session in the reporter's installed Insiders window. Keeping this PR in draft for review and real-window confirmation.
Suggested verification: start background subagents with delayed startup; confirm pills become openable when the child chats resolve, show tool activity without opening the child first, stop showing busy state when the corresponding background-completion notification arrives, and remain correct after reopening the parent chat.