[object Object]

← back to Exo

Add status=downloaded filter for model endpoint (#1539)

19bc09550d55ca52344d53ac44a5c8089bf20219 · 2026-02-18 22:34:11 +0000 · rltakashige

## Motivation

https://github.com/exo-explore/exo/issues/1346#issuecomment-3831427905


## Test Plan

### Manual Testing
**Without filter**
<img width="1708" height="1010" alt="Screenshot 2026-02-18 at 22 26 22"
src="https://github.com/user-attachments/assets/f4bf7142-717d-4042-ac28-d8a55a8e45e7"
/>

**With filter**
<img width="1723" height="1021" alt="Screenshot 2026-02-18 at 22 26 45"
src="https://github.com/user-attachments/assets/40a522d5-c6e6-4148-b21a-02caa1221ebe"
/>

Files touched

Diff

commit 19bc09550d55ca52344d53ac44a5c8089bf20219
Author: rltakashige <rl.takashige@gmail.com>
Date:   Wed Feb 18 22:34:11 2026 +0000

    Add status=downloaded filter for model endpoint (#1539)
    
    ## Motivation
    
    https://github.com/exo-explore/exo/issues/1346#issuecomment-3831427905
    
    
    ## Test Plan
    
    ### Manual Testing
    **Without filter**
    <img width="1708" height="1010" alt="Screenshot 2026-02-18 at 22 26 22"
    src="https://github.com/user-attachments/assets/f4bf7142-717d-4042-ac28-d8a55a8e45e7"
    />
    
    **With filter**
    <img width="1723" height="1021" alt="Screenshot 2026-02-18 at 22 26 45"
    src="https://github.com/user-attachments/assets/40a522d5-c6e6-4148-b21a-02caa1221ebe"
    />
---
 src/exo/master/api.py | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/exo/master/api.py b/src/exo/master/api.py
index 3c29b041..c85999a3 100644
--- a/src/exo/master/api.py
+++ b/src/exo/master/api.py
@@ -145,6 +145,7 @@ from exo.shared.types.openai_responses import (
     ResponsesResponse,
 )
 from exo.shared.types.state import State
+from exo.shared.types.worker.downloads import DownloadCompleted
 from exo.shared.types.worker.instances import Instance, InstanceId, InstanceMeta
 from exo.shared.types.worker.shards import Sharding
 from exo.utils.banner import print_startup_banner
@@ -1292,8 +1293,18 @@ class API:
 
         return total_available
 
-    async def get_models(self) -> ModelList:
-        """Returns list of available models."""
+    async def get_models(self, status: str | None = Query(default=None)) -> ModelList:
+        """Returns list of available models, optionally filtered by being downloaded."""
+        cards = await get_model_cards()
+
+        if status == "downloaded":
+            downloaded_model_ids: set[str] = set()
+            for node_downloads in self.state.downloads.values():
+                for dl in node_downloads:
+                    if isinstance(dl, DownloadCompleted):
+                        downloaded_model_ids.add(dl.shard_metadata.model_card.model_id)
+            cards = [c for c in cards if c.model_id in downloaded_model_ids]
+
         return ModelList(
             data=[
                 ModelListModel(
@@ -1311,7 +1322,7 @@ class API:
                     base_model=card.base_model,
                     capabilities=card.capabilities,
                 )
-                for card in await get_model_cards()
+                for card in cards
             ]
         )
 

← 7cadca4f Try multiple endpoints for internet connectivity check (#151  ·  back to Exo  ·  feat: add prefill progress bar for long prompts (#1181) 025ed9fd →