Skip to content

Commit ffac786

Browse files
charley-oaicodex
andcommitted
codex: keep BTW prompts out of shell execution
Co-authored-by: Codex <noreply@openai.com>
1 parent 48b240c commit ffac786

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

codex-rs/tui/src/chatwidget.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4877,8 +4877,11 @@ impl ChatWidget {
48774877
}
48784878

48794879
fn submit_user_message(&mut self, user_message: UserMessage) {
4880-
let _ =
4881-
self.submit_user_message_for_current_thread_with_collaboration_mode(user_message, None);
4880+
let _ = self.submit_user_message_for_current_thread_with_collaboration_mode(
4881+
user_message,
4882+
None,
4883+
true,
4884+
);
48824885
}
48834886

48844887
pub(crate) fn submit_user_message_with_developer_instructions(
@@ -4894,13 +4897,15 @@ impl ChatWidget {
48944897
self.submit_user_message_for_current_thread_with_collaboration_mode(
48954898
user_message,
48964899
collaboration_mode,
4900+
false,
48974901
)
48984902
}
48994903

49004904
fn submit_user_message_for_current_thread_with_collaboration_mode(
49014905
&mut self,
49024906
user_message: UserMessage,
49034907
collaboration_mode_override: Option<CollaborationMode>,
4908+
allow_shell_command_execution: bool,
49044909
) -> Option<Op> {
49054910
if !self.is_session_configured() {
49064911
tracing::warn!("cannot submit user message before session is configured; queueing");
@@ -4941,7 +4946,7 @@ impl ChatWidget {
49414946
let mut items: Vec<UserInput> = Vec::new();
49424947

49434948
// Special-case: "!cmd" executes a local shell command instead of sending to the model.
4944-
if let Some(stripped) = text.strip_prefix('!') {
4949+
if allow_shell_command_execution && let Some(stripped) = text.strip_prefix('!') {
49454950
let cmd = stripped.trim();
49464951
if cmd.is_empty() {
49474952
self.app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(

codex-rs/tui/src/chatwidget/tests.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,6 +2517,28 @@ async fn submit_user_message_with_developer_instructions_overrides_turn_mode() {
25172517
}
25182518
}
25192519

2520+
#[tokio::test]
2521+
async fn submit_user_message_with_developer_instructions_does_not_run_shell_commands() {
2522+
let (mut chat, _rx, mut op_rx) = make_chatwidget_manual(Some("gpt-5")).await;
2523+
chat.thread_id = Some(ThreadId::new());
2524+
2525+
chat.submit_user_message_with_developer_instructions(
2526+
"!echo hello".into(),
2527+
"<btw_context>Answer a side question.</btw_context>".to_string(),
2528+
);
2529+
2530+
match next_submit_op(&mut op_rx) {
2531+
Op::UserTurn { items, .. } => assert_eq!(
2532+
items,
2533+
vec![UserInput::Text {
2534+
text: "!echo hello".to_string(),
2535+
text_elements: Vec::new(),
2536+
}]
2537+
),
2538+
other => panic!("expected Op::UserTurn for BTW shell-like input, got {other:?}"),
2539+
}
2540+
}
2541+
25202542
#[tokio::test]
25212543
async fn reasoning_selection_in_plan_mode_opens_scope_prompt_event() {
25222544
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(Some("gpt-5.1-codex-max")).await;

0 commit comments

Comments
 (0)