@@ -34,6 +34,7 @@ pub use error::ApiClientError;
3434use parking_lot:: Mutex ;
3535pub use profile:: list_available_profiles;
3636use serde_json:: Map ;
37+ use tokio:: sync:: RwLock ;
3738use tracing:: {
3839 debug,
3940 error,
@@ -75,6 +76,7 @@ pub struct ApiClient {
7576 sigv4_streaming_client : Option < QDeveloperStreamingClient > ,
7677 mock_client : Option < Arc < Mutex < std:: vec:: IntoIter < Vec < ChatResponseStream > > > > > ,
7778 profile : Option < AuthProfile > ,
79+ model_cache : Arc < RwLock < Option < ( Vec < Model > , Option < Model > ) > > > ,
7880}
7981
8082impl ApiClient {
@@ -114,6 +116,7 @@ impl ApiClient {
114116 sigv4_streaming_client : None ,
115117 mock_client : None ,
116118 profile : None ,
119+ model_cache : Arc :: new ( RwLock :: new ( None ) ) ,
117120 } ;
118121
119122 if let Ok ( json) = env. get ( "Q_MOCK_CHAT_RESPONSE" ) {
@@ -181,6 +184,7 @@ impl ApiClient {
181184 sigv4_streaming_client,
182185 mock_client : None ,
183186 profile,
187+ model_cache : Arc :: new ( RwLock :: new ( None ) ) ,
184188 } )
185189 }
186190
@@ -277,6 +281,30 @@ impl ApiClient {
277281 Ok ( ( models, default_model) )
278282 }
279283
284+ pub async fn list_available_models_cached ( & self ) -> Result < ( Vec < Model > , Option < Model > ) , ApiClientError > {
285+ {
286+ let cache = self . model_cache . read ( ) . await ;
287+ if let Some ( cached) = cache. as_ref ( ) {
288+ tracing:: debug!( "Returning cached model list" ) ;
289+ return Ok ( cached. clone ( ) ) ;
290+ }
291+ }
292+
293+ tracing:: debug!( "Cache miss, fetching models from list_available_models API" ) ;
294+ let result = self . list_available_models ( ) . await ?;
295+ {
296+ let mut cache = self . model_cache . write ( ) . await ;
297+ * cache = Some ( result. clone ( ) ) ;
298+ }
299+ Ok ( result)
300+ }
301+
302+ pub async fn invalidate_model_cache ( & self ) {
303+ let mut cache = self . model_cache . write ( ) . await ;
304+ * cache = None ;
305+ tracing:: info!( "Model cache invalidated" ) ;
306+ }
307+
280308 pub async fn create_subscription_token ( & self ) -> Result < CreateSubscriptionTokenOutput , ApiClientError > {
281309 if cfg ! ( test) {
282310 return Ok ( CreateSubscriptionTokenOutput :: builder ( )
0 commit comments