Codex Handbook
tui/src/chatwidget/plan_implementation.rs 114 lines
use codex_protocol::config_types::CollaborationModeMask;use crate::app_event::AppEvent;use crate::bottom_pane::SelectionAction;use crate::bottom_pane::SelectionItem;use crate::bottom_pane::SelectionViewParams;use crate::bottom_pane::popup_consts::standard_popup_hint_line;pub(super) const PLAN_IMPLEMENTATION_TITLE: &str = "Implement this plan?";const PLAN_IMPLEMENTATION_YES: &str = "Yes, implement this plan";const PLAN_IMPLEMENTATION_CLEAR_CONTEXT: &str = "Yes, clear context and implement";const PLAN_IMPLEMENTATION_NO: &str = "No, stay in Plan mode";pub(super) const PLAN_IMPLEMENTATION_CODING_MESSAGE: &str = "Implement the plan.";pub(super) const PLAN_IMPLEMENTATION_CLEAR_CONTEXT_PREFIX: &str = concat!(    "A previous agent produced the plan below to accomplish the user's task. ",    "Implement the plan in a fresh context. Treat the plan as the source of ",    "user intent, re-read files as needed, and carry the work through ",    "implementation and verification.");pub(super) const PLAN_IMPLEMENTATION_DEFAULT_UNAVAILABLE: &str = "Default mode unavailable";pub(super) const PLAN_IMPLEMENTATION_NO_APPROVED_PLAN: &str = "No approved plan available";/// Builds the confirmation prompt shown after a plan is approved in Plan mode.////// The optional usage label is already phrased for display, such as `89% used`/// or `123K used`. This module only decides where that label belongs in the/// decision copy so action wiring stays separate from token accounting.pub(super) fn selection_view_params(    default_mask: Option<CollaborationModeMask>,    plan_markdown: Option<&str>,    clear_context_usage_label: Option<&str>,) -> SelectionViewParams {    let (implement_actions, implement_disabled_reason) = match default_mask.clone() {        Some(mask) => {            let user_text = PLAN_IMPLEMENTATION_CODING_MESSAGE.to_string();            let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {                tx.send(AppEvent::SubmitUserMessageWithMode {                    text: user_text.clone(),                    collaboration_mode: mask.clone(),                });            })];            (actions, None)        }        None => (            Vec::new(),            Some(PLAN_IMPLEMENTATION_DEFAULT_UNAVAILABLE.to_string()),        ),    };    let (clear_context_actions, clear_context_disabled_reason) = match (default_mask, plan_markdown)    {        (None, _) => (            Vec::new(),            Some(PLAN_IMPLEMENTATION_DEFAULT_UNAVAILABLE.to_string()),        ),        (Some(_), Some(plan_markdown)) if !plan_markdown.trim().is_empty() => {            let user_text =                format!("{PLAN_IMPLEMENTATION_CLEAR_CONTEXT_PREFIX}\n\n{plan_markdown}");            let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {                tx.send(AppEvent::ClearUiAndSubmitUserMessage {                    text: user_text.clone(),                });            })];            (actions, None)        }        (Some(_), _) => (            Vec::new(),            Some(PLAN_IMPLEMENTATION_NO_APPROVED_PLAN.to_string()),        ),    };    let clear_context_description = clear_context_usage_label.map_or_else(        || "Fresh thread with this plan.".to_string(),        |label| format!("Fresh thread. Context: {label}."),    );    SelectionViewParams {        title: Some(PLAN_IMPLEMENTATION_TITLE.to_string()),        subtitle: None,        footer_hint: Some(standard_popup_hint_line()),        items: vec![            SelectionItem {                name: PLAN_IMPLEMENTATION_YES.to_string(),                description: Some("Switch to Default and start coding.".to_string()),                selected_description: None,                is_current: false,                actions: implement_actions,                disabled_reason: implement_disabled_reason,                dismiss_on_select: true,                ..Default::default()            },            SelectionItem {                name: PLAN_IMPLEMENTATION_CLEAR_CONTEXT.to_string(),                description: Some(clear_context_description),                selected_description: None,                is_current: false,                actions: clear_context_actions,                disabled_reason: clear_context_disabled_reason,                dismiss_on_select: true,                ..Default::default()            },            SelectionItem {                name: PLAN_IMPLEMENTATION_NO.to_string(),                description: Some("Continue planning with the model.".to_string()),                selected_description: None,                is_current: false,                actions: Vec::new(),                dismiss_on_select: true,                ..Default::default()            },        ],        ..Default::default()    }}