[object Object]

← back to Exo

adding a fetch to get initail model object to show models before going through and checking all the download percentages

e99a73949889589cb4ec1fab82b1a82f5de4c154 · 2024-11-25 16:56:32 -0800 · cadenmackenzie

Files touched

Diff

commit e99a73949889589cb4ec1fab82b1a82f5de4c154
Author: cadenmackenzie <cadenmackenzie@gmail.com>
Date:   Mon Nov 25 16:56:32 2024 -0800

    adding a fetch to get initail model object to show models before going through and checking all the download percentages
---
 exo/api/chatgpt_api.py  | 14 ++++++++++++++
 exo/tinychat/index.css  | 14 ++++++++++++++
 exo/tinychat/index.html |  5 ++++-
 exo/tinychat/index.js   | 30 ++++++++++++++++++++++++++----
 4 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/exo/api/chatgpt_api.py b/exo/api/chatgpt_api.py
index de139b91..1747f4ce 100644
--- a/exo/api/chatgpt_api.py
+++ b/exo/api/chatgpt_api.py
@@ -180,6 +180,7 @@ class ChatGPTAPI:
     cors.add(self.app.router.add_get("/healthcheck", self.handle_healthcheck), {"*": cors_options})
     cors.add(self.app.router.add_post("/quit", self.handle_quit), {"*": cors_options})
     cors.add(self.app.router.add_delete("/models/{model_name}", self.handle_delete_model), {"*": cors_options})
+    cors.add(self.app.router.add_get("/initial_models", self.handle_get_initial_models), {"*": cors_options})
 
     if "__compiled__" not in globals():
       self.static_dir = Path(__file__).parent.parent/"tinychat"
@@ -478,6 +479,19 @@ class ChatGPTAPI:
             "detail": f"Server error: {str(e)}"
         }, status=500)
 
+  async def handle_get_initial_models(self, request):
+    model_data = {}
+    for model_name, pretty in pretty_name.items():
+        model_data[model_name] = {
+            "name": pretty,
+            "downloaded": None,  # Initially unknown
+            "download_percentage": None,  # Change from 0 to null
+            "total_size": None,
+            "total_downloaded": None,
+            "loading": True  # Add loading state
+        }
+    return web.json_response(model_data)
+
   async def run(self, host: str = "0.0.0.0", port: int = 52415):
     runner = web.AppRunner(self.app)
     await runner.setup()
diff --git a/exo/tinychat/index.css b/exo/tinychat/index.css
index a565bf4e..3a38ce8a 100644
--- a/exo/tinychat/index.css
+++ b/exo/tinychat/index.css
@@ -600,4 +600,18 @@ main {
 
 .loading-container span {
     font-size: 14px;
+}
+
+/* Add this to your CSS */
+.fa-spin {
+    animation: fa-spin 2s infinite linear;
+}
+
+@keyframes fa-spin {
+    0% {
+        transform: rotate(0deg);
+    }
+    100% {
+        transform: rotate(360deg);
+    }
 }
\ No newline at end of file
diff --git a/exo/tinychat/index.html b/exo/tinychat/index.html
index 530caa3f..6cdc80b0 100644
--- a/exo/tinychat/index.html
+++ b/exo/tinychat/index.html
@@ -49,7 +49,10 @@
             </div>
             <div class="model-info">
                 <div class="model-progress">
-                    <template x-if="model.download_percentage != null">
+                    <template x-if="model.loading">
+                        <span><i class="fas fa-spinner fa-spin"></i> Checking download status...</span>
+                    </template>
+                    <template x-if="!model.loading && model.download_percentage != null">
                         <span x-text="model.downloaded ? 'Downloaded' : `${Math.round(model.download_percentage)}% downloaded`"></span>
                     </template>
                 </div>
diff --git a/exo/tinychat/index.js b/exo/tinychat/index.js
index e724b490..d6b2ee8e 100644
--- a/exo/tinychat/index.js
+++ b/exo/tinychat/index.js
@@ -43,6 +43,9 @@ document.addEventListener("alpine:init", () => {
       // Clean up any pending messages
       localStorage.removeItem("pendingMessage");
 
+      // Get initial model list
+      this.fetchInitialModels();
+
       // Start polling for download progress
       this.startDownloadProgressPolling();
       
@@ -50,6 +53,19 @@ document.addEventListener("alpine:init", () => {
       this.startModelPolling();
     },
 
+    async fetchInitialModels() {
+      try {
+        const response = await fetch(`${window.location.origin}/initial_models`);
+        if (response.ok) {
+          const initialModels = await response.json();
+          this.models = initialModels;
+          console.log('Initial models fetched:', initialModels);
+        }
+      } catch (error) {
+        console.error('Error fetching initial models:', error);
+      }
+    },
+
     async startModelPolling() {
       while (true) {
         try {
@@ -76,10 +92,16 @@ document.addEventListener("alpine:init", () => {
           }
           
           const modelData = JSON.parse(event.data);
-          this.models = {
-            ...this.models,
-            ...modelData
-          };
+          // Update existing model data while preserving other properties
+          Object.entries(modelData).forEach(([modelName, data]) => {
+            if (this.models[modelName]) {
+              this.models[modelName] = {
+                ...this.models[modelName],
+                ...data,
+                loading: false
+              };
+            }
+          });
         };
         
         evtSource.onerror = (error) => {

← ded80b0f ensuring requests do not stack up by moving polling to while  ·  back to Exo  ·  configure git lfs for mp3 files 39a95347 →