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:
@@ -143,6 +143,22 @@ async fn execute_user_input<W: UiWriter>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if plan is terminal and exit plan mode if so.
|
||||
///
|
||||
/// Returns true if plan mode was exited (plan is complete or all blocked).
|
||||
fn check_and_exit_plan_mode_if_terminal<W: UiWriter>(
|
||||
agent: &mut Agent<W>,
|
||||
in_plan_mode: &mut bool,
|
||||
output: &SimpleOutput,
|
||||
) -> bool {
|
||||
if *in_plan_mode && agent.is_plan_terminal() {
|
||||
output.print("\n📋 Plan complete - exiting plan mode");
|
||||
*in_plan_mode = false;
|
||||
agent.set_plan_mode(false);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Run interactive mode with console output.
|
||||
/// If `agent_name` is Some, we're in agent+chat mode: skip session resume/verbose welcome,
|
||||
@@ -298,6 +314,9 @@ pub async fn run_interactive<W: UiWriter>(
|
||||
execute_user_input(
|
||||
&mut agent, &final_input, show_prompt, show_code, &output, from_agent_mode
|
||||
).await;
|
||||
|
||||
// Check if plan completed and exit plan mode if so
|
||||
check_and_exit_plan_mode_if_terminal(&mut agent, &mut in_plan_mode, &output);
|
||||
} else {
|
||||
// Single line input
|
||||
let input = line.trim().to_string();
|
||||
@@ -365,6 +384,9 @@ pub async fn run_interactive<W: UiWriter>(
|
||||
execute_user_input(
|
||||
&mut agent, &final_input, show_prompt, show_code, &output, from_agent_mode
|
||||
).await;
|
||||
|
||||
// Check if plan completed and exit plan mode if so
|
||||
check_and_exit_plan_mode_if_terminal(&mut agent, &mut in_plan_mode, &output);
|
||||
}
|
||||
}
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
|
||||
@@ -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
|
||||
// =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user