@@ -157,6 +157,8 @@ def __init__(self, options: Optional[CopilotClientOptions] = None):
157157 self ._state : ConnectionState = "disconnected"
158158 self ._sessions : dict [str , CopilotSession ] = {}
159159 self ._sessions_lock = threading .Lock ()
160+ self ._models_cache : Optional [list ["ModelInfo" ]] = None
161+ self ._models_cache_lock = threading .Lock ()
160162
161163 def _parse_cli_url (self , url : str ) -> tuple [str , int ]:
162164 """
@@ -281,6 +283,10 @@ async def stop(self) -> list["StopError"]:
281283 await self ._client .stop ()
282284 self ._client = None
283285
286+ # Clear models cache
287+ with self ._models_cache_lock :
288+ self ._models_cache = None
289+
284290 # Kill CLI process
285291 # Kill CLI process (only if we spawned it)
286292 if self ._process and not self ._is_external_server :
@@ -325,6 +331,10 @@ async def force_stop(self) -> None:
325331 pass # Ignore errors during force stop
326332 self ._client = None
327333
334+ # Clear models cache
335+ with self ._models_cache_lock :
336+ self ._models_cache = None
337+
328338 # Kill CLI process immediately
329339 if self ._process and not self ._is_external_server :
330340 self ._process .kill ()
@@ -705,6 +715,9 @@ async def list_models(self) -> list["ModelInfo"]:
705715 """
706716 List available models with their metadata.
707717
718+ Results are cached after the first successful call to avoid rate limiting.
719+ The cache is cleared when the client disconnects.
720+
708721 Returns:
709722 A list of ModelInfo objects with model details.
710723
@@ -720,9 +733,21 @@ async def list_models(self) -> list["ModelInfo"]:
720733 if not self ._client :
721734 raise RuntimeError ("Client not connected" )
722735
736+ # Check cache first (thread-safe)
737+ with self ._models_cache_lock :
738+ if self ._models_cache is not None :
739+ return self ._models_cache
740+
741+ # Cache miss - fetch from backend
723742 response = await self ._client .request ("models.list" , {})
724743 models_data = response .get ("models" , [])
725- return [ModelInfo .from_dict (model ) for model in models_data ]
744+ models = [ModelInfo .from_dict (model ) for model in models_data ]
745+
746+ # Update cache (thread-safe)
747+ with self ._models_cache_lock :
748+ self ._models_cache = models
749+
750+ return models
726751
727752 async def list_sessions (self ) -> list ["SessionMetadata" ]:
728753 """
0 commit comments