mihailik commited on
Commit
06b891a
·
1 Parent(s): f40bfec

Cache model list for network failures.

Browse files
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "localm",
3
- "version": "1.1.21",
4
  "description": "Chat application",
5
  "scripts": {
6
  "build": "esbuild src/index.js --target=es6 --bundle --sourcemap --outfile=./index.js --format=iife --external:fs --external:path --external:child_process --external:ws --external:katex/dist/katex.min.css",
 
1
  {
2
  "name": "localm",
3
+ "version": "1.1.22",
4
  "description": "Chat application",
5
  "scripts": {
6
  "build": "esbuild src/index.js --target=es6 --bundle --sourcemap --outfile=./index.js --format=iife --external:fs --external:path --external:child_process --external:ws --external:katex/dist/katex.min.css",
src/app/model-list.js CHANGED
@@ -1,5 +1,7 @@
1
  // @ts-check
2
 
 
 
3
  /**
4
  * @typedef {{
5
  * id: string,
@@ -24,6 +26,8 @@
24
  let modelCache = null;
25
  let cacheTimestamp = 0;
26
  const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
 
 
27
 
28
  /**
29
  * Size thresholds for mobile capability (in billions of parameters)
@@ -113,15 +117,44 @@ export async function fetchBrowserModels() {
113
 
114
  modelCache = final;
115
  cacheTimestamp = now;
 
 
 
 
 
 
 
 
 
116
 
117
  console.log(`Selected ${auth.length} auth + ${pub.length} public models (total ${final.length})`);
118
- return final;
119
  } catch (error) {
120
  console.error('Failed to fetch models from Hugging Face Hub:', error);
121
-
122
- // Return fallback models if API fails
123
- return getFallbackModels();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
 
 
 
125
  }
126
 
127
  /**
 
1
  // @ts-check
2
 
3
+ import fallbackModels from '../model-cache-filtered.json';
4
+
5
  /**
6
  * @typedef {{
7
  * id: string,
 
26
  let modelCache = null;
27
  let cacheTimestamp = 0;
28
  const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
29
+ const STORAGE_KEY = 'localm_models_cache_v1';
30
+ const STORAGE_TTL = 24 * 60 * 60 * 1000; // 24 hours for persisted cache
31
 
32
  /**
33
  * Size thresholds for mobile capability (in billions of parameters)
 
117
 
118
  modelCache = final;
119
  cacheTimestamp = now;
120
+ // Persist filtered list to localStorage as a fallback for offline or HF failures
121
+ try {
122
+ if (typeof localStorage !== 'undefined') {
123
+ const payload = JSON.stringify({ ts: now, models: final });
124
+ localStorage.setItem(STORAGE_KEY, payload);
125
+ }
126
+ } catch (e) {
127
+ // ignore storage errors
128
+ }
129
 
130
  console.log(`Selected ${auth.length} auth + ${pub.length} public models (total ${final.length})`);
131
+ if (final.length) return final;
132
  } catch (error) {
133
  console.error('Failed to fetch models from Hugging Face Hub:', error);
134
+ // Try to restore from persisted cache before returning static fallback
135
+ }
136
+ try {
137
+ if (typeof localStorage !== 'undefined') {
138
+ const raw = localStorage.getItem(STORAGE_KEY);
139
+ if (raw) {
140
+ const parsed = JSON.parse(raw);
141
+ if (parsed && Array.isArray(parsed.models)) {
142
+ const age = Date.now() - (parsed.ts || 0);
143
+ if (age < STORAGE_TTL) {
144
+ console.warn('Restoring models from localStorage cache (age ' + Math.round(age / 1000) + 's)');
145
+ modelCache = parsed.models;
146
+ cacheTimestamp = Date.now();
147
+ return modelCache;
148
+ }
149
+ }
150
+ }
151
+ }
152
+ } catch (e) {
153
+ // ignore parse/storage errors
154
  }
155
+
156
+ // Return fallback models if API fails and no persisted cache
157
+ return fallbackModels;
158
  }
159
 
160
  /**
src/model-cache-filtered.json ADDED
@@ -0,0 +1,531 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": "sentence-transformers/all-MiniLM-L6-v2",
4
+ "name": "All MiniLM L6 V2",
5
+ "vendor": "sentence-transformers",
6
+ "size": "5.0B",
7
+ "slashCommand": "allminil",
8
+ "description": "5.0B parameter model from sentence-transformers",
9
+ "downloads": 91944061,
10
+ "pipeline_tag": "sentence-similarity",
11
+ "requiresAuth": false,
12
+ "hasOnnx": true,
13
+ "hasTokenizer": true,
14
+ "missingFiles": false,
15
+ "missingReason": "",
16
+ "tags": [
17
+ "sentence-transformers",
18
+ "pytorch",
19
+ "tf",
20
+ "rust",
21
+ "onnx",
22
+ "safetensors",
23
+ "openvino",
24
+ "bert",
25
+ "feature-extraction",
26
+ "sentence-similarity",
27
+ "transformers",
28
+ "en",
29
+ "dataset:s2orc",
30
+ "dataset:flax-sentence-embeddings/stackexchange_xml",
31
+ "dataset:ms_marco",
32
+ "dataset:gooaq",
33
+ "dataset:yahoo_answers_topics",
34
+ "dataset:code_search_net",
35
+ "dataset:search_qa",
36
+ "dataset:eli5",
37
+ "dataset:snli",
38
+ "dataset:multi_nli",
39
+ "dataset:wikihow",
40
+ "dataset:natural_questions",
41
+ "dataset:trivia_qa",
42
+ "dataset:embedding-data/sentence-compression",
43
+ "dataset:embedding-data/flickr30k-captions",
44
+ "dataset:embedding-data/altlex",
45
+ "dataset:embedding-data/simple-wiki",
46
+ "dataset:embedding-data/QQP",
47
+ "dataset:embedding-data/SPECTER",
48
+ "dataset:embedding-data/PAQ_pairs",
49
+ "dataset:embedding-data/WikiAnswers",
50
+ "arxiv:1904.06472",
51
+ "arxiv:2102.07033",
52
+ "arxiv:2104.08727",
53
+ "arxiv:1704.05179",
54
+ "arxiv:1810.09305",
55
+ "license:apache-2.0",
56
+ "autotrain_compatible",
57
+ "text-embeddings-inference",
58
+ "endpoints_compatible",
59
+ "region:us"
60
+ ]
61
+ },
62
+ {
63
+ "id": "sentence-transformers/all-mpnet-base-v2",
64
+ "name": "All Mpnet Base V2",
65
+ "vendor": "sentence-transformers",
66
+ "size": "5.0B",
67
+ "slashCommand": "allmpnet",
68
+ "description": "5.0B parameter model from sentence-transformers",
69
+ "downloads": 19348223,
70
+ "pipeline_tag": "sentence-similarity",
71
+ "requiresAuth": false,
72
+ "hasOnnx": true,
73
+ "hasTokenizer": true,
74
+ "missingFiles": false,
75
+ "missingReason": "",
76
+ "tags": [
77
+ "sentence-transformers",
78
+ "pytorch",
79
+ "onnx",
80
+ "safetensors",
81
+ "openvino",
82
+ "mpnet",
83
+ "fill-mask",
84
+ "feature-extraction",
85
+ "sentence-similarity",
86
+ "transformers",
87
+ "text-embeddings-inference",
88
+ "en",
89
+ "dataset:s2orc",
90
+ "dataset:flax-sentence-embeddings/stackexchange_xml",
91
+ "dataset:ms_marco",
92
+ "dataset:gooaq",
93
+ "dataset:yahoo_answers_topics",
94
+ "dataset:code_search_net",
95
+ "dataset:search_qa",
96
+ "dataset:eli5",
97
+ "dataset:snli",
98
+ "dataset:multi_nli",
99
+ "dataset:wikihow",
100
+ "dataset:natural_questions",
101
+ "dataset:trivia_qa",
102
+ "dataset:embedding-data/sentence-compression",
103
+ "dataset:embedding-data/flickr30k-captions",
104
+ "dataset:embedding-data/altlex",
105
+ "dataset:embedding-data/simple-wiki",
106
+ "dataset:embedding-data/QQP",
107
+ "dataset:embedding-data/SPECTER",
108
+ "dataset:embedding-data/PAQ_pairs",
109
+ "dataset:embedding-data/WikiAnswers",
110
+ "arxiv:1904.06472",
111
+ "arxiv:2102.07033",
112
+ "arxiv:2104.08727",
113
+ "arxiv:1704.05179",
114
+ "arxiv:1810.09305",
115
+ "license:apache-2.0",
116
+ "autotrain_compatible",
117
+ "endpoints_compatible",
118
+ "region:us"
119
+ ]
120
+ },
121
+ {
122
+ "id": "openai-community/gpt2",
123
+ "name": "Gpt2",
124
+ "vendor": "OpenAI",
125
+ "size": "200M",
126
+ "slashCommand": "gpt2",
127
+ "description": "200M parameter model from OpenAI",
128
+ "downloads": 11354477,
129
+ "pipeline_tag": "text-generation",
130
+ "requiresAuth": false,
131
+ "hasOnnx": true,
132
+ "hasTokenizer": true,
133
+ "missingFiles": false,
134
+ "missingReason": "",
135
+ "tags": [
136
+ "transformers",
137
+ "pytorch",
138
+ "tf",
139
+ "jax",
140
+ "tflite",
141
+ "rust",
142
+ "onnx",
143
+ "safetensors",
144
+ "gpt2",
145
+ "text-generation",
146
+ "exbert",
147
+ "en",
148
+ "doi:10.57967/hf/0039",
149
+ "license:mit",
150
+ "autotrain_compatible",
151
+ "text-generation-inference",
152
+ "endpoints_compatible",
153
+ "region:us"
154
+ ]
155
+ },
156
+ {
157
+ "id": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
158
+ "name": "Paraphrase Multilingual MiniLM L12 V2",
159
+ "vendor": "sentence-transformers",
160
+ "size": "5.0B",
161
+ "slashCommand": "paraphra",
162
+ "description": "5.0B parameter model from sentence-transformers",
163
+ "downloads": 11032270,
164
+ "pipeline_tag": "sentence-similarity",
165
+ "requiresAuth": false,
166
+ "hasOnnx": true,
167
+ "hasTokenizer": true,
168
+ "missingFiles": false,
169
+ "missingReason": "",
170
+ "tags": [
171
+ "sentence-transformers",
172
+ "pytorch",
173
+ "tf",
174
+ "onnx",
175
+ "safetensors",
176
+ "openvino",
177
+ "bert",
178
+ "feature-extraction",
179
+ "sentence-similarity",
180
+ "transformers",
181
+ "multilingual",
182
+ "ar",
183
+ "bg",
184
+ "ca",
185
+ "cs",
186
+ "da",
187
+ "de",
188
+ "el",
189
+ "en",
190
+ "es",
191
+ "et",
192
+ "fa",
193
+ "fi",
194
+ "fr",
195
+ "gl",
196
+ "gu",
197
+ "he",
198
+ "hi",
199
+ "hr",
200
+ "hu",
201
+ "hy",
202
+ "id",
203
+ "it",
204
+ "ja",
205
+ "ka",
206
+ "ko",
207
+ "ku",
208
+ "lt",
209
+ "lv",
210
+ "mk",
211
+ "mn",
212
+ "mr",
213
+ "ms",
214
+ "my",
215
+ "nb",
216
+ "nl",
217
+ "pl",
218
+ "pt",
219
+ "ro",
220
+ "ru",
221
+ "sk",
222
+ "sl",
223
+ "sq",
224
+ "sr",
225
+ "sv",
226
+ "th",
227
+ "tr",
228
+ "uk",
229
+ "ur",
230
+ "vi",
231
+ "arxiv:1908.10084",
232
+ "license:apache-2.0",
233
+ "autotrain_compatible",
234
+ "text-embeddings-inference",
235
+ "endpoints_compatible",
236
+ "region:us"
237
+ ]
238
+ },
239
+ {
240
+ "id": "sentence-transformers/paraphrase-MiniLM-L6-v2",
241
+ "name": "Paraphrase MiniLM L6 V2",
242
+ "vendor": "sentence-transformers",
243
+ "size": "5.0B",
244
+ "slashCommand": "paraphra",
245
+ "description": "5.0B parameter model from sentence-transformers",
246
+ "downloads": 5189076,
247
+ "pipeline_tag": "sentence-similarity",
248
+ "requiresAuth": false,
249
+ "hasOnnx": true,
250
+ "hasTokenizer": true,
251
+ "missingFiles": false,
252
+ "missingReason": "",
253
+ "tags": [
254
+ "sentence-transformers",
255
+ "pytorch",
256
+ "tf",
257
+ "onnx",
258
+ "safetensors",
259
+ "openvino",
260
+ "bert",
261
+ "feature-extraction",
262
+ "sentence-similarity",
263
+ "transformers",
264
+ "arxiv:1908.10084",
265
+ "license:apache-2.0",
266
+ "autotrain_compatible",
267
+ "text-embeddings-inference",
268
+ "endpoints_compatible",
269
+ "region:us"
270
+ ]
271
+ },
272
+ {
273
+ "id": "sentence-transformers/all-MiniLM-L12-v2",
274
+ "name": "All MiniLM L12 V2",
275
+ "vendor": "sentence-transformers",
276
+ "size": "5.0B",
277
+ "slashCommand": "allminil",
278
+ "description": "5.0B parameter model from sentence-transformers",
279
+ "downloads": 3418403,
280
+ "pipeline_tag": "sentence-similarity",
281
+ "requiresAuth": false,
282
+ "hasOnnx": true,
283
+ "hasTokenizer": true,
284
+ "missingFiles": false,
285
+ "missingReason": "",
286
+ "tags": [
287
+ "sentence-transformers",
288
+ "pytorch",
289
+ "rust",
290
+ "onnx",
291
+ "safetensors",
292
+ "openvino",
293
+ "bert",
294
+ "feature-extraction",
295
+ "sentence-similarity",
296
+ "transformers",
297
+ "en",
298
+ "dataset:s2orc",
299
+ "dataset:flax-sentence-embeddings/stackexchange_xml",
300
+ "dataset:ms_marco",
301
+ "dataset:gooaq",
302
+ "dataset:yahoo_answers_topics",
303
+ "dataset:code_search_net",
304
+ "dataset:search_qa",
305
+ "dataset:eli5",
306
+ "dataset:snli",
307
+ "dataset:multi_nli",
308
+ "dataset:wikihow",
309
+ "dataset:natural_questions",
310
+ "dataset:trivia_qa",
311
+ "dataset:embedding-data/sentence-compression",
312
+ "dataset:embedding-data/flickr30k-captions",
313
+ "dataset:embedding-data/altlex",
314
+ "dataset:embedding-data/simple-wiki",
315
+ "dataset:embedding-data/QQP",
316
+ "dataset:embedding-data/SPECTER",
317
+ "dataset:embedding-data/PAQ_pairs",
318
+ "dataset:embedding-data/WikiAnswers",
319
+ "arxiv:1904.06472",
320
+ "arxiv:2102.07033",
321
+ "arxiv:2104.08727",
322
+ "arxiv:1704.05179",
323
+ "arxiv:1810.09305",
324
+ "license:apache-2.0",
325
+ "autotrain_compatible",
326
+ "text-embeddings-inference",
327
+ "endpoints_compatible",
328
+ "region:us"
329
+ ]
330
+ },
331
+ {
332
+ "id": "sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
333
+ "name": "Paraphrase Multilingual Mpnet Base V2",
334
+ "vendor": "sentence-transformers",
335
+ "size": "5.0B",
336
+ "slashCommand": "paraphra",
337
+ "description": "5.0B parameter model from sentence-transformers",
338
+ "downloads": 2900179,
339
+ "pipeline_tag": "sentence-similarity",
340
+ "requiresAuth": false,
341
+ "hasOnnx": true,
342
+ "hasTokenizer": true,
343
+ "missingFiles": false,
344
+ "missingReason": "",
345
+ "tags": [
346
+ "sentence-transformers",
347
+ "pytorch",
348
+ "tf",
349
+ "onnx",
350
+ "safetensors",
351
+ "openvino",
352
+ "xlm-roberta",
353
+ "feature-extraction",
354
+ "sentence-similarity",
355
+ "transformers",
356
+ "text-embeddings-inference",
357
+ "multilingual",
358
+ "ar",
359
+ "bg",
360
+ "ca",
361
+ "cs",
362
+ "da",
363
+ "de",
364
+ "el",
365
+ "en",
366
+ "es",
367
+ "et",
368
+ "fa",
369
+ "fi",
370
+ "fr",
371
+ "gl",
372
+ "gu",
373
+ "he",
374
+ "hi",
375
+ "hr",
376
+ "hu",
377
+ "hy",
378
+ "id",
379
+ "it",
380
+ "ja",
381
+ "ka",
382
+ "ko",
383
+ "ku",
384
+ "lt",
385
+ "lv",
386
+ "mk",
387
+ "mn",
388
+ "mr",
389
+ "ms",
390
+ "my",
391
+ "nb",
392
+ "nl",
393
+ "pl",
394
+ "pt",
395
+ "ro",
396
+ "ru",
397
+ "sk",
398
+ "sl",
399
+ "sq",
400
+ "sr",
401
+ "sv",
402
+ "th",
403
+ "tr",
404
+ "uk",
405
+ "ur",
406
+ "vi",
407
+ "arxiv:1908.10084",
408
+ "license:apache-2.0",
409
+ "autotrain_compatible",
410
+ "endpoints_compatible",
411
+ "region:us"
412
+ ]
413
+ },
414
+ {
415
+ "id": "google-t5/t5-small",
416
+ "name": "T5 Small",
417
+ "vendor": "google-t5",
418
+ "size": "5.0B",
419
+ "slashCommand": "t5small",
420
+ "description": "5.0B parameter model from google-t5",
421
+ "downloads": 2749085,
422
+ "pipeline_tag": "translation",
423
+ "requiresAuth": false,
424
+ "hasOnnx": true,
425
+ "hasTokenizer": true,
426
+ "missingFiles": false,
427
+ "missingReason": "",
428
+ "tags": [
429
+ "transformers",
430
+ "pytorch",
431
+ "tf",
432
+ "jax",
433
+ "rust",
434
+ "onnx",
435
+ "safetensors",
436
+ "t5",
437
+ "text2text-generation",
438
+ "summarization",
439
+ "translation",
440
+ "en",
441
+ "fr",
442
+ "ro",
443
+ "de",
444
+ "multilingual",
445
+ "dataset:c4",
446
+ "arxiv:1805.12471",
447
+ "arxiv:1708.00055",
448
+ "arxiv:1704.05426",
449
+ "arxiv:1606.05250",
450
+ "arxiv:1808.09121",
451
+ "arxiv:1810.12885",
452
+ "arxiv:1905.10044",
453
+ "arxiv:1910.09700",
454
+ "license:apache-2.0",
455
+ "text-generation-inference",
456
+ "endpoints_compatible",
457
+ "region:us"
458
+ ]
459
+ },
460
+ {
461
+ "id": "openai-community/gpt2-large",
462
+ "name": "Gpt2 Large",
463
+ "vendor": "OpenAI",
464
+ "size": "200M",
465
+ "slashCommand": "gpt2",
466
+ "description": "200M parameter model from OpenAI",
467
+ "downloads": 2658351,
468
+ "pipeline_tag": "text-generation",
469
+ "requiresAuth": false,
470
+ "hasOnnx": true,
471
+ "hasTokenizer": true,
472
+ "missingFiles": false,
473
+ "missingReason": "",
474
+ "tags": [
475
+ "transformers",
476
+ "pytorch",
477
+ "tf",
478
+ "jax",
479
+ "rust",
480
+ "onnx",
481
+ "safetensors",
482
+ "gpt2",
483
+ "text-generation",
484
+ "en",
485
+ "arxiv:1910.09700",
486
+ "license:mit",
487
+ "autotrain_compatible",
488
+ "text-generation-inference",
489
+ "endpoints_compatible",
490
+ "region:us"
491
+ ]
492
+ },
493
+ {
494
+ "id": "sentence-transformers/all-roberta-large-v1",
495
+ "name": "All Roberta Large V1",
496
+ "vendor": "sentence-transformers",
497
+ "size": "5.0B",
498
+ "slashCommand": "allrober",
499
+ "description": "5.0B parameter model from sentence-transformers",
500
+ "downloads": 2215738,
501
+ "pipeline_tag": "sentence-similarity",
502
+ "requiresAuth": false,
503
+ "hasOnnx": true,
504
+ "hasTokenizer": true,
505
+ "missingFiles": false,
506
+ "missingReason": "",
507
+ "tags": [
508
+ "sentence-transformers",
509
+ "pytorch",
510
+ "onnx",
511
+ "safetensors",
512
+ "openvino",
513
+ "roberta",
514
+ "fill-mask",
515
+ "feature-extraction",
516
+ "sentence-similarity",
517
+ "transformers",
518
+ "en",
519
+ "arxiv:1904.06472",
520
+ "arxiv:2102.07033",
521
+ "arxiv:2104.08727",
522
+ "arxiv:1704.05179",
523
+ "arxiv:1810.09305",
524
+ "license:apache-2.0",
525
+ "autotrain_compatible",
526
+ "text-embeddings-inference",
527
+ "endpoints_compatible",
528
+ "region:us"
529
+ ]
530
+ }
531
+ ]
src/model-cache.json ADDED
The diff for this file is too large to render. See raw diff