Skip to content

Improve agent pane startup and response latency - #830

Open
Hamza Usmani (hamza-usmani) wants to merge 1 commit into
mainfrom
hamza-usmani-agent-pane-latency-analysis
Open

Improve agent pane startup and response latency#830
Hamza Usmani (hamza-usmani) wants to merge 1 commit into
mainfrom
hamza-usmani-agent-pane-latency-analysis

Conversation

@hamza-usmani

Copy link
Copy Markdown
Collaborator

Summary

  • Add tiered WTA prewarming: retain the master, prewarm one policy-approved default provider, and materialize only the selected tab's speculative helper/session.
  • Let the helper render and accept one generation-bound queued prompt while ACP is still connecting.
  • Add Terminal Protocol 2.3 GetPromptContext / wtcli prompt-context, including bounded buffer-tail capture and explicit-pane safety.
  • Move PowerShell command recall off the prompt critical path with single-flight background caching.
  • Separate master-control clients from provider-bound helpers so session inspection cannot spawn duplicate agents.
  • Make host-agent availability asynchronous, policy-safe, generation-aware, and refresh FRE/Settings consumers safely.
  • Add correlated startup/prompt milestones, lifecycle regressions, deployed E2E coverage, and an engineering report in doc/specs/agent-pane-latency-results.md.

Benchmarks

Metric Before After Improvement
Healthy pane pre-warm to Connected 3,716 ms 3,248 ms p50 12.6% faster
Helper start to ACP session ready 2,983 ms p50 2,265 ms p50 24.1% faster
WTA overhead above direct Copilot ACP median 744 ms 276 ms 62.9% lower
Prompt terminal-context collection 230.6 ms p50 76.8 ms p50 66.7% faster
Prompt-context child processes 3 1 66.7% fewer
Blocking PowerShell recall on observed autofix 5,820 ms 0 ms awaited Removed from critical path
First editable helper frame Not instrumented 321 ms p50 Input available ~1,928 ms before session readiness
WTA children after visiting five tabs 6 2 66.7% fewer

The first Debug launch after deployment remained an 8.46-second outlier because wta.exe process startup itself took 4.3 seconds; subsequent trials stabilized at 3.17-3.37 seconds. Copilot/provider initialize and session/new remain the dominant steady startup cost.

Validation

  • WTA full explicit-target suite: 1,949 passed, 1 ignored, 0 failed
  • Explicit-target WTA build: passed
  • Full Debug Terminal/package build: passed
  • SharedWta: 43/43
  • Settings/policy: 31/31
  • ControlCore: 33/33
  • TerminalApp: 215/215
  • Terminal Protocol: 7/7
  • Agent availability: 5/5
  • Speculative helper: 5/5
  • Deployed E2E: 30 passed, 0 failed, 1 documented skip
  • Added release-checklist coverage: C288 - Background tabs do not pre-warm unused agent helpers

Full methodology, implementation contracts, lifecycle decisions, test mapping, and limitations are documented in the linked report.

Add tiered provider/helper prewarming, queued input while connecting, consolidated prompt context, non-blocking command recall, control-client isolation, and latency coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 4, 2026 00:59

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.

🔵 Needs a closer look

It is a large cross-cutting change spanning WTA orchestration, Terminal Protocol/COM surfaces, UI behavior, and process lifecycle management, so a final human review is needed despite strong test coverage.

Pull request overview

This PR targets end-to-end latency in the agent pane workflow by reducing unnecessary helper/session materialization, allowing one prompt to be accepted while ACP connects, consolidating prompt-context capture into a single Terminal Protocol call, and moving expensive PowerShell recall work off the prompt critical path.

Changes:

  • Introduces tiered prewarming (process master lease + default provider prewarm + selected-tab-only speculative helper/session) and adds generation-aware queued prompt dispatch while connecting.
  • Adds Terminal Protocol 2.3 GetPromptContext + wtcli prompt-context, including bounded tail capture via ReadBufferTail.
  • Makes host-agent availability + PowerShell command recall caching asynchronous/single-flight, and adds/updates unit + E2E coverage plus supporting docs.
File summaries
File Description
tools/wta/src/telemetry.rs Adds telemetry event for master default-provider prewarm completion.
tools/wta/src/slash_command_tests.rs Updates tests for new binding_generation field in AgentConnected.
tools/wta/src/shell/wt_channel/cli_channel.rs Adds get_prompt_context WTCLI routing + argument builder + tests.
tools/wta/src/shell/shell_manager.rs Adds wt_get_prompt_context wrapper calling get_prompt_context.
tools/wta/src/session_registry.rs Adds _meta.wta.connection_role for master-control clients + tests.
tools/wta/src/protocol/acp/turn_metrics.rs Removes prompt preview tracing from prompt timing metrics.
tools/wta/src/protocol/acp/prompt_builder.rs Logs terminal-context RPC timing; plumbs timing IDs into context request; updates mocks.
tools/wta/src/protocol/acp/mock_agent_tests.rs Updates rename-session dispatch tests to include binding_generation.
tools/wta/src/protocol/acp/client.rs Adds binding_generation wiring + stale binding guards; adjusts provider binding semantics.
tools/wta/src/master/session_mcp.rs Adds test helper for capability registry emptiness checks.
tools/wta/src/master/config.rs Extends master config with model + cloud model fields.
tools/wta/src/main.rs Plumbs new CLI fields into master config.
tools/wta/src/helper/runtime.rs Starts background command-recall prewarm; makes preflight non-blocking; logs first-frame timing.
tools/wta/src/command_recall.rs Reworks PowerShell recall to memory-only lookup with single-flight background refresh + TTL.
tools/wta/src/cli/sessions.rs Adds versioned “master-control” ACP init role stamping to avoid spawning agents.
tools/wta/src/app/turn_state.rs Adds Queued turn state for one visible prompt while connecting + tests.
tools/wta/src/app.rs Adds binding generation + queued prompt plumbing + reconnect/rekey durability + startup preflight obsolescence.
tools/wta/src/app_turn.rs Implements queue/dispatch/cancel/restore paths for queued prompts; adds reconnect interruption handling.
tools/wta/src/app_keys.rs Allows Enter while connecting (single queued prompt); Esc/Ctrl+C cancel queued prompt; improves timing log payload.
tools/wta/src/app_events.rs Adds TabSessionRekeyed event; gates AgentConnected by binding generation; dispatches queued prompt on connect/rekey.
tools/wta/src/app_contracts/event.rs Extends AppEvent with binding_generation and TabSessionRekeyed.
test/e2e/tests/Feature.AgentPaneInteraction.Tests.ps1 Adds E2E coverage for “background tabs do not prewarm helpers”; hardens /model picker assertion; updates cleanup test.
test/e2e/README.md Updates suite description and test count for AgentPaneInteraction.
src/tools/wtcli/main.cpp Adds prompt-context subcommand and protocol version gating helper.
src/host/proxy/ITerminalProtocol.idl Adds COM method GetPromptContext appended for vtable compatibility.
src/cascadia/WindowsTerminal/TerminalProtocolComServer.h Declares GetPromptContext COM method.
src/cascadia/WindowsTerminal/TerminalProtocolComServer.cpp Implements COM GetPromptContext, updates protocol version to 2.3, exposes capability name.
src/cascadia/ut_app/SharedWtaTests.cpp Adds unit tests for master lease/pane ownership and configuration tracking behavior.
src/cascadia/ut_app/ProtocolParsingTests.cpp Adds tests for prompt tail routing and metadata correctness.
src/cascadia/UnitTests_Control/ControlCoreTests.cpp Adds tests for ControlCore::ReadBufferTail.
src/cascadia/TerminalSettingsEditor/MainPage.cpp Forces host-agent availability invalidation + refresh on Settings startup.
src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.h Adds async refresh + list rebuild helpers for agent availability.
src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp Uses cached availability immediately + async refresh; rebuilds ACP agent list with policy-safe selection fallback.
src/cascadia/TerminalProtocol/TerminalProtocol.idl Adds PromptContext struct + GetPromptContext to the WinRT protocol surface.
src/cascadia/TerminalProtocol/ProtocolParsing.h Adds prompt capture routing + bounded tail building helpers.
src/cascadia/TerminalControl/TermControl.idl Adds ReadBufferTail to TermControl WinRT surface.
src/cascadia/TerminalControl/TermControl.h Declares ReadBufferTail.
src/cascadia/TerminalControl/TermControl.cpp Implements TermControl::ReadBufferTail.
src/cascadia/TerminalControl/ControlCore.idl Adds ReadBufferTail to ControlCore WinRT surface.
src/cascadia/TerminalControl/ControlCore.h Declares ControlCore::ReadBufferTail.
src/cascadia/TerminalControl/ControlCore.cpp Implements bounded buffer-tail capture in ControlCore.
src/cascadia/TerminalApp/TerminalPage.Protocol.cpp Adds TerminalPage::GetProtocolPromptContext implementation.
src/cascadia/TerminalApp/TerminalPage.idl Adds GetProtocolPromptContext to TerminalPage projection.
src/cascadia/TerminalApp/TerminalPage.h Adds prewarm/availability scheduling plumbing and protocol prompt-context declaration.
src/cascadia/TerminalApp/TabManagement.cpp Switches to active-tab-only speculative prewarm; fixes SharedWta pane release accounting via transferable one-shot token.
src/cascadia/TerminalApp/Tab.h Adds per-tab agent prewarm state tracker and APIs for speculative materialization/eviction/explicit-close suppression.
src/cascadia/TerminalApp/Tab.cpp Transfers SharedWta pane token across window drag; marks prewarm tracker used/explicitly closed.
src/cascadia/TerminalApp/SharedWta.h Adds process master lease ownership, configuration tracking, and one-shot pane reference token types.
src/cascadia/TerminalApp/SharedWta.cpp Implements lease/pane dual ownership, configuration tracking, and updated crash recovery semantics.
src/cascadia/TerminalApp/Pane.h Stores transferable SharedWta pane reference token on panes.
src/cascadia/TerminalApp/FreOverlay.h Adds agent availability refresh + updates FRE problem kinds.
src/cascadia/TerminalApp/FreOverlay.cpp Uses cached + refreshed agent availability; blocks saving when no valid selection; validates post-install refresh; hooks install gating.
src/cascadia/TerminalApp/AgentPaneDragStash.h Stashes transferable SharedWta token for drag; adds expiry/discard + one-shot release.
src/cascadia/LocalTests_TerminalApp/TabTests.cpp Adds tests for drag-stash discard/release behavior and explicit-close suppression.
src/cascadia/inc/FreAgentSetup.h Introduces helper functions for FRE availability + save/install decision logic.
src/cascadia/inc/AgentRegistry.h Adds policy-snapshot overloads for filtering builtin agent lists.
src/cascadia/inc/AgentPolicy.h Makes Reload() return snapshot; adds snapshot-aware IsAgentAllowed/policy configured helper.
src/cascadia/inc/AgentAvailability.h Adds generation-aware, single-flight cached host agent discovery with test hooks.
doc/specs/Multi-window-agent-pane.md Updates spec to reflect tiered prewarm and queued prompt behavior.
doc/specs/agent-pane-latency-results.md Adds engineering report with methodology, results, and limitations.
doc/release-check-list.md Adds new checklist item C288 with E2E mapping.
AGENTS.md Updates repo invariants to reflect tiered prewarm behavior.
Review details
  • Files reviewed: 68/68 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +173 to +192
fn prompt_context_args(params: &serde_json::Value) -> Vec<String> {
let source = params
.get("source_session_id")
.and_then(json_id_as_str)
.unwrap_or_default();
let fallback_lines = params
.get("fallback_lines")
.and_then(|value| value.as_u64())
.unwrap_or(24)
.to_string();
let mut args = vec![
"prompt-context".to_string(),
"--fallback-lines".to_string(),
fallback_lines,
];
if !source.is_empty() {
args.extend(["--source".to_string(), source]);
}
args
}
Comment thread src/tools/wtcli/main.cpp
Comment on lines +569 to +579
GUID source{};
const auto hasExplicitSource = !promptContextSource.empty();
if (hasExplicitSource)
{
source = GuidFromString(promptContextSource);
if (InlineIsEqualGUID(source, GUID{}))
{
exitCode = 1;
return;
}
}
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

check-spelling-bot Report

⚠️ Dictionary not found

Problems were encountered retrieving check dictionaries (cspell:npm/dict/npm.txt cspell:golang/dict/go.txt cspell:cpp/src/compiler-clang-attributes.txt cspell:powershell/dict/powershell.txt cspell:dotnet/dict/dotnet.txt cspell:gaming-terms/dict/gaming-terms.txt cspell:python/src/python/python.txt cspell:public-licenses/src/additional-licenses.txt cspell:elixir/dict/elixir.txt cspell:cpp/src/stdlib-cerrno.txt cspell:redis/dict/redis.txt cspell:clojure/src/clojure.txt cspell:public-licenses/src/generated/public-licenses.txt cspell:cpp/src/compiler-gcc.txt cspell:rust/dict/rust.txt cspell:scala/dict/scala.txt cspell:r/src/r.txt cspell:sql/src/tsql.txt cspell:software-terms/dict/softwareTerms.txt cspell:python/src/additional_words.txt cspell:cpp/src/compiler-msvc.txt cspell:svelte/dict/svelte.txt cspell:cpp/src/stdlib-cmath.txt cspell:node/dict/node.txt cspell:php/dict/php.txt cspell:python/src/common/extra.txt cspell:cpp/src/stdlib-c.txt cspell:cpp/src/stdlib-cpp.txt cspell:typescript/dict/typescript.txt cspell:monkeyc/src/monkeyc_keywords.txt cspell:cpp/src/template-strings.txt cspell:haskell/dict/haskell.txt cspell:cpp/src/lang-jargon.txt cspell:lua/dict/lua.txt cspell:dart/src/dart.txt cspell:ada/dict/ada.txt cspell:k8s/dict/k8s.txt cspell:docker/src/docker-words.txt cspell:java/src/java-terms.txt cspell:html/dict/html.txt cspell:css/dict/css.txt cspell:python/src/python/python-lib.txt cspell:cpp/src/ecosystem.txt cspell:cpp/src/people.txt cspell:fullstack/dict/fullstack.txt cspell:cpp/src/lang-keywords.txt cspell:ruby/dict/ruby.txt cspell:latex/dict/latex.txt cspell:sql/src/sql.txt cspell:shell/dict/shell-all-words.txt cspell:software-terms/dict/webServices.txt cspell:django/dict/django.txt cspell:swift/src/swift.txt cspell:java/src/java.txt).

⚠️ For more information, see check-dictionary-not-found.

🔴 Please review

See the 📂 files view, the 📜action log, 👼 SARIF report, or 📝 job summary for details.

Unrecognized words (3)

nnot
nsecond
reconnectable

These words are not needed and should be removed AHP aiu Backgrounder CANTCALLOUT Ccc cplusplus ctl Debian depl dotnet drv endptr EOFs evt frob frobnicate Fullwidth gitlab hdr idl IME inbox ININPUTSYNCCALL INJ intelligentterminal Ioctl KVM lbl lld lsb NODEFAULT NONINFRINGEMENT notif oss outdir Podcast pri prioritization rcv segfault SND sourced SWP Tbl testname transitioning unk unparseable unregisters Virt VMs webpage websites WINVER WSLENV xsi

To accept these unrecognized words as correct and remove the previously acknowledged and now absent words, you could run the following commands

... in a clone of the git@github.com:microsoft/intelligent-terminal.git repository
on the hamza-usmani-agent-pane-latency-analysis branch (ℹ️ how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c/apply.pl' |
perl - 'https://github.com/microsoft/intelligent-terminal/actions/runs/33823994500/attempts/1' &&
git commit -m 'Update check-spelling metadata'
Available 📚 dictionaries could cover words (expected and unrecognized) not in the 📘 dictionary

This includes both expected items (2103) from .github/actions/spelling/expect/alphabet.txt .github/actions/spelling/expect/expect.txt .github/actions/spelling/expect/web.txt and unrecognized words (3)

Dictionary Entries Covers Uniquely
cspell:csharp/csharp.txt 32 2 2
cspell:aws/aws.txt 232 2 2
cspell:fonts/fonts.txt 536 1 1

Consider adding to the extra_dictionaries array (in the .github/actions/spelling/config.json file):

    "cspell:csharp/csharp.txt",
    "cspell:aws/aws.txt",
    "cspell:fonts/fonts.txt",

To stop checking additional dictionaries, put (in the .github/actions/spelling/config.json file):

"check_extra_dictionaries": []

Forbidden patterns 🙅 (1)

In order to address this, you could change the content to not match the forbidden patterns (comments before forbidden patterns may help explain why they're forbidden), add patterns for acceptable instances, or adjust the forbidden patterns themselves.

These forbidden patterns matched content:

Should be preexisting
[Pp]re[- ]existing

Pattern suggestions ✂️ (1)

You could add these patterns to .github/actions/spelling/patterns/b361d91b25dda4b455a7f58ca04909c90f56bae3.txt:

# Automatically suggested patterns

# hit-count: 1 file-count: 1
# container images
image: [-\w./:@]+

Alternatively, if a pattern suggestion doesn't make sense for this project, add a # to the beginning of the line in the candidates file with the pattern to stop suggesting it.

Errors, Warnings, and Notices ❌ (3)

See the 📂 files view, the 📜action log, 👼 SARIF report, or 📝 job summary for details.

❌ Errors, Warnings, and Notices Count
ℹ️ candidate-pattern 1
⚠️ check-dictionary-not-found 54
❌ forbidden-pattern 1

See ❌ Event descriptions for more information.

✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

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