@@ -119,6 +119,7 @@ pub async fn chat(initial_input: Option<String>) -> Result<ExitCode> {
119119 if is_interactive {
120120 queue ! (
121121 output,
122+ cursor:: MoveToColumn ( 0 ) ,
122123 style:: SetAttribute ( Attribute :: Reset ) ,
123124 style:: ResetColor ,
124125 cursor:: Show
@@ -130,63 +131,6 @@ pub async fn chat(initial_input: Option<String>) -> Result<ExitCode> {
130131 result. map ( |_| ExitCode :: SUCCESS )
131132}
132133
133- /// Testing helper
134- fn split_tool_use_event ( value : & Map < String , serde_json:: Value > ) -> Vec < ChatResponseStream > {
135- let tool_use_id = value. get ( "tool_use_id" ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_string ( ) ;
136- let name = value. get ( "name" ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_string ( ) ;
137- let args_str = value. get ( "args" ) . unwrap ( ) . to_string ( ) ;
138- let split_point = args_str. len ( ) / 2 ;
139- vec ! [
140- ChatResponseStream :: ToolUseEvent {
141- tool_use_id: tool_use_id. clone( ) ,
142- name: name. clone( ) ,
143- input: None ,
144- stop: None ,
145- } ,
146- ChatResponseStream :: ToolUseEvent {
147- tool_use_id: tool_use_id. clone( ) ,
148- name: name. clone( ) ,
149- input: Some ( args_str. split_at( split_point) . 0 . to_string( ) ) ,
150- stop: None ,
151- } ,
152- ChatResponseStream :: ToolUseEvent {
153- tool_use_id: tool_use_id. clone( ) ,
154- name: name. clone( ) ,
155- input: Some ( args_str. split_at( split_point) . 1 . to_string( ) ) ,
156- stop: None ,
157- } ,
158- ChatResponseStream :: ToolUseEvent {
159- tool_use_id: tool_use_id. clone( ) ,
160- name: name. clone( ) ,
161- input: None ,
162- stop: Some ( true ) ,
163- } ,
164- ]
165- }
166-
167- /// Testing helper
168- fn create_stream ( model_responses : serde_json:: Value ) -> StreamingClient {
169- let mut mock = Vec :: new ( ) ;
170- for response in model_responses. as_array ( ) . unwrap ( ) {
171- let mut stream = Vec :: new ( ) ;
172- for event in response. as_array ( ) . unwrap ( ) {
173- match event {
174- serde_json:: Value :: String ( assistant_text) => {
175- stream. push ( ChatResponseStream :: AssistantResponseEvent {
176- content : assistant_text. to_string ( ) ,
177- } ) ;
178- } ,
179- serde_json:: Value :: Object ( tool_use) => {
180- stream. append ( & mut split_tool_use_event ( tool_use) ) ;
181- } ,
182- other => panic ! ( "Unexpected value: {:?}" , other) ,
183- }
184- }
185- mock. push ( stream) ;
186- }
187- StreamingClient :: mock ( mock)
188- }
189-
190134/// The tools that can be used by the model.
191135#[ derive( Debug , Clone ) ]
192136pub struct ToolConfiguration {
@@ -330,7 +274,10 @@ Hi, I'm <g>Amazon Q</g>. Ask me anything.
330274 } ;
331275 } ,
332276 Err ( err) => {
333- bail ! ( "An error occurred reading the model's response: {:?}" , err) ;
277+ bail ! (
278+ "We're having trouble responding right now, please try again later: {:?}" ,
279+ err
280+ ) ;
334281 } ,
335282 }
336283
@@ -508,24 +455,36 @@ Hi, I'm <g>Amazon Q</g>. Ask me anything.
508455 if self . tool_use_recursions > MAX_TOOL_USE_RECURSIONS {
509456 bail ! ( "Exceeded max tool use recursion limit: {}" , MAX_TOOL_USE_RECURSIONS ) ;
510457 }
511- for ( _, tool) in & queued_tools {
512- queue ! ( self . output, style:: Print ( format!( "{}\n " , "▔" . repeat( terminal_width) ) ) ) ?;
513- queue ! ( self . output, style:: SetAttribute ( Attribute :: Bold ) ) ?;
514- queue ! ( self . output, style:: Print ( format!( "{}\n " , tool. display_name( ) ) ) ) ?;
515- queue ! ( self . output, style:: SetAttribute ( Attribute :: NormalIntensity ) ) ?;
516- queue ! ( self . output, style:: Print ( format!( "{}\n \n " , "▁" . repeat( terminal_width) ) ) ) ?;
458+
459+ for ( i, ( _, tool) ) in queued_tools. iter ( ) . enumerate ( ) {
460+ queue ! (
461+ self . output,
462+ style:: SetForegroundColor ( Color :: Cyan ) ,
463+ style:: Print ( format!( "{}. {}\n " , i + 1 , tool. display_name( ) ) ) ,
464+ style:: SetForegroundColor ( Color :: Reset ) ,
465+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
466+ style:: Print ( format!( "{}\n " , "▔" . repeat( terminal_width) ) ) ,
467+ ) ?;
517468 tool. queue_description ( & self . ctx , self . output ) ?;
518469 queue ! ( self . output, style:: Print ( "\n " ) ) ?;
519470 }
520- queue ! ( self . output, style:: Print ( "▁" . repeat( terminal_width) ) ) ?;
521- queue ! ( self . output, style:: Print ( "\n \n " ) ) ?;
471+
522472 execute ! (
523473 self . output,
524- style:: Print ( "Enter " ) ,
474+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
475+ style:: Print ( "▁" . repeat( terminal_width) ) ,
476+ style:: ResetColor ,
477+ style:: Print ( "\n \n Enter " ) ,
525478 style:: SetForegroundColor ( Color :: Green ) ,
526479 style:: Print ( "y" ) ,
527480 style:: ResetColor ,
528- style:: Print ( " to consent to running these tools, or anything else to continue your conversation.\n \n " )
481+ style:: Print ( format!(
482+ " to run {}, or otherwise continue your conversation.\n \n " ,
483+ match queued_tools. len( ) == 1 {
484+ true => "this tool" ,
485+ false => "these tools" ,
486+ }
487+ ) ) ,
529488 ) ?;
530489 }
531490
@@ -727,6 +686,63 @@ impl From<ToolUseEventBuilder> for fig_telemetry::EventType {
727686 }
728687}
729688
689+ /// Testing helper
690+ fn split_tool_use_event ( value : & Map < String , serde_json:: Value > ) -> Vec < ChatResponseStream > {
691+ let tool_use_id = value. get ( "tool_use_id" ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_string ( ) ;
692+ let name = value. get ( "name" ) . unwrap ( ) . as_str ( ) . unwrap ( ) . to_string ( ) ;
693+ let args_str = value. get ( "args" ) . unwrap ( ) . to_string ( ) ;
694+ let split_point = args_str. len ( ) / 2 ;
695+ vec ! [
696+ ChatResponseStream :: ToolUseEvent {
697+ tool_use_id: tool_use_id. clone( ) ,
698+ name: name. clone( ) ,
699+ input: None ,
700+ stop: None ,
701+ } ,
702+ ChatResponseStream :: ToolUseEvent {
703+ tool_use_id: tool_use_id. clone( ) ,
704+ name: name. clone( ) ,
705+ input: Some ( args_str. split_at( split_point) . 0 . to_string( ) ) ,
706+ stop: None ,
707+ } ,
708+ ChatResponseStream :: ToolUseEvent {
709+ tool_use_id: tool_use_id. clone( ) ,
710+ name: name. clone( ) ,
711+ input: Some ( args_str. split_at( split_point) . 1 . to_string( ) ) ,
712+ stop: None ,
713+ } ,
714+ ChatResponseStream :: ToolUseEvent {
715+ tool_use_id: tool_use_id. clone( ) ,
716+ name: name. clone( ) ,
717+ input: None ,
718+ stop: Some ( true ) ,
719+ } ,
720+ ]
721+ }
722+
723+ /// Testing helper
724+ fn create_stream ( model_responses : serde_json:: Value ) -> StreamingClient {
725+ let mut mock = Vec :: new ( ) ;
726+ for response in model_responses. as_array ( ) . unwrap ( ) {
727+ let mut stream = Vec :: new ( ) ;
728+ for event in response. as_array ( ) . unwrap ( ) {
729+ match event {
730+ serde_json:: Value :: String ( assistant_text) => {
731+ stream. push ( ChatResponseStream :: AssistantResponseEvent {
732+ content : assistant_text. to_string ( ) ,
733+ } ) ;
734+ } ,
735+ serde_json:: Value :: Object ( tool_use) => {
736+ stream. append ( & mut split_tool_use_event ( tool_use) ) ;
737+ } ,
738+ other => panic ! ( "Unexpected value: {:?}" , other) ,
739+ }
740+ }
741+ mock. push ( stream) ;
742+ }
743+ StreamingClient :: mock ( mock)
744+ }
745+
730746#[ cfg( test) ]
731747mod tests {
732748 use fig_api_client:: model:: ChatResponseStream ;
0 commit comments