Skip to content

agentHost: speed up subagent session enrichment (parallel load + memoized reconstruction)#322674

Open
DonJayamanne wants to merge 3 commits into
microsoft:mainfrom
DonJayamanne:agents/performance-improvement-sub-agents-ab67c900
Open

agentHost: speed up subagent session enrichment (parallel load + memoized reconstruction)#322674
DonJayamanne wants to merge 3 commits into
microsoft:mainfrom
DonJayamanne:agents/performance-improvement-sub-agents-ab67c900

Conversation

@DonJayamanne

@DonJayamanne DonJayamanne commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Why

Opening an agent session that used subagents (a parent agent that spawned helper "child" agents) was slow. To render the transcript, VS Code rebuilds the full conversation and groups each child's inner steps under its parent tool call. That rebuild was slow because:

  • the client loaded each subagent one at a time (sequentially), and
  • the backend rebuilt the entire parent conversation from scratch once per subagent — a session with 10 subagents re-parsed the whole event log 11 times.

What changed

  • A — Parallel subagent loading (client). agentHostSessionHandler now collects all subagent insertions across the whole history, dedupes child-state loads via a Map, and loads them in parallel (Promise.all) instead of sequentially.
  • B — Reconstruct once / memoization (backend). CopilotAgentSession memoizes the getEvents() + mapSessionEvents() result (_getMappedEvents), shared by getMessages, getSubagentMessages, and the new getSubagentSessions. The memo is invalidated whenever the persisted event log could change (user message, turn start/end, tool complete, subagent completed/failed, compaction, truncation, snapshot rewind) so it never serves stale turns for an active session.
  • C — Eager registration up-front (backend). New optional IAgent.getSubagentSessions() + IRestoredSubagentSession. During restoreSession, the dispatcher registers every discovered child session eagerly (reusing B's single reconstruction — no extra event-log reads), so the client's later per-child lookups are instant in-memory hits.
  • D — Correctness fix (client). _loadSubagentState now waits for both the child's session summary and its default-chat channel to hydrate before reading. After the multi-chat protocol split, turns live on the chat channel; awaiting only the session subscription read too early and silently produced zero inner steps.

Results

For a real 90-turn / 4-subagent session:

  • enrichment: ~2161 ms → ~53 ms
  • total click-to-displayed: ~5324 ms → ~2700 ms

Notes for reviewers

  • The memo is intentionally scoped to the resume/restore wave and dropped on any log-mutating event and on dispose; rejected reconstructions are not cached so the next caller retries.
  • getSubagentSessions is optional on IAgent; agents without subagents simply omit it.
  • Tests added: eager registration during parent restore (agentService.test.ts) and memoization + invalidation (copilotAgentSession.test.ts).

For #320303

Copilot AI review requested due to automatic review settings June 24, 2026 06:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes subagent session enrichment when reopening agent-host chat sessions by parallelizing child-session hydration on the client and eliminating repeated event-log reconstruction on the backend via memoization. It also adds an optional backend API to eagerly surface subagent child sessions during parent restore so subsequent client lookups hit in-memory state.

Changes:

  • Parallelize client-side subagent child-session loads during history enrichment and ensure both session + default-chat channels are hydrated before reading turns.
  • Memoize getEvents() + mapSessionEvents() in CopilotAgentSession, share it across parent/subagent lookups, and invalidate it on session log mutations.
  • Add optional IAgent.getSubagentSessions() and eagerly register restored subagent child sessions during parent restoreSession, with tests covering memoization and eager registration.
Show a summary per file
File Description
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts Collect subagent insertions across history, dedupe + parallelize child loads, and wait for both session and default-chat hydration before reading child turns.
src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts Add memoized reconstruction shared across message/subagent lookups, plus getSubagentSessions() for eager child discovery.
src/vs/platform/agentHost/node/copilot/copilotAgent.ts Implement optional getSubagentSessions() for Copilot sessions (skipping peer chats, subagent URIs, and provisional sessions).
src/vs/platform/agentHost/node/agentService.ts During restore, eagerly register subagent child sessions from agent-provided discovery to avoid per-child re-restore work.
src/vs/platform/agentHost/common/agentService.ts Introduce IRestoredSubagentSession and optional IAgent.getSubagentSessions().
src/vs/platform/agentHost/test/node/agentService.test.ts Add test ensuring parent restore eagerly registers subagent child state.
src/vs/platform/agentHost/test/node/copilotAgentSession.test.ts Add test for memoization across message/subagent lookups and invalidation on log change.

Copilot's findings

  • Files reviewed: 7/7 changed files
  • Comments generated: 1

Comment thread src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@DonJayamanne DonJayamanne requested a review from roblourens June 24, 2026 07:57
@DonJayamanne DonJayamanne marked this pull request as ready for review June 24, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants