Skip to content

Commit 4254886

Browse files
Add download cancellation option for models
1 parent cbd6dfd commit 4254886

File tree

2 files changed

+86
-24
lines changed

2 files changed

+86
-24
lines changed

assets/js/chatmkAI.js

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class ChatMKAI {
88
this.wllama = null;
99
this.isLoading = false;
1010
this.isLoaded = false;
11+
this.downloadController = null; // For cancelling downloads
1112
this.modelPath =
1213
"https://huggingface.co/QuantFactory/SmolLM2-360M-Instruct-GGUF/resolve/main/SmolLM2-360M-Instruct.Q8_0.gguf";
1314
}
@@ -21,6 +22,7 @@ class ChatMKAI {
2122
}
2223

2324
this.isLoading = true;
25+
this.downloadController = new AbortController(); // Create abort controller
2426
console.log("ChatMK AI: Starting model initialization...");
2527

2628
try {
@@ -61,6 +63,11 @@ class ChatMKAI {
6163
n_ctx: 2048, // Set context size during model loading
6264
n_ctx_per_seq: 2048, // Set per-sequence context during model loading
6365
progressCallback: ({ loaded, total }) => {
66+
// Check if cancelled
67+
if (this.downloadController?.signal.aborted) {
68+
throw new Error('Download cancelled by user');
69+
}
70+
6471
const percent = Math.round((loaded / total) * 100);
6572
const mbLoaded = Math.round(loaded / 1024 / 1024);
6673
const mbTotal = Math.round(total / 1024 / 1024);
@@ -79,22 +86,36 @@ class ChatMKAI {
7986

8087
this.isLoaded = true;
8188
this.isLoading = false;
89+
this.downloadController = null;
8290
console.log("ChatMK AI: Model loaded successfully!");
8391

84-
// Update UI to show AI is ready
85-
this.updateLoadingStatus("Language model ready!");
86-
8792
return true;
8893
} catch (error) {
89-
console.error("ChatMK AI: Failed to initialize model:", error);
9094
this.isLoading = false;
95+
this.downloadController = null;
9196

92-
// For now, disable AI if it fails to load
93-
this.updateLoadingStatus("Language model unavailable - using search only");
97+
if (error.message.includes('cancelled')) {
98+
console.log("ChatMK AI: Download cancelled by user");
99+
this.showProgressInModal(0, 0, 150, 'Language model skipped → using search only');
100+
return false;
101+
}
102+
103+
console.error("ChatMK AI: Failed to initialize model:", error);
104+
this.showProgressInModal(0, 0, 150, 'Language model failed → using search only');
94105
return false;
95106
}
96107
}
97108

109+
/**
110+
* Cancel the download
111+
*/
112+
cancelDownload() {
113+
if (this.downloadController) {
114+
this.downloadController.abort();
115+
console.log("ChatMK AI: Download cancelled");
116+
}
117+
}
118+
98119
/**
99120
* Generate AI response (without search results - those are shown separately)
100121
*/
@@ -194,26 +215,20 @@ ${userMessage}
194215
return cleaned.trim();
195216
}
196217

197-
/**
198-
* Update loading status in the UI
199-
*/
200-
updateLoadingStatus(message) {
201-
// This will be called from the modal to update status
202-
if (typeof window.updateAIStatus === "function") {
203-
window.updateAIStatus(message);
204-
}
205-
}
218+
206219

207220
/**
208221
* Show progress in ChatMK modal if it's open
209222
*/
210-
showProgressInModal(percent, mbLoaded, mbTotal) {
223+
showProgressInModal(percent, mbLoaded, mbTotal, customMessage = null) {
211224
const modal = document.getElementById("chatmk-modal");
212225
if (modal && modal.classList.contains("is-active")) {
213226
// Add a system message about AI loading progress
214-
const progressMsg = percent === 100
227+
const progressMsg = customMessage
228+
? customMessage
229+
: percent === 100
215230
? `Language model loaded: SmolLM2-360M-Q8`
216-
: `Language model loading: ${percent}% (${mbLoaded}/${mbTotal} MB)`;
231+
: `Language model loading: ${percent}% (${mbLoaded}/${mbTotal} MB) <span onclick="window.chatMKAI.cancelDownload()" style="margin-left: 10px; font-size: 11px; color: var(--text-sub); cursor: pointer; text-decoration: underline;">skip magic</span>`;
217232

218233
// Check if there's already a progress message and update it
219234
const messages = document.getElementById("chatmk-messages");
@@ -252,6 +267,19 @@ ${userMessage}
252267
}
253268
}
254269

270+
/**
271+
* Hide AI progress message
272+
*/
273+
hideProgressMessage() {
274+
const messagesContainer = document.getElementById("chatmk-messages");
275+
if (messagesContainer) {
276+
const progressMessage = messagesContainer.querySelector(".ai-progress");
277+
if (progressMessage) {
278+
progressMessage.remove();
279+
}
280+
}
281+
}
282+
255283
/**
256284
* Check if AI is ready
257285
*/

assets/js/chatmkSearch.js

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class ChatMKSearch {
99
this.isLoaded = false;
1010
this.model = null;
1111
this.transformersLoaded = false;
12+
this.embeddingController = null; // For cancelling embedding downloads
1213
}
1314

1415
/**
@@ -72,7 +73,7 @@ class ChatMKSearch {
7273
/**
7374
* Show embedding model loading progress
7475
*/
75-
showEmbeddingProgress(percent, mbLoaded, mbTotal) {
76+
showEmbeddingProgress(percent, mbLoaded, mbTotal, customMessage = null) {
7677
const messagesContainer = document.getElementById('chatmk-messages');
7778
if (messagesContainer) {
7879
// Check if there's already a progress message and update it
@@ -82,19 +83,23 @@ class ChatMKSearch {
8283
// Update existing progress message
8384
const content = existingProgress.querySelector('.message-content');
8485
if (content) {
85-
if (percent === 100) {
86+
if (customMessage) {
87+
content.innerHTML = `<p>${customMessage}</p>`;
88+
} else if (percent === 100) {
8689
content.innerHTML = `<p>Embedding model loaded: MiniLM-L6-v2</p>`;
8790
} else {
88-
content.innerHTML = `<p>Embedding model loading: ${percent}% (${mbLoaded}/${mbTotal} MB)</p>`;
91+
content.innerHTML = `<p>Embedding model loading: ${percent}% (${mbLoaded}/${mbTotal} MB) <span onclick="window.chatMKSearch.cancelEmbeddingDownload()" style="margin-left: 10px; font-size: 11px; color: var(--text-sub); cursor: pointer; text-decoration: underline;">skip magic</span></p>`;
8992
}
9093
}
9194
} else {
9295
// Create new progress message
9396
const messageDiv = document.createElement('div');
9497
messageDiv.className = 'chatmk-message system embedding-loading';
95-
const messageContent = percent === 100
98+
const messageContent = customMessage
99+
? `<p>${customMessage}</p>`
100+
: percent === 100
96101
? `<p>Embedding model loaded: MiniLM-L6-v2</p>`
97-
: `<p>Embedding model loading: ${percent}% (${mbLoaded}/${mbTotal} MB)</p>`;
102+
: `<p>Embedding model loading: ${percent}% (${mbLoaded}/${mbTotal} MB) <span onclick="window.chatMKSearch.cancelEmbeddingDownload()" style="margin-left: 10px; font-size: 11px; color: var(--text-sub); cursor: pointer; text-decoration: underline;">skip magic</span></p>`;
98103

99104
messageDiv.innerHTML = `
100105
<div class="message-content">
@@ -108,6 +113,16 @@ class ChatMKSearch {
108113
}
109114
}
110115

116+
/**
117+
* Cancel the embedding download
118+
*/
119+
cancelEmbeddingDownload() {
120+
if (this.embeddingController) {
121+
this.embeddingController.abort();
122+
console.log("Embedding download cancelled");
123+
}
124+
}
125+
111126
/**
112127
* Simulate embedding model loading progress
113128
*/
@@ -116,6 +131,11 @@ class ChatMKSearch {
116131

117132
// Simulate progress from 0% to 100%
118133
for (let percent = 0; percent <= 100; percent += 20) {
134+
// Check if cancelled
135+
if (this.embeddingController?.signal.aborted) {
136+
throw new Error('Embedding download cancelled by user');
137+
}
138+
119139
const mbLoaded = Math.round((percent / 100) * totalMB);
120140
this.showEmbeddingProgress(percent, mbLoaded, totalMB);
121141

@@ -134,6 +154,7 @@ class ChatMKSearch {
134154
return;
135155
}
136156

157+
this.embeddingController = new AbortController(); // Create abort controller
137158
console.log('ChatMK: Pre-loading embedding model...');
138159

139160
try {
@@ -160,9 +181,19 @@ class ChatMKSearch {
160181
// Keep showing 100% when done (like AI model)
161182
this.showEmbeddingProgress(100, 25, 25);
162183

184+
this.embeddingController = null;
185+
163186
} catch (error) {
187+
this.embeddingController = null;
188+
189+
if (error.message.includes('cancelled')) {
190+
console.log('ChatMK: Embedding download cancelled by user');
191+
this.showEmbeddingProgress(0, 0, 25, 'Embedding model skipped → this won\'t work');
192+
return false;
193+
}
194+
164195
console.error('ChatMK: Failed to pre-load embedding model:', error);
165-
this.hideModelLoadingMessage();
196+
this.showEmbeddingProgress(0, 0, 25, 'Embedding model failed → this won\'t work');
166197
// Don't throw - allow fallback to keyword search
167198
}
168199
}
@@ -378,3 +409,6 @@ class ChatMKSearch {
378409

379410
// Export for use in other modules
380411
window.ChatMKSearch = ChatMKSearch;
412+
413+
// Global instance
414+
window.chatMKSearch = new ChatMKSearch();

0 commit comments

Comments
 (0)