@@ -39,6 +39,7 @@ use clap::{
39
39
Parser ,
40
40
} ;
41
41
use cli:: compact:: CompactStrategy ;
42
+ use cli:: model:: select_model;
42
43
use context:: ContextManager ;
43
44
pub use conversation:: ConversationState ;
44
45
use conversation:: TokenWarningLevel ;
@@ -660,6 +661,12 @@ impl ChatSession {
660
661
Err ( ChatError :: Interrupted { tool_uses: None } )
661
662
}
662
663
} ,
664
+ ChatState :: RetryModelOverload => tokio:: select! {
665
+ res = self . retry_model_overload( os) => res,
666
+ Ok ( _) = ctrl_c_stream => {
667
+ Err ( ChatError :: Interrupted { tool_uses: None } )
668
+ }
669
+ } ,
663
670
ChatState :: Exit => return Ok ( ( ) ) ,
664
671
} ;
665
672
@@ -776,15 +783,49 @@ impl ChatSession {
776
783
} ,
777
784
ApiClientError :: QuotaBreach { message, .. } => ( message, Report :: from ( err) , true ) ,
778
785
ApiClientError :: ModelOverloadedError { request_id, .. } => {
786
+ if self . interactive {
787
+ execute ! (
788
+ self . stderr,
789
+ style:: SetAttribute ( Attribute :: Bold ) ,
790
+ style:: SetForegroundColor ( Color :: Red ) ,
791
+ style:: Print (
792
+ "\n The model you've selected is temporarily unavailable. Please select a different model.\n "
793
+ ) ,
794
+ style:: SetAttribute ( Attribute :: Reset ) ,
795
+ style:: SetForegroundColor ( Color :: Reset ) ,
796
+ ) ?;
797
+
798
+ if let Some ( id) = request_id {
799
+ self . conversation
800
+ . append_transcript ( format ! ( "Model unavailable (Request ID: {})" , id) ) ;
801
+ }
802
+
803
+ self . inner = Some ( ChatState :: RetryModelOverload ) ;
804
+
805
+ return Ok ( ( ) ) ;
806
+ }
807
+
808
+ // non-interactive throws this error
809
+ let model_instruction = "Please relaunch with '--model <model_id>' to use a different model." ;
779
810
let err = format ! (
780
- "The model you've selected is temporarily unavailable. Please use '/model' to select a different model and try again.{}\n \n " ,
811
+ "The model you've selected is temporarily unavailable. {}{}\n \n " ,
812
+ model_instruction,
781
813
match request_id {
782
814
Some ( id) => format!( "\n Request ID: {}" , id) ,
783
815
None => "" . to_owned( ) ,
784
816
}
785
817
) ;
786
818
self . conversation . append_transcript ( err. clone ( ) ) ;
787
- ( "Amazon Q is having trouble responding right now" , eyre ! ( err) , true )
819
+ execute ! (
820
+ self . stderr,
821
+ style:: SetAttribute ( Attribute :: Bold ) ,
822
+ style:: SetForegroundColor ( Color :: Red ) ,
823
+ style:: Print ( "Amazon Q is having trouble responding right now:\n " ) ,
824
+ style:: Print ( format!( " {}\n " , err. clone( ) ) ) ,
825
+ style:: SetAttribute ( Attribute :: Reset ) ,
826
+ style:: SetForegroundColor ( Color :: Reset ) ,
827
+ ) ?;
828
+ ( "Amazon Q is having trouble responding right now" , eyre ! ( err) , false )
788
829
} ,
789
830
ApiClientError :: MonthlyLimitReached { .. } => {
790
831
let subscription_status = get_subscription_status ( os) . await ;
@@ -935,6 +976,8 @@ enum ChatState {
935
976
/// Parameters for how to perform the compaction request.
936
977
strategy : CompactStrategy ,
937
978
} ,
979
+ /// Retry the current request if we encounter a model overloaded error.
980
+ RetryModelOverload ,
938
981
/// Exit the chat.
939
982
Exit ,
940
983
}
@@ -2086,6 +2129,35 @@ impl ChatSession {
2086
2129
Ok ( ChatState :: ExecuteTools )
2087
2130
}
2088
2131
2132
+ async fn retry_model_overload ( & mut self , os : & mut Os ) -> Result < ChatState , ChatError > {
2133
+ match select_model ( self ) {
2134
+ Ok ( Some ( _) ) => ( ) ,
2135
+ Ok ( None ) => {
2136
+ // User did not select a model, so reset the current request state.
2137
+ self . conversation . enforce_conversation_invariants ( ) ;
2138
+ self . conversation . reset_next_user_message ( ) ;
2139
+ self . pending_tool_index = None ;
2140
+ return Ok ( ChatState :: PromptUser {
2141
+ skip_printing_tools : false ,
2142
+ } ) ;
2143
+ } ,
2144
+ Err ( err) => return Err ( err) ,
2145
+ }
2146
+
2147
+ let conv_state = self
2148
+ . conversation
2149
+ . as_sendable_conversation_state ( os, & mut self . stderr , true )
2150
+ . await ?;
2151
+
2152
+ if self . interactive {
2153
+ self . spinner = Some ( Spinner :: new ( Spinners :: Dots , "Thinking..." . to_owned ( ) ) ) ;
2154
+ }
2155
+
2156
+ Ok ( ChatState :: HandleResponseStream (
2157
+ os. client . send_message ( conv_state) . await ?,
2158
+ ) )
2159
+ }
2160
+
2089
2161
/// Apply program context to tools that Q may not have.
2090
2162
// We cannot attach this any other way because Tools are constructed by deserializing
2091
2163
// output from Amazon Q.
0 commit comments