Exit plan mode when plan is completed or blocked

When a plan reaches a terminal state (all items done or blocked) in
interactive mode, automatically exit plan mode and return to normal
prompt.

Changes:
- Add Agent::is_plan_terminal() method to check if plan is complete
- Add check_and_exit_plan_mode_if_terminal() helper in interactive.rs
- Call the helper after each execute_user_input() to detect completion

Fixes issue where plan mode prompt ' >> ' persisted after plan completion.
This commit is contained in:
Dhanji R. Prasanna
2026-02-05 20:31:24 +11:00
parent 30627bce97
commit 19162b1fe6
2 changed files with 39 additions and 1 deletions

View File

@@ -50,7 +50,7 @@ pub use skills::{Skill, discover_skills, generate_skills_prompt};
#[cfg(test)]
mod task_result_comprehensive_tests;
use crate::ui_writer::UiWriter;
use tools::plan::{check_plan_approval_gate, ApprovalGateResult};
use tools::plan::{check_plan_approval_gate, read_plan, ApprovalGateResult};
#[cfg(test)]
mod tilde_expansion_tests;
@@ -1548,6 +1548,22 @@ impl<W: UiWriter> Agent<W> {
self.in_plan_mode
}
/// Check if the current plan is in a terminal state (all items done or blocked).
///
/// Returns true if:
/// - A plan exists AND all items are in terminal state (done or blocked)
///
/// Returns false if:
/// - No session_id is set
/// - No plan exists for the session
/// - Plan has items that are not terminal (todo or doing)
pub fn is_plan_terminal(&self) -> bool {
let Some(session_id) = &self.session_id else {
return false;
};
read_plan(session_id).ok().flatten().map_or(false, |plan| plan.is_complete())
}
// =========================================================================
// STREAMING & LLM INTERACTION
// =========================================================================