From 9351b058f34973016a5d5973297d0567513e67a4 Mon Sep 17 00:00:00 2001 From: akbash Date: Fri, 14 Aug 2026 01:22:46 +0300 Subject: fix: reject prompts to blocked agents (#2790) * fix: reject prompts to blocked agents refs #2788 * docs: clarify agent prompt timing refs #2788 --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> --- src/app/api/agents.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src/app/api') diff --git a/src/app/api/agents.rs b/src/app/api/agents.rs index e5e5525f..1ed13efc 100644 --- a/src/app/api/agents.rs +++ b/src/app/api/agents.rs @@ -79,6 +79,16 @@ impl App { let Some(terminal) = self.state.terminals.get(&terminal_id) else { return agent_not_found(id, ¶ms.target); }; + if terminal.state == crate::detect::AgentState::Blocked { + return encode_error( + id, + "agent_blocked", + format!( + "agent {} is blocked and requires interactive input", + params.target + ), + ); + } let Some(expected_agent) = terminal.effective_known_agent() else { return agent_not_ready(id, ¶ms.target); }; @@ -406,6 +416,41 @@ mod tests { assert!(rx.try_recv().is_err()); } + #[tokio::test] + async fn agent_prompt_rejects_blocked_agent_without_writing() { + let mut app = app_with_agent(); + let pane_id = app.state.workspaces[0].tabs[0].root_pane; + let terminal_id = app.state.workspaces[0].tabs[0].panes[&pane_id] + .attached_terminal_id + .clone(); + let terminal = app.state.terminals.get_mut(&terminal_id).unwrap(); + terminal.set_agent_name("reviewer".into()); + terminal.set_detected_state(Some(Agent::GithubCopilot), AgentState::Blocked); + let (runtime, mut rx) = crate::terminal::TerminalRuntime::test_with_channel(80, 24); + app.state.insert_test_runtime(pane_id, runtime); + + let response = app.handle_agent_prompt( + "req".into(), + AgentPromptParams { + target: "reviewer".into(), + text: "unrelated prompt".into(), + wait: None, + }, + ); + + let error: crate::api::schema::ErrorResponse = serde_json::from_str(&response).unwrap(); + assert_eq!(error.error.code, "agent_blocked"); + assert!( + tokio::time::timeout( + AGENT_PROMPT_SUBMIT_DELAY + Duration::from_millis(100), + rx.recv() + ) + .await + .is_err(), + "blocked prompt wrote or scheduled terminal input" + ); + } + #[tokio::test] async fn agent_prompt_focuses_copilot_before_submitting() { let mut app = app_with_agent(); -- cgit v1.2.3