mirror of
https://github.com/openai/codex.git
synced 2026-02-18 06:43:47 +00:00
Compare commits
3 Commits
dev/mzeng/
...
remove/ste
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
369f404414 | ||
|
|
de28968ed6 | ||
|
|
7d62a922ef |
@@ -128,6 +128,7 @@ pub enum Feature {
|
||||
/// Prompt for missing skill env var dependencies.
|
||||
SkillEnvVarDependencyPrompt,
|
||||
/// Steer feature flag - when enabled, Enter submits immediately instead of queuing.
|
||||
/// Kept for config backward compatibility; behavior is always steer-enabled.
|
||||
Steer,
|
||||
/// Enable collaboration modes (Plan, Default).
|
||||
CollaborationModes,
|
||||
@@ -592,7 +593,7 @@ pub const FEATURES: &[FeatureSpec] = &[
|
||||
FeatureSpec {
|
||||
id: Feature::Steer,
|
||||
key: "steer",
|
||||
stage: Stage::Stable,
|
||||
stage: Stage::Removed,
|
||||
default_enabled: true,
|
||||
},
|
||||
FeatureSpec {
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
//!
|
||||
//! # Submission and Prompt Expansion
|
||||
//!
|
||||
//! When steer is enabled, `Enter` submits immediately. `Tab` requests queuing while a task is
|
||||
//! running; if no task is running, `Tab` submits just like Enter so input is never dropped.
|
||||
//! `Enter` submits immediately. `Tab` requests queuing while a task is running; if no task is
|
||||
//! running, `Tab` submits just like Enter so input is never dropped.
|
||||
//! `Tab` does not submit when entering a `!` shell command.
|
||||
//!
|
||||
//! On submit/queue paths, the composer:
|
||||
@@ -326,8 +326,6 @@ pub(crate) struct ChatComposer {
|
||||
dismissed_mention_popup_token: Option<String>,
|
||||
mention_bindings: HashMap<u64, ComposerMentionBinding>,
|
||||
recent_submission_mention_bindings: Vec<MentionBinding>,
|
||||
/// When enabled, `Enter` submits immediately and `Tab` requests queuing behavior.
|
||||
steer_enabled: bool,
|
||||
collaboration_modes_enabled: bool,
|
||||
config: ChatComposerConfig,
|
||||
collaboration_mode_indicator: Option<CollaborationModeIndicator>,
|
||||
@@ -427,7 +425,6 @@ impl ChatComposer {
|
||||
dismissed_mention_popup_token: None,
|
||||
mention_bindings: HashMap::new(),
|
||||
recent_submission_mention_bindings: Vec::new(),
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
config,
|
||||
collaboration_mode_indicator: None,
|
||||
@@ -476,17 +473,6 @@ impl ChatComposer {
|
||||
ordered
|
||||
}
|
||||
|
||||
/// Enables or disables "Steer" behavior for submission keys.
|
||||
///
|
||||
/// When steer is enabled, `Enter` produces [`InputResult::Submitted`] (send immediately) and
|
||||
/// `Tab` produces [`InputResult::Queued`] when a task is running; otherwise it submits
|
||||
/// immediately. `Tab` does not submit when the input is a `!` shell command.
|
||||
/// When steer is disabled, `Enter` produces [`InputResult::Queued`], preserving the default
|
||||
/// "queue while a task is running" behavior.
|
||||
pub fn set_steer_enabled(&mut self, enabled: bool) {
|
||||
self.steer_enabled = enabled;
|
||||
}
|
||||
|
||||
pub fn set_collaboration_modes_enabled(&mut self, enabled: bool) {
|
||||
self.collaboration_modes_enabled = enabled;
|
||||
}
|
||||
@@ -2565,25 +2551,12 @@ impl ChatComposer {
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: KeyEventKind::Press,
|
||||
..
|
||||
} if self.steer_enabled && !self.is_bang_shell_command() => {
|
||||
self.handle_submission(self.is_task_running)
|
||||
}
|
||||
KeyEvent {
|
||||
code: KeyCode::Tab,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
kind: KeyEventKind::Press,
|
||||
..
|
||||
} if self.is_task_running && !self.is_bang_shell_command() => {
|
||||
self.handle_submission(true)
|
||||
}
|
||||
} if !self.is_bang_shell_command() => self.handle_submission(self.is_task_running),
|
||||
KeyEvent {
|
||||
code: KeyCode::Enter,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
..
|
||||
} => {
|
||||
let should_queue = !self.steer_enabled;
|
||||
self.handle_submission(should_queue)
|
||||
}
|
||||
} => self.handle_submission(false),
|
||||
input => self.handle_input_basic(input),
|
||||
}
|
||||
}
|
||||
@@ -2849,7 +2822,6 @@ impl ChatComposer {
|
||||
use_shift_enter_hint: self.use_shift_enter_hint,
|
||||
is_task_running: self.is_task_running,
|
||||
quit_shortcut_key: self.quit_shortcut_key,
|
||||
steer_enabled: self.steer_enabled,
|
||||
collaboration_modes_enabled: self.collaboration_modes_enabled,
|
||||
is_wsl,
|
||||
context_window_percent: self.context_window_percent,
|
||||
@@ -3489,9 +3461,7 @@ impl ChatComposer {
|
||||
| FooterMode::ComposerHasDraft => false,
|
||||
};
|
||||
let show_queue_hint = match footer_props.mode {
|
||||
FooterMode::ComposerHasDraft => {
|
||||
footer_props.is_task_running && footer_props.steer_enabled
|
||||
}
|
||||
FooterMode::ComposerHasDraft => footer_props.is_task_running,
|
||||
FooterMode::QuitShortcutReminder
|
||||
| FooterMode::ComposerEmpty
|
||||
| FooterMode::ShortcutOverlay
|
||||
@@ -4106,10 +4076,9 @@ mod tests {
|
||||
},
|
||||
);
|
||||
|
||||
// Textarea has content, agent running, steer enabled: queue hint is shown.
|
||||
// Textarea has content, agent running: queue hint is shown.
|
||||
snapshot_composer_state_with_width("footer_collapse_queue_full", 120, true, |composer| {
|
||||
setup_collab_footer(composer, 98, None);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
});
|
||||
@@ -4119,7 +4088,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, None);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4130,7 +4098,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, None);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4141,7 +4108,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, None);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4152,20 +4118,18 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, None);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
);
|
||||
|
||||
// Textarea has content, plan mode active, agent running, steer enabled: queue hint + mode.
|
||||
// Textarea has content, plan mode active, agent running: queue hint + mode.
|
||||
snapshot_composer_state_with_width(
|
||||
"footer_collapse_plan_queue_full",
|
||||
120,
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, Some(CollaborationModeIndicator::Plan));
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4176,7 +4140,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, Some(CollaborationModeIndicator::Plan));
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4187,7 +4150,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, Some(CollaborationModeIndicator::Plan));
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4198,7 +4160,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, Some(CollaborationModeIndicator::Plan));
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4209,7 +4170,6 @@ mod tests {
|
||||
true,
|
||||
|composer| {
|
||||
setup_collab_footer(composer, 98, Some(CollaborationModeIndicator::Plan));
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(true);
|
||||
composer.set_text_content("Test".to_string(), Vec::new(), Vec::new());
|
||||
},
|
||||
@@ -4281,11 +4241,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_text_content("draft text".to_string(), Vec::new(), Vec::new());
|
||||
assert_eq!(composer.clear_for_ctrl_c(), Some("draft text".to_string()));
|
||||
@@ -4349,7 +4304,6 @@ mod tests {
|
||||
assert_eq!(composer.pending_pastes, vec![(placeholder.clone(), large)]);
|
||||
assert_eq!(composer.textarea.element_payloads(), vec![placeholder]);
|
||||
|
||||
composer.set_steer_enabled(true);
|
||||
let (result, _needs_redraw) =
|
||||
composer.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
|
||||
match result {
|
||||
@@ -4503,13 +4457,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let (result, needs_redraw) =
|
||||
composer.handle_key_event(KeyEvent::new(KeyCode::Char('?'), KeyModifiers::NONE));
|
||||
@@ -4552,10 +4499,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Force an active paste burst so this test doesn't depend on tight timing.
|
||||
composer
|
||||
@@ -4663,10 +4606,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let _ = composer.handle_key_event(KeyEvent::new(KeyCode::Char('?'), KeyModifiers::NONE));
|
||||
assert_eq!(composer.footer_mode, FooterMode::ShortcutOverlay);
|
||||
@@ -4844,10 +4783,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let _ = composer.handle_key_event(KeyEvent::new(KeyCode::Char('1'), KeyModifiers::NONE));
|
||||
assert!(composer.is_in_paste_burst());
|
||||
@@ -4879,10 +4814,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let _ = composer.handle_key_event(KeyEvent::new(KeyCode::Char('あ'), KeyModifiers::NONE));
|
||||
|
||||
@@ -5025,9 +4956,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let mut now = Instant::now();
|
||||
let step = Duration::from_millis(1);
|
||||
@@ -5043,7 +4971,7 @@ mod tests {
|
||||
);
|
||||
now += step;
|
||||
|
||||
let (result, _) = composer.handle_submission_with_time(!composer.steer_enabled, now);
|
||||
let (result, _) = composer.handle_submission_with_time(false, now);
|
||||
assert!(
|
||||
matches!(result, InputResult::None),
|
||||
"Enter during a burst should insert newline, not submit"
|
||||
@@ -5179,9 +5107,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let needs_redraw = composer.handle_paste("hello".to_string());
|
||||
assert!(needs_redraw);
|
||||
@@ -5211,9 +5136,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Ensure composer is empty and press Enter.
|
||||
assert!(composer.textarea.text().is_empty());
|
||||
@@ -5243,7 +5165,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let large = "x".repeat(LARGE_PASTE_CHAR_THRESHOLD + 10);
|
||||
let needs_redraw = composer.handle_paste(large.clone());
|
||||
@@ -5281,7 +5202,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.handle_paste(large);
|
||||
assert_eq!(composer.pending_pastes.len(), 1);
|
||||
@@ -5415,7 +5335,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Type "/mo" humanlike so paste-burst doesn’t interfere.
|
||||
type_chars_humanlike(&mut composer, &['/', 'm', 'o']);
|
||||
@@ -5444,7 +5363,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
type_chars_humanlike(&mut composer, &['/', 'm', 'o']);
|
||||
|
||||
match &composer.active_popup {
|
||||
@@ -5476,7 +5394,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Type "/res" humanlike so paste-burst doesn’t interfere.
|
||||
type_chars_humanlike(&mut composer, &['/', 'r', 'e', 's']);
|
||||
@@ -5794,7 +5711,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_submits_when_no_task_running_in_steer_mode() {
|
||||
fn tab_submits_when_no_task_running() {
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
use crossterm::event::KeyModifiers;
|
||||
@@ -5808,7 +5725,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
type_chars_humanlike(&mut composer, &['h', 'i']);
|
||||
|
||||
@@ -5823,7 +5739,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_does_not_submit_for_bang_shell_command_in_steer_mode() {
|
||||
fn tab_does_not_submit_for_bang_shell_command() {
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
use crossterm::event::KeyModifiers;
|
||||
@@ -5837,7 +5753,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
composer.set_task_running(false);
|
||||
|
||||
type_chars_humanlike(&mut composer, &['!', 'l', 's']);
|
||||
@@ -5948,7 +5863,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Define test cases: (paste content, is_large)
|
||||
let test_cases = [
|
||||
@@ -6229,7 +6143,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
let path = PathBuf::from("/tmp/image1.png");
|
||||
composer.attach_image(path.clone());
|
||||
composer.handle_paste(" hi".into());
|
||||
@@ -6268,7 +6181,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let mention_bindings = vec![MentionBinding {
|
||||
mention: "figma".to_string(),
|
||||
@@ -6302,7 +6214,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
let remote_image_url = "https://example.com/remote.png".to_string();
|
||||
composer.set_remote_image_urls(vec![remote_image_url.clone()]);
|
||||
let path = PathBuf::from("/tmp/image1.png");
|
||||
@@ -6369,7 +6280,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
type_chars_humanlike(&mut composer, &['f', 'i', 'r', 's', 't']);
|
||||
let (result, _needs_redraw) =
|
||||
@@ -6435,7 +6345,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let large_content = "x".repeat(LARGE_PASTE_CHAR_THRESHOLD + 5);
|
||||
composer.handle_paste(large_content.clone());
|
||||
@@ -6479,7 +6388,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let large_content = format!(" {}", "x".repeat(LARGE_PASTE_CHAR_THRESHOLD + 5));
|
||||
composer.handle_paste(large_content.clone());
|
||||
@@ -6523,7 +6431,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
let pasted = "line1\r\nline2\r\n".to_string();
|
||||
composer.handle_paste(pasted);
|
||||
@@ -6567,7 +6474,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.textarea.set_text_clearing_elements("/unknown ");
|
||||
composer.textarea.set_cursor("/unknown ".len());
|
||||
@@ -6614,7 +6520,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
let path = PathBuf::from("/tmp/image2.png");
|
||||
composer.attach_image(path.clone());
|
||||
let (result, _) =
|
||||
@@ -6926,7 +6831,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Inject prompts as if received via event.
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
@@ -6966,7 +6870,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7002,7 +6905,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7042,7 +6944,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7098,7 +6999,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7155,7 +7055,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7204,7 +7103,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
// Create a custom prompt with positional args (no named args like $USER)
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
@@ -7269,7 +7167,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7328,7 +7225,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer
|
||||
.textarea
|
||||
@@ -7365,7 +7261,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer
|
||||
.textarea
|
||||
@@ -7503,7 +7398,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7542,7 +7436,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7581,7 +7474,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7625,7 +7517,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7666,7 +7557,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(false);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "my-prompt".to_string(),
|
||||
@@ -7681,9 +7571,10 @@ mod tests {
|
||||
.set_text_clearing_elements("/prompts:my-prompt foo ");
|
||||
composer.textarea.set_cursor(composer.textarea.text().len());
|
||||
composer.attach_image(PathBuf::from("/tmp/unused.png"));
|
||||
composer.set_task_running(true);
|
||||
|
||||
let (result, _needs_redraw) =
|
||||
composer.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
|
||||
composer.handle_key_event(KeyEvent::new(KeyCode::Tab, KeyModifiers::NONE));
|
||||
|
||||
assert!(matches!(
|
||||
result,
|
||||
@@ -7739,7 +7630,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "elegant".to_string(),
|
||||
@@ -7812,7 +7702,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "price".to_string(),
|
||||
@@ -7851,7 +7740,6 @@ mod tests {
|
||||
"Ask Codex to do anything".to_string(),
|
||||
false,
|
||||
);
|
||||
composer.set_steer_enabled(true);
|
||||
|
||||
composer.set_custom_prompts(vec![CustomPrompt {
|
||||
name: "repeat".to_string(),
|
||||
|
||||
@@ -59,7 +59,6 @@ pub(crate) struct FooterProps {
|
||||
pub(crate) esc_backtrack_hint: bool,
|
||||
pub(crate) use_shift_enter_hint: bool,
|
||||
pub(crate) is_task_running: bool,
|
||||
pub(crate) steer_enabled: bool,
|
||||
pub(crate) collaboration_modes_enabled: bool,
|
||||
pub(crate) is_wsl: bool,
|
||||
/// Which key the user must press again to quit.
|
||||
@@ -126,8 +125,8 @@ pub(crate) enum FooterMode {
|
||||
ComposerEmpty,
|
||||
/// Base single-line footer when the composer contains a draft.
|
||||
///
|
||||
/// The shortcuts hint is suppressed here; when a task is running with
|
||||
/// steer enabled, this mode can show the queue hint instead.
|
||||
/// The shortcuts hint is suppressed here; when a task is running, this
|
||||
/// mode can show the queue hint instead.
|
||||
ComposerHasDraft,
|
||||
}
|
||||
|
||||
@@ -179,7 +178,7 @@ pub(crate) fn footer_height(props: &FooterProps) -> u16 {
|
||||
| FooterMode::ComposerHasDraft => false,
|
||||
};
|
||||
let show_queue_hint = match props.mode {
|
||||
FooterMode::ComposerHasDraft => props.is_task_running && props.steer_enabled,
|
||||
FooterMode::ComposerHasDraft => props.is_task_running,
|
||||
FooterMode::QuitShortcutReminder
|
||||
| FooterMode::ComposerEmpty
|
||||
| FooterMode::ShortcutOverlay
|
||||
@@ -1020,7 +1019,7 @@ mod tests {
|
||||
| FooterMode::ComposerHasDraft => false,
|
||||
};
|
||||
let show_queue_hint = match props.mode {
|
||||
FooterMode::ComposerHasDraft => props.is_task_running && props.steer_enabled,
|
||||
FooterMode::ComposerHasDraft => props.is_task_running,
|
||||
FooterMode::QuitShortcutReminder
|
||||
| FooterMode::ComposerEmpty
|
||||
| FooterMode::ShortcutOverlay
|
||||
@@ -1189,7 +1188,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1207,7 +1205,6 @@ mod tests {
|
||||
esc_backtrack_hint: true,
|
||||
use_shift_enter_hint: true,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1225,7 +1222,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1243,7 +1239,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1261,7 +1256,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: true,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1279,7 +1273,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1297,7 +1290,6 @@ mod tests {
|
||||
esc_backtrack_hint: true,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1315,7 +1307,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: true,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1333,7 +1324,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1344,24 +1334,6 @@ mod tests {
|
||||
},
|
||||
);
|
||||
|
||||
snapshot_footer(
|
||||
"footer_composer_has_draft_queue_hint_disabled",
|
||||
FooterProps {
|
||||
mode: FooterMode::ComposerHasDraft,
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: true,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
context_window_percent: None,
|
||||
context_window_used_tokens: None,
|
||||
status_line_value: None,
|
||||
status_line_enabled: false,
|
||||
},
|
||||
);
|
||||
|
||||
snapshot_footer(
|
||||
"footer_composer_has_draft_queue_hint_enabled",
|
||||
FooterProps {
|
||||
@@ -1369,7 +1341,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: true,
|
||||
steer_enabled: true,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1385,7 +1356,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1414,7 +1384,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: true,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1436,7 +1405,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1453,7 +1421,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1475,7 +1442,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1497,7 +1463,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: false,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1520,7 +1485,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
@@ -1547,7 +1511,6 @@ mod tests {
|
||||
esc_backtrack_hint: false,
|
||||
use_shift_enter_hint: false,
|
||||
is_task_running: false,
|
||||
steer_enabled: false,
|
||||
collaboration_modes_enabled: true,
|
||||
is_wsl: false,
|
||||
quit_shortcut_key: key_hint::ctrl(KeyCode::Char('c')),
|
||||
|
||||
@@ -255,10 +255,6 @@ impl BottomPane {
|
||||
let _ = self.take_mention_bindings();
|
||||
}
|
||||
|
||||
pub fn set_steer_enabled(&mut self, enabled: bool) {
|
||||
self.composer.set_steer_enabled(enabled);
|
||||
}
|
||||
|
||||
pub fn set_collaboration_modes_enabled(&mut self, enabled: bool) {
|
||||
self.composer.set_collaboration_modes_enabled(enabled);
|
||||
self.request_redraw();
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
source: tui/src/bottom_pane/footer.rs
|
||||
expression: terminal.backend()
|
||||
---
|
||||
" 100% context left "
|
||||
@@ -2689,9 +2689,6 @@ impl ChatWidget {
|
||||
};
|
||||
|
||||
widget.prefetch_rate_limits();
|
||||
widget
|
||||
.bottom_pane
|
||||
.set_steer_enabled(widget.config.features.enabled(Feature::Steer));
|
||||
widget.bottom_pane.set_status_line_enabled(
|
||||
widget
|
||||
.config
|
||||
@@ -2856,9 +2853,6 @@ impl ChatWidget {
|
||||
};
|
||||
|
||||
widget.prefetch_rate_limits();
|
||||
widget
|
||||
.bottom_pane
|
||||
.set_steer_enabled(widget.config.features.enabled(Feature::Steer));
|
||||
widget.bottom_pane.set_status_line_enabled(
|
||||
widget
|
||||
.config
|
||||
@@ -3012,9 +3006,6 @@ impl ChatWidget {
|
||||
};
|
||||
|
||||
widget.prefetch_rate_limits();
|
||||
widget
|
||||
.bottom_pane
|
||||
.set_steer_enabled(widget.config.features.enabled(Feature::Steer));
|
||||
widget.bottom_pane.set_status_line_enabled(
|
||||
widget
|
||||
.config
|
||||
@@ -3141,7 +3132,7 @@ impl ChatWidget {
|
||||
.take_recent_submission_mention_bindings(),
|
||||
};
|
||||
if self.is_session_configured() && !self.is_plan_streaming_in_tui() {
|
||||
// Submitted is only emitted when steer is enabled.
|
||||
// Submitted is emitted when user submits.
|
||||
// Reset any reasoning header only when we are actually submitting a turn.
|
||||
self.reasoning_buffer.clear();
|
||||
self.full_reasoning_buffer.clear();
|
||||
@@ -6025,9 +6016,6 @@ impl ChatWidget {
|
||||
} else {
|
||||
self.config.features.disable(feature);
|
||||
}
|
||||
if feature == Feature::Steer {
|
||||
self.bottom_pane.set_steer_enabled(enabled);
|
||||
}
|
||||
if feature == Feature::CollaborationModes {
|
||||
self.bottom_pane.set_collaboration_modes_enabled(enabled);
|
||||
let settings = self.current_collaboration_mode.settings.clone();
|
||||
|
||||
@@ -1574,7 +1574,6 @@ async fn make_chatwidget_manual(
|
||||
animations_enabled: cfg.animations,
|
||||
skills: None,
|
||||
});
|
||||
bottom.set_steer_enabled(true);
|
||||
bottom.set_collaboration_modes_enabled(cfg.features.enabled(Feature::CollaborationModes));
|
||||
let auth_manager =
|
||||
codex_core::test_support::auth_manager_from_auth(CodexAuth::from_api_key("test"));
|
||||
@@ -3006,7 +3005,7 @@ async fn unified_exec_begin_restores_working_status_snapshot() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn steer_enter_queues_while_plan_stream_is_active() {
|
||||
async fn enter_queues_while_plan_stream_is_active() {
|
||||
let (mut chat, _rx, mut op_rx) = make_chatwidget_manual(None).await;
|
||||
chat.thread_id = Some(ThreadId::new());
|
||||
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
||||
@@ -3031,7 +3030,7 @@ async fn steer_enter_queues_while_plan_stream_is_active() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn steer_enter_submits_when_plan_stream_is_not_active() {
|
||||
async fn enter_submits_when_plan_stream_is_not_active() {
|
||||
let (mut chat, _rx, mut op_rx) = make_chatwidget_manual(None).await;
|
||||
chat.thread_id = Some(ThreadId::new());
|
||||
chat.set_feature_enabled(Feature::CollaborationModes, true);
|
||||
|
||||
@@ -97,9 +97,8 @@ popup so gating stays in sync.
|
||||
|
||||
There are multiple submission paths, but they share the same core rules:
|
||||
|
||||
When steer mode is enabled, `Tab` requests queuing if a task is already running; otherwise it
|
||||
submits immediately. `Enter` always submits immediately in this mode. `Tab` does not submit when
|
||||
the input starts with `!` (shell command).
|
||||
`Tab` requests queuing if a task is already running; otherwise it submits immediately. `Enter`
|
||||
always submits immediately. `Tab` does not submit when the input starts with `!` (shell command).
|
||||
|
||||
### Normal submit/queue path
|
||||
|
||||
|
||||
Reference in New Issue
Block a user