Skip to content

Delegate new-tab action blocks on synchronous terminal initialization #445

Description

@vanzue

Note

Architecture update (2026-07-24): #428 was superseded by #484. Terminal-action proposals now use a short-lived WTA CLI that connects directly to the owning Helper through a per-Helper named pipe; proposal payloads and state do not transit wta-master. This issue remains focused on delegate startup latency after the recommendation card is confirmed.

Summary

Confirming an open_and_send proposal with target=tab and destination=delegate can make Intelligent Terminal appear hung while the new tab is created. The recommendation proposal transport itself is not blocked; the delay occurs after card confirmation in the terminal-creation path.

Reproduction

  1. Open the Terminal Agent pane with Copilot configured as the delegate agent.
  2. Produce and confirm an open_and_send proposal with:
    • target=tab
    • destination=delegate
    • a non-empty prompt
  3. Observe that the card/new-tab transition pauses, then the new tab remains idle while a standalone Copilot process starts.

Observed timeline

From a Debug run on 2026-07-18:

open_and_send begin                 +0.000s
create_tab response                 +8.477s
new-tab agent-pane prewarm begins   +8.521s
new-tab agent-pane prewarm ends     +8.840s
standalone Copilot prompt hook      ~+29.9s

The hidden per-tab agent-pane prewarm took about 0.31 seconds and started only after create_tab returned, so it was not the source of the initial pause. The delegated copilot.exe -i ... process also paid a separate cold-start cost: about 26 seconds elapsed between process creation and its prompt-submit hook.

Root cause

The current path couples "the tab exists" with "the terminal child has synchronously initialized":

  1. tools/wta/src/coordinator.rs awaits ShellManager::wt_create_tab.
  2. wtcli new-tab calls the synchronous COM CreateTab method.
  3. src/cascadia/WindowsTerminal/TerminalProtocolComServer.cpp blocks on page.CreateProtocolTab(...).get().
  4. src/cascadia/TerminalApp/TerminalPage.Protocol.cpp creates the pane and then calls:
_tabContent.UpdateLayout(); // Force synchronous terminal initialization

The COM call therefore does not return until UI-thread terminal initialization has run. For a delegate action, the initial command is a new standalone agent CLI, so slow CLI startup is exposed directly in the card/new-tab UX.

This is independent of how recommendation proposals are transported or approved.

Potential solution

Phase 1: two-phase terminal creation

Separate terminal creation into Created and Ready states:

  1. Add a protocol fast/deferred creation path for create_tab and split_pane.
  2. Return session_id/tab_id after the pane is inserted, without forcing synchronous child-process initialization. A PID may be unavailable at this point; callers that need it can query later.
  3. Use the existing connection_state: connected event as the readiness signal.
  4. Update WTA coordinator behavior:
    • open and delegates using LaunchWithStartupPrompt: finish the card action as soon as the target is Created.
    • shell open_and_send using LaunchThenSend: wait asynchronously for Connected before sending input, replacing the fixed 700 ms sleep.
  5. Show explicit startup feedback such as Starting Copilot... while a delegate process is cold-starting.

This removes the UI-blocking portion without weakening target routing or sending input before a pane is ready.

Phase 2: eliminate delegate cold start

Route delegated work through the already-running wta-master agent CLI and create a new ACP session instead of launching a separate copilot.exe -i process. This is a larger architectural change, especially for panel targets, but would remove the remaining standalone CLI cold-start cost rather than merely making it non-blocking.

Acceptance criteria

  • Confirming a delegate new-tab card does not block the existing Terminal UI while the delegate process starts.
  • The new tab becomes visible without waiting for agent CLI initialization.
  • Startup-prompt delivery occurs exactly once.
  • Shell open_and_send waits for an explicit readiness signal rather than a fixed delay.
  • Existing trusted pane routing, configured delegate selection, close-on-exit behavior, tab/panel actions, and error reporting remain intact.
  • Logs distinguish Created, Connected, prompt-delivered, and delegate-ready timing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions