pi-parasail-provider 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/README.md +19 -12
- package/deprecated-models.json +1 -0
- package/index.ts +43 -2
- package/models.json +154 -8
- package/package.json +1 -1
- package/patch.json +387 -31
- package/scripts/update-models.js +67 -0
package/AGENTS.md
CHANGED
|
@@ -7,6 +7,7 @@ The following files are **idempotent** and regenerated by `scripts/update-models
|
|
|
7
7
|
| File | Why it's auto-generated |
|
|
8
8
|
|------|------------------------|
|
|
9
9
|
| `models.json` | Built from the provider API. `update-models.js` fetches models, preserves curated data for known IDs, and writes this file. |
|
|
10
|
+
| `deprecated-models.json` | Graveyard for models the API delisted. update-models.js stamps them with deprecatedAt and pi keeps serving them for a 2-week grace period, then evicts them. Never edit by hand. |
|
|
10
11
|
| `README.md` (model table) | The table under `## Available Models` is replaced in-place by `update-models.js` after merging base models → patch → custom models. |
|
|
11
12
|
|
|
12
13
|
## Correct Files to Edit
|
package/README.md
CHANGED
|
@@ -72,26 +72,31 @@ Get your API key at [parasail.io](https://parasail.io/).
|
|
|
72
72
|
|-------|---------|-----------|-------|------------|-----------|------------|-----------|
|
|
73
73
|
| Cydonia 24B v4.1 | 131K | ❌ | Text | 16K | $0.30 | $0.50 | $0.15 |
|
|
74
74
|
| DeepSeek V4 Flash | 1M | ✅ | Text | 384K | $0.14 | $0.28 | $0.07 |
|
|
75
|
-
| Deepseek V4 Flash
|
|
75
|
+
| Deepseek V4 Flash 0731 | 1M | ✅ | Text | 16K | $0.14 | $0.28 | $0.07 |
|
|
76
76
|
| DeepSeek V4 Pro | 1M | ✅ | Text | 384K | $1.74 | $3.48 | $0.10 |
|
|
77
77
|
| Gemma 3 27B | 131K | ❌ | Text + Image | 16K | $0.08 | $0.45 | $0.04 |
|
|
78
|
-
| Gemma 4 26B (A4B) | 262K |
|
|
79
|
-
| Gemma 4 31B | 262K |
|
|
78
|
+
| Gemma 4 26B (A4B) | 262K | ✅ | Text + Image | 16K | $0.13 | $0.40 | $0.05 |
|
|
79
|
+
| Gemma 4 31B | 262K | ✅ | Text + Image | 16K | $0.15 | $0.40 | $0.06 |
|
|
80
80
|
| GLM 5 | 203K | ✅ | Text | 16K | $1.00 | $3.20 | $0.20 |
|
|
81
81
|
| GLM 5.1 | 203K | ✅ | Text | 16K | $1.40 | $4.40 | $0.26 |
|
|
82
|
-
| Glm 52 | 262K |
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
| GPT-OSS
|
|
82
|
+
| Glm 52 | 262K | ✅ | Text | 16K | $1.40 | $4.40 | $0.26 |
|
|
83
|
+
| Googlegemma 3 4b It | 131K | ❌ | Text | 16K | $0.05 | Free | Free |
|
|
84
|
+
| Gpt Oss 120b Fast | 131K | ✅ | Text | 16K | $0.15 | $0.60 | Free |
|
|
85
|
+
| GPT-OSS 120B | 131K | ✅ | Text | 16K | $0.10 | $0.75 | $0.06 |
|
|
86
|
+
| GPT-OSS 20B | 131K | ✅ | Text | 16K | $0.03 | $0.15 | $0.02 |
|
|
86
87
|
| Kimi K2.6 | 262K | ✅ | Text + Image | 16K | $0.75 | $3.50 | $0.16 |
|
|
87
|
-
| Kimi K27 Code | 262K |
|
|
88
|
+
| Kimi K27 Code | 262K | ✅ | Text + Image | 16K | $0.76 | $3.50 | $0.16 |
|
|
89
|
+
| Kimi K3 | 1M | ✅ | Text + Image | 16K | $3.00 | $15.00 | $0.30 |
|
|
90
|
+
| Kimi K3 Fast | 1M | ✅ | Text + Image | 16K | $3.00 | $15.00 | $0.30 |
|
|
88
91
|
| Llama 3.3 70B | 131K | ❌ | Text | 16K | $0.22 | $0.50 | $0.11 |
|
|
89
92
|
| Llama 32 3b Instruct | 131K | ❌ | Text | 16K | $0.05 | $0.33 | Free |
|
|
90
93
|
| Llama 4 Maverick 17B-128E | 524K | ❌ | Text + Image | 16K | $0.35 | $1.00 | $0.17 |
|
|
91
|
-
| Mimo V25 | 1M |
|
|
94
|
+
| Mimo V25 | 1M | ✅ | Text | 16K | $0.14 | $0.28 | $0.05 |
|
|
92
95
|
| MiniMax M2.5 | 197K | ✅ | Text | 16K | $0.30 | $1.20 | $0.03 |
|
|
93
|
-
| Minimax M3 | 1M |
|
|
94
|
-
| Mistral Small
|
|
96
|
+
| Minimax M3 | 1M | ✅ | Text + Image | 16K | $0.30 | $1.20 | $0.06 |
|
|
97
|
+
| Mistral Small 32 24b | 131K | ❌ | Text | 16K | $0.09 | $0.30 | $0.05 |
|
|
98
|
+
| Mistralaimistral Nemo | 131K | ❌ | Text | 16K | $0.03 | $0.03 | Free |
|
|
99
|
+
| Mythomax 13b | 4K | ❌ | Text | 16K | $0.08 | $0.11 | Free |
|
|
95
100
|
| Qwen 3.5 35B (A3B) | 262K | ✅ | Text + Image | 33K | $0.15 | $1.00 | $0.05 |
|
|
96
101
|
| Qwen 3.5 397B (A17B) | 262K | ✅ | Text + Image | 33K | $0.50 | $3.60 | $0.30 |
|
|
97
102
|
| Qwen 3.6 35B (A3B) | 262K | ✅ | Text + Image | 33K | $0.15 | $1.00 | $0.05 |
|
|
@@ -105,8 +110,10 @@ Get your API key at [parasail.io](https://parasail.io/).
|
|
|
105
110
|
| Qwen3-VL 8B | 262K | ✅ | Text + Image | 8K | $0.25 | $0.75 | $0.12 |
|
|
106
111
|
| Qwen35 9b | 262K | ❌ | Text | 16K | $0.10 | $0.25 | Free |
|
|
107
112
|
| Rocinante 12b | 66K | ❌ | Text | 16K | $0.25 | $0.50 | Free |
|
|
113
|
+
| Sao10kl3 Lunaris 8b | 8K | ❌ | Text | 16K | $0.04 | $0.05 | Free |
|
|
108
114
|
| Skyfall 36b V2 Fp8 | 33K | ❌ | Text | 16K | $0.55 | $0.80 | $0.25 |
|
|
109
|
-
| Trinity Large Thinking | 262K |
|
|
115
|
+
| Trinity Large Thinking | 262K | ✅ | Text | 16K | $0.22 | $0.85 | $0.06 |
|
|
116
|
+
| Unslopnemo 12b | 1M | ❌ | Text | 16K | $0.40 | $0.40 | Free |
|
|
110
117
|
|
|
111
118
|
*Pricing fetched live from [Parasail's pricing API](https://www.saas.parasail.io/api/v1/prices/serverlessEndpoints). Prices are per million tokens and subject to change.*
|
|
112
119
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
package/index.ts
CHANGED
|
@@ -35,6 +35,7 @@ import { getAgentDir, type ExtensionAPI, type ModelRegistry } from "@earendil-wo
|
|
|
35
35
|
import modelsData from "./models.json" with { type: "json" };
|
|
36
36
|
import customModelsData from "./custom-models.json" with { type: "json" };
|
|
37
37
|
import patchData from "./patch.json" with { type: "json" };
|
|
38
|
+
import deprecatedData from "./deprecated-models.json" with { type: "json" };
|
|
38
39
|
import fs from "fs";
|
|
39
40
|
import path from "path";
|
|
40
41
|
|
|
@@ -53,12 +54,15 @@ interface JsonModel {
|
|
|
53
54
|
};
|
|
54
55
|
contextWindow: number;
|
|
55
56
|
maxTokens: number;
|
|
57
|
+
thinkingLevelMap?: Record<string, string | null>;
|
|
56
58
|
compat?: {
|
|
57
59
|
supportsDeveloperRole?: boolean;
|
|
58
60
|
supportsStore?: boolean;
|
|
59
61
|
maxTokensField?: "max_completion_tokens" | "max_tokens";
|
|
60
|
-
thinkingFormat?: "openai" | "zai" | "qwen" | "qwen-chat-template";
|
|
62
|
+
thinkingFormat?: "openai" | "zai" | "qwen" | "qwen-chat-template" | "chat-template";
|
|
61
63
|
supportsReasoningEffort?: boolean;
|
|
64
|
+
requiresReasoningContentOnAssistantMessages?: boolean;
|
|
65
|
+
chatTemplateKwargs?: Record<string, unknown>;
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
68
|
|
|
@@ -74,6 +78,7 @@ interface PatchEntry {
|
|
|
74
78
|
};
|
|
75
79
|
contextWindow?: number;
|
|
76
80
|
maxTokens?: number;
|
|
81
|
+
thinkingLevelMap?: Record<string, string | null>;
|
|
77
82
|
compat?: Record<string, unknown>;
|
|
78
83
|
}
|
|
79
84
|
|
|
@@ -89,6 +94,7 @@ function applyPatch(model: JsonModel, patch: PatchEntry): JsonModel {
|
|
|
89
94
|
if (patch.input !== undefined) result.input = patch.input;
|
|
90
95
|
if (patch.contextWindow !== undefined) result.contextWindow = patch.contextWindow;
|
|
91
96
|
if (patch.maxTokens !== undefined) result.maxTokens = patch.maxTokens;
|
|
97
|
+
if (patch.thinkingLevelMap !== undefined) result.thinkingLevelMap = { ...patch.thinkingLevelMap };
|
|
92
98
|
|
|
93
99
|
if (patch.cost) {
|
|
94
100
|
result.cost = {
|
|
@@ -105,6 +111,9 @@ function applyPatch(model: JsonModel, patch: PatchEntry): JsonModel {
|
|
|
105
111
|
if (!result.reasoning && result.compat?.thinkingFormat) {
|
|
106
112
|
delete result.compat.thinkingFormat;
|
|
107
113
|
}
|
|
114
|
+
if (!result.reasoning && result.thinkingLevelMap) {
|
|
115
|
+
delete result.thinkingLevelMap;
|
|
116
|
+
}
|
|
108
117
|
if (result.compat && Object.keys(result.compat).length === 0) {
|
|
109
118
|
delete result.compat;
|
|
110
119
|
}
|
|
@@ -116,7 +125,10 @@ function applyPatch(model: JsonModel, patch: PatchEntry): JsonModel {
|
|
|
116
125
|
function buildModels(base: JsonModel[], custom: JsonModel[], patch: PatchData): JsonModel[] {
|
|
117
126
|
const modelMap = new Map<string, JsonModel>();
|
|
118
127
|
|
|
119
|
-
|
|
128
|
+
// Seed with the base list plus grace-period deprecated models so patch.json
|
|
129
|
+
// entries apply to deprecated models exactly as while the model was live
|
|
130
|
+
// (withDeprecated keeps live data on id conflicts).
|
|
131
|
+
for (const model of withDeprecated(base)) {
|
|
120
132
|
modelMap.set(model.id, model);
|
|
121
133
|
}
|
|
122
134
|
|
|
@@ -319,6 +331,35 @@ function mergeWithEmbedded(liveModels: JsonModel[], embeddedModels: JsonModel[])
|
|
|
319
331
|
return result;
|
|
320
332
|
}
|
|
321
333
|
|
|
334
|
+
// Grace period for delisted models. When the provider API stops listing a
|
|
335
|
+
// model, update-models.js moves its last-known definition into
|
|
336
|
+
// deprecated-models.json (stamped with deprecatedAt) instead of dropping it.
|
|
337
|
+
// For 14 days the model keeps working here so in-flight sessions and saved
|
|
338
|
+
// model settings do not break; afterwards it is evicted permanently.
|
|
339
|
+
const DEPRECATED_MODEL_TTL_MS = 14 * 24 * 60 * 60 * 1000;
|
|
340
|
+
|
|
341
|
+
// Grace-period deprecated models with deprecation metadata stripped.
|
|
342
|
+
function activeDeprecatedModels(): JsonModel[] {
|
|
343
|
+
const now = Date.now();
|
|
344
|
+
const result: JsonModel[] = [];
|
|
345
|
+
for (const entry of Object.values(deprecatedData as Record<string, JsonModel & { deprecatedAt?: string }>)) {
|
|
346
|
+
if (!entry?.id) continue;
|
|
347
|
+
const removedAt = Date.parse(entry.deprecatedAt ?? "");
|
|
348
|
+
if (Number.isNaN(removedAt) || now - removedAt > DEPRECATED_MODEL_TTL_MS) continue;
|
|
349
|
+
const model = { ...entry } as JsonModel & { deprecatedAt?: string };
|
|
350
|
+
delete model.deprecatedAt;
|
|
351
|
+
result.push(model);
|
|
352
|
+
}
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Append grace-period deprecated models the list does not already have (live data wins).
|
|
357
|
+
function withDeprecated(models: JsonModel[]): JsonModel[] {
|
|
358
|
+
const seen = new Set(models.map((m) => m.id));
|
|
359
|
+
const extras = activeDeprecatedModels().filter((m) => !seen.has(m.id));
|
|
360
|
+
return extras.length > 0 ? [...models, ...extras] : models;
|
|
361
|
+
}
|
|
362
|
+
|
|
322
363
|
function loadStaleModels(embeddedModels: JsonModel[]): JsonModel[] {
|
|
323
364
|
const cached = loadCachedModels();
|
|
324
365
|
if (!cached || cached.length === 0) return embeddedModels;
|
package/models.json
CHANGED
|
@@ -311,16 +311,58 @@
|
|
|
311
311
|
}
|
|
312
312
|
},
|
|
313
313
|
{
|
|
314
|
-
"id": "parasail-deepseek-v4-flash-
|
|
315
|
-
"name": "Deepseek V4 Flash
|
|
314
|
+
"id": "parasail-deepseek-v4-flash-0731",
|
|
315
|
+
"name": "Deepseek V4 Flash 0731",
|
|
316
316
|
"reasoning": false,
|
|
317
317
|
"input": [
|
|
318
318
|
"text"
|
|
319
319
|
],
|
|
320
320
|
"cost": {
|
|
321
|
-
"input": 0,
|
|
322
|
-
"output": 0,
|
|
323
|
-
"cacheRead": 0,
|
|
321
|
+
"input": 0.14,
|
|
322
|
+
"output": 0.28,
|
|
323
|
+
"cacheRead": 0.07,
|
|
324
|
+
"cacheWrite": 0
|
|
325
|
+
},
|
|
326
|
+
"contextWindow": 1048576,
|
|
327
|
+
"maxTokens": 16384,
|
|
328
|
+
"compat": {
|
|
329
|
+
"maxTokensField": "max_completion_tokens",
|
|
330
|
+
"supportsDeveloperRole": false,
|
|
331
|
+
"supportsStore": false
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"id": "parasail-kimi-k3",
|
|
336
|
+
"name": "Kimi K3",
|
|
337
|
+
"reasoning": false,
|
|
338
|
+
"input": [
|
|
339
|
+
"text"
|
|
340
|
+
],
|
|
341
|
+
"cost": {
|
|
342
|
+
"input": 3,
|
|
343
|
+
"output": 15,
|
|
344
|
+
"cacheRead": 0.3,
|
|
345
|
+
"cacheWrite": 0
|
|
346
|
+
},
|
|
347
|
+
"contextWindow": 1048576,
|
|
348
|
+
"maxTokens": 16384,
|
|
349
|
+
"compat": {
|
|
350
|
+
"maxTokensField": "max_completion_tokens",
|
|
351
|
+
"supportsDeveloperRole": false,
|
|
352
|
+
"supportsStore": false
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"id": "parasail-kimi-k3-fast",
|
|
357
|
+
"name": "Kimi K3 Fast",
|
|
358
|
+
"reasoning": false,
|
|
359
|
+
"input": [
|
|
360
|
+
"text"
|
|
361
|
+
],
|
|
362
|
+
"cost": {
|
|
363
|
+
"input": 3,
|
|
364
|
+
"output": 15,
|
|
365
|
+
"cacheRead": 0.3,
|
|
324
366
|
"cacheWrite": 0
|
|
325
367
|
},
|
|
326
368
|
"contextWindow": 1048576,
|
|
@@ -373,6 +415,27 @@
|
|
|
373
415
|
"supportsStore": false
|
|
374
416
|
}
|
|
375
417
|
},
|
|
418
|
+
{
|
|
419
|
+
"id": "parasail-unslopnemo-12b",
|
|
420
|
+
"name": "Unslopnemo 12b",
|
|
421
|
+
"reasoning": false,
|
|
422
|
+
"input": [
|
|
423
|
+
"text"
|
|
424
|
+
],
|
|
425
|
+
"cost": {
|
|
426
|
+
"input": 0.4,
|
|
427
|
+
"output": 0.4,
|
|
428
|
+
"cacheRead": 0,
|
|
429
|
+
"cacheWrite": 0
|
|
430
|
+
},
|
|
431
|
+
"contextWindow": 1024000,
|
|
432
|
+
"maxTokens": 16384,
|
|
433
|
+
"compat": {
|
|
434
|
+
"maxTokensField": "max_completion_tokens",
|
|
435
|
+
"supportsDeveloperRole": false,
|
|
436
|
+
"supportsStore": false
|
|
437
|
+
}
|
|
438
|
+
},
|
|
376
439
|
{
|
|
377
440
|
"id": "parasail-llama-4-maverick-instruct-fp8",
|
|
378
441
|
"name": "Llama 4 Maverick 17B-128E",
|
|
@@ -566,6 +629,27 @@
|
|
|
566
629
|
"supportsStore": false
|
|
567
630
|
}
|
|
568
631
|
},
|
|
632
|
+
{
|
|
633
|
+
"id": "parasail-googlegemma-3-4b-it",
|
|
634
|
+
"name": "Googlegemma 3 4b It",
|
|
635
|
+
"reasoning": false,
|
|
636
|
+
"input": [
|
|
637
|
+
"text"
|
|
638
|
+
],
|
|
639
|
+
"cost": {
|
|
640
|
+
"input": 0.05,
|
|
641
|
+
"output": 0,
|
|
642
|
+
"cacheRead": 0,
|
|
643
|
+
"cacheWrite": 0
|
|
644
|
+
},
|
|
645
|
+
"contextWindow": 131072,
|
|
646
|
+
"maxTokens": 16384,
|
|
647
|
+
"compat": {
|
|
648
|
+
"maxTokensField": "max_completion_tokens",
|
|
649
|
+
"supportsDeveloperRole": false,
|
|
650
|
+
"supportsStore": false
|
|
651
|
+
}
|
|
652
|
+
},
|
|
569
653
|
{
|
|
570
654
|
"id": "parasail-gpt-oss-120b-fast",
|
|
571
655
|
"name": "Gpt Oss 120b Fast",
|
|
@@ -673,11 +757,10 @@
|
|
|
673
757
|
},
|
|
674
758
|
{
|
|
675
759
|
"id": "parasail-mistral-small-32-24b",
|
|
676
|
-
"name": "Mistral Small
|
|
760
|
+
"name": "Mistral Small 32 24b",
|
|
677
761
|
"reasoning": false,
|
|
678
762
|
"input": [
|
|
679
|
-
"text"
|
|
680
|
-
"image"
|
|
763
|
+
"text"
|
|
681
764
|
],
|
|
682
765
|
"cost": {
|
|
683
766
|
"input": 0.09,
|
|
@@ -693,6 +776,27 @@
|
|
|
693
776
|
"supportsStore": false
|
|
694
777
|
}
|
|
695
778
|
},
|
|
779
|
+
{
|
|
780
|
+
"id": "parasail-mistralaimistral-nemo",
|
|
781
|
+
"name": "Mistralaimistral Nemo",
|
|
782
|
+
"reasoning": false,
|
|
783
|
+
"input": [
|
|
784
|
+
"text"
|
|
785
|
+
],
|
|
786
|
+
"cost": {
|
|
787
|
+
"input": 0.03,
|
|
788
|
+
"output": 0.03,
|
|
789
|
+
"cacheRead": 0,
|
|
790
|
+
"cacheWrite": 0
|
|
791
|
+
},
|
|
792
|
+
"contextWindow": 131072,
|
|
793
|
+
"maxTokens": 16384,
|
|
794
|
+
"compat": {
|
|
795
|
+
"maxTokensField": "max_completion_tokens",
|
|
796
|
+
"supportsDeveloperRole": false,
|
|
797
|
+
"supportsStore": false
|
|
798
|
+
}
|
|
799
|
+
},
|
|
696
800
|
{
|
|
697
801
|
"id": "parasail-qwen25-vl-72b-instruct",
|
|
698
802
|
"name": "Qwen2.5-VL 72B",
|
|
@@ -798,5 +902,47 @@
|
|
|
798
902
|
"supportsDeveloperRole": false,
|
|
799
903
|
"supportsStore": false
|
|
800
904
|
}
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
"id": "parasail-sao10kl3-lunaris-8b",
|
|
908
|
+
"name": "Sao10kl3 Lunaris 8b",
|
|
909
|
+
"reasoning": false,
|
|
910
|
+
"input": [
|
|
911
|
+
"text"
|
|
912
|
+
],
|
|
913
|
+
"cost": {
|
|
914
|
+
"input": 0.04,
|
|
915
|
+
"output": 0.05,
|
|
916
|
+
"cacheRead": 0,
|
|
917
|
+
"cacheWrite": 0
|
|
918
|
+
},
|
|
919
|
+
"contextWindow": 8192,
|
|
920
|
+
"maxTokens": 16384,
|
|
921
|
+
"compat": {
|
|
922
|
+
"maxTokensField": "max_completion_tokens",
|
|
923
|
+
"supportsDeveloperRole": false,
|
|
924
|
+
"supportsStore": false
|
|
925
|
+
}
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"id": "parasail-mythomax-13b",
|
|
929
|
+
"name": "Mythomax 13b",
|
|
930
|
+
"reasoning": false,
|
|
931
|
+
"input": [
|
|
932
|
+
"text"
|
|
933
|
+
],
|
|
934
|
+
"cost": {
|
|
935
|
+
"input": 0.08,
|
|
936
|
+
"output": 0.11,
|
|
937
|
+
"cacheRead": 0,
|
|
938
|
+
"cacheWrite": 0
|
|
939
|
+
},
|
|
940
|
+
"contextWindow": 4096,
|
|
941
|
+
"maxTokens": 16384,
|
|
942
|
+
"compat": {
|
|
943
|
+
"maxTokensField": "max_completion_tokens",
|
|
944
|
+
"supportsDeveloperRole": false,
|
|
945
|
+
"supportsStore": false
|
|
946
|
+
}
|
|
801
947
|
}
|
|
802
948
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-parasail-provider",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Parasail provider extension for pi - Access top open-source models (DeepSeek, Qwen, GLM, Kimi, Llama, Gemma, Mistral) through the Parasail API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
package/patch.json
CHANGED
|
@@ -1,85 +1,441 @@
|
|
|
1
1
|
{
|
|
2
|
-
"parasail-kimi-k25": {
|
|
3
|
-
"input": ["text", "image"],
|
|
4
|
-
"compat": {
|
|
5
|
-
"supportsReasoningEffort": true
|
|
6
|
-
}
|
|
7
|
-
},
|
|
8
2
|
"parasail-kimi-k26": {
|
|
9
|
-
"input": [
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
"input": [
|
|
4
|
+
"text",
|
|
5
|
+
"image"
|
|
6
|
+
],
|
|
7
|
+
"thinkingLevelMap": {
|
|
8
|
+
"off": "none",
|
|
9
|
+
"minimal": null,
|
|
10
|
+
"low": null,
|
|
11
|
+
"medium": null,
|
|
12
|
+
"high": "high",
|
|
13
|
+
"xhigh": null,
|
|
14
|
+
"max": null
|
|
15
|
+
},
|
|
16
16
|
"compat": {
|
|
17
|
-
"
|
|
17
|
+
"thinkingFormat": "qwen-chat-template",
|
|
18
|
+
"supportsReasoningEffort": false,
|
|
19
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
18
20
|
}
|
|
19
21
|
},
|
|
20
22
|
"parasail-qwen3p5-35b-a3b": {
|
|
21
|
-
"input": [
|
|
23
|
+
"input": [
|
|
24
|
+
"text",
|
|
25
|
+
"image"
|
|
26
|
+
],
|
|
27
|
+
"thinkingLevelMap": {
|
|
28
|
+
"off": "none",
|
|
29
|
+
"minimal": null,
|
|
30
|
+
"low": "low",
|
|
31
|
+
"medium": "medium",
|
|
32
|
+
"high": "high",
|
|
33
|
+
"xhigh": null,
|
|
34
|
+
"max": null
|
|
35
|
+
},
|
|
22
36
|
"compat": {
|
|
23
|
-
"
|
|
37
|
+
"thinkingFormat": "qwen-chat-template",
|
|
38
|
+
"supportsReasoningEffort": false,
|
|
39
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
24
40
|
}
|
|
25
41
|
},
|
|
26
42
|
"parasail-qwen3p6-35b-a3b": {
|
|
27
|
-
"input": [
|
|
43
|
+
"input": [
|
|
44
|
+
"text",
|
|
45
|
+
"image"
|
|
46
|
+
],
|
|
47
|
+
"thinkingLevelMap": {
|
|
48
|
+
"off": "none",
|
|
49
|
+
"minimal": null,
|
|
50
|
+
"low": "low",
|
|
51
|
+
"medium": "medium",
|
|
52
|
+
"high": "high",
|
|
53
|
+
"xhigh": null,
|
|
54
|
+
"max": null
|
|
55
|
+
},
|
|
28
56
|
"compat": {
|
|
29
|
-
"
|
|
57
|
+
"thinkingFormat": "qwen-chat-template",
|
|
58
|
+
"supportsReasoningEffort": false,
|
|
59
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
30
60
|
}
|
|
31
61
|
},
|
|
32
62
|
"parasail-qwen35-397b-a17b": {
|
|
63
|
+
"input": [
|
|
64
|
+
"text",
|
|
65
|
+
"image"
|
|
66
|
+
],
|
|
67
|
+
"thinkingLevelMap": {
|
|
68
|
+
"off": "none",
|
|
69
|
+
"minimal": null,
|
|
70
|
+
"low": "low",
|
|
71
|
+
"medium": "medium",
|
|
72
|
+
"high": "high",
|
|
73
|
+
"xhigh": null,
|
|
74
|
+
"max": null
|
|
75
|
+
},
|
|
33
76
|
"compat": {
|
|
34
|
-
"
|
|
77
|
+
"thinkingFormat": "qwen-chat-template",
|
|
78
|
+
"supportsReasoningEffort": false,
|
|
79
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
35
80
|
}
|
|
36
81
|
},
|
|
37
82
|
"parasail-qwen3-coder-next": {
|
|
83
|
+
"thinkingLevelMap": {
|
|
84
|
+
"off": "none",
|
|
85
|
+
"minimal": null,
|
|
86
|
+
"low": "low",
|
|
87
|
+
"medium": "medium",
|
|
88
|
+
"high": "high",
|
|
89
|
+
"xhigh": null,
|
|
90
|
+
"max": null
|
|
91
|
+
},
|
|
38
92
|
"compat": {
|
|
39
|
-
"
|
|
93
|
+
"thinkingFormat": "qwen-chat-template",
|
|
94
|
+
"supportsReasoningEffort": false,
|
|
95
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
40
96
|
}
|
|
41
97
|
},
|
|
42
98
|
"parasail-qwen-3-next-80b-instruct": {
|
|
99
|
+
"thinkingLevelMap": {
|
|
100
|
+
"off": "none",
|
|
101
|
+
"minimal": null,
|
|
102
|
+
"low": "low",
|
|
103
|
+
"medium": "medium",
|
|
104
|
+
"high": "high",
|
|
105
|
+
"xhigh": null,
|
|
106
|
+
"max": null
|
|
107
|
+
},
|
|
43
108
|
"compat": {
|
|
44
|
-
"
|
|
109
|
+
"thinkingFormat": "qwen-chat-template",
|
|
110
|
+
"supportsReasoningEffort": false,
|
|
111
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
45
112
|
}
|
|
46
113
|
},
|
|
47
114
|
"parasail-qwen3vl-8b-instruct": {
|
|
115
|
+
"thinkingLevelMap": {
|
|
116
|
+
"off": "none",
|
|
117
|
+
"minimal": null,
|
|
118
|
+
"low": "low",
|
|
119
|
+
"medium": "medium",
|
|
120
|
+
"high": "high",
|
|
121
|
+
"xhigh": null,
|
|
122
|
+
"max": null
|
|
123
|
+
},
|
|
48
124
|
"compat": {
|
|
49
|
-
"
|
|
125
|
+
"thinkingFormat": "qwen-chat-template",
|
|
126
|
+
"supportsReasoningEffort": false,
|
|
127
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
50
128
|
}
|
|
51
129
|
},
|
|
52
130
|
"parasail-trinity-large-thinking": {
|
|
131
|
+
"reasoning": true,
|
|
132
|
+
"thinkingLevelMap": {
|
|
133
|
+
"off": "none",
|
|
134
|
+
"minimal": null,
|
|
135
|
+
"low": "low",
|
|
136
|
+
"medium": "medium",
|
|
137
|
+
"high": "high",
|
|
138
|
+
"xhigh": null,
|
|
139
|
+
"max": null
|
|
140
|
+
},
|
|
53
141
|
"compat": {
|
|
54
|
-
"
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
"parasail-glm47": {
|
|
58
|
-
"compat": {
|
|
142
|
+
"thinkingFormat": "openai",
|
|
59
143
|
"supportsReasoningEffort": true
|
|
60
144
|
}
|
|
61
145
|
},
|
|
62
146
|
"parasail-glm-5": {
|
|
147
|
+
"thinkingLevelMap": {
|
|
148
|
+
"off": "none",
|
|
149
|
+
"minimal": null,
|
|
150
|
+
"low": null,
|
|
151
|
+
"medium": null,
|
|
152
|
+
"high": "high",
|
|
153
|
+
"xhigh": null,
|
|
154
|
+
"max": null
|
|
155
|
+
},
|
|
63
156
|
"compat": {
|
|
64
|
-
"
|
|
157
|
+
"thinkingFormat": "qwen-chat-template",
|
|
158
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
65
159
|
}
|
|
66
160
|
},
|
|
67
161
|
"parasail-glm-51": {
|
|
162
|
+
"thinkingLevelMap": {
|
|
163
|
+
"off": "none",
|
|
164
|
+
"minimal": null,
|
|
165
|
+
"low": null,
|
|
166
|
+
"medium": null,
|
|
167
|
+
"high": "high",
|
|
168
|
+
"xhigh": null,
|
|
169
|
+
"max": null
|
|
170
|
+
},
|
|
68
171
|
"compat": {
|
|
69
|
-
"
|
|
172
|
+
"thinkingFormat": "qwen-chat-template",
|
|
173
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
70
174
|
}
|
|
71
175
|
},
|
|
72
176
|
"parasail-minimax-m25": {
|
|
177
|
+
"thinkingLevelMap": {
|
|
178
|
+
"off": "none",
|
|
179
|
+
"minimal": null,
|
|
180
|
+
"low": null,
|
|
181
|
+
"medium": null,
|
|
182
|
+
"high": "high",
|
|
183
|
+
"xhigh": null,
|
|
184
|
+
"max": null
|
|
185
|
+
},
|
|
73
186
|
"compat": {
|
|
74
|
-
"
|
|
187
|
+
"thinkingFormat": "qwen-chat-template",
|
|
188
|
+
"supportsReasoningEffort": false,
|
|
189
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
75
190
|
}
|
|
76
191
|
},
|
|
77
192
|
"parasail-qwen3-235b-a22b-instruct-2507": {
|
|
193
|
+
"thinkingLevelMap": {
|
|
194
|
+
"off": "none",
|
|
195
|
+
"minimal": null,
|
|
196
|
+
"low": "low",
|
|
197
|
+
"medium": "medium",
|
|
198
|
+
"high": "high",
|
|
199
|
+
"xhigh": null,
|
|
200
|
+
"max": null
|
|
201
|
+
},
|
|
78
202
|
"compat": {
|
|
79
|
-
"
|
|
203
|
+
"thinkingFormat": "qwen-chat-template",
|
|
204
|
+
"supportsReasoningEffort": false,
|
|
205
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
80
206
|
}
|
|
81
207
|
},
|
|
82
208
|
"parasail-qwen3-vl-235b-a22b-instruct": {
|
|
209
|
+
"thinkingLevelMap": {
|
|
210
|
+
"off": "none",
|
|
211
|
+
"minimal": null,
|
|
212
|
+
"low": "low",
|
|
213
|
+
"medium": "medium",
|
|
214
|
+
"high": "high",
|
|
215
|
+
"xhigh": null,
|
|
216
|
+
"max": null
|
|
217
|
+
},
|
|
218
|
+
"compat": {
|
|
219
|
+
"thinkingFormat": "qwen-chat-template",
|
|
220
|
+
"supportsReasoningEffort": false,
|
|
221
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"parasail-deepseek-v4-flash-0731": {
|
|
225
|
+
"reasoning": true,
|
|
226
|
+
"thinkingLevelMap": {
|
|
227
|
+
"off": "none",
|
|
228
|
+
"minimal": null,
|
|
229
|
+
"low": null,
|
|
230
|
+
"medium": null,
|
|
231
|
+
"high": "high",
|
|
232
|
+
"xhigh": null,
|
|
233
|
+
"max": null
|
|
234
|
+
},
|
|
235
|
+
"compat": {
|
|
236
|
+
"thinkingFormat": "deepseek",
|
|
237
|
+
"supportsReasoningEffort": false,
|
|
238
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
"parasail-kimi-k3": {
|
|
242
|
+
"reasoning": true,
|
|
243
|
+
"input": [
|
|
244
|
+
"text",
|
|
245
|
+
"image"
|
|
246
|
+
],
|
|
247
|
+
"thinkingLevelMap": {
|
|
248
|
+
"off": "none",
|
|
249
|
+
"minimal": null,
|
|
250
|
+
"low": null,
|
|
251
|
+
"medium": null,
|
|
252
|
+
"high": "high",
|
|
253
|
+
"xhigh": null,
|
|
254
|
+
"max": null
|
|
255
|
+
},
|
|
256
|
+
"compat": {
|
|
257
|
+
"thinkingFormat": "chat-template",
|
|
258
|
+
"supportsReasoningEffort": false,
|
|
259
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
"parasail-kimi-k3-fast": {
|
|
263
|
+
"reasoning": true,
|
|
264
|
+
"input": [
|
|
265
|
+
"text",
|
|
266
|
+
"image"
|
|
267
|
+
],
|
|
268
|
+
"thinkingLevelMap": {
|
|
269
|
+
"off": "none",
|
|
270
|
+
"minimal": null,
|
|
271
|
+
"low": null,
|
|
272
|
+
"medium": null,
|
|
273
|
+
"high": "high",
|
|
274
|
+
"xhigh": null,
|
|
275
|
+
"max": null
|
|
276
|
+
},
|
|
277
|
+
"compat": {
|
|
278
|
+
"thinkingFormat": "chat-template",
|
|
279
|
+
"supportsReasoningEffort": false,
|
|
280
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"parasail-mimo-v25": {
|
|
284
|
+
"reasoning": true,
|
|
285
|
+
"thinkingLevelMap": {
|
|
286
|
+
"off": "none",
|
|
287
|
+
"minimal": null,
|
|
288
|
+
"low": null,
|
|
289
|
+
"medium": null,
|
|
290
|
+
"high": "high",
|
|
291
|
+
"xhigh": null,
|
|
292
|
+
"max": null
|
|
293
|
+
},
|
|
294
|
+
"compat": {
|
|
295
|
+
"thinkingFormat": "chat-template",
|
|
296
|
+
"supportsReasoningEffort": false,
|
|
297
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"parasail-minimax-m3": {
|
|
301
|
+
"reasoning": true,
|
|
302
|
+
"input": [
|
|
303
|
+
"text",
|
|
304
|
+
"image"
|
|
305
|
+
],
|
|
306
|
+
"thinkingLevelMap": {
|
|
307
|
+
"off": "disabled",
|
|
308
|
+
"minimal": "adaptive",
|
|
309
|
+
"low": "adaptive",
|
|
310
|
+
"medium": "adaptive",
|
|
311
|
+
"high": "enabled",
|
|
312
|
+
"xhigh": null,
|
|
313
|
+
"max": null
|
|
314
|
+
},
|
|
315
|
+
"compat": {
|
|
316
|
+
"thinkingFormat": "chat-template",
|
|
317
|
+
"supportsReasoningEffort": false,
|
|
318
|
+
"requiresReasoningContentOnAssistantMessages": true,
|
|
319
|
+
"chatTemplateKwargs": {
|
|
320
|
+
"thinking_mode": {
|
|
321
|
+
"$var": "thinking.effort"
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
"parasail-gemma-4-26b-a4b-it": {
|
|
327
|
+
"reasoning": true,
|
|
328
|
+
"thinkingLevelMap": {
|
|
329
|
+
"off": "none",
|
|
330
|
+
"minimal": null,
|
|
331
|
+
"low": null,
|
|
332
|
+
"medium": null,
|
|
333
|
+
"high": "high",
|
|
334
|
+
"xhigh": null,
|
|
335
|
+
"max": null
|
|
336
|
+
},
|
|
337
|
+
"compat": {
|
|
338
|
+
"thinkingFormat": "chat-template",
|
|
339
|
+
"supportsReasoningEffort": false,
|
|
340
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"parasail-gemma-4-31b-it": {
|
|
344
|
+
"reasoning": true,
|
|
345
|
+
"thinkingLevelMap": {
|
|
346
|
+
"off": "none",
|
|
347
|
+
"minimal": null,
|
|
348
|
+
"low": null,
|
|
349
|
+
"medium": null,
|
|
350
|
+
"high": "high",
|
|
351
|
+
"xhigh": null,
|
|
352
|
+
"max": null
|
|
353
|
+
},
|
|
354
|
+
"compat": {
|
|
355
|
+
"thinkingFormat": "chat-template",
|
|
356
|
+
"supportsReasoningEffort": false,
|
|
357
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
"parasail-glm-52": {
|
|
361
|
+
"reasoning": true,
|
|
362
|
+
"thinkingLevelMap": {
|
|
363
|
+
"off": "none",
|
|
364
|
+
"minimal": null,
|
|
365
|
+
"low": null,
|
|
366
|
+
"medium": null,
|
|
367
|
+
"high": "high",
|
|
368
|
+
"xhigh": null,
|
|
369
|
+
"max": null
|
|
370
|
+
},
|
|
371
|
+
"compat": {
|
|
372
|
+
"thinkingFormat": "chat-template",
|
|
373
|
+
"supportsReasoningEffort": false,
|
|
374
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
"parasail-kimi-k27-code": {
|
|
378
|
+
"reasoning": true,
|
|
379
|
+
"input": [
|
|
380
|
+
"text",
|
|
381
|
+
"image"
|
|
382
|
+
],
|
|
383
|
+
"thinkingLevelMap": {
|
|
384
|
+
"off": "none",
|
|
385
|
+
"minimal": null,
|
|
386
|
+
"low": null,
|
|
387
|
+
"medium": null,
|
|
388
|
+
"high": "high",
|
|
389
|
+
"xhigh": null,
|
|
390
|
+
"max": null
|
|
391
|
+
},
|
|
392
|
+
"compat": {
|
|
393
|
+
"thinkingFormat": "chat-template",
|
|
394
|
+
"supportsReasoningEffort": false,
|
|
395
|
+
"requiresReasoningContentOnAssistantMessages": true
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
"parasail-gpt-oss-120b-fast": {
|
|
399
|
+
"reasoning": true,
|
|
400
|
+
"thinkingLevelMap": {
|
|
401
|
+
"off": null,
|
|
402
|
+
"minimal": null,
|
|
403
|
+
"low": "low",
|
|
404
|
+
"medium": "medium",
|
|
405
|
+
"high": "high",
|
|
406
|
+
"xhigh": null,
|
|
407
|
+
"max": null
|
|
408
|
+
},
|
|
409
|
+
"compat": {
|
|
410
|
+
"supportsReasoningEffort": true
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"parasail-gpt-oss-120b": {
|
|
414
|
+
"reasoning": true,
|
|
415
|
+
"thinkingLevelMap": {
|
|
416
|
+
"off": null,
|
|
417
|
+
"minimal": null,
|
|
418
|
+
"low": "low",
|
|
419
|
+
"medium": "medium",
|
|
420
|
+
"high": "high",
|
|
421
|
+
"xhigh": null,
|
|
422
|
+
"max": null
|
|
423
|
+
},
|
|
424
|
+
"compat": {
|
|
425
|
+
"supportsReasoningEffort": true
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
"parasail-gpt-oss-20b": {
|
|
429
|
+
"reasoning": true,
|
|
430
|
+
"thinkingLevelMap": {
|
|
431
|
+
"off": null,
|
|
432
|
+
"minimal": null,
|
|
433
|
+
"low": "low",
|
|
434
|
+
"medium": "medium",
|
|
435
|
+
"high": "high",
|
|
436
|
+
"xhigh": null,
|
|
437
|
+
"max": null
|
|
438
|
+
},
|
|
83
439
|
"compat": {
|
|
84
440
|
"supportsReasoningEffort": true
|
|
85
441
|
}
|
package/scripts/update-models.js
CHANGED
|
@@ -173,6 +173,7 @@ function generateDisplayName(id) {
|
|
|
173
173
|
|
|
174
174
|
function applyPatch(model, patch) {
|
|
175
175
|
const result = { ...model };
|
|
176
|
+
if (patch.thinkingLevelMap !== undefined) result.thinkingLevelMap = { ...patch.thinkingLevelMap };
|
|
176
177
|
if (patch.name !== undefined) result.name = patch.name;
|
|
177
178
|
if (patch.reasoning !== undefined) result.reasoning = patch.reasoning;
|
|
178
179
|
if (patch.input !== undefined) result.input = patch.input;
|
|
@@ -192,6 +193,9 @@ function applyPatch(model, patch) {
|
|
|
192
193
|
if (!result.reasoning && result.compat?.thinkingFormat) {
|
|
193
194
|
delete result.compat.thinkingFormat;
|
|
194
195
|
}
|
|
196
|
+
if (!result.reasoning && result.thinkingLevelMap) {
|
|
197
|
+
delete result.thinkingLevelMap;
|
|
198
|
+
}
|
|
195
199
|
if (result.compat && Object.keys(result.compat).length === 0) {
|
|
196
200
|
delete result.compat;
|
|
197
201
|
}
|
|
@@ -278,6 +282,67 @@ function updateReadme(models) {
|
|
|
278
282
|
|
|
279
283
|
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
280
284
|
|
|
285
|
+
// Grace period for delisted models: update-models.js moves models the API no
|
|
286
|
+
// longer lists into deprecated-models.json (stamped with deprecatedAt) instead
|
|
287
|
+
// of dropping them; the runtime appends them back so sessions and saved model
|
|
288
|
+
// settings keep working, and after 14 days they are evicted permanently.
|
|
289
|
+
const DEPRECATED_MODEL_TTL_MS = 14 * 24 * 60 * 60 * 1000;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Reconcile deprecated-models.json against the freshly fetched model list.
|
|
293
|
+
* - in old models.json but not the API: moved into the deprecated file
|
|
294
|
+
* (deprecatedAt = now; preserved on repeat runs so the grace clock is not reset)
|
|
295
|
+
* - back in the API: resurrected (dropped from the deprecated file)
|
|
296
|
+
* - deprecatedAt older than 14 days: evicted permanently
|
|
297
|
+
* Must run BEFORE the new models.json is written; it reads the old file itself.
|
|
298
|
+
*/
|
|
299
|
+
function updateDeprecatedModels(modelsJsonPath, newModels) {
|
|
300
|
+
const deprecatedPath = path.join(path.dirname(modelsJsonPath), 'deprecated-models.json');
|
|
301
|
+
|
|
302
|
+
let oldModels = [];
|
|
303
|
+
try {
|
|
304
|
+
const parsed = JSON.parse(fs.readFileSync(modelsJsonPath, 'utf8'));
|
|
305
|
+
if (Array.isArray(parsed)) oldModels = parsed;
|
|
306
|
+
} catch { /* first run: no previous models.json */ }
|
|
307
|
+
|
|
308
|
+
let deprecated = {};
|
|
309
|
+
try {
|
|
310
|
+
const parsed = JSON.parse(fs.readFileSync(deprecatedPath, 'utf8'));
|
|
311
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) deprecated = parsed;
|
|
312
|
+
} catch { /* no graveyard yet */ }
|
|
313
|
+
|
|
314
|
+
const currentIds = new Set(newModels.map(m => m.id));
|
|
315
|
+
const now = new Date().toISOString();
|
|
316
|
+
const added = [];
|
|
317
|
+
const resurrected = [];
|
|
318
|
+
const evicted = [];
|
|
319
|
+
|
|
320
|
+
for (const old of oldModels) {
|
|
321
|
+
if (old && old.id && !currentIds.has(old.id) && !deprecated[old.id]) {
|
|
322
|
+
deprecated[old.id] = { ...old, deprecatedAt: now };
|
|
323
|
+
added.push(old.id);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
for (const [id, entry] of Object.entries(deprecated)) {
|
|
328
|
+
if (currentIds.has(id)) {
|
|
329
|
+
delete deprecated[id];
|
|
330
|
+
resurrected.push(id);
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const removedAt = Date.parse(entry && entry.deprecatedAt ? entry.deprecatedAt : '');
|
|
334
|
+
if (Number.isNaN(removedAt) || Date.now() - removedAt > DEPRECATED_MODEL_TTL_MS) {
|
|
335
|
+
delete deprecated[id];
|
|
336
|
+
evicted.push(id);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (added.length > 0 || resurrected.length > 0 || evicted.length > 0) {
|
|
341
|
+
fs.writeFileSync(deprecatedPath, JSON.stringify(deprecated, null, 2) + '\n');
|
|
342
|
+
console.log('Updated deprecated-models.json ' + JSON.stringify({ added, resurrected, evicted }));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
281
346
|
async function main() {
|
|
282
347
|
try {
|
|
283
348
|
const [apiModels, pricing] = await Promise.all([
|
|
@@ -308,6 +373,8 @@ async function main() {
|
|
|
308
373
|
});
|
|
309
374
|
|
|
310
375
|
// Save models.json (pure API output, no patch/custom baked in)
|
|
376
|
+
// Move delisted models to deprecated-models.json BEFORE models.json is overwritten
|
|
377
|
+
updateDeprecatedModels(MODELS_JSON_PATH, models);
|
|
311
378
|
saveJson(MODELS_JSON_PATH, models);
|
|
312
379
|
|
|
313
380
|
// Build full model list for README: base → patch → custom
|