Skip to content

Make recommendation pane routing host-owned - #534

Open
vanzue wants to merge 2 commits into
mainfrom
dev/vanzue/host-owned-pane-routing
Open

Make recommendation pane routing host-owned#534
vanzue wants to merge 2 commits into
mainfrom
dev/vanzue/host-owned-pane-routing

Conversation

@vanzue

@vanzue vanzue commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • capture the authoritative source pane used to assemble each planner prompt
  • bind send and panel actions to that host-owned target at the executor boundary
  • remove model-owned pane IDs from the planner prompt and reject target-requiring actions when no host target exists
  • preserve routing across focus changes, tab renames, autofix, and manual /fix

Root cause

The planner prompt asked the model to return parent, and its JSON example hard-coded "parent": "10". The parser accepted that non-empty value and passed it unchanged to wtcli, even though pane addressing requires a WT session GUID.

Tests

  • cargo test --manifest-path tools\wta\Cargo.toml (1221 passed)

Capture the source pane used to build each prompt and force recommendation actions to use that host-resolved target instead of model-generated pane IDs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d9186409-ee54-4e89-8a75-51e00eacaf2f
Copilot AI review requested due to automatic review settings July 31, 2026 08:14

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 makes recommendation execution routing host-owned by capturing the authoritative target pane used when assembling a planner prompt, then binding send / panel actions to that host-resolved target at execution time (instead of trusting model-provided pane IDs like "parent": "10").

Changes:

  • Capture and persist a per-turn target_pane_id (resolved from Terminal Context) and plumb it through prompt building + app turn state.
  • Bind/override action targets at the executor boundary (bind_choice_target) and reject target-requiring actions when no host target is available.
  • Update the planner prompt guidance to omit model-owned parent fields, and extend tests to cover host-owned target behavior.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tools/wta/src/ui/chat.rs Updates test fixtures for the new SubmittedPrompt.target_pane_id field.
tools/wta/src/protocol/acp/prompt_context.rs Refactors planner terminal context building to return both JSON + authoritative target pane; plumbs this into provider context.
tools/wta/src/protocol/acp/prompt_builder.rs Includes injected planner terminal context in prompt assembly and returns a resolved target pane for turn binding.
tools/wta/src/protocol/acp/client.rs Emits AppEvent::PromptTargetResolved to bind the authoritative target pane to the matching turn.
tools/wta/src/coordinator.rs Adds ChoiceExecution.target_pane_id and introduces bind_choice_target to override/reject target-requiring actions at execution time.
tools/wta/src/app/turn_state.rs Adds SubmittedPrompt.target_pane_id to persist the host-resolved target associated with a prompt.
tools/wta/src/app/autofix.rs Ensures autofix-submitted prompts carry the authoritative pane target and execution passes it to the coordinator.
tools/wta/src/app.rs Renames and broadens the target-binding event handling (PromptTargetResolved) and binds targets by prompt id (robust across tab renames).
tools/wta/src/app_turn.rs Stops filtering recommendation sets by model-provided coordinator targets; execution now relies on host binding.
tools/wta/src/app_tests.rs Updates fixtures and adds coverage for /fix and prompt target binding behavior.
tools/wta/src/app_keys.rs Ensures planner prompts carry the captured source pane session id for stable routing across focus changes.
tools/wta/src/app_events.rs Routes PromptTargetResolved to the new binding handler.
tools/wta/src/app_contracts/event.rs Renames the event variant to PromptTargetResolved.
tools/wta/prompts/terminal-agent.md Updates planner instructions/examples so the model omits parent; host binds to captured activeTarget.

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

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (1)

tools/wta/src/protocol/acp/prompt_context.rs:311

  • build_terminal_context always falls back to resolve_pane_by_session_id when pane_context.source_pane_id is present. That helper enumerates windows/tabs/panes, which is significantly more expensive than wt_get_active_pane() and will now run for most planner prompts (since source_pane_id is set at submission). Consider short-circuiting when the current active pane already matches the captured source_pane_id, and only doing the full enumeration when focus actually changed.
    let active = match pane_context.and_then(|context| context.source_pane_id.as_deref()) {
        Some(source) => resolve_pane_by_session_id(shell_mgr, source).await?,
        None => shell_mgr.wt_get_active_pane().await.ok()?,
    };

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f3637cc5-ad00-400b-a426-92a7ddfc94e5
Copilot AI review requested due to automatic review settings July 31, 2026 09:14

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

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (2)

tools/wta/src/app_keys.rs:811

  • source_pane_id is being set from self.source_session_id, but source_session_id is only read once from the WTA_SOURCE_SESSION_ID env var at helper startup (see helper/runtime.rs). That means planner prompts can get “stuck” routing to the tab’s initial pane instead of the pane that was active when the user actually submitted the prompt (e.g., after splitting panes or changing focus within the tab). This undermines the goal of capturing an authoritative per-prompt target.
                        tab_id: self.tab_id.clone(),
                        window_id: self.window_id.clone(),
                        cwd: self.source_cwd.clone(),
                        source_pane_id: self.source_session_id.clone(),
                    };

tools/wta/src/app.rs:4426

  • /fix now seeds PaneContext.source_pane_id (and the prompt’s target_pane_id) from self.source_session_id, but that value is only initialized from WTA_SOURCE_SESSION_ID at helper startup. If the user’s working pane changes after the helper is spawned (pane splits/focus changes), manual /fix can resolve context/output and route execution to the wrong pane.
            pane_id: self.pane_id.clone(),
            tab_id: Some(target_tab_id.clone()),
            window_id: self.window_id.clone(),
            cwd: None,
            source_pane_id: source_pane_id.clone(),

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