@qvac/sdk 0.2.1-dev.1760851161.68dc306 → 0.2.1
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/README.md +4 -3
- package/dist/examples/llamacpp-multimodal.js +3 -3
- package/dist/examples/rag/rag-hyperdb-workspaces.js +2 -1
- package/dist/models/hyperdrive/models.d.ts +49 -1
- package/dist/models/hyperdrive/models.js +105 -54
- package/dist/schemas/common.d.ts +4 -0
- package/dist/schemas/llamacpp-config.d.ts +1 -0
- package/dist/schemas/llamacpp-config.js +4 -1
- package/dist/schemas/load-model.d.ts +10 -0
- package/dist/schemas/rag.d.ts +3 -0
- package/dist/schemas/rag.js +3 -1
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +28 -2
- package/dist/server/bare/registry/model-registry.d.ts +1 -0
- package/dist/server/rpc/handlers/completion-stream.js +31 -45
- package/dist/server/rpc/handlers/index.d.ts +2 -0
- package/dist/server/rpc/handlers/index.js +2 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +0 -19
- package/dist/server/rpc/handlers/load-model/download-manager.js +10 -25
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +121 -80
- package/dist/server/rpc/handlers/load-model/resolve.js +8 -55
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ npm i expo-file-system react-native-bare-kit
|
|
|
79
79
|
```js
|
|
80
80
|
export default {
|
|
81
81
|
expo: {
|
|
82
|
-
plugins: ["qvac
|
|
82
|
+
plugins: ["@qvac/sdk/expo-plugin"],
|
|
83
83
|
},
|
|
84
84
|
};
|
|
85
85
|
```
|
|
@@ -141,6 +141,7 @@ const cachedResponse = completion({
|
|
|
141
141
|
|
|
142
142
|
// Unload model to free up system resources
|
|
143
143
|
await unloadModel({ modelId });
|
|
144
|
+
process.exit();
|
|
144
145
|
```
|
|
145
146
|
|
|
146
147
|
**For more on how to use QVAC SDK, see [SDK at QVAC documentation](https://tether-2.gitbook.io/qvac-by-tether-or-reference/y2AsIh94H9DJ1pIBCNj9/sdk)**.
|
|
@@ -161,10 +162,10 @@ bun run build # or `watch` for hotreload
|
|
|
161
162
|
bun run build:pack
|
|
162
163
|
```
|
|
163
164
|
|
|
164
|
-
This outputs a tarball under `dist/
|
|
165
|
+
This outputs a tarball under `dist/qvac-sdk-{version}.tgz` that you can install in your project, e.g.:
|
|
165
166
|
|
|
166
167
|
```bash
|
|
167
|
-
npm i path/to/
|
|
168
|
+
npm i path/to/qvac-sdk-0.1.0.tgz
|
|
168
169
|
```
|
|
169
170
|
|
|
170
171
|
## Examples
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { completion, loadModel, unloadModel } from "@qvac/sdk";
|
|
1
|
+
import { completion, loadModel, SMOLVLM2_2_500M_MULTIMODAL_Q8_0, MMPROJ_SMOLVLM2_2_500M_MULTIMODAL_Q8_0, unloadModel, } from "@qvac/sdk";
|
|
2
2
|
if (process.argv.length < 3) {
|
|
3
3
|
console.error(`Specify an image file path as the first argument and a second image file path as the second (optional) argument`);
|
|
4
4
|
process.exit(1);
|
|
@@ -8,9 +8,9 @@ try {
|
|
|
8
8
|
const imageFilePath = process.argv[2];
|
|
9
9
|
// Load the main model with projection in a single step
|
|
10
10
|
const modelId = await loadModel({
|
|
11
|
-
modelSrc:
|
|
11
|
+
modelSrc: SMOLVLM2_2_500M_MULTIMODAL_Q8_0,
|
|
12
12
|
modelType: "llm",
|
|
13
|
-
projectionModelSrc:
|
|
13
|
+
projectionModelSrc: MMPROJ_SMOLVLM2_2_500M_MULTIMODAL_Q8_0,
|
|
14
14
|
modelConfig: {
|
|
15
15
|
ctx_size: 1024,
|
|
16
16
|
},
|
|
@@ -41,9 +41,10 @@ try {
|
|
|
41
41
|
documents: medicalArticle,
|
|
42
42
|
chunk: true,
|
|
43
43
|
chunkOpts: {
|
|
44
|
-
chunkSize:
|
|
44
|
+
chunkSize: 100,
|
|
45
45
|
chunkOverlap: 10,
|
|
46
46
|
chunkStrategy: "paragraph",
|
|
47
|
+
splitStrategy: "token",
|
|
47
48
|
},
|
|
48
49
|
});
|
|
49
50
|
console.log(`✅ Created ${medicalResult.processed.length} chunks from medical article`);
|
|
@@ -62,6 +62,20 @@ export declare const models: readonly [{
|
|
|
62
62
|
readonly addon: "llm";
|
|
63
63
|
readonly expectedSize: 1056782912;
|
|
64
64
|
readonly sha256Checksum: "c876f159707a4e4f70e045106c69db15bfc935a4981706fd4f65c6e7ea1e81c5";
|
|
65
|
+
}, {
|
|
66
|
+
readonly hyperdriveKey: "583f04c31d151b29e02aaf98f80d16aff585714ef9e2806a5067651c0f64ae31";
|
|
67
|
+
readonly hyperbeeKey: "generation:qwen2.5-omni:multimodal::3B::1.0.0";
|
|
68
|
+
readonly modelId: "Qwen2.5-Omni-3B-Q4_K_M.gguf";
|
|
69
|
+
readonly addon: "llm";
|
|
70
|
+
readonly expectedSize: 2104931648;
|
|
71
|
+
readonly sha256Checksum: "4b0bd358c1e9ec55dd3055ef6d71c958c821533d85916a10cfa89c4552a86e29";
|
|
72
|
+
}, {
|
|
73
|
+
readonly hyperdriveKey: "583f04c31d151b29e02aaf98f80d16aff585714ef9e2806a5067651c0f64ae31";
|
|
74
|
+
readonly hyperbeeKey: "generation:qwen2.5-omni:multimodal::3B::1.0.0";
|
|
75
|
+
readonly modelId: "mmproj-Qwen2.5-Omni-3B-Q8_0.gguf";
|
|
76
|
+
readonly addon: "llm";
|
|
77
|
+
readonly expectedSize: 1538031328;
|
|
78
|
+
readonly sha256Checksum: "4e6c816cd33f7298d07cb780c136a396631e50e62f6501660271f8c6e302e565";
|
|
65
79
|
}, {
|
|
66
80
|
readonly hyperdriveKey: "d331ed49c444f90b3b2a70aa5b820752685142bf2d769a0592ed666140477578";
|
|
67
81
|
readonly hyperbeeKey: "generation:qwen3:instruct::0.6B::1.0.0";
|
|
@@ -97,6 +111,34 @@ export declare const models: readonly [{
|
|
|
97
111
|
readonly addon: "llm";
|
|
98
112
|
readonly expectedSize: 2401075552;
|
|
99
113
|
readonly sha256Checksum: "9cfebb63cd7e6b6d1755ea8ef001fcdadfa17831da1db96eafe3fc554913d5e1";
|
|
114
|
+
}, {
|
|
115
|
+
readonly hyperdriveKey: "b99c6f5dcadaad827cdcb1a129a3b34aff6ad28056738e0bd559c7ffb807e30f";
|
|
116
|
+
readonly hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:f16:1.0.0:video-instruct";
|
|
117
|
+
readonly modelId: "SmolVLM2-500M-Video-Instruct-f16.gguf";
|
|
118
|
+
readonly addon: "llm";
|
|
119
|
+
readonly expectedSize: 820424704;
|
|
120
|
+
readonly sha256Checksum: "80f7e3f04bc2d3324ac1a9f52f5776fe13a69912adf74f8e7edacf773d140d77";
|
|
121
|
+
}, {
|
|
122
|
+
readonly hyperdriveKey: "b99c6f5dcadaad827cdcb1a129a3b34aff6ad28056738e0bd559c7ffb807e30f";
|
|
123
|
+
readonly hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:f16:1.0.0:video-instruct";
|
|
124
|
+
readonly modelId: "mmproj-SmolVLM2-500M-Video-Instruct-f16.gguf";
|
|
125
|
+
readonly addon: "llm";
|
|
126
|
+
readonly expectedSize: 199470624;
|
|
127
|
+
readonly sha256Checksum: "b5dc8ebe7cbeab66a5369693960a52515d7824f13d4063ceca78431f2a6b59b0";
|
|
128
|
+
}, {
|
|
129
|
+
readonly hyperdriveKey: "73b1bc01d01e25fa27be7d7f434337d14f054b0315e8463766ca31e778ac6576";
|
|
130
|
+
readonly hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:q8_0:1.0.0:video-instruct";
|
|
131
|
+
readonly modelId: "SmolVLM2-500M-Video-Instruct-Q8_0.gguf";
|
|
132
|
+
readonly addon: "llm";
|
|
133
|
+
readonly expectedSize: 436808704;
|
|
134
|
+
readonly sha256Checksum: "6f67b8036b2469fcd71728702720c6b51aebd759b78137a8120733b4d66438bc";
|
|
135
|
+
}, {
|
|
136
|
+
readonly hyperdriveKey: "73b1bc01d01e25fa27be7d7f434337d14f054b0315e8463766ca31e778ac6576";
|
|
137
|
+
readonly hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:q8_0:1.0.0:video-instruct";
|
|
138
|
+
readonly modelId: "mmproj-SmolVLM2-500M-Video-Instruct-Q8_0.gguf";
|
|
139
|
+
readonly addon: "llm";
|
|
140
|
+
readonly expectedSize: 108785184;
|
|
141
|
+
readonly sha256Checksum: "921dc7e259f308e5b027111fa185efcbf33db13f6e35749ddf7f5cdb60ef520b";
|
|
100
142
|
}, {
|
|
101
143
|
readonly hyperdriveKey: "268c2e9b2a3420632e4b6649e32822f42d5dfbda4c7e96daec5b629ed20f99f7";
|
|
102
144
|
readonly hyperbeeKey: "translation:ggml-indictrans:dist:2:200M:q0f32:1.0.0:en-hi";
|
|
@@ -421,11 +463,17 @@ export declare const GTE_LARGE_FP16: "pear://d1896d9259692818df95bd2480e90c2d057
|
|
|
421
463
|
export declare const LASER_DOLPHIN_2_6_2X7B_INST_Q2_K: "pear://bd40e4bfae48b5bf436d1b0b447ae26e4c384aebe101a5e7df6ae71c919dadf1/dolphin-mixtral-2x7b-dop-Q2_K.gguf";
|
|
422
464
|
export declare const LLAMA_3_2_1B_INST_Q4_0: "pear://afa79ee07c0a138bb9f11bfaee771fb1bdfca8c82d961cff0474e49827bd1de3/Llama-3.2-1B-Instruct-Q4_0.gguf";
|
|
423
465
|
export declare const QWEN_3_1_7B_INST_Q4: "pear://05d3d7ad9cd650f53c28f85e312ef09a645dd487845897958b3be8a19cb3aab9/Qwen3-1.7B-Q4_0.gguf";
|
|
466
|
+
export declare const QWEN2_5_OMNI_3B_MULTIMODAL: "pear://583f04c31d151b29e02aaf98f80d16aff585714ef9e2806a5067651c0f64ae31/Qwen2.5-Omni-3B-Q4_K_M.gguf";
|
|
467
|
+
export declare const MMPROJ_QWEN2_5_OMNI_3B_MULTIMODAL: "pear://583f04c31d151b29e02aaf98f80d16aff585714ef9e2806a5067651c0f64ae31/mmproj-Qwen2.5-Omni-3B-Q8_0.gguf";
|
|
424
468
|
export declare const QWEN3_0_6B_INST: "pear://d331ed49c444f90b3b2a70aa5b820752685142bf2d769a0592ed666140477578/Qwen3-0.6B-UD-IQ1_S.gguf";
|
|
425
469
|
export declare const QWEN3_4B_INST_Q4: "pear://19ffb75463149955ee24d786dfddd84d41fc872ea813cd4465f5f7299d165adc/model.gguf";
|
|
426
470
|
export declare const QWEN3_600M_INST_Q4: "pear://211874c9885f6b88b9926904420e365f5e74e1b6ac47207b7536408539bef4b7/Qwen3-0.6B-Q4_0.gguf";
|
|
427
471
|
export declare const SALAMANDRATA_2B_INST_Q4: "pear://1610d81772a9e7c37660666dbdfdcef915b6b83c522ea1ad31c19cab0075811d/salamandrata_2b_inst_q4.gguf";
|
|
428
472
|
export declare const SALAMANDRATA_2B_INST_Q8: "pear://96860337b0bdffdbb8ef0df4c8b2c3ab5e78568f5f7e15815a0a6b392512c9b5/salamandrata_2b_inst_q8.gguf";
|
|
473
|
+
export declare const SMOLVLM2_2_500M_MULTIMODAL_F16: "pear://b99c6f5dcadaad827cdcb1a129a3b34aff6ad28056738e0bd559c7ffb807e30f/SmolVLM2-500M-Video-Instruct-f16.gguf";
|
|
474
|
+
export declare const MMPROJ_SMOLVLM2_2_500M_MULTIMODAL_F16: "pear://b99c6f5dcadaad827cdcb1a129a3b34aff6ad28056738e0bd559c7ffb807e30f/mmproj-SmolVLM2-500M-Video-Instruct-f16.gguf";
|
|
475
|
+
export declare const SMOLVLM2_2_500M_MULTIMODAL_Q8_0: "pear://73b1bc01d01e25fa27be7d7f434337d14f054b0315e8463766ca31e778ac6576/SmolVLM2-500M-Video-Instruct-Q8_0.gguf";
|
|
476
|
+
export declare const MMPROJ_SMOLVLM2_2_500M_MULTIMODAL_Q8_0: "pear://73b1bc01d01e25fa27be7d7f434337d14f054b0315e8463766ca31e778ac6576/mmproj-SmolVLM2-500M-Video-Instruct-Q8_0.gguf";
|
|
429
477
|
export declare const MARIAN_EN_HI_INDIC_200M_Q0F32: "pear://268c2e9b2a3420632e4b6649e32822f42d5dfbda4c7e96daec5b629ed20f99f7/ggml-indictrans2-en-indic-dist-200M.bin";
|
|
430
478
|
export declare const MARIAN_HI_EN_INDIC_200M_Q0F32: "pear://dfea395ffe1cb6d259029e5c81c290f8828981987855e23e7b66fd7c705901eb/ggml-indictrans2-indic-en-dist-200M.bin";
|
|
431
479
|
export declare const MARIAN_HI_HI_INDIC_320M_Q0F32: "pear://9a66da960931c449b41e3315d9aea4d3925f2cda024e8a4c139b64d0a539ed41/ggml-indictrans2-indic-indic-dist-320M.bin";
|
|
@@ -471,5 +519,5 @@ export declare const WHISPER_LARGE_3: "pear://76fb36d7f16a430618962d3e78b0e22e61
|
|
|
471
519
|
export declare const WHISPER_SMALL: "pear://c6a987fbb4ad8fba1526e446501f88ee45dfafbf1685410a7aeadb589fe18608/ggml-small.en-q8_0.bin";
|
|
472
520
|
export declare const WHISPER_TINY: "pear://9281d61503593fdf3eaa9d5e5d44746c271ef930aed3b7f8ee9ce153c76399d6/ggml-tiny.bin";
|
|
473
521
|
export declare const WHISPER_TINY_SILERO: "pear://ebfb94b378276da139554668f1ff737644eadff529c2ea0f2662d7df61fd86ca/ggml-tiny.bin";
|
|
474
|
-
export declare function getModelBySrc(modelId: string, hyperdriveKey
|
|
522
|
+
export declare function getModelBySrc(modelId: string, hyperdriveKey: string): HyperdriveItem | undefined;
|
|
475
523
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -65,6 +65,22 @@ export const models = [
|
|
|
65
65
|
expectedSize: 1056782912,
|
|
66
66
|
sha256Checksum: "c876f159707a4e4f70e045106c69db15bfc935a4981706fd4f65c6e7ea1e81c5",
|
|
67
67
|
},
|
|
68
|
+
{
|
|
69
|
+
hyperdriveKey: "583f04c31d151b29e02aaf98f80d16aff585714ef9e2806a5067651c0f64ae31",
|
|
70
|
+
hyperbeeKey: "generation:qwen2.5-omni:multimodal::3B::1.0.0",
|
|
71
|
+
modelId: "Qwen2.5-Omni-3B-Q4_K_M.gguf",
|
|
72
|
+
addon: "llm",
|
|
73
|
+
expectedSize: 2104931648,
|
|
74
|
+
sha256Checksum: "4b0bd358c1e9ec55dd3055ef6d71c958c821533d85916a10cfa89c4552a86e29",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
hyperdriveKey: "583f04c31d151b29e02aaf98f80d16aff585714ef9e2806a5067651c0f64ae31",
|
|
78
|
+
hyperbeeKey: "generation:qwen2.5-omni:multimodal::3B::1.0.0",
|
|
79
|
+
modelId: "mmproj-Qwen2.5-Omni-3B-Q8_0.gguf",
|
|
80
|
+
addon: "llm",
|
|
81
|
+
expectedSize: 1538031328,
|
|
82
|
+
sha256Checksum: "4e6c816cd33f7298d07cb780c136a396631e50e62f6501660271f8c6e302e565",
|
|
83
|
+
},
|
|
68
84
|
{
|
|
69
85
|
hyperdriveKey: "d331ed49c444f90b3b2a70aa5b820752685142bf2d769a0592ed666140477578",
|
|
70
86
|
hyperbeeKey: "generation:qwen3:instruct::0.6B::1.0.0",
|
|
@@ -105,6 +121,38 @@ export const models = [
|
|
|
105
121
|
expectedSize: 2401075552,
|
|
106
122
|
sha256Checksum: "9cfebb63cd7e6b6d1755ea8ef001fcdadfa17831da1db96eafe3fc554913d5e1",
|
|
107
123
|
},
|
|
124
|
+
{
|
|
125
|
+
hyperdriveKey: "b99c6f5dcadaad827cdcb1a129a3b34aff6ad28056738e0bd559c7ffb807e30f",
|
|
126
|
+
hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:f16:1.0.0:video-instruct",
|
|
127
|
+
modelId: "SmolVLM2-500M-Video-Instruct-f16.gguf",
|
|
128
|
+
addon: "llm",
|
|
129
|
+
expectedSize: 820424704,
|
|
130
|
+
sha256Checksum: "80f7e3f04bc2d3324ac1a9f52f5776fe13a69912adf74f8e7edacf773d140d77",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
hyperdriveKey: "b99c6f5dcadaad827cdcb1a129a3b34aff6ad28056738e0bd559c7ffb807e30f",
|
|
134
|
+
hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:f16:1.0.0:video-instruct",
|
|
135
|
+
modelId: "mmproj-SmolVLM2-500M-Video-Instruct-f16.gguf",
|
|
136
|
+
addon: "llm",
|
|
137
|
+
expectedSize: 199470624,
|
|
138
|
+
sha256Checksum: "b5dc8ebe7cbeab66a5369693960a52515d7824f13d4063ceca78431f2a6b59b0",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
hyperdriveKey: "73b1bc01d01e25fa27be7d7f434337d14f054b0315e8463766ca31e778ac6576",
|
|
142
|
+
hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:q8_0:1.0.0:video-instruct",
|
|
143
|
+
modelId: "SmolVLM2-500M-Video-Instruct-Q8_0.gguf",
|
|
144
|
+
addon: "llm",
|
|
145
|
+
expectedSize: 436808704,
|
|
146
|
+
sha256Checksum: "6f67b8036b2469fcd71728702720c6b51aebd759b78137a8120733b4d66438bc",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
hyperdriveKey: "73b1bc01d01e25fa27be7d7f434337d14f054b0315e8463766ca31e778ac6576",
|
|
150
|
+
hyperbeeKey: "generation:smolVLM2:multimodal:2:500M:q8_0:1.0.0:video-instruct",
|
|
151
|
+
modelId: "mmproj-SmolVLM2-500M-Video-Instruct-Q8_0.gguf",
|
|
152
|
+
addon: "llm",
|
|
153
|
+
expectedSize: 108785184,
|
|
154
|
+
sha256Checksum: "921dc7e259f308e5b027111fa185efcbf33db13f6e35749ddf7f5cdb60ef520b",
|
|
155
|
+
},
|
|
108
156
|
{
|
|
109
157
|
hyperdriveKey: "268c2e9b2a3420632e4b6649e32822f42d5dfbda4c7e96daec5b629ed20f99f7",
|
|
110
158
|
hyperbeeKey: "translation:ggml-indictrans:dist:2:200M:q0f32:1.0.0:en-hi",
|
|
@@ -475,60 +523,63 @@ export const GTE_LARGE_FP16 = `pear://${models[4].hyperdriveKey}/${models[4].mod
|
|
|
475
523
|
export const LASER_DOLPHIN_2_6_2X7B_INST_Q2_K = `pear://${models[5].hyperdriveKey}/${models[5].modelId}`;
|
|
476
524
|
export const LLAMA_3_2_1B_INST_Q4_0 = `pear://${models[6].hyperdriveKey}/${models[6].modelId}`;
|
|
477
525
|
export const QWEN_3_1_7B_INST_Q4 = `pear://${models[7].hyperdriveKey}/${models[7].modelId}`;
|
|
478
|
-
export const
|
|
479
|
-
export const
|
|
480
|
-
export const
|
|
481
|
-
export const
|
|
482
|
-
export const
|
|
483
|
-
export const
|
|
484
|
-
export const
|
|
485
|
-
export const
|
|
486
|
-
export const
|
|
487
|
-
export const
|
|
488
|
-
export const
|
|
489
|
-
export const
|
|
490
|
-
export const
|
|
491
|
-
export const
|
|
492
|
-
export const
|
|
493
|
-
export const
|
|
494
|
-
export const
|
|
495
|
-
export const
|
|
496
|
-
export const
|
|
497
|
-
export const
|
|
498
|
-
export const
|
|
499
|
-
export const
|
|
500
|
-
export const
|
|
501
|
-
export const
|
|
502
|
-
export const
|
|
503
|
-
export const
|
|
504
|
-
export const
|
|
505
|
-
export const
|
|
506
|
-
export const
|
|
507
|
-
export const
|
|
508
|
-
export const
|
|
509
|
-
export const
|
|
510
|
-
export const
|
|
511
|
-
export const
|
|
512
|
-
export const
|
|
513
|
-
export const
|
|
514
|
-
export const
|
|
515
|
-
export const
|
|
516
|
-
export const
|
|
517
|
-
export const
|
|
518
|
-
export const
|
|
519
|
-
export const
|
|
520
|
-
export const
|
|
521
|
-
export const
|
|
522
|
-
export const
|
|
523
|
-
export const
|
|
524
|
-
export const
|
|
525
|
-
export const
|
|
526
|
-
export const
|
|
527
|
-
export const
|
|
526
|
+
export const QWEN2_5_OMNI_3B_MULTIMODAL = `pear://${models[8].hyperdriveKey}/${models[8].modelId}`;
|
|
527
|
+
export const MMPROJ_QWEN2_5_OMNI_3B_MULTIMODAL = `pear://${models[9].hyperdriveKey}/${models[9].modelId}`;
|
|
528
|
+
export const QWEN3_0_6B_INST = `pear://${models[10].hyperdriveKey}/${models[10].modelId}`;
|
|
529
|
+
export const QWEN3_4B_INST_Q4 = `pear://${models[11].hyperdriveKey}/${models[11].modelId}`;
|
|
530
|
+
export const QWEN3_600M_INST_Q4 = `pear://${models[12].hyperdriveKey}/${models[12].modelId}`;
|
|
531
|
+
export const SALAMANDRATA_2B_INST_Q4 = `pear://${models[13].hyperdriveKey}/${models[13].modelId}`;
|
|
532
|
+
export const SALAMANDRATA_2B_INST_Q8 = `pear://${models[14].hyperdriveKey}/${models[14].modelId}`;
|
|
533
|
+
export const SMOLVLM2_2_500M_MULTIMODAL_F16 = `pear://${models[15].hyperdriveKey}/${models[15].modelId}`;
|
|
534
|
+
export const MMPROJ_SMOLVLM2_2_500M_MULTIMODAL_F16 = `pear://${models[16].hyperdriveKey}/${models[16].modelId}`;
|
|
535
|
+
export const SMOLVLM2_2_500M_MULTIMODAL_Q8_0 = `pear://${models[17].hyperdriveKey}/${models[17].modelId}`;
|
|
536
|
+
export const MMPROJ_SMOLVLM2_2_500M_MULTIMODAL_Q8_0 = `pear://${models[18].hyperdriveKey}/${models[18].modelId}`;
|
|
537
|
+
export const MARIAN_EN_HI_INDIC_200M_Q0F32 = `pear://${models[19].hyperdriveKey}/${models[19].modelId}`;
|
|
538
|
+
export const MARIAN_HI_EN_INDIC_200M_Q0F32 = `pear://${models[20].hyperdriveKey}/${models[20].modelId}`;
|
|
539
|
+
export const MARIAN_HI_HI_INDIC_320M_Q0F32 = `pear://${models[21].hyperdriveKey}/${models[21].modelId}`;
|
|
540
|
+
export const MARIAN_EN_HI_INDIC_1B_Q0F16 = `pear://${models[22].hyperdriveKey}/${models[22].modelId}`;
|
|
541
|
+
export const MARIAN_HI_EN_INDIC_1B_Q0F16 = `pear://${models[23].hyperdriveKey}/${models[23].modelId}`;
|
|
542
|
+
export const MARIAN_HI_HI_INDIC_1B_Q0F16 = `pear://${models[24].hyperdriveKey}/${models[24].modelId}`;
|
|
543
|
+
export const MARIAN_EN_HI_INDIC_1B_Q0F32 = `pear://${models[25].hyperdriveKey}/${models[25].modelId}`;
|
|
544
|
+
export const MARIAN_HI_EN_INDIC_1B_Q0F32 = `pear://${models[26].hyperdriveKey}/${models[26].modelId}`;
|
|
545
|
+
export const MARIAN_HI_HI_INDIC_1B_Q0F32 = `pear://${models[27].hyperdriveKey}/${models[27].modelId}`;
|
|
546
|
+
export const MARIAN_EN_HI_INDIC_1B_Q4_0 = `pear://${models[28].hyperdriveKey}/${models[28].modelId}`;
|
|
547
|
+
export const MARIAN_HI_EN_INDIC_1B_Q4_0 = `pear://${models[29].hyperdriveKey}/${models[29].modelId}`;
|
|
548
|
+
export const MARIAN_HI_HI_INDIC_1B_Q4_0 = `pear://${models[30].hyperdriveKey}/${models[30].modelId}`;
|
|
549
|
+
export const MARIAN_EN_HI_INDIC_200M_Q0F16 = `pear://${models[31].hyperdriveKey}/${models[31].modelId}`;
|
|
550
|
+
export const MARIAN_HI_EN_INDIC_200M_Q0F16 = `pear://${models[32].hyperdriveKey}/${models[32].modelId}`;
|
|
551
|
+
export const MARIAN_EN_HI_INDIC_200M_Q4_0 = `pear://${models[33].hyperdriveKey}/${models[33].modelId}`;
|
|
552
|
+
export const MARIAN_HI_EN_INDIC_200M_Q4_0 = `pear://${models[34].hyperdriveKey}/${models[34].modelId}`;
|
|
553
|
+
export const MARIAN_HI_HI_INDIC_320M_Q0F16 = `pear://${models[35].hyperdriveKey}/${models[35].modelId}`;
|
|
554
|
+
export const MARIAN_HI_HI_INDIC_320M_Q4_0 = `pear://${models[36].hyperdriveKey}/${models[36].modelId}`;
|
|
555
|
+
export const MARIAN_OPUS_EN_IT = `pear://${models[37].hyperdriveKey}/${models[37].modelId}`;
|
|
556
|
+
export const MARIAN_OPUS_IT_EN = `pear://${models[38].hyperdriveKey}/${models[38].modelId}`;
|
|
557
|
+
export const MARIAN_OPUS_DE_EN_Q0F32 = `pear://${models[39].hyperdriveKey}/${models[39].modelId}`;
|
|
558
|
+
export const MARIAN_OPUS_DE_ES_Q0F32 = `pear://${models[40].hyperdriveKey}/${models[40].modelId}`;
|
|
559
|
+
export const MARIAN_OPUS_DE_IT_Q0F32 = `pear://${models[41].hyperdriveKey}/${models[41].modelId}`;
|
|
560
|
+
export const MARIAN_OPUS_EN_DE_Q0F32 = `pear://${models[42].hyperdriveKey}/${models[42].modelId}`;
|
|
561
|
+
export const MARIAN_OPUS_EN_ES_Q0F32 = `pear://${models[43].hyperdriveKey}/${models[43].modelId}`;
|
|
562
|
+
export const MARIAN_OPUS_EN_IT_Q0F32 = `pear://${models[44].hyperdriveKey}/${models[44].modelId}`;
|
|
563
|
+
export const MARIAN_OPUS_ES_DE_Q0F32 = `pear://${models[45].hyperdriveKey}/${models[45].modelId}`;
|
|
564
|
+
export const MARIAN_OPUS_ES_EN_Q0F32 = `pear://${models[46].hyperdriveKey}/${models[46].modelId}`;
|
|
565
|
+
export const MARIAN_OPUS_ES_IT_Q0F32 = `pear://${models[47].hyperdriveKey}/${models[47].modelId}`;
|
|
566
|
+
export const MARIAN_OPUS_IT_DE_Q0F32 = `pear://${models[48].hyperdriveKey}/${models[48].modelId}`;
|
|
567
|
+
export const MARIAN_OPUS_IT_EN_Q0F32 = `pear://${models[49].hyperdriveKey}/${models[49].modelId}`;
|
|
568
|
+
export const MARIAN_OPUS_IT_ES_Q0F32 = `pear://${models[50].hyperdriveKey}/${models[50].modelId}`;
|
|
569
|
+
export const MARIAN_OPUS_EN_RU_Q0F16 = `pear://${models[51].hyperdriveKey}/${models[51].modelId}`;
|
|
570
|
+
export const MARIAN_OPUS_RU_EN_Q0F16 = `pear://${models[52].hyperdriveKey}/${models[52].modelId}`;
|
|
571
|
+
export const MARIAN_OPUS_EN_RU_Q0F32 = `pear://${models[53].hyperdriveKey}/${models[53].modelId}`;
|
|
572
|
+
export const MARIAN_OPUS_RU_EN_Q0F32 = `pear://${models[54].hyperdriveKey}/${models[54].modelId}`;
|
|
573
|
+
export const MARIAN_OPUS_EN_RU_Q4_0 = `pear://${models[55].hyperdriveKey}/${models[55].modelId}`;
|
|
574
|
+
export const MARIAN_OPUS_RU_EN_Q4_0 = `pear://${models[56].hyperdriveKey}/${models[56].modelId}`;
|
|
575
|
+
export const MARIAN_OPUS_EN_JA_Q4F16_1 = `pear://${models[57].hyperdriveKey}/${models[57].modelId}`;
|
|
576
|
+
export const MARIAN_OPUS_JA_EN_Q4F16_1 = `pear://${models[58].hyperdriveKey}/${models[58].modelId}`;
|
|
577
|
+
export const VAD_SILERO_5_1_2 = `pear://${models[59].hyperdriveKey}/${models[59].modelId}`;
|
|
578
|
+
export const WHISPER_LARGE_3 = `pear://${models[60].hyperdriveKey}/${models[60].modelId}`;
|
|
579
|
+
export const WHISPER_SMALL = `pear://${models[61].hyperdriveKey}/${models[61].modelId}`;
|
|
580
|
+
export const WHISPER_TINY = `pear://${models[62].hyperdriveKey}/${models[62].modelId}`;
|
|
581
|
+
export const WHISPER_TINY_SILERO = `pear://${models[63].hyperdriveKey}/${models[63].modelId}`;
|
|
528
582
|
// Helper function for our curated model list
|
|
529
583
|
export function getModelBySrc(modelId, hyperdriveKey) {
|
|
530
|
-
|
|
531
|
-
return models.find((model) => model.modelId === modelId && model.hyperdriveKey === hyperdriveKey);
|
|
532
|
-
}
|
|
533
|
-
return models.find((model) => model.modelId === modelId);
|
|
584
|
+
return models.find((model) => model.modelId === modelId && model.hyperdriveKey === hyperdriveKey);
|
|
534
585
|
}
|
package/dist/schemas/common.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
32
32
|
frequency_penalty: z.ZodOptional<z.ZodNumber>;
|
|
33
33
|
repeat_penalty: z.ZodOptional<z.ZodNumber>;
|
|
34
34
|
reverse_prompt: z.ZodOptional<z.ZodString>;
|
|
35
|
+
n_discarded: z.ZodOptional<z.ZodNumber>;
|
|
35
36
|
}, z.core.$strip>;
|
|
36
37
|
}, z.core.$strip>, z.ZodObject<{
|
|
37
38
|
type: z.ZodLiteral<"loadModel">;
|
|
@@ -199,6 +200,7 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
199
200
|
frequency_penalty?: number | undefined;
|
|
200
201
|
repeat_penalty?: number | undefined;
|
|
201
202
|
reverse_prompt?: string | undefined;
|
|
203
|
+
n_discarded?: number | undefined;
|
|
202
204
|
};
|
|
203
205
|
projectionModelSrc?: string | undefined;
|
|
204
206
|
vadModelSrc?: string | undefined;
|
|
@@ -296,6 +298,7 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
296
298
|
frequency_penalty?: number | undefined;
|
|
297
299
|
repeat_penalty?: number | undefined;
|
|
298
300
|
reverse_prompt?: string | undefined;
|
|
301
|
+
n_discarded?: number | undefined;
|
|
299
302
|
};
|
|
300
303
|
projectionModelSrc?: string | undefined;
|
|
301
304
|
vadModelSrc?: string | undefined;
|
|
@@ -483,6 +486,7 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
483
486
|
paragraph: "paragraph";
|
|
484
487
|
}>>;
|
|
485
488
|
splitStrategy: z.ZodOptional<z.ZodEnum<{
|
|
489
|
+
token: "token";
|
|
486
490
|
character: "character";
|
|
487
491
|
word: "word";
|
|
488
492
|
sentence: "sentence";
|
|
@@ -21,6 +21,7 @@ export declare const llmConfigSchema: z.ZodObject<{
|
|
|
21
21
|
frequency_penalty: z.ZodOptional<z.ZodNumber>;
|
|
22
22
|
repeat_penalty: z.ZodOptional<z.ZodNumber>;
|
|
23
23
|
reverse_prompt: z.ZodOptional<z.ZodString>;
|
|
24
|
+
n_discarded: z.ZodOptional<z.ZodNumber>;
|
|
24
25
|
}, z.core.$strip>;
|
|
25
26
|
export declare const embedConfigSchema: z.ZodObject<{
|
|
26
27
|
config: z.ZodDefault<z.ZodString>;
|
|
@@ -32,8 +32,11 @@ export const llmConfigSchema = z.object({
|
|
|
32
32
|
frequency_penalty: z.number().optional(),
|
|
33
33
|
repeat_penalty: z.number().optional(),
|
|
34
34
|
reverse_prompt: z.string().optional(),
|
|
35
|
+
n_discarded: z.number().optional(),
|
|
35
36
|
});
|
|
36
37
|
export const embedConfigSchema = z.object({
|
|
37
38
|
// https://github.com/tetherto/qvac-lib-infer-llamacpp-embed/tree/main?tab=readme-ov-file#4-create-config
|
|
38
|
-
config: z
|
|
39
|
+
config: z
|
|
40
|
+
.string()
|
|
41
|
+
.default("-ngl\t99\n-dev\tgpu\n--embd-separator\t⟪§§§EMBED_SEP§§§⟫\n-c\t512"),
|
|
39
42
|
});
|
|
@@ -19,6 +19,7 @@ export declare const loadModelOptionsSchema: z.ZodPipe<z.ZodUnion<readonly [z.Zo
|
|
|
19
19
|
frequency_penalty: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
20
20
|
repeat_penalty: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
21
21
|
reverse_prompt: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
22
|
+
n_discarded: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
22
23
|
}, z.core.$strict>>;
|
|
23
24
|
seed: z.ZodOptional<z.ZodBoolean>;
|
|
24
25
|
projectionModelSrc: z.ZodOptional<z.ZodString>;
|
|
@@ -187,6 +188,7 @@ export declare const loadModelOptionsSchema: z.ZodPipe<z.ZodUnion<readonly [z.Zo
|
|
|
187
188
|
frequency_penalty?: number | undefined;
|
|
188
189
|
repeat_penalty?: number | undefined;
|
|
189
190
|
reverse_prompt?: string | undefined;
|
|
191
|
+
n_discarded?: number | undefined;
|
|
190
192
|
} | undefined;
|
|
191
193
|
projectionModelSrc?: string | undefined;
|
|
192
194
|
delegate?: {
|
|
@@ -271,6 +273,7 @@ export declare const loadModelOptionsSchema: z.ZodPipe<z.ZodUnion<readonly [z.Zo
|
|
|
271
273
|
frequency_penalty?: number | undefined;
|
|
272
274
|
repeat_penalty?: number | undefined;
|
|
273
275
|
reverse_prompt?: string | undefined;
|
|
276
|
+
n_discarded?: number | undefined;
|
|
274
277
|
} | undefined;
|
|
275
278
|
seed?: boolean | undefined;
|
|
276
279
|
projectionModelSrc?: string | undefined;
|
|
@@ -370,6 +373,7 @@ export declare const loadLlmModelRequestSchema: z.ZodObject<{
|
|
|
370
373
|
frequency_penalty: z.ZodOptional<z.ZodNumber>;
|
|
371
374
|
repeat_penalty: z.ZodOptional<z.ZodNumber>;
|
|
372
375
|
reverse_prompt: z.ZodOptional<z.ZodString>;
|
|
376
|
+
n_discarded: z.ZodOptional<z.ZodNumber>;
|
|
373
377
|
}, z.core.$strip>;
|
|
374
378
|
}, z.core.$strip>;
|
|
375
379
|
export declare const loadWhisperModelRequestSchema: z.ZodObject<{
|
|
@@ -550,6 +554,7 @@ export declare const loadModelRequestSchema: z.ZodPipe<z.ZodDiscriminatedUnion<[
|
|
|
550
554
|
frequency_penalty: z.ZodOptional<z.ZodNumber>;
|
|
551
555
|
repeat_penalty: z.ZodOptional<z.ZodNumber>;
|
|
552
556
|
reverse_prompt: z.ZodOptional<z.ZodString>;
|
|
557
|
+
n_discarded: z.ZodOptional<z.ZodNumber>;
|
|
553
558
|
}, z.core.$strip>;
|
|
554
559
|
}, z.core.$strip>, z.ZodObject<{
|
|
555
560
|
type: z.ZodLiteral<"loadModel">;
|
|
@@ -717,6 +722,7 @@ export declare const loadModelRequestSchema: z.ZodPipe<z.ZodDiscriminatedUnion<[
|
|
|
717
722
|
frequency_penalty?: number | undefined;
|
|
718
723
|
repeat_penalty?: number | undefined;
|
|
719
724
|
reverse_prompt?: string | undefined;
|
|
725
|
+
n_discarded?: number | undefined;
|
|
720
726
|
};
|
|
721
727
|
projectionModelSrc?: string | undefined;
|
|
722
728
|
vadModelSrc?: string | undefined;
|
|
@@ -814,6 +820,7 @@ export declare const loadModelRequestSchema: z.ZodPipe<z.ZodDiscriminatedUnion<[
|
|
|
814
820
|
frequency_penalty?: number | undefined;
|
|
815
821
|
repeat_penalty?: number | undefined;
|
|
816
822
|
reverse_prompt?: string | undefined;
|
|
823
|
+
n_discarded?: number | undefined;
|
|
817
824
|
};
|
|
818
825
|
projectionModelSrc?: string | undefined;
|
|
819
826
|
vadModelSrc?: string | undefined;
|
|
@@ -932,6 +939,7 @@ export declare const loadModelServerParamsSchema: z.ZodObject<{
|
|
|
932
939
|
frequency_penalty: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
933
940
|
repeat_penalty: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
934
941
|
reverse_prompt: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
942
|
+
n_discarded: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
935
943
|
}, z.core.$strict>>;
|
|
936
944
|
seed: z.ZodOptional<z.ZodBoolean>;
|
|
937
945
|
projectionModelSrc: z.ZodOptional<z.ZodString>;
|
|
@@ -1100,6 +1108,7 @@ export declare const loadModelServerParamsSchema: z.ZodObject<{
|
|
|
1100
1108
|
frequency_penalty?: number | undefined;
|
|
1101
1109
|
repeat_penalty?: number | undefined;
|
|
1102
1110
|
reverse_prompt?: string | undefined;
|
|
1111
|
+
n_discarded?: number | undefined;
|
|
1103
1112
|
} | undefined;
|
|
1104
1113
|
projectionModelSrc?: string | undefined;
|
|
1105
1114
|
delegate?: {
|
|
@@ -1184,6 +1193,7 @@ export declare const loadModelServerParamsSchema: z.ZodObject<{
|
|
|
1184
1193
|
frequency_penalty?: number | undefined;
|
|
1185
1194
|
repeat_penalty?: number | undefined;
|
|
1186
1195
|
reverse_prompt?: string | undefined;
|
|
1196
|
+
n_discarded?: number | undefined;
|
|
1187
1197
|
} | undefined;
|
|
1188
1198
|
seed?: boolean | undefined;
|
|
1189
1199
|
projectionModelSrc?: string | undefined;
|
package/dist/schemas/rag.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ declare const ragSaveEmbeddingsParamsSchema: z.ZodObject<{
|
|
|
25
25
|
paragraph: "paragraph";
|
|
26
26
|
}>>;
|
|
27
27
|
splitStrategy: z.ZodOptional<z.ZodEnum<{
|
|
28
|
+
token: "token";
|
|
28
29
|
character: "character";
|
|
29
30
|
word: "word";
|
|
30
31
|
sentence: "sentence";
|
|
@@ -45,6 +46,7 @@ export declare const ragSaveEmbeddingsOperationSchema: z.ZodObject<{
|
|
|
45
46
|
paragraph: "paragraph";
|
|
46
47
|
}>>;
|
|
47
48
|
splitStrategy: z.ZodOptional<z.ZodEnum<{
|
|
49
|
+
token: "token";
|
|
48
50
|
character: "character";
|
|
49
51
|
word: "word";
|
|
50
52
|
sentence: "sentence";
|
|
@@ -95,6 +97,7 @@ export declare const ragRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
95
97
|
paragraph: "paragraph";
|
|
96
98
|
}>>;
|
|
97
99
|
splitStrategy: z.ZodOptional<z.ZodEnum<{
|
|
100
|
+
token: "token";
|
|
98
101
|
character: "character";
|
|
99
102
|
word: "word";
|
|
100
103
|
sentence: "sentence";
|
package/dist/schemas/rag.js
CHANGED
|
@@ -4,7 +4,9 @@ const llmChunkOptsSchema = z.object({
|
|
|
4
4
|
chunkSize: z.number().optional(),
|
|
5
5
|
chunkOverlap: z.number().optional(),
|
|
6
6
|
chunkStrategy: z.enum(["character", "paragraph"]).optional(),
|
|
7
|
-
splitStrategy: z
|
|
7
|
+
splitStrategy: z
|
|
8
|
+
.enum(["character", "word", "token", "sentence", "line"])
|
|
9
|
+
.optional(),
|
|
8
10
|
});
|
|
9
11
|
const ragSaveEmbeddingsResultSchema = z.object({
|
|
10
12
|
status: z.enum(["fulfilled", "rejected"]),
|
|
@@ -54,8 +54,34 @@ function prepareMessagesForCache(cachePathToUse, cacheExists, history) {
|
|
|
54
54
|
}
|
|
55
55
|
async function* processModelResponse(model, messagesToSend, shouldSaveCache) {
|
|
56
56
|
const response = await model.run(messagesToSend);
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// Create a promise that rejects when onError is triggered
|
|
58
|
+
let rejectOnError = null;
|
|
59
|
+
const errorPromise = new Promise((_, reject) => {
|
|
60
|
+
rejectOnError = reject;
|
|
61
|
+
});
|
|
62
|
+
response.onError((error) => {
|
|
63
|
+
if (rejectOnError) {
|
|
64
|
+
rejectOnError(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const iterator = response.iterate();
|
|
68
|
+
try {
|
|
69
|
+
while (true) {
|
|
70
|
+
// Race between getting the next token and an error occurring
|
|
71
|
+
const result = await Promise.race([iterator.next(), errorPromise]);
|
|
72
|
+
if (result.done) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
yield result.value;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw new Error(String(error));
|
|
84
|
+
}
|
|
59
85
|
}
|
|
60
86
|
if (shouldSaveCache) {
|
|
61
87
|
await model.run([{ role: "session", content: "save" }]);
|
|
@@ -1,52 +1,38 @@
|
|
|
1
1
|
import { completion } from "../../bare/addons/llamacpp/index.js";
|
|
2
2
|
export async function* handleCompletionStream(request) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const filteredHistory = request.history.map(({ role, content, attachments }) => ({
|
|
4
|
+
role,
|
|
5
|
+
content,
|
|
6
|
+
attachments: attachments ?? [],
|
|
7
|
+
}));
|
|
8
|
+
const stream = completion({
|
|
9
|
+
history: filteredHistory,
|
|
10
|
+
modelId: request.modelId,
|
|
11
|
+
kvCache: request.kvCache,
|
|
12
|
+
});
|
|
13
|
+
let stats;
|
|
14
|
+
let done = false;
|
|
15
|
+
let buffer = "";
|
|
16
|
+
while (!done) {
|
|
17
|
+
const result = await stream.next();
|
|
18
|
+
if (result.done) {
|
|
19
|
+
stats = result.value;
|
|
20
|
+
done = true;
|
|
7
21
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
modelId: request.modelId,
|
|
16
|
-
kvCache: request.kvCache,
|
|
17
|
-
});
|
|
18
|
-
let stats;
|
|
19
|
-
let done = false;
|
|
20
|
-
let buffer = "";
|
|
21
|
-
while (!done) {
|
|
22
|
-
const result = await stream.next();
|
|
23
|
-
if (result.done) {
|
|
24
|
-
stats = result.value;
|
|
25
|
-
done = true;
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
buffer += result.value;
|
|
29
|
-
if (request.stream) {
|
|
30
|
-
yield {
|
|
31
|
-
type: "completionStream",
|
|
32
|
-
token: result.value,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
22
|
+
else {
|
|
23
|
+
buffer += result.value;
|
|
24
|
+
if (request.stream) {
|
|
25
|
+
yield {
|
|
26
|
+
type: "completionStream",
|
|
27
|
+
token: result.value,
|
|
28
|
+
};
|
|
35
29
|
}
|
|
36
30
|
}
|
|
37
|
-
yield {
|
|
38
|
-
type: "completionStream",
|
|
39
|
-
token: buffer,
|
|
40
|
-
done: true,
|
|
41
|
-
stats,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error("Error during completion stream:", error);
|
|
46
|
-
yield {
|
|
47
|
-
type: "completionStream",
|
|
48
|
-
token: "",
|
|
49
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
50
|
-
};
|
|
51
31
|
}
|
|
32
|
+
yield {
|
|
33
|
+
type: "completionStream",
|
|
34
|
+
token: buffer,
|
|
35
|
+
done: true,
|
|
36
|
+
stats,
|
|
37
|
+
};
|
|
52
38
|
}
|
|
@@ -9,9 +9,11 @@ import { handleTranslate } from "./translate";
|
|
|
9
9
|
import { handleLoggingStream } from "./logging-stream";
|
|
10
10
|
import { handleRag } from "./rag";
|
|
11
11
|
import { cancelHandler } from "./cancelHandler";
|
|
12
|
+
import { handleDeleteCache } from "./delete-cache";
|
|
12
13
|
export declare const handlers: {
|
|
13
14
|
completionStream: typeof handleCompletionStream;
|
|
14
15
|
downloadAsset: typeof handleDownloadAsset;
|
|
16
|
+
deleteCache: typeof handleDeleteCache;
|
|
15
17
|
loadModel: typeof handleLoadModel;
|
|
16
18
|
unloadModel: typeof handleUnloadModel;
|
|
17
19
|
embed: typeof handleEmbed;
|
|
@@ -9,9 +9,11 @@ import { handleTranslate } from "./translate.js";
|
|
|
9
9
|
import { handleLoggingStream } from "./logging-stream.js";
|
|
10
10
|
import { handleRag } from "./rag.js";
|
|
11
11
|
import { cancelHandler } from "./cancelHandler.js";
|
|
12
|
+
import { handleDeleteCache } from "./delete-cache.js";
|
|
12
13
|
export const handlers = {
|
|
13
14
|
completionStream: handleCompletionStream,
|
|
14
15
|
downloadAsset: handleDownloadAsset,
|
|
16
|
+
deleteCache: handleDeleteCache,
|
|
15
17
|
loadModel: handleLoadModel,
|
|
16
18
|
unloadModel: handleUnloadModel,
|
|
17
19
|
embed: handleEmbed,
|
|
@@ -4,28 +4,9 @@ export declare const registerDownload: (key: string, entry: DownloadEntry) => vo
|
|
|
4
4
|
export declare const unregisterDownload: (key: string) => void;
|
|
5
5
|
export declare const createHyperdriveDownloadKey: (hyperdriveKey: string, modelFileName: string) => string;
|
|
6
6
|
export declare const createHttpDownloadKey: (url: string) => string;
|
|
7
|
-
export declare const getAllActiveDownloads: () => Map<string, DownloadEntry>;
|
|
8
7
|
export declare const setClearCacheFlag: (downloadKey: string, clearCache: boolean) => void;
|
|
9
8
|
export declare const shouldClearCache: (downloadKey: string) => boolean;
|
|
10
9
|
export declare const clearClearCacheFlag: (downloadKey: string) => void;
|
|
11
10
|
export declare const createCancelFunction: (downloadKey: string, clearCache?: boolean) => () => void;
|
|
12
11
|
export declare const cancelAllDownloads: () => void;
|
|
13
|
-
export declare const getDownloadStats: () => {
|
|
14
|
-
activeCount: number;
|
|
15
|
-
downloads: ({
|
|
16
|
-
hyperdriveKey: string;
|
|
17
|
-
modelFileName: string;
|
|
18
|
-
key: string;
|
|
19
|
-
startTime: number;
|
|
20
|
-
duration: number;
|
|
21
|
-
type: "hyperdrive" | "http";
|
|
22
|
-
} | {
|
|
23
|
-
url: string;
|
|
24
|
-
modelPath: string;
|
|
25
|
-
key: string;
|
|
26
|
-
startTime: number;
|
|
27
|
-
duration: number;
|
|
28
|
-
type: "hyperdrive" | "http";
|
|
29
|
-
})[];
|
|
30
|
-
};
|
|
31
12
|
//# sourceMappingURL=download-manager.d.ts.map
|
|
@@ -12,7 +12,6 @@ export const unregisterDownload = (key) => {
|
|
|
12
12
|
};
|
|
13
13
|
export const createHyperdriveDownloadKey = (hyperdriveKey, modelFileName) => `${hyperdriveKey}:${modelFileName}`;
|
|
14
14
|
export const createHttpDownloadKey = (url) => `http:${url}`;
|
|
15
|
-
export const getAllActiveDownloads = () => new Map(activeDownloads);
|
|
16
15
|
export const setClearCacheFlag = (downloadKey, clearCache) => {
|
|
17
16
|
if (clearCache) {
|
|
18
17
|
clearCacheFlags.set(downloadKey, true);
|
|
@@ -39,24 +38,6 @@ export const cancelAllDownloads = () => {
|
|
|
39
38
|
console.log(`🧹 Cancelling ${activeDownloads.size} active downloads`);
|
|
40
39
|
Array.from(activeDownloads.keys()).forEach((key) => createCancelFunction(key)());
|
|
41
40
|
};
|
|
42
|
-
export const getDownloadStats = () => ({
|
|
43
|
-
activeCount: activeDownloads.size,
|
|
44
|
-
downloads: Array.from(activeDownloads.entries()).map(([key, entry]) => ({
|
|
45
|
-
key,
|
|
46
|
-
startTime: entry.startTime,
|
|
47
|
-
duration: Date.now() - entry.startTime,
|
|
48
|
-
type: entry.type,
|
|
49
|
-
...(entry.type === "hyperdrive"
|
|
50
|
-
? {
|
|
51
|
-
hyperdriveKey: entry.hyperdriveKey,
|
|
52
|
-
modelFileName: entry.modelFileName,
|
|
53
|
-
}
|
|
54
|
-
: {
|
|
55
|
-
url: entry.url,
|
|
56
|
-
modelPath: entry.modelPath,
|
|
57
|
-
}),
|
|
58
|
-
})),
|
|
59
|
-
});
|
|
60
41
|
// Register cleanup handlers for graceful shutdown
|
|
61
42
|
let cleanupRegistered = false;
|
|
62
43
|
let isCleaningUp = false;
|
|
@@ -79,10 +60,14 @@ const registerCleanupHandlers = () => {
|
|
|
79
60
|
console.error("❌ Error during download cleanup:", error);
|
|
80
61
|
}
|
|
81
62
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
63
|
+
let handlingExit = false;
|
|
64
|
+
const exitHandler = async () => {
|
|
65
|
+
if (handlingExit)
|
|
66
|
+
return;
|
|
67
|
+
handlingExit = true;
|
|
68
|
+
await cleanup();
|
|
69
|
+
process.exit(0);
|
|
70
|
+
};
|
|
71
|
+
process.once("SIGTERM", () => void exitHandler());
|
|
72
|
+
process.once("SIGINT", () => void exitHandler());
|
|
88
73
|
};
|
|
@@ -10,24 +10,49 @@ import { getEnv } from "../../../worker.js";
|
|
|
10
10
|
import { getModelsCacheDir, generateShortHash } from "../../../utils/index.js";
|
|
11
11
|
import { getModelBySrc } from "../../../../models/hyperdrive/index.js";
|
|
12
12
|
import { getActiveDownload, registerDownload, unregisterDownload, createHyperdriveDownloadKey, shouldClearCache, clearClearCacheFlag, } from "./download-manager.js";
|
|
13
|
+
function createProgressHandler(blob, progressCallback, downloadKey, initialBytes = 0) {
|
|
14
|
+
let downloadedBytes = initialBytes;
|
|
15
|
+
return (index, bytes) => {
|
|
16
|
+
if (index >= blob.blockOffset &&
|
|
17
|
+
index < blob.blockOffset + blob.blockLength) {
|
|
18
|
+
downloadedBytes += bytes;
|
|
19
|
+
if (progressCallback && downloadKey) {
|
|
20
|
+
progressCallback({
|
|
21
|
+
type: "modelProgress",
|
|
22
|
+
downloaded: downloadedBytes,
|
|
23
|
+
total: blob.byteLength,
|
|
24
|
+
percentage: blob.byteLength > 0 ? (downloadedBytes / blob.byteLength) * 100 : 0,
|
|
25
|
+
downloadKey,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
13
31
|
async function setupHyperdrive(hyperdriveKey, corestoreDir) {
|
|
14
32
|
const corestore = new Corestore(corestoreDir);
|
|
15
33
|
await corestore.ready();
|
|
16
34
|
const drive = new Hyperdrive(corestore, Buffer.from(hyperdriveKey, "hex"));
|
|
17
35
|
await drive.ready();
|
|
18
36
|
const swarm = new Hyperswarm();
|
|
19
|
-
|
|
37
|
+
const doneFindingPeers = drive.findingPeers();
|
|
20
38
|
swarm.on("connection", (connection) => {
|
|
21
39
|
console.log(`🤝 Connected to peer for hyperdrive download`);
|
|
22
40
|
drive.replicate(connection);
|
|
23
41
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
doneFindingPeers();
|
|
42
|
+
swarm.join(drive.discoveryKey, { server: false, client: true });
|
|
43
|
+
swarm.flush().then(doneFindingPeers, doneFindingPeers);
|
|
27
44
|
return { corestore, drive, swarm, corestoreDir };
|
|
28
45
|
}
|
|
29
46
|
async function cleanupHyperdrive(setup) {
|
|
30
47
|
console.log("🧹 Cleaning up hyperdrive setup");
|
|
48
|
+
if (!setup.swarm.suspended) {
|
|
49
|
+
try {
|
|
50
|
+
await setup.swarm.suspend();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// If suspend fails, continue with cleanup
|
|
54
|
+
}
|
|
55
|
+
}
|
|
31
56
|
await setup.swarm.destroy();
|
|
32
57
|
await setup.drive.close();
|
|
33
58
|
await setup.corestore.close();
|
|
@@ -42,43 +67,81 @@ export async function deleteCorestoreDirectory(corestoreDir) {
|
|
|
42
67
|
}
|
|
43
68
|
}
|
|
44
69
|
async function findFileInHyperdrive(drive, modelFileName) {
|
|
70
|
+
if (drive.core.length === 0) {
|
|
71
|
+
// this method will update the length of the core using the first peer it finds
|
|
72
|
+
// this will ensure that the hyperdrive is usable
|
|
73
|
+
await drive.core.update();
|
|
74
|
+
}
|
|
45
75
|
const paths = [modelFileName, `/${modelFileName}`, `./${modelFileName}`];
|
|
46
|
-
let entry = null;
|
|
47
|
-
let targetPath = modelFileName;
|
|
48
76
|
for (const pathVariation of paths) {
|
|
49
77
|
try {
|
|
50
|
-
entry = await drive.entry(pathVariation);
|
|
78
|
+
const entry = await drive.entry(pathVariation, { wait: true });
|
|
51
79
|
if (entry) {
|
|
52
|
-
targetPath
|
|
53
|
-
break;
|
|
80
|
+
return { entry, targetPath: pathVariation };
|
|
54
81
|
}
|
|
55
82
|
}
|
|
56
83
|
catch {
|
|
57
84
|
// Continue trying other paths
|
|
58
85
|
}
|
|
59
86
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
// If not found, list available files for debugging
|
|
88
|
+
const availableFiles = [];
|
|
89
|
+
try {
|
|
90
|
+
// Try both with and without leading slash
|
|
91
|
+
for (const prefix of ["/", ""]) {
|
|
92
|
+
const files = drive.list(prefix, { recursive: true, wait: true });
|
|
93
|
+
for await (const file of files) {
|
|
66
94
|
availableFiles.push(file.key);
|
|
67
95
|
}
|
|
68
|
-
if (availableFiles.length
|
|
69
|
-
|
|
70
|
-
const noSlashFiles = drive.list("", false);
|
|
71
|
-
for await (const file of noSlashFiles) {
|
|
72
|
-
availableFiles.push(file.key);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
throw new Error(`File ${modelFileName} not found in hyperdrive. Available files: ${availableFiles.join(", ")}`);
|
|
96
|
+
if (availableFiles.length > 0)
|
|
97
|
+
break;
|
|
76
98
|
}
|
|
77
|
-
|
|
78
|
-
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Ignore listing errors
|
|
102
|
+
}
|
|
103
|
+
const filesInfo = availableFiles.length > 0
|
|
104
|
+
? `Available files: ${availableFiles.join(", ")}`
|
|
105
|
+
: "Could not list available files";
|
|
106
|
+
throw new Error(`File ${modelFileName} not found in hyperdrive. ${filesInfo}`);
|
|
107
|
+
}
|
|
108
|
+
async function checkFileDownloaded(drive, entry) {
|
|
109
|
+
const blobs = await drive.getBlobs();
|
|
110
|
+
const blob = entry?.value?.blob;
|
|
111
|
+
if (!blob) {
|
|
112
|
+
return {
|
|
113
|
+
blobs,
|
|
114
|
+
blocksDownloaded: 0,
|
|
115
|
+
totalBlocks: 0,
|
|
116
|
+
totalBytes: 0,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// Check how many blocks are already downloaded
|
|
120
|
+
let blocksDownloaded = 0;
|
|
121
|
+
for (let i = blob.blockOffset; i < blob.blockOffset + blob.blockLength; i++) {
|
|
122
|
+
const hasBlock = await blobs.core.has(i);
|
|
123
|
+
if (hasBlock) {
|
|
124
|
+
blocksDownloaded++;
|
|
79
125
|
}
|
|
80
126
|
}
|
|
81
|
-
return {
|
|
127
|
+
return {
|
|
128
|
+
blobs,
|
|
129
|
+
blocksDownloaded,
|
|
130
|
+
totalBlocks: blob.blockLength,
|
|
131
|
+
totalBytes: blob.byteLength,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async function validateFileExistence(drive, file) {
|
|
135
|
+
const { entry, targetPath } = await findFileInHyperdrive(drive, file);
|
|
136
|
+
const { blobs, blocksDownloaded, totalBlocks, totalBytes } = await checkFileDownloaded(drive, entry);
|
|
137
|
+
return {
|
|
138
|
+
entry,
|
|
139
|
+
blobs,
|
|
140
|
+
targetPath,
|
|
141
|
+
blocksDownloaded,
|
|
142
|
+
totalBlocks,
|
|
143
|
+
totalBytes,
|
|
144
|
+
};
|
|
82
145
|
}
|
|
83
146
|
async function validateFileChecksum(filePath, expectedChecksum) {
|
|
84
147
|
console.log(`🔍 Validating SHA256 checksum...`);
|
|
@@ -153,13 +216,15 @@ async function performHyperdriveDownload(modelPath, modelFileName, hyperdriveKey
|
|
|
153
216
|
}
|
|
154
217
|
console.log(`Downloading model from hyperdrive ${hyperdriveKey} to ${modelPath}`);
|
|
155
218
|
const setup = await setupHyperdrive(hyperdriveKey, corestoreDir);
|
|
156
|
-
let downloadedBytes = 0;
|
|
157
|
-
let totalBytes = 0;
|
|
158
219
|
// Set up abort handler
|
|
159
220
|
let readStream;
|
|
160
221
|
let writeStream;
|
|
161
222
|
const cleanup = () => {
|
|
162
223
|
console.log("🛑 Aborting hyperdrive download...");
|
|
224
|
+
setup.swarm.suspended = true;
|
|
225
|
+
setup.swarm.suspend().catch(() => {
|
|
226
|
+
// Ignore errors during emergency suspend
|
|
227
|
+
});
|
|
163
228
|
// Destroy streams if they exist
|
|
164
229
|
if (readStream) {
|
|
165
230
|
readStream.destroy();
|
|
@@ -169,48 +234,19 @@ async function performHyperdriveDownload(modelPath, modelFileName, hyperdriveKey
|
|
|
169
234
|
}
|
|
170
235
|
};
|
|
171
236
|
signal?.addEventListener("abort", cleanup);
|
|
237
|
+
let downloadHandler;
|
|
172
238
|
try {
|
|
173
|
-
const
|
|
174
|
-
const { entry, targetPath } = result;
|
|
175
|
-
totalBytes = entry?.value?.blob?.byteLength || 0;
|
|
176
|
-
console.log(`📏 Model size: ${totalBytes} bytes (${(totalBytes / 1024 / 1024).toFixed(2)} MB)`);
|
|
177
|
-
// Get blobs and file blob range
|
|
178
|
-
const blobs = await setup.drive.getBlobs();
|
|
239
|
+
const { entry, blobs, targetPath, blocksDownloaded, totalBlocks, totalBytes, } = await validateFileExistence(setup.drive, modelFileName);
|
|
179
240
|
const blob = entry?.value?.blob;
|
|
180
241
|
if (!blob) {
|
|
181
242
|
throw new Error(`No blob found for ${modelFileName}`);
|
|
182
243
|
}
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const hasBlock = await blobs.core.has(i);
|
|
187
|
-
if (hasBlock) {
|
|
188
|
-
alreadyDownloaded++;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
downloadedBytes = 0;
|
|
192
|
-
if (alreadyDownloaded > 0) {
|
|
193
|
-
console.log(`📥 Resuming download (${alreadyDownloaded}/${blob.blockLength} blocks already in corestore)`);
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
console.log(`📥 Starting fresh download`);
|
|
197
|
-
}
|
|
244
|
+
// Calculate already downloaded bytes for resuming
|
|
245
|
+
const bytesPerBlock = totalBlocks > 0 ? totalBytes / totalBlocks : 0;
|
|
246
|
+
const initialBytes = Math.floor(blocksDownloaded * bytesPerBlock);
|
|
198
247
|
// Track only downloads for blocks within our file's blob range
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
index < blob.blockOffset + blob.blockLength) {
|
|
202
|
-
downloadedBytes += bytes;
|
|
203
|
-
if (progressCallback) {
|
|
204
|
-
progressCallback({
|
|
205
|
-
type: "modelProgress",
|
|
206
|
-
downloaded: downloadedBytes,
|
|
207
|
-
total: totalBytes,
|
|
208
|
-
percentage: totalBytes > 0 ? (downloadedBytes / totalBytes) * 100 : 0,
|
|
209
|
-
downloadKey,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
});
|
|
248
|
+
downloadHandler = createProgressHandler(blob, progressCallback, downloadKey, initialBytes);
|
|
249
|
+
blobs.core.on("download", downloadHandler);
|
|
214
250
|
// Check if aborted before starting streams
|
|
215
251
|
if (signal?.aborted) {
|
|
216
252
|
throw new Error("Download cancelled");
|
|
@@ -223,15 +259,13 @@ async function performHyperdriveDownload(modelPath, modelFileName, hyperdriveKey
|
|
|
223
259
|
readStream.pipe(writeStream);
|
|
224
260
|
// Wait for download to complete
|
|
225
261
|
await new Promise((resolve, reject) => {
|
|
226
|
-
writeStream.on("finish",
|
|
262
|
+
writeStream.on("finish", resolve);
|
|
227
263
|
writeStream.on("error", reject);
|
|
228
264
|
readStream.on("error", reject);
|
|
229
265
|
// Also reject on abort
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}, { once: true });
|
|
234
|
-
}
|
|
266
|
+
signal?.addEventListener("abort", () => {
|
|
267
|
+
reject(new Error("Download cancelled"));
|
|
268
|
+
}, { once: true });
|
|
235
269
|
});
|
|
236
270
|
console.log(`✅ Model downloaded successfully to ${modelPath}`);
|
|
237
271
|
// Delete corestore directory after successful download (only when not seeding, to save space)
|
|
@@ -249,22 +283,29 @@ async function performHyperdriveDownload(modelPath, modelFileName, hyperdriveKey
|
|
|
249
283
|
}
|
|
250
284
|
finally {
|
|
251
285
|
signal?.removeEventListener("abort", cleanup);
|
|
286
|
+
if (downloadHandler) {
|
|
287
|
+
try {
|
|
288
|
+
const { blobs } = await validateFileExistence(setup.drive, modelFileName);
|
|
289
|
+
blobs.core.off("download", downloadHandler);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
// If we can't get blobs, setup is already closed
|
|
293
|
+
}
|
|
294
|
+
}
|
|
252
295
|
if (!seed) {
|
|
253
296
|
await cleanupHyperdrive(setup);
|
|
254
297
|
}
|
|
255
298
|
// Only delete corestore and partial file if user explicitly requested clearCache
|
|
256
|
-
if (signal?.aborted) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
// no-op
|
|
263
|
-
}
|
|
264
|
-
await deleteCorestoreDirectory(corestoreDir);
|
|
299
|
+
if (signal?.aborted && shouldClearCache(downloadKey)) {
|
|
300
|
+
try {
|
|
301
|
+
await fsPromises.unlink(modelPath);
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// no-op
|
|
265
305
|
}
|
|
266
|
-
|
|
306
|
+
await deleteCorestoreDirectory(corestoreDir);
|
|
267
307
|
}
|
|
308
|
+
clearClearCacheFlag(downloadKey);
|
|
268
309
|
}
|
|
269
310
|
}
|
|
270
311
|
export async function downloadModelFromHyperdrive(hyperdriveKey, modelFileName, seed, progressCallback, expectedChecksum) {
|
|
@@ -1,46 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { models } from "../../../../models/hyperdrive/models.js";
|
|
2
2
|
import { hyperdriveUrlSchema } from "../../../../schemas/index.js";
|
|
3
3
|
import { getModelsCacheDir } from "../../../utils/index.js";
|
|
4
4
|
import { promises as fsPromises } from "bare-fs";
|
|
5
5
|
import path from "bare-path";
|
|
6
6
|
import { downloadModelFromHttp } from "./http.js";
|
|
7
7
|
import { downloadModelFromHyperdrive } from "./hyperdrive.js";
|
|
8
|
-
/**
|
|
9
|
-
* Attempts to resolve a model from cache (without validation)
|
|
10
|
-
* Validation will be handled by the hyperdrive download logic
|
|
11
|
-
*/
|
|
12
|
-
async function tryResolveCachedModel(modelId) {
|
|
13
|
-
const cacheDir = getModelsCacheDir();
|
|
14
|
-
const cachedPath = path.join(cacheDir, modelId);
|
|
15
|
-
try {
|
|
16
|
-
await fsPromises.access(cachedPath);
|
|
17
|
-
// File exists - return null to let hyperdrive validation handle size/checksum
|
|
18
|
-
// This ensures partial downloads are properly resumed instead of being
|
|
19
|
-
// incorrectly validated and deleted
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
// File doesn't exist
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Resolves a known model by ID from hyperdrive, checking cache first
|
|
29
|
-
*/
|
|
30
|
-
async function resolveKnownModel(model, modelIdOrPath, progressCallback, seed) {
|
|
31
|
-
if (!model) {
|
|
32
|
-
throw new Error("Model is null");
|
|
33
|
-
}
|
|
34
|
-
console.log(`Loading model ID '${modelIdOrPath}' from hyperdrive`);
|
|
35
|
-
// Try to resolve from cache first
|
|
36
|
-
const cachedPath = await tryResolveCachedModel(model.modelId);
|
|
37
|
-
if (cachedPath) {
|
|
38
|
-
return cachedPath;
|
|
39
|
-
}
|
|
40
|
-
// Not cached or invalid, download from hyperdrive
|
|
41
|
-
const downloadedPath = await downloadModelFromHyperdrive(model.hyperdriveKey, model.modelId, seed, progressCallback, model.sha256Checksum);
|
|
42
|
-
return downloadedPath;
|
|
43
|
-
}
|
|
44
8
|
/**
|
|
45
9
|
* Resolves a local file path or cached file
|
|
46
10
|
*/
|
|
@@ -84,10 +48,7 @@ export async function resolveModelPath(modelSrc, progressCallback, seed) {
|
|
|
84
48
|
let actualPath;
|
|
85
49
|
// Validate seeding is only used with hyperdrive models
|
|
86
50
|
if (seed && !hyperdriveKey) {
|
|
87
|
-
|
|
88
|
-
if (!model) {
|
|
89
|
-
throw new Error("Seeding is only supported for hyperdrive models");
|
|
90
|
-
}
|
|
51
|
+
throw new Error("Seeding is only supported for hyperdrive models");
|
|
91
52
|
}
|
|
92
53
|
// Check if it's an HTTP/HTTPS URL
|
|
93
54
|
if (actualModelSrc.startsWith("http://") ||
|
|
@@ -101,21 +62,13 @@ export async function resolveModelPath(modelSrc, progressCallback, seed) {
|
|
|
101
62
|
console.log(`Loading from hyperdrive: ${hyperdriveKey}`);
|
|
102
63
|
actualPath = await downloadModelFromHyperdrive(hyperdriveKey, actualModelSrc, seed, progressCallback);
|
|
103
64
|
}
|
|
65
|
+
else if (actualModelSrc.includes("/") || actualModelSrc.includes("\\")) {
|
|
66
|
+
// Handle file paths (absolute or relative with slashes)
|
|
67
|
+
actualPath = actualModelSrc;
|
|
68
|
+
}
|
|
104
69
|
else {
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
if (model) {
|
|
108
|
-
actualPath = await resolveKnownModel(model, actualModelSrc, progressCallback, seed);
|
|
109
|
-
}
|
|
110
|
-
else if (actualModelSrc.includes("/") || actualModelSrc.includes("\\")) {
|
|
111
|
-
// Handle file paths (absolute or relative with slashes)
|
|
112
|
-
console.log(`Loading from file: ${actualModelSrc}`);
|
|
113
|
-
actualPath = actualModelSrc;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
// Handle local files and cached files
|
|
117
|
-
actualPath = await resolveLocalOrCachedFile(actualModelSrc);
|
|
118
|
-
}
|
|
70
|
+
// Handle local files and cached files
|
|
71
|
+
actualPath = await resolveLocalOrCachedFile(actualModelSrc);
|
|
119
72
|
}
|
|
120
73
|
return actualPath;
|
|
121
74
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qvac/sdk",
|
|
3
|
-
"version": "0.2.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"bare:ensureprebuilds:whispercpp": "cp -r node_modules/@qvac/transcription-whispercpp/prebuilds/android-arm64 node_modules/@qvac/transcription-whispercpp/prebuilds/android-ia32 && cp -r node_modules/@qvac/transcription-whispercpp/prebuilds/android-arm64 node_modules/@qvac/transcription-whispercpp/prebuilds/android-arm && cp -r node_modules/@qvac/transcription-whispercpp/prebuilds/android-arm64 node_modules/@qvac/transcription-whispercpp/prebuilds/android-x64",
|
|
46
46
|
"bare:ensureprebuilds:embeddings": "cp -r node_modules/@qvac/embed-llamacpp/prebuilds/android-arm64 node_modules/@qvac/embed-llamacpp/prebuilds/android-ia32 && cp -r node_modules/@qvac/embed-llamacpp/prebuilds/android-arm64 node_modules/@qvac/embed-llamacpp/prebuilds/android-arm && cp -r node_modules/@qvac/embed-llamacpp/prebuilds/android-arm64 node_modules/@qvac/embed-llamacpp/prebuilds/android-x64",
|
|
47
47
|
"bare:ensureprebuilds": "bun run bare:ensureprebuilds:llamacpp && bun run bare:ensureprebuilds:whispercpp && bun run bare:ensureprebuilds:embeddings",
|
|
48
|
-
"prepare": "bun run husky",
|
|
48
|
+
"prepare:husky": "bun run husky",
|
|
49
49
|
"bare:example": "./scripts/run-with-bare.sh",
|
|
50
50
|
"docs_api:website": "typedoc --out ./docs/api/website --entryPoints index.ts --entryPointStrategy expand --readme none",
|
|
51
51
|
"docs_api:markdown": "typedoc --plugin typedoc-plugin-markdown --out ./docs/api/markdown --entryPoints index.ts --entryPointStrategy expand --readme none && sed -i '1,4d' ./docs/api/markdown/README.md",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
"update-models": "node ./scripts/update-models.js"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@qvac/embed-llamacpp": "^0.1
|
|
57
|
-
"@qvac/llm-llamacpp": "^0.
|
|
56
|
+
"@qvac/embed-llamacpp": "^0.3.1",
|
|
57
|
+
"@qvac/llm-llamacpp": "^0.3.2",
|
|
58
58
|
"@qvac/decoder-audio": "^0.1.0",
|
|
59
59
|
"@qvac/error": "^0.1.0",
|
|
60
60
|
"@qvac/langdetect-text": "^0.1.0",
|
|
61
61
|
"@qvac/logging": "^0.1.0",
|
|
62
|
-
"@qvac/rag": "^0.1
|
|
62
|
+
"@qvac/rag": "^0.2.1",
|
|
63
63
|
"@qvac/transcription-whispercpp": "^0.1.4",
|
|
64
64
|
"@qvac/translation-nmtcpp": "^0.1.0",
|
|
65
65
|
"fast-safe-stringify": "2.1.1",
|
|
@@ -126,4 +126,4 @@
|
|
|
126
126
|
"patchedDependencies": {
|
|
127
127
|
"bare-rpc@0.2.11": "patches/bare-rpc@0.2.11.patch"
|
|
128
128
|
}
|
|
129
|
-
}
|
|
129
|
+
}
|