← 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
M exo/api/chatgpt_api.pyM exo/tinychat/index.cssM exo/tinychat/index.htmlM exo/tinychat/index.js
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 →