tui: reset plan popup state after steer

This commit is contained in:
Charles Cunningham
2026-03-02 16:14:52 -08:00
parent 5f141c3485
commit 4a377df0ec
2 changed files with 90 additions and 12 deletions
+88 -1
View File
@@ -1710,7 +1710,6 @@ async fn make_chatwidget_manual(
startup_tooltip_override: None,
queued_user_messages: VecDeque::new(),
pending_steers: VecDeque::new(),
steer_submitted_this_turn: false,
queued_message_edit_binding: crate::key_hint::alt(KeyCode::Up),
suppress_session_configured_redraw: false,
pending_notification: None,
@@ -2744,6 +2743,94 @@ async fn plan_implementation_popup_shows_after_proposed_plan_output() {
);
}
#[tokio::test]
async fn plan_implementation_popup_skips_when_steer_follows_proposed_plan() {
let (mut chat, _rx, mut op_rx) = make_chatwidget_manual(Some("gpt-5")).await;
chat.set_feature_enabled(Feature::CollaborationModes, true);
let plan_mask =
collaboration_modes::mask_for_kind(chat.models_manager.as_ref(), ModeKind::Plan)
.expect("expected plan collaboration mask");
chat.set_collaboration_mask(plan_mask);
chat.thread_id = Some(ThreadId::new());
chat.on_task_started();
chat.on_plan_item_completed(
"- Step 1
- Step 2
"
.to_string(),
);
chat.bottom_pane
.set_composer_text("Please continue.".to_string(), Vec::new(), Vec::new());
chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
match next_submit_op(&mut op_rx) {
Op::UserTurn { items, .. } => assert_eq!(
items,
vec![UserInput::Text {
text: "Please continue.".to_string(),
text_elements: Vec::new(),
}]
),
other => panic!("expected Op::UserTurn, got {other:?}"),
}
complete_user_message(&mut chat, "user-1", "Please continue.");
chat.on_task_complete(None, false);
let popup = render_bottom_popup(&chat, 80);
assert!(
!popup.contains(PLAN_IMPLEMENTATION_TITLE),
"expected no plan popup after a steer follows the plan, got {popup:?}"
);
}
#[tokio::test]
async fn plan_implementation_popup_shows_after_new_plan_follows_steer() {
let (mut chat, _rx, mut op_rx) = make_chatwidget_manual(Some("gpt-5")).await;
chat.set_feature_enabled(Feature::CollaborationModes, true);
let plan_mask =
collaboration_modes::mask_for_kind(chat.models_manager.as_ref(), ModeKind::Plan)
.expect("expected plan collaboration mask");
chat.set_collaboration_mask(plan_mask);
chat.thread_id = Some(ThreadId::new());
chat.on_task_started();
chat.on_plan_item_completed(
"- Initial plan
"
.to_string(),
);
chat.bottom_pane
.set_composer_text("Please revise.".to_string(), Vec::new(), Vec::new());
chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
match next_submit_op(&mut op_rx) {
Op::UserTurn { items, .. } => assert_eq!(
items,
vec![UserInput::Text {
text: "Please revise.".to_string(),
text_elements: Vec::new(),
}]
),
other => panic!("expected Op::UserTurn, got {other:?}"),
}
complete_user_message(&mut chat, "user-1", "Please revise.");
chat.on_plan_item_completed(
"- Revised plan
"
.to_string(),
);
chat.on_task_complete(None, false);
let popup = render_bottom_popup(&chat, 80);
assert!(
popup.contains(PLAN_IMPLEMENTATION_TITLE),
"expected plan popup after a newer plan follows the steer, got {popup:?}"
);
}
#[tokio::test]
async fn plan_implementation_popup_skips_when_rate_limit_prompt_pending() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(Some("gpt-5")).await;