@@ -51,6 +51,8 @@ use crate::sandbox_cli::{
5151 resolve_effective_sandbox_state_with_defaults, sandbox_plan_requests_inherited_state,
5252 validate_sandbox_plan_with_defaults,
5353} ;
54+ use crate :: stdin_payload:: prepare_worker_stdin_payload;
55+ pub ( crate ) use crate :: stdin_payload:: { WriteStdinControlAction , split_write_stdin_control_prefix} ;
5456use crate :: worker_protocol:: {
5557 ContentOrigin , TextStream , WORKER_MODE_ARG , WorkerContent , WorkerErrorCode , WorkerReply ,
5658} ;
@@ -275,7 +277,14 @@ fn prechecked_follow_up_requires_meta_error() -> WorkerError {
275277}
276278
277279trait BackendDriver : Send {
278- fn prepare_input_payload ( & self , text : & str ) -> Vec < u8 > ;
280+ fn prepare_input_text ( & self , text : String ) -> String {
281+ text
282+ }
283+
284+ fn prepare_input_payload ( & self , text : & str ) -> Vec < u8 > {
285+ prepare_worker_stdin_payload ( text)
286+ }
287+
279288 fn on_input_start (
280289 & mut self ,
281290 text : & str ,
@@ -473,12 +482,8 @@ fn driver_refresh_worker_ready(
473482}
474483
475484impl BackendDriver for RBackendDriver {
476- fn prepare_input_payload ( & self , text : & str ) -> Vec < u8 > {
477- let mut payload = text. as_bytes ( ) . to_vec ( ) ;
478- if !payload. is_empty ( ) && !payload. ends_with ( b"\n " ) {
479- payload. push ( b'\n' ) ;
480- }
481- payload
485+ fn prepare_input_text ( & self , text : String ) -> String {
486+ normalize_input_newlines ( & text)
482487 }
483488
484489 fn on_input_start (
@@ -850,14 +855,6 @@ fn strip_one_line_ending(text: &str) -> Option<&str> {
850855
851856#[ cfg( not( target_family = "unix" ) ) ]
852857impl BackendDriver for PythonBackendDriver {
853- fn prepare_input_payload ( & self , text : & str ) -> Vec < u8 > {
854- let mut payload = text. as_bytes ( ) . to_vec ( ) ;
855- if !payload. is_empty ( ) && !payload. ends_with ( b"\n " ) {
856- payload. push ( b'\n' ) ;
857- }
858- payload
859- }
860-
861858 fn on_input_start (
862859 & mut self ,
863860 text : & str ,
@@ -934,14 +931,6 @@ impl ProtocolBackendDriver {
934931}
935932
936933impl BackendDriver for ProtocolBackendDriver {
937- fn prepare_input_payload ( & self , text : & str ) -> Vec < u8 > {
938- let mut payload = text. as_bytes ( ) . to_vec ( ) ;
939- if !payload. is_empty ( ) && !payload. ends_with ( b"\n " ) {
940- payload. push ( b'\n' ) ;
941- }
942- payload
943- }
944-
945934 fn on_input_start (
946935 & mut self ,
947936 _text : & str ,
@@ -1196,12 +1185,6 @@ fn completion_info_from_ipc(
11961185
11971186const DEFERRED_SANDBOX_UPDATE_TIMEOUT : Duration = Duration :: from_secs ( 5 ) ;
11981187
1199- #[ derive( Clone , Copy ) ]
1200- pub ( crate ) enum WriteStdinControlAction {
1201- Interrupt ,
1202- Restart ,
1203- }
1204-
12051188#[ derive( Debug , Clone , Default ) ]
12061189pub ( crate ) struct WriteStdinOptions {
12071190 pub page_bytes_override : Option < u64 > ,
@@ -1223,29 +1206,6 @@ impl WriteStdinOptions {
12231206 }
12241207}
12251208
1226- pub ( crate ) fn split_write_stdin_control_prefix (
1227- input : & str ,
1228- ) -> Option < ( WriteStdinControlAction , & str ) > {
1229- let first = input. chars ( ) . next ( ) ?;
1230- let action = match first {
1231- '\u{3}' => WriteStdinControlAction :: Interrupt ,
1232- '\u{4}' => WriteStdinControlAction :: Restart ,
1233- _ => return None ,
1234- } ;
1235-
1236- let tail = & input[ first. len_utf8 ( ) ..] ;
1237- let tail = if let Some ( rest) = tail. strip_prefix ( "\r \n " ) {
1238- rest
1239- } else if let Some ( rest) = tail. strip_prefix ( '\n' ) {
1240- rest
1241- } else if let Some ( rest) = tail. strip_prefix ( '\r' ) {
1242- rest
1243- } else {
1244- tail
1245- } ;
1246- Some ( ( action, tail) )
1247- }
1248-
12491209fn worker_context_event_payload (
12501210 worker_launch : & WorkerLaunch ,
12511211 backend : Backend ,
@@ -2574,7 +2534,7 @@ impl WorkerManager {
25742534 worker_timeout : Duration ,
25752535 server_timeout : Duration ,
25762536 ) -> Result < RequestState , WorkerError > {
2577- let text = normalize_input_newlines ( & text) ;
2537+ let text = self . driver . prepare_input_text ( text) ;
25782538 let started_at = std:: time:: Instant :: now ( ) ;
25792539 let prompt = self . current_prompt_hint ( ) ;
25802540 self . remember_prompt ( prompt) ;
@@ -7605,11 +7565,11 @@ mod tests {
76057565 }
76067566
76077567 #[ test]
7608- fn control_prefix_strips_single_separator_newline ( ) {
7568+ fn control_prefix_preserves_immediate_newline_tail ( ) {
76097569 let ( action, remaining) =
76107570 split_write_stdin_control_prefix ( "\u{4} \n print(1)" ) . expect ( "expected control prefix" ) ;
76117571 assert ! ( matches!( action, WriteStdinControlAction :: Restart ) ) ;
7612- assert_eq ! ( remaining, "print (1)" ) ;
7572+ assert_eq ! ( remaining, "\n print (1)" ) ;
76137573 }
76147574
76157575 #[ test]
0 commit comments