@@ -4,7 +4,10 @@ use spinners::{
44} ;
55
66use crate :: theme:: StyledText ;
7- use crate :: util:: ui:: should_send_structured_message;
7+ use crate :: util:: ui:: {
8+ should_send_structured_message,
9+ should_use_ui_managed_input,
10+ } ;
811pub mod cli;
912mod consts;
1013pub mod context;
@@ -429,13 +432,18 @@ impl ChatArgs {
429432 . build ( os, Box :: new ( std:: io:: stderr ( ) ) , !self . no_interactive )
430433 . await ?;
431434 let tool_config = tool_manager. load_tools ( os, & mut stderr) . await ?;
435+ let input_source = if should_use_ui_managed_input ( ) {
436+ None
437+ } else {
438+ Some ( InputSource :: new ( os, prompt_request_sender, prompt_response_receiver) ?)
439+ } ;
432440
433441 ChatSession :: new (
434442 os,
435443 & conversation_id,
436444 agents,
437445 input,
438- InputSource :: new ( os , prompt_request_sender , prompt_response_receiver ) ? ,
446+ input_source ,
439447 self . resume ,
440448 || terminal:: window_size ( ) . map ( |s| s. columns . into ( ) ) . ok ( ) ,
441449 tool_manager,
@@ -578,7 +586,7 @@ pub struct ChatSession {
578586 initial_input : Option < String > ,
579587 /// Whether we're starting a new conversation or continuing an old one.
580588 existing_conversation : bool ,
581- input_source : InputSource ,
589+ input_source : Option < InputSource > ,
582590 /// Width of the terminal, required for [ParseState].
583591 terminal_width_provider : fn ( ) -> Option < usize > ,
584592 spinner : Option < Spinner > ,
@@ -617,7 +625,7 @@ impl ChatSession {
617625 conversation_id : & str ,
618626 mut agents : Agents ,
619627 mut input : Option < String > ,
620- input_source : InputSource ,
628+ input_source : Option < InputSource > ,
621629 resume_conversation : bool ,
622630 terminal_width_provider : fn ( ) -> Option < usize > ,
623631 tool_manager : ToolManager ,
@@ -630,13 +638,14 @@ impl ChatSession {
630638 // Only load prior conversation if we need to resume
631639 let mut existing_conversation = false ;
632640
641+ let should_use_ui_managed_input = input_source. is_none ( ) ;
633642 let should_send_structured_msg = should_send_structured_message ( os) ;
634643 let ( view_end, managed_input, mut control_end_stderr, control_end_stdout) =
635644 get_legacy_conduits ( should_send_structured_msg) ;
636645
637646 let stderr = std:: io:: stderr ( ) ;
638647 let stdout = std:: io:: stdout ( ) ;
639- if let Err ( e) = view_end. into_legacy_mode ( true , StyledText , stderr, stdout) {
648+ if let Err ( e) = view_end. into_legacy_mode ( should_use_ui_managed_input , StyledText , stderr, stdout) {
640649 error ! ( "Conduit view end legacy mode exited: {:?}" , e) ;
641650 }
642651
@@ -740,7 +749,11 @@ impl ChatSession {
740749 inner : Some ( ChatState :: default ( ) ) ,
741750 ctrlc_rx,
742751 wrap,
743- managed_input : Some ( managed_input) ,
752+ managed_input : if should_use_ui_managed_input {
753+ Some ( managed_input)
754+ } else {
755+ None
756+ } ,
744757 } )
745758 }
746759
@@ -1938,8 +1951,9 @@ impl ChatSession {
19381951 . filter ( |name| * name != DUMMY_TOOL_NAME )
19391952 . cloned ( )
19401953 . collect :: < Vec < _ > > ( ) ;
1941- self . input_source
1942- . put_skim_command_selector ( os, Arc :: new ( context_manager. clone ( ) ) , tool_names) ;
1954+ if let Some ( input_source) = & mut self . input_source {
1955+ input_source. put_skim_command_selector ( os, Arc :: new ( context_manager. clone ( ) ) , tool_names) ;
1956+ }
19431957 }
19441958
19451959 execute ! ( self . stderr, StyledText :: reset( ) , StyledText :: reset_attributes( ) ) ?;
@@ -3438,9 +3452,14 @@ impl ChatSession {
34383452
34393453 /// Helper function to read user input with a prompt and Ctrl+C handling
34403454 fn read_user_input ( & mut self , prompt : & str , exit_on_single_ctrl_c : bool ) -> Option < String > {
3455+ // If this function is called at all, input_source should not be None
3456+ debug_assert ! ( self . input_source. is_some( ) ) ;
3457+
34413458 let mut ctrl_c = false ;
3459+ let input_source = self . input_source . as_mut ( ) ?;
3460+
34423461 loop {
3443- match ( self . input_source . read_line ( Some ( prompt) ) , ctrl_c) {
3462+ match ( input_source. read_line ( Some ( prompt) ) , ctrl_c) {
34443463 ( Ok ( Some ( line) ) , _) => {
34453464 if line. trim ( ) . is_empty ( ) {
34463465 continue ; // Reprompt if the input is empty
@@ -3912,11 +3931,11 @@ mod tests {
39123931 "fake_conv_id" ,
39133932 agents,
39143933 None ,
3915- InputSource :: new_mock ( vec ! [
3934+ Some ( InputSource :: new_mock ( vec ! [
39163935 "create a new file" . to_string( ) ,
39173936 "y" . to_string( ) ,
39183937 "exit" . to_string( ) ,
3919- ] ) ,
3938+ ] ) ) ,
39203939 false ,
39213940 || Some ( 80 ) ,
39223941 tool_manager,
@@ -4040,7 +4059,7 @@ mod tests {
40404059 "fake_conv_id" ,
40414060 agents,
40424061 None ,
4043- InputSource :: new_mock ( vec ! [
4062+ Some ( InputSource :: new_mock ( vec ! [
40444063 "/tools" . to_string( ) ,
40454064 "/tools help" . to_string( ) ,
40464065 "create a new file" . to_string( ) ,
@@ -4057,7 +4076,7 @@ mod tests {
40574076 "create a file" . to_string( ) , // prompt again due to reset
40584077 "n" . to_string( ) , // cancel
40594078 "exit" . to_string( ) ,
4060- ] ) ,
4079+ ] ) ) ,
40614080 false ,
40624081 || Some ( 80 ) ,
40634082 tool_manager,
@@ -4145,15 +4164,15 @@ mod tests {
41454164 "fake_conv_id" ,
41464165 agents,
41474166 None ,
4148- InputSource :: new_mock ( vec ! [
4167+ Some ( InputSource :: new_mock ( vec ! [
41494168 "create 2 new files parallel" . to_string( ) ,
41504169 "t" . to_string( ) ,
41514170 "/tools reset" . to_string( ) ,
41524171 "create 2 new files parallel" . to_string( ) ,
41534172 "y" . to_string( ) ,
41544173 "y" . to_string( ) ,
41554174 "exit" . to_string( ) ,
4156- ] ) ,
4175+ ] ) ) ,
41574176 false ,
41584177 || Some ( 80 ) ,
41594178 tool_manager,
@@ -4221,13 +4240,13 @@ mod tests {
42214240 "fake_conv_id" ,
42224241 agents,
42234242 None ,
4224- InputSource :: new_mock ( vec ! [
4243+ Some ( InputSource :: new_mock ( vec ! [
42254244 "/tools trust-all" . to_string( ) ,
42264245 "create a new file" . to_string( ) ,
42274246 "/tools reset" . to_string( ) ,
42284247 "create a new file" . to_string( ) ,
42294248 "exit" . to_string( ) ,
4230- ] ) ,
4249+ ] ) ) ,
42314250 false ,
42324251 || Some ( 80 ) ,
42334252 tool_manager,
@@ -4277,7 +4296,11 @@ mod tests {
42774296 "fake_conv_id" ,
42784297 agents,
42794298 None ,
4280- InputSource :: new_mock ( vec ! [ "/subscribe" . to_string( ) , "y" . to_string( ) , "/quit" . to_string( ) ] ) ,
4299+ Some ( InputSource :: new_mock ( vec ! [
4300+ "/subscribe" . to_string( ) ,
4301+ "y" . to_string( ) ,
4302+ "/quit" . to_string( ) ,
4303+ ] ) ) ,
42814304 false ,
42824305 || Some ( 80 ) ,
42834306 tool_manager,
@@ -4380,11 +4403,11 @@ mod tests {
43804403 "fake_conv_id" ,
43814404 agents,
43824405 None , // No initial input
4383- InputSource :: new_mock ( vec ! [
4406+ Some ( InputSource :: new_mock ( vec ! [
43844407 "read /test.txt" . to_string( ) ,
43854408 "y" . to_string( ) , // Accept tool execution
43864409 "exit" . to_string( ) ,
4387- ] ) ,
4410+ ] ) ) ,
43884411 false ,
43894412 || Some ( 80 ) ,
43904413 tool_manager,
@@ -4514,7 +4537,10 @@ mod tests {
45144537 "test_conv_id" ,
45154538 agents,
45164539 None ,
4517- InputSource :: new_mock ( vec ! [ "read /sensitive.txt" . to_string( ) , "exit" . to_string( ) ] ) ,
4540+ Some ( InputSource :: new_mock ( vec ! [
4541+ "read /sensitive.txt" . to_string( ) ,
4542+ "exit" . to_string( ) ,
4543+ ] ) ) ,
45184544 false ,
45194545 || Some ( 80 ) ,
45204546 tool_manager,
0 commit comments