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( ) ) ?;
@@ -3361,9 +3375,14 @@ impl ChatSession {
33613375
33623376 /// Helper function to read user input with a prompt and Ctrl+C handling
33633377 fn read_user_input ( & mut self , prompt : & str , exit_on_single_ctrl_c : bool ) -> Option < String > {
3378+ // If this function is called at all, input_source should not be None
3379+ debug_assert ! ( self . input_source. is_some( ) ) ;
3380+
33643381 let mut ctrl_c = false ;
3382+ let input_source = self . input_source . as_mut ( ) ?;
3383+
33653384 loop {
3366- match ( self . input_source . read_line ( Some ( prompt) ) , ctrl_c) {
3385+ match ( input_source. read_line ( Some ( prompt) ) , ctrl_c) {
33673386 ( Ok ( Some ( line) ) , _) => {
33683387 if line. trim ( ) . is_empty ( ) {
33693388 continue ; // Reprompt if the input is empty
@@ -3835,11 +3854,11 @@ mod tests {
38353854 "fake_conv_id" ,
38363855 agents,
38373856 None ,
3838- InputSource :: new_mock ( vec ! [
3857+ Some ( InputSource :: new_mock ( vec ! [
38393858 "create a new file" . to_string( ) ,
38403859 "y" . to_string( ) ,
38413860 "exit" . to_string( ) ,
3842- ] ) ,
3861+ ] ) ) ,
38433862 false ,
38443863 || Some ( 80 ) ,
38453864 tool_manager,
@@ -3963,7 +3982,7 @@ mod tests {
39633982 "fake_conv_id" ,
39643983 agents,
39653984 None ,
3966- InputSource :: new_mock ( vec ! [
3985+ Some ( InputSource :: new_mock ( vec ! [
39673986 "/tools" . to_string( ) ,
39683987 "/tools help" . to_string( ) ,
39693988 "create a new file" . to_string( ) ,
@@ -3980,7 +3999,7 @@ mod tests {
39803999 "create a file" . to_string( ) , // prompt again due to reset
39814000 "n" . to_string( ) , // cancel
39824001 "exit" . to_string( ) ,
3983- ] ) ,
4002+ ] ) ) ,
39844003 false ,
39854004 || Some ( 80 ) ,
39864005 tool_manager,
@@ -4068,15 +4087,15 @@ mod tests {
40684087 "fake_conv_id" ,
40694088 agents,
40704089 None ,
4071- InputSource :: new_mock ( vec ! [
4090+ Some ( InputSource :: new_mock ( vec ! [
40724091 "create 2 new files parallel" . to_string( ) ,
40734092 "t" . to_string( ) ,
40744093 "/tools reset" . to_string( ) ,
40754094 "create 2 new files parallel" . to_string( ) ,
40764095 "y" . to_string( ) ,
40774096 "y" . to_string( ) ,
40784097 "exit" . to_string( ) ,
4079- ] ) ,
4098+ ] ) ) ,
40804099 false ,
40814100 || Some ( 80 ) ,
40824101 tool_manager,
@@ -4144,13 +4163,13 @@ mod tests {
41444163 "fake_conv_id" ,
41454164 agents,
41464165 None ,
4147- InputSource :: new_mock ( vec ! [
4166+ Some ( InputSource :: new_mock ( vec ! [
41484167 "/tools trust-all" . to_string( ) ,
41494168 "create a new file" . to_string( ) ,
41504169 "/tools reset" . to_string( ) ,
41514170 "create a new file" . to_string( ) ,
41524171 "exit" . to_string( ) ,
4153- ] ) ,
4172+ ] ) ) ,
41544173 false ,
41554174 || Some ( 80 ) ,
41564175 tool_manager,
@@ -4200,7 +4219,11 @@ mod tests {
42004219 "fake_conv_id" ,
42014220 agents,
42024221 None ,
4203- InputSource :: new_mock ( vec ! [ "/subscribe" . to_string( ) , "y" . to_string( ) , "/quit" . to_string( ) ] ) ,
4222+ Some ( InputSource :: new_mock ( vec ! [
4223+ "/subscribe" . to_string( ) ,
4224+ "y" . to_string( ) ,
4225+ "/quit" . to_string( ) ,
4226+ ] ) ) ,
42044227 false ,
42054228 || Some ( 80 ) ,
42064229 tool_manager,
@@ -4303,11 +4326,11 @@ mod tests {
43034326 "fake_conv_id" ,
43044327 agents,
43054328 None , // No initial input
4306- InputSource :: new_mock ( vec ! [
4329+ Some ( InputSource :: new_mock ( vec ! [
43074330 "read /test.txt" . to_string( ) ,
43084331 "y" . to_string( ) , // Accept tool execution
43094332 "exit" . to_string( ) ,
4310- ] ) ,
4333+ ] ) ) ,
43114334 false ,
43124335 || Some ( 80 ) ,
43134336 tool_manager,
@@ -4437,7 +4460,10 @@ mod tests {
44374460 "test_conv_id" ,
44384461 agents,
44394462 None ,
4440- InputSource :: new_mock ( vec ! [ "read /sensitive.txt" . to_string( ) , "exit" . to_string( ) ] ) ,
4463+ Some ( InputSource :: new_mock ( vec ! [
4464+ "read /sensitive.txt" . to_string( ) ,
4465+ "exit" . to_string( ) ,
4466+ ] ) ) ,
44414467 false ,
44424468 || Some ( 80 ) ,
44434469 tool_manager,
0 commit comments