11use crate :: theme:: StyledText ;
2- use crate :: util:: ui:: should_send_structured_message;
2+ use crate :: util:: ui:: {
3+ should_send_structured_message,
4+ should_use_ui_managed_input,
5+ } ;
36pub mod cli;
47mod consts;
58pub mod context;
@@ -426,13 +429,18 @@ impl ChatArgs {
426429 . build ( os, Box :: new ( std:: io:: stderr ( ) ) , !self . no_interactive )
427430 . await ?;
428431 let tool_config = tool_manager. load_tools ( os, & mut stderr) . await ?;
432+ let input_source = if should_use_ui_managed_input ( ) {
433+ None
434+ } else {
435+ Some ( InputSource :: new ( os, prompt_request_sender, prompt_response_receiver) ?)
436+ } ;
429437
430438 ChatSession :: new (
431439 os,
432440 & conversation_id,
433441 agents,
434442 input,
435- InputSource :: new ( os , prompt_request_sender , prompt_response_receiver ) ? ,
443+ input_source ,
436444 self . resume ,
437445 || terminal:: window_size ( ) . map ( |s| s. columns . into ( ) ) . ok ( ) ,
438446 tool_manager,
@@ -575,7 +583,7 @@ pub struct ChatSession {
575583 initial_input : Option < String > ,
576584 /// Whether we're starting a new conversation or continuing an old one.
577585 existing_conversation : bool ,
578- input_source : InputSource ,
586+ input_source : Option < InputSource > ,
579587 /// Width of the terminal, required for [ParseState].
580588 terminal_width_provider : fn ( ) -> Option < usize > ,
581589 spinner : Option < Spinners > ,
@@ -614,7 +622,7 @@ impl ChatSession {
614622 conversation_id : & str ,
615623 mut agents : Agents ,
616624 mut input : Option < String > ,
617- input_source : InputSource ,
625+ input_source : Option < InputSource > ,
618626 resume_conversation : bool ,
619627 terminal_width_provider : fn ( ) -> Option < usize > ,
620628 tool_manager : ToolManager ,
@@ -627,13 +635,14 @@ impl ChatSession {
627635 // Only load prior conversation if we need to resume
628636 let mut existing_conversation = false ;
629637
638+ let should_use_ui_managed_input = input_source. is_none ( ) ;
630639 let should_send_structured_msg = should_send_structured_message ( os) ;
631640 let ( view_end, managed_input, mut control_end_stderr, control_end_stdout) =
632641 get_legacy_conduits ( should_send_structured_msg) ;
633642
634643 let stderr = std:: io:: stderr ( ) ;
635644 let stdout = std:: io:: stdout ( ) ;
636- if let Err ( e) = view_end. into_legacy_mode ( true , StyledText , stderr, stdout) {
645+ if let Err ( e) = view_end. into_legacy_mode ( should_use_ui_managed_input , StyledText , stderr, stdout) {
637646 error ! ( "Conduit view end legacy mode exited: {:?}" , e) ;
638647 }
639648
@@ -737,7 +746,11 @@ impl ChatSession {
737746 inner : Some ( ChatState :: default ( ) ) ,
738747 ctrlc_rx,
739748 wrap,
740- managed_input : Some ( managed_input) ,
749+ managed_input : if should_use_ui_managed_input {
750+ Some ( managed_input)
751+ } else {
752+ None
753+ } ,
741754 } )
742755 }
743756
@@ -1904,8 +1917,9 @@ impl ChatSession {
19041917 . filter ( |name| * name != DUMMY_TOOL_NAME )
19051918 . cloned ( )
19061919 . collect :: < Vec < _ > > ( ) ;
1907- self . input_source
1908- . put_skim_command_selector ( os, Arc :: new ( context_manager. clone ( ) ) , tool_names) ;
1920+ if let Some ( input_source) = & mut self . input_source {
1921+ input_source. put_skim_command_selector ( os, Arc :: new ( context_manager. clone ( ) ) , tool_names) ;
1922+ }
19091923 }
19101924
19111925 execute ! ( self . stderr, StyledText :: reset( ) , StyledText :: reset_attributes( ) ) ?;
@@ -3382,9 +3396,14 @@ impl ChatSession {
33823396
33833397 /// Helper function to read user input with a prompt and Ctrl+C handling
33843398 fn read_user_input ( & mut self , prompt : & str , exit_on_single_ctrl_c : bool ) -> Option < String > {
3399+ // If this function is called at all, input_source should not be None
3400+ debug_assert ! ( self . input_source. is_some( ) ) ;
3401+
33853402 let mut ctrl_c = false ;
3403+ let input_source = self . input_source . as_mut ( ) ?;
3404+
33863405 loop {
3387- match ( self . input_source . read_line ( Some ( prompt) ) , ctrl_c) {
3406+ match ( input_source. read_line ( Some ( prompt) ) , ctrl_c) {
33883407 ( Ok ( Some ( line) ) , _) => {
33893408 if line. trim ( ) . is_empty ( ) {
33903409 continue ; // Reprompt if the input is empty
@@ -3856,11 +3875,11 @@ mod tests {
38563875 "fake_conv_id" ,
38573876 agents,
38583877 None ,
3859- InputSource :: new_mock ( vec ! [
3878+ Some ( InputSource :: new_mock ( vec ! [
38603879 "create a new file" . to_string( ) ,
38613880 "y" . to_string( ) ,
38623881 "exit" . to_string( ) ,
3863- ] ) ,
3882+ ] ) ) ,
38643883 false ,
38653884 || Some ( 80 ) ,
38663885 tool_manager,
@@ -3984,7 +4003,7 @@ mod tests {
39844003 "fake_conv_id" ,
39854004 agents,
39864005 None ,
3987- InputSource :: new_mock ( vec ! [
4006+ Some ( InputSource :: new_mock ( vec ! [
39884007 "/tools" . to_string( ) ,
39894008 "/tools help" . to_string( ) ,
39904009 "create a new file" . to_string( ) ,
@@ -4001,7 +4020,7 @@ mod tests {
40014020 "create a file" . to_string( ) , // prompt again due to reset
40024021 "n" . to_string( ) , // cancel
40034022 "exit" . to_string( ) ,
4004- ] ) ,
4023+ ] ) ) ,
40054024 false ,
40064025 || Some ( 80 ) ,
40074026 tool_manager,
@@ -4089,15 +4108,15 @@ mod tests {
40894108 "fake_conv_id" ,
40904109 agents,
40914110 None ,
4092- InputSource :: new_mock ( vec ! [
4111+ Some ( InputSource :: new_mock ( vec ! [
40934112 "create 2 new files parallel" . to_string( ) ,
40944113 "t" . to_string( ) ,
40954114 "/tools reset" . to_string( ) ,
40964115 "create 2 new files parallel" . to_string( ) ,
40974116 "y" . to_string( ) ,
40984117 "y" . to_string( ) ,
40994118 "exit" . to_string( ) ,
4100- ] ) ,
4119+ ] ) ) ,
41014120 false ,
41024121 || Some ( 80 ) ,
41034122 tool_manager,
@@ -4165,13 +4184,13 @@ mod tests {
41654184 "fake_conv_id" ,
41664185 agents,
41674186 None ,
4168- InputSource :: new_mock ( vec ! [
4187+ Some ( InputSource :: new_mock ( vec ! [
41694188 "/tools trust-all" . to_string( ) ,
41704189 "create a new file" . to_string( ) ,
41714190 "/tools reset" . to_string( ) ,
41724191 "create a new file" . to_string( ) ,
41734192 "exit" . to_string( ) ,
4174- ] ) ,
4193+ ] ) ) ,
41754194 false ,
41764195 || Some ( 80 ) ,
41774196 tool_manager,
@@ -4221,7 +4240,11 @@ mod tests {
42214240 "fake_conv_id" ,
42224241 agents,
42234242 None ,
4224- InputSource :: new_mock ( vec ! [ "/subscribe" . to_string( ) , "y" . to_string( ) , "/quit" . to_string( ) ] ) ,
4243+ Some ( InputSource :: new_mock ( vec ! [
4244+ "/subscribe" . to_string( ) ,
4245+ "y" . to_string( ) ,
4246+ "/quit" . to_string( ) ,
4247+ ] ) ) ,
42254248 false ,
42264249 || Some ( 80 ) ,
42274250 tool_manager,
@@ -4324,11 +4347,11 @@ mod tests {
43244347 "fake_conv_id" ,
43254348 agents,
43264349 None , // No initial input
4327- InputSource :: new_mock ( vec ! [
4350+ Some ( InputSource :: new_mock ( vec ! [
43284351 "read /test.txt" . to_string( ) ,
43294352 "y" . to_string( ) , // Accept tool execution
43304353 "exit" . to_string( ) ,
4331- ] ) ,
4354+ ] ) ) ,
43324355 false ,
43334356 || Some ( 80 ) ,
43344357 tool_manager,
@@ -4458,7 +4481,10 @@ mod tests {
44584481 "test_conv_id" ,
44594482 agents,
44604483 None ,
4461- InputSource :: new_mock ( vec ! [ "read /sensitive.txt" . to_string( ) , "exit" . to_string( ) ] ) ,
4484+ Some ( InputSource :: new_mock ( vec ! [
4485+ "read /sensitive.txt" . to_string( ) ,
4486+ "exit" . to_string( ) ,
4487+ ] ) ) ,
44624488 false ,
44634489 || Some ( 80 ) ,
44644490 tool_manager,
0 commit comments