@qvac/sdk 0.13.5 → 0.14.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/NOTICE +95 -1151
- package/README.md +1 -2
- package/bare-imports.json +0 -5
- package/dist/client/api/bci-transcribe.js +2 -1
- package/dist/client/api/download-asset.js +2 -1
- package/dist/client/api/finetune.js +6 -5
- package/dist/client/api/index.d.ts +1 -0
- package/dist/client/api/index.js +1 -0
- package/dist/client/api/load-model.d.ts +11 -8
- package/dist/client/api/load-model.js +6 -6
- package/dist/client/api/subscribe-logs.d.ts +28 -0
- package/dist/client/api/subscribe-logs.js +43 -0
- package/dist/client/api/text-to-speech.js +2 -1
- package/dist/client/config-loader/config-utils.js +2 -4
- package/dist/client/config-loader/resolve-config.bare.js +4 -3
- package/dist/client/parse-input.d.ts +3 -0
- package/dist/client/parse-input.js +14 -0
- package/dist/client/rpc/expo-rpc-client.js +2 -11
- package/dist/client/rpc/node-rpc-client.js +8 -2
- package/dist/client/rpc/rpc-client.js +39 -7
- package/dist/commands/bundle/constants.js +2 -1
- package/dist/commands/bundle/entry-gen.d.ts +1 -1
- package/dist/commands/bundle/entry-gen.js +6 -6
- package/dist/commands/bundle/index.js +3 -1
- package/dist/commands/bundle/resolve-sdk-import.d.ts +6 -0
- package/dist/commands/bundle/resolve-sdk-import.js +60 -0
- package/dist/examples/bci/bci-filesystem-streaming.js +14 -14
- package/dist/examples/bci/bci-filesystem.js +17 -13
- package/dist/examples/cache-management.js +38 -38
- package/dist/examples/cancel-by-request-id.js +9 -9
- package/dist/examples/completion-events.js +20 -14
- package/dist/examples/completion-stop-reason.js +13 -7
- package/dist/examples/concurrent-completion-collision.js +7 -7
- package/dist/examples/config-reload.js +7 -8
- package/dist/examples/default-config-usage.js +4 -4
- package/dist/examples/delegated-inference/composite.js +14 -10
- package/dist/examples/delegated-inference/consumer-profiled.js +13 -13
- package/dist/examples/delegated-inference/consumer.js +16 -12
- package/dist/examples/delegated-inference/provider.js +12 -12
- package/dist/examples/diffusion-esrgan-upscale.js +19 -15
- package/dist/examples/diffusion-flux2-klein-img2img.js +16 -11
- package/dist/examples/diffusion-flux2-klein.js +14 -9
- package/dist/examples/diffusion-img2img.js +9 -10
- package/dist/examples/diffusion-img2vid.js +17 -12
- package/dist/examples/diffusion-simple.js +1 -1
- package/dist/examples/diffusion-txt2img.js +14 -9
- package/dist/examples/diffusion-txt2vid.js +15 -10
- package/dist/examples/download-with-blind-relays.js +16 -21
- package/dist/examples/download-with-cancel.js +15 -16
- package/dist/examples/embed-multi-gpu.js +3 -4
- package/dist/examples/embed-p2p.js +11 -7
- package/dist/examples/finetune/llamacpp-finetune.js +7 -7
- package/dist/examples/kv-cache-cleanup.js +35 -35
- package/dist/examples/kv-cache-custom-key.js +24 -24
- package/dist/examples/kv-cache-example.js +9 -9
- package/dist/examples/llamacpp-cache.js +18 -14
- package/dist/examples/llamacpp-dynamic-tools.js +15 -9
- package/dist/examples/llamacpp-filesystem.js +15 -9
- package/dist/examples/llamacpp-http.js +12 -10
- package/dist/examples/llamacpp-multi-gpu.js +4 -4
- package/dist/examples/llamacpp-multimodal.js +13 -9
- package/dist/examples/llamacpp-p2p.js +8 -4
- package/dist/examples/llamacpp-sharded.js +5 -5
- package/dist/examples/llamacpp-structured-output.js +15 -9
- package/dist/examples/logging-file-transport.js +3 -3
- package/dist/examples/logging-global.d.ts +2 -0
- package/dist/examples/logging-global.js +34 -0
- package/dist/examples/logging-streaming.js +7 -10
- package/dist/examples/mcp-websearch.js +24 -18
- package/dist/examples/multi-model-demo.js +17 -11
- package/dist/examples/ocr-fasttext.js +14 -16
- package/dist/examples/parallel-download.js +7 -7
- package/dist/examples/plugins.js +40 -28
- package/dist/examples/profiling/basic.js +16 -10
- package/dist/examples/profiling/per-call.js +17 -11
- package/dist/examples/quickstart.bare.d.ts +2 -0
- package/dist/examples/quickstart.bare.js +18 -0
- package/dist/examples/quickstart.js +10 -3
- package/dist/examples/rag/rag-chromadb.js +18 -14
- package/dist/examples/rag/rag-hyperdb/cancellation.js +17 -14
- package/dist/examples/rag/rag-hyperdb/ingest.js +14 -12
- package/dist/examples/rag/rag-hyperdb/pipeline.js +19 -17
- package/dist/examples/rag/rag-hyperdb/workspaces.js +31 -27
- package/dist/examples/rag/rag-lancedb.js +12 -8
- package/dist/examples/rag/rag-sqlite.js +11 -7
- package/dist/examples/registry-query.js +17 -17
- package/dist/examples/seed-p2p.js +10 -6
- package/dist/examples/suspend-resume.js +20 -16
- package/dist/examples/tools/llamacpp-native-tools.js +24 -18
- package/dist/examples/tools/llamacpp-tools-gemma4.js +14 -8
- package/dist/examples/tools/llamacpp-tools-harmony-multiturn.js +20 -14
- package/dist/examples/tools/llamacpp-tools-pythonic.js +14 -8
- package/dist/examples/tools/llamacpp-tools-qwen35.js +14 -8
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +12 -9
- package/dist/examples/transcription/parakeet-microphone-record.js +15 -9
- package/dist/examples/transcription/parakeet-microphone-stream.js +15 -9
- package/dist/examples/transcription/parakeet-sortformer-streaming.js +12 -6
- package/dist/examples/transcription/parakeet-sortformer.js +3 -5
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +13 -10
- package/dist/examples/transcription/whispercpp-filesystem-streaming.js +16 -17
- package/dist/examples/transcription/whispercpp-filesystem.js +14 -10
- package/dist/examples/transcription/whispercpp-microphone-conversation.js +10 -10
- package/dist/examples/transcription/whispercpp-microphone-record.js +6 -6
- package/dist/examples/transcription/whispercpp-prompt.js +14 -10
- package/dist/examples/translation/translation-bergamot-batch.js +11 -7
- package/dist/examples/translation/translation-bergamot-pivot.js +13 -9
- package/dist/examples/translation/translation-bergamot.js +8 -4
- package/dist/examples/translation/translation-indic.js +8 -4
- package/dist/examples/translation/translation-llm-afriquegemma.js +7 -3
- package/dist/examples/translation/translation-llm-context.js +8 -4
- package/dist/examples/translation/translation-llm.js +7 -3
- package/dist/examples/translation/translation-stream.js +4 -4
- package/dist/examples/tts/chatterbox.js +19 -11
- package/dist/examples/tts/llm-to-tts-streaming.js +27 -14
- package/dist/examples/tts/supertonic-multilingual.js +18 -14
- package/dist/examples/tts/supertonic.js +19 -15
- package/dist/examples/tts/utils.js +1 -1
- package/dist/examples/vla-pi05.js +18 -14
- package/dist/examples/vla-smolvla.js +18 -14
- package/dist/examples/voice-assistant/voice-assistant.js +12 -12
- package/dist/index.d.ts +3 -4
- package/dist/index.js +3 -4
- package/dist/logging/client-logger.js +2 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/logging/namespaces.d.ts +1 -0
- package/dist/logging/namespaces.js +2 -0
- package/dist/logging/server-logger.js +1 -4
- package/dist/logging/utils.js +6 -1
- package/dist/models/registry/index.d.ts +17 -0
- package/dist/models/registry/index.js +20 -1
- package/dist/models/registry/models.d.ts +1062 -38
- package/dist/models/registry/models.js +3546 -2490
- package/dist/pear/pre.js +2 -2
- package/dist/schemas/bci-config.d.ts +37 -0
- package/dist/schemas/bci-config.js +2 -0
- package/dist/schemas/bci.d.ts +2 -0
- package/dist/schemas/common.d.ts +171 -94
- package/dist/schemas/completion-stream.d.ts +6 -3
- package/dist/schemas/completion-stream.js +10 -2
- package/dist/schemas/download-asset.d.ts +5 -5
- package/dist/schemas/engine-addon-map.d.ts +1 -1
- package/dist/schemas/engine-addon-map.js +6 -3
- package/dist/schemas/error.js +6 -1
- package/dist/schemas/llamacpp-config.d.ts +27 -8
- package/dist/schemas/llamacpp-config.js +19 -2
- package/dist/schemas/load-model.d.ts +4170 -570
- package/dist/schemas/load-model.js +85 -26
- package/dist/schemas/logging-stream.js +7 -1
- package/dist/schemas/model-src-utils.d.ts +6 -6
- package/dist/schemas/model-types.d.ts +14 -15
- package/dist/schemas/model-types.js +10 -11
- package/dist/schemas/ocr.d.ts +10 -8
- package/dist/schemas/ocr.js +8 -6
- package/dist/schemas/plugin.d.ts +6 -5
- package/dist/schemas/plugin.js +4 -4
- package/dist/schemas/rag.d.ts +4 -4
- package/dist/schemas/registry.d.ts +8 -8
- package/dist/schemas/registry.js +1 -1
- package/dist/schemas/reload-config.d.ts +6 -6
- package/dist/schemas/sdcpp-config.d.ts +12 -12
- package/dist/schemas/sdk-config.d.ts +171 -117
- package/dist/schemas/sdk-config.js +5 -5
- package/dist/schemas/sdk-errors-client.d.ts +1 -0
- package/dist/schemas/sdk-errors-client.js +7 -2
- package/dist/schemas/text-to-speech.d.ts +157 -13
- package/dist/schemas/text-to-speech.js +70 -7
- package/dist/schemas/transcription-config.d.ts +5 -1
- package/dist/schemas/transcription-config.js +2 -0
- package/dist/schemas/transcription.d.ts +3 -0
- package/dist/schemas/transcription.js +2 -1
- package/dist/schemas/translate.d.ts +6 -6
- package/dist/schemas/translate.js +2 -3
- package/dist/schemas/translation-config.d.ts +20 -20
- package/dist/server/bare/hyperswarm.js +3 -3
- package/dist/server/bare/ops/transcribe.js +46 -15
- package/dist/server/bare/plugins/bci-whispercpp-transcription/args.d.ts +3 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/args.js +13 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.d.ts +41 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.js +6 -11
- package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.d.ts +75 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.js +11 -0
- package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.d.ts +16 -10
- package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.js +25 -18
- package/dist/server/bare/plugins/index.d.ts +1 -1
- package/dist/server/bare/plugins/index.js +1 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.d.ts +10 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.js +29 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +4 -22
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +15 -7
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +7 -7
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +2 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +10 -10
- package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +14 -8
- package/dist/server/bare/plugins/tts-ggml/plugin.js +12 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +3 -1
- package/dist/server/bare/registry/logging-stream-registry.d.ts +4 -2
- package/dist/server/bare/registry/logging-stream-registry.js +12 -7
- package/dist/server/bare/registry/model-config-utils.js +2 -2
- package/dist/server/bare/registry/registry-client.js +1 -1
- package/dist/server/bare/runtime-lifecycle.d.ts +9 -0
- package/dist/server/bare/runtime-lifecycle.js +24 -0
- package/dist/server/bare/types/addon-responses.d.ts +1 -0
- package/dist/server/env.js +7 -10
- package/dist/server/plugins/registry.js +2 -4
- package/dist/server/rpc/handlers/load-model/handler.js +2 -4
- package/dist/server/rpc/handlers/load-model/http.js +253 -51
- package/dist/server/rpc/handlers/logging-stream.js +4 -2
- package/dist/server/rpc/handlers/plugin-invoke.js +5 -16
- package/dist/server/utils/completion-normalizer.js +13 -4
- package/dist/server/utils/worker-lock.js +5 -5
- package/dist/server/worker-core.d.ts +1 -1
- package/dist/server/worker-core.js +28 -18
- package/dist/utils/errors-client.d.ts +3 -0
- package/dist/utils/errors-client.js +5 -0
- package/dist/utils/errors-server.d.ts +2 -0
- package/dist/utils/errors-server.js +3 -0
- package/dist/utils/zod-error.d.ts +3 -0
- package/dist/utils/zod-error.js +4 -0
- package/package.json +21 -24
- package/dist/polyfills/bare-globals.d.ts +0 -2
- package/dist/polyfills/bare-globals.js +0 -4
- package/dist/polyfills/bare-globals.noop.d.ts +0 -2
- package/dist/polyfills/bare-globals.noop.js +0 -1
- /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.d.ts +0 -0
- /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.js +0 -0
|
@@ -45,11 +45,11 @@ function parseSearchResults(mcpResult) {
|
|
|
45
45
|
}
|
|
46
46
|
let mcpClient = null;
|
|
47
47
|
try {
|
|
48
|
-
console.log("
|
|
48
|
+
console.log("▸ MCP DuckDuckGo Search Example\n");
|
|
49
49
|
// ============================================================
|
|
50
50
|
// STEP 1: Connect to DuckDuckGo MCP server
|
|
51
51
|
// ============================================================
|
|
52
|
-
console.log("
|
|
52
|
+
console.log("▸ Starting DuckDuckGo MCP server...");
|
|
53
53
|
mcpClient = new Client({
|
|
54
54
|
name: "qvac-ddg-example",
|
|
55
55
|
version: "1.0.0",
|
|
@@ -59,20 +59,26 @@ try {
|
|
|
59
59
|
args: ["-y", "@oevortex/ddg_search"],
|
|
60
60
|
});
|
|
61
61
|
await mcpClient.connect(transport);
|
|
62
|
-
console.log("
|
|
62
|
+
console.log("▸ MCP server connected\n");
|
|
63
63
|
// ============================================================
|
|
64
64
|
// STEP 2: Load model
|
|
65
65
|
// ============================================================
|
|
66
|
-
console.log("
|
|
66
|
+
console.log("▸ Loading model...");
|
|
67
67
|
const modelId = await loadModel({
|
|
68
68
|
modelSrc: QWEN3_1_7B_INST_Q4,
|
|
69
69
|
modelConfig: {
|
|
70
70
|
ctx_size: 4096,
|
|
71
71
|
tools: true,
|
|
72
72
|
},
|
|
73
|
-
onProgress: (
|
|
73
|
+
onProgress: (p) => {
|
|
74
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
75
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
76
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
77
|
+
if (p.percentage >= 100)
|
|
78
|
+
process.stderr.write("\n");
|
|
79
|
+
},
|
|
74
80
|
});
|
|
75
|
-
console.log(`\n
|
|
81
|
+
console.log(`\n▸ Model loaded\n`);
|
|
76
82
|
// ============================================================
|
|
77
83
|
// STEP 3: Ask AI to search the web (with MCP client)
|
|
78
84
|
// ============================================================
|
|
@@ -88,8 +94,8 @@ Always cite your sources with the URL.`,
|
|
|
88
94
|
content: "What is the current weather in New York City?",
|
|
89
95
|
},
|
|
90
96
|
];
|
|
91
|
-
console.log("
|
|
92
|
-
console.log("
|
|
97
|
+
console.log("▸ Asking AI to search the web...\n");
|
|
98
|
+
console.log("▸ AI Response:");
|
|
93
99
|
// Pass MCP client directly to completion - tools are adapted internally!
|
|
94
100
|
const result = completion({
|
|
95
101
|
modelId,
|
|
@@ -106,19 +112,19 @@ Always cite your sources with the URL.`,
|
|
|
106
112
|
// STEP 4: Execute tool calls using call() - automatic MCP routing!
|
|
107
113
|
// ============================================================
|
|
108
114
|
if (toolCalls.length > 0) {
|
|
109
|
-
console.log("
|
|
115
|
+
console.log("▸ Executing search...\n");
|
|
110
116
|
const toolResults = [];
|
|
111
117
|
for (const toolCall of toolCalls) {
|
|
112
|
-
console.log(
|
|
118
|
+
console.log(`▸ ${toolCall.name}(${JSON.stringify(toolCall.arguments)})`);
|
|
113
119
|
if (!toolCall.invoke) {
|
|
114
|
-
console.log(
|
|
120
|
+
console.log(`▸ No handler found for tool "${toolCall.name}"`);
|
|
115
121
|
continue;
|
|
116
122
|
}
|
|
117
123
|
// Use invoke() - automatically routes to the correct MCP client!
|
|
118
124
|
const mcpResult = await toolCall.invoke();
|
|
119
125
|
// Parse and clean up the search results
|
|
120
126
|
const cleanResult = parseSearchResults(mcpResult);
|
|
121
|
-
console.log(
|
|
127
|
+
console.log(`▸ Got search results:`);
|
|
122
128
|
console.log(cleanResult
|
|
123
129
|
.split("\n")
|
|
124
130
|
.map((l) => ` ${l}`)
|
|
@@ -129,7 +135,7 @@ Always cite your sources with the URL.`,
|
|
|
129
135
|
// ============================================================
|
|
130
136
|
// STEP 5: Continue with search results
|
|
131
137
|
// ============================================================
|
|
132
|
-
console.log("
|
|
138
|
+
console.log("▸ Getting AI response with search results...\n");
|
|
133
139
|
history.push({
|
|
134
140
|
role: "assistant",
|
|
135
141
|
content: await result.text,
|
|
@@ -140,7 +146,7 @@ Always cite your sources with the URL.`,
|
|
|
140
146
|
content: tr.result,
|
|
141
147
|
});
|
|
142
148
|
}
|
|
143
|
-
console.log("
|
|
149
|
+
console.log("▸ Final Response:");
|
|
144
150
|
const finalResult = completion({
|
|
145
151
|
modelId,
|
|
146
152
|
history,
|
|
@@ -155,14 +161,14 @@ Always cite your sources with the URL.`,
|
|
|
155
161
|
// ============================================================
|
|
156
162
|
// Cleanup
|
|
157
163
|
// ============================================================
|
|
158
|
-
console.log("
|
|
164
|
+
console.log("▸ Cleaning up...");
|
|
159
165
|
await unloadModel({ modelId, clearStorage: false });
|
|
160
|
-
console.log("
|
|
161
|
-
console.log("
|
|
166
|
+
console.log("▸ Done\n");
|
|
167
|
+
console.log("▸ Example completed!");
|
|
162
168
|
process.exit(0);
|
|
163
169
|
}
|
|
164
170
|
catch (error) {
|
|
165
|
-
console.error("
|
|
171
|
+
console.error("✖", error);
|
|
166
172
|
process.exit(1);
|
|
167
173
|
}
|
|
168
174
|
finally {
|
|
@@ -11,7 +11,13 @@ try {
|
|
|
11
11
|
modelConfig: {
|
|
12
12
|
ctx_size: 4096,
|
|
13
13
|
},
|
|
14
|
-
onProgress: (
|
|
14
|
+
onProgress: (p) => {
|
|
15
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
16
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
17
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
18
|
+
if (p.percentage >= 100)
|
|
19
|
+
process.stderr.write("\n");
|
|
20
|
+
},
|
|
15
21
|
});
|
|
16
22
|
const aliceHistory = [
|
|
17
23
|
{
|
|
@@ -26,7 +32,7 @@ try {
|
|
|
26
32
|
content: "You ask questions about Bitcoin in one sentence.",
|
|
27
33
|
},
|
|
28
34
|
];
|
|
29
|
-
console.log("
|
|
35
|
+
console.log("Bob: ", "What is Bitcoin?");
|
|
30
36
|
const aliceResponse = completion({
|
|
31
37
|
modelId: alice,
|
|
32
38
|
history: [...aliceHistory],
|
|
@@ -34,8 +40,8 @@ try {
|
|
|
34
40
|
});
|
|
35
41
|
const aliceText = await aliceResponse.text;
|
|
36
42
|
aliceHistory.push({ role: "assistant", content: aliceText });
|
|
37
|
-
console.log("
|
|
38
|
-
console.log("
|
|
43
|
+
console.log("Alice: ", aliceText);
|
|
44
|
+
console.log("▸ Alice Stats: ", await aliceResponse.stats);
|
|
39
45
|
const bobResponse = completion({
|
|
40
46
|
modelId: bob,
|
|
41
47
|
history: [...bobHistory, { role: "user", content: aliceText }],
|
|
@@ -43,8 +49,8 @@ try {
|
|
|
43
49
|
});
|
|
44
50
|
const bobText = await bobResponse.text;
|
|
45
51
|
bobHistory.push({ role: "assistant", content: bobText });
|
|
46
|
-
console.log("
|
|
47
|
-
console.log("
|
|
52
|
+
console.log("Bob: ", bobText);
|
|
53
|
+
console.log("▸ Bob Stats: ", await bobResponse.stats);
|
|
48
54
|
const aliceResponse2 = completion({
|
|
49
55
|
modelId: alice,
|
|
50
56
|
history: [...aliceHistory, { role: "user", content: bobText }],
|
|
@@ -52,8 +58,8 @@ try {
|
|
|
52
58
|
});
|
|
53
59
|
const aliceText2 = await aliceResponse2.text;
|
|
54
60
|
aliceHistory.push({ role: "assistant", content: aliceText2 });
|
|
55
|
-
console.log("
|
|
56
|
-
console.log("
|
|
61
|
+
console.log("Alice: ", aliceText2);
|
|
62
|
+
console.log("▸ Alice Stats: ", await aliceResponse2.stats);
|
|
57
63
|
const bobResponse2 = completion({
|
|
58
64
|
modelId: bob,
|
|
59
65
|
history: [...bobHistory, { role: "user", content: aliceText2 }],
|
|
@@ -61,12 +67,12 @@ try {
|
|
|
61
67
|
});
|
|
62
68
|
const bobText2 = await bobResponse2.text;
|
|
63
69
|
bobHistory.push({ role: "assistant", content: bobText2 });
|
|
64
|
-
console.log("
|
|
65
|
-
console.log("
|
|
70
|
+
console.log("Bob: ", bobText2);
|
|
71
|
+
console.log("▸ Bob Stats: ", await bobResponse2.stats);
|
|
66
72
|
await unloadModel({ modelId: alice, clearStorage: false });
|
|
67
73
|
await unloadModel({ modelId: bob, clearStorage: false });
|
|
68
74
|
}
|
|
69
75
|
catch (error) {
|
|
70
|
-
console.error("
|
|
76
|
+
console.error("✖", error);
|
|
71
77
|
process.exit(1);
|
|
72
78
|
}
|
|
@@ -9,19 +9,17 @@
|
|
|
9
9
|
* Pass a custom image path, or download the default image into examples/image/:
|
|
10
10
|
* https://github.com/tetherto/qvac/blob/main/packages/sdk/examples/image/basic_test.bmp
|
|
11
11
|
*/
|
|
12
|
-
import { close, loadModel, ocr,
|
|
12
|
+
import { close, loadModel, ocr, OCR_LATIN, unloadModel, } from "@qvac/sdk";
|
|
13
13
|
import path from "path";
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
16
16
|
const imagePath = process.argv[2] || path.join(__dirname, "image/basic_test.bmp");
|
|
17
17
|
try {
|
|
18
|
-
console.log("
|
|
18
|
+
console.log("▸ Loading OCR model...");
|
|
19
19
|
const modelId = await loadModel({
|
|
20
|
-
modelSrc:
|
|
20
|
+
modelSrc: OCR_LATIN,
|
|
21
21
|
modelConfig: {
|
|
22
22
|
langList: ["en"],
|
|
23
|
-
useGPU: true,
|
|
24
|
-
timeout: 30000,
|
|
25
23
|
magRatio: 1.5,
|
|
26
24
|
defaultRotationAngles: [90, 180, 270],
|
|
27
25
|
contrastRetry: false,
|
|
@@ -29,8 +27,8 @@ try {
|
|
|
29
27
|
recognizerBatchSize: 1,
|
|
30
28
|
},
|
|
31
29
|
});
|
|
32
|
-
console.log(
|
|
33
|
-
console.log(`\n
|
|
30
|
+
console.log(`▸ Model loaded successfully! Model ID: ${modelId}`);
|
|
31
|
+
console.log(`\n▸ Running OCR on: ${imagePath}`);
|
|
34
32
|
const { blocks } = ocr({
|
|
35
33
|
modelId,
|
|
36
34
|
image: imagePath,
|
|
@@ -39,24 +37,24 @@ try {
|
|
|
39
37
|
},
|
|
40
38
|
});
|
|
41
39
|
const result = await blocks;
|
|
42
|
-
console.log("\n
|
|
43
|
-
console.log("================================");
|
|
40
|
+
console.log("\n▸ OCR Results:");
|
|
41
|
+
console.log("▸ ================================");
|
|
44
42
|
for (const block of result) {
|
|
45
|
-
console.log(
|
|
43
|
+
console.log(block.text);
|
|
46
44
|
if (block.bbox) {
|
|
47
|
-
console.log(
|
|
45
|
+
console.log(`▸ BBox: [${block.bbox.join(", ")}]`);
|
|
48
46
|
}
|
|
49
47
|
if (block.confidence !== undefined) {
|
|
50
|
-
console.log(
|
|
48
|
+
console.log(`▸ Confidence: ${block.confidence}`);
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
|
-
console.log("\n================================");
|
|
54
|
-
console.log("\n
|
|
51
|
+
console.log("\n▸ ================================");
|
|
52
|
+
console.log("\n▸ Unloading model...");
|
|
55
53
|
await unloadModel({ modelId, clearStorage: false });
|
|
56
|
-
console.log("
|
|
54
|
+
console.log("▸ Model unloaded successfully.");
|
|
57
55
|
process.exit(0);
|
|
58
56
|
}
|
|
59
57
|
catch (error) {
|
|
60
|
-
console.error("
|
|
58
|
+
console.error("✖", error);
|
|
61
59
|
await close();
|
|
62
60
|
}
|
|
@@ -9,7 +9,7 @@ const assets = [
|
|
|
9
9
|
{ name: "GTE Large FP16", src: GTE_LARGE_FP16 },
|
|
10
10
|
];
|
|
11
11
|
const timers = {};
|
|
12
|
-
console.log(`\n
|
|
12
|
+
console.log(`\n▸ Parallel Download (${assets.length} assets)\n`);
|
|
13
13
|
const wallStart = now();
|
|
14
14
|
try {
|
|
15
15
|
const promises = assets.map((asset) => {
|
|
@@ -20,18 +20,18 @@ try {
|
|
|
20
20
|
const t = timers[asset.name];
|
|
21
21
|
if (t.firstProgress == null) {
|
|
22
22
|
t.firstProgress = now();
|
|
23
|
-
console.log(
|
|
23
|
+
console.log(`▸ [${asset.name}] first progress at ${((t.firstProgress - wallStart) / 1000).toFixed(1)}s — ${progress.percentage}%`);
|
|
24
24
|
}
|
|
25
25
|
if (progress.percentage === 100 && t.end == null) {
|
|
26
26
|
t.end = now();
|
|
27
|
-
console.log(
|
|
27
|
+
console.log(`▸ [${asset.name}] done at ${((t.end - wallStart) / 1000).toFixed(1)}s`);
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
32
|
const results = await Promise.allSettled(promises);
|
|
33
33
|
const wallEnd = now();
|
|
34
|
-
console.log(`\n
|
|
34
|
+
console.log(`\n▸ Results\n`);
|
|
35
35
|
for (let i = 0; i < assets.length; i++) {
|
|
36
36
|
const asset = assets[i];
|
|
37
37
|
const result = results[i];
|
|
@@ -42,12 +42,12 @@ try {
|
|
|
42
42
|
? `${((t.firstProgress - t.start) / 1000).toFixed(1)}s`
|
|
43
43
|
: "N/A";
|
|
44
44
|
const total = t.end != null ? `${((t.end - t.start) / 1000).toFixed(1)}s` : "N/A";
|
|
45
|
-
console.log(
|
|
45
|
+
console.log(`▸ ${status} ${asset.name}: first-progress=${timeToFirst}, total=${total}${reason}`);
|
|
46
46
|
}
|
|
47
|
-
console.log(`\
|
|
47
|
+
console.log(`\n▸ Wall time: ${((wallEnd - wallStart) / 1000).toFixed(1)}s`);
|
|
48
48
|
void close();
|
|
49
49
|
}
|
|
50
50
|
catch (error) {
|
|
51
|
-
console.error("
|
|
51
|
+
console.error("✖", error);
|
|
52
52
|
process.exit(1);
|
|
53
53
|
}
|
package/dist/examples/plugins.js
CHANGED
|
@@ -18,16 +18,16 @@ const configPath = `${configDir}/config/plugins/plugins.config.json`;
|
|
|
18
18
|
const projectRoot = path.resolve(configDir, "..");
|
|
19
19
|
const qvacOutputDir = path.join(projectRoot, "qvac");
|
|
20
20
|
// ─── Generate the worker bundle from the plugins config ─────────────────────
|
|
21
|
-
console.log(
|
|
22
|
-
console.log(
|
|
23
|
-
console.log("
|
|
24
|
-
console.log("
|
|
21
|
+
console.log(`▸ Config: ${configPath}`);
|
|
22
|
+
console.log(`▸ This example will generate a worker bundle in ${qvacOutputDir} and delete it on exit.`);
|
|
23
|
+
console.log("▸ If you have an existing qvac/ folder with bundled files, they will be overwritten and removed.\n");
|
|
24
|
+
console.log("▸ Generating worker bundle from plugins config...\n");
|
|
25
25
|
try {
|
|
26
26
|
await bundleSdk({ projectRoot, configPath, quiet: true });
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
|
-
console.error("
|
|
30
|
-
console.error("
|
|
29
|
+
console.error("✖ Failed to generate worker bundle.");
|
|
30
|
+
console.error("✖", error);
|
|
31
31
|
process.exit(1);
|
|
32
32
|
}
|
|
33
33
|
console.log("");
|
|
@@ -35,7 +35,7 @@ console.log("");
|
|
|
35
35
|
function cleanup() {
|
|
36
36
|
if (existsSync(qvacOutputDir)) {
|
|
37
37
|
rmSync(qvacOutputDir, { recursive: true, force: true });
|
|
38
|
-
console.log(`\n
|
|
38
|
+
console.log(`\n▸ Cleaned up ${qvacOutputDir}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
process.on("exit", cleanup);
|
|
@@ -43,34 +43,40 @@ process.on("exit", cleanup);
|
|
|
43
43
|
// In a real app, place qvac.config.json (or .js/.ts) in your project root (auto-discovered).
|
|
44
44
|
process.env["QVAC_CONFIG_PATH"] = configPath;
|
|
45
45
|
const { completion, translate, embed, loadModel, unloadModel, LLAMA_3_2_1B_INST_Q4_0, BERGAMOT_EN_ES, GTE_LARGE_FP16, } = await import("@qvac/sdk");
|
|
46
|
-
console.log("1. LLM Completion (llamacpp-completion plugin)");
|
|
46
|
+
console.log("▸ 1. LLM Completion (llamacpp-completion plugin)");
|
|
47
47
|
try {
|
|
48
48
|
const llmModelId = await loadModel({
|
|
49
49
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
50
50
|
modelConfig: { ctx_size: 2048 },
|
|
51
|
-
onProgress: (p) =>
|
|
51
|
+
onProgress: (p) => {
|
|
52
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
53
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
54
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
55
|
+
if (p.percentage >= 100)
|
|
56
|
+
process.stderr.write("\n");
|
|
57
|
+
},
|
|
52
58
|
});
|
|
53
|
-
console.log(
|
|
59
|
+
console.log(`▸ Model loaded: ${llmModelId}`);
|
|
54
60
|
const question = "What is 2 + 2? Answer in one word.";
|
|
55
|
-
console.log(
|
|
61
|
+
console.log(`▸ Question: ${question}`);
|
|
56
62
|
const result = completion({
|
|
57
63
|
modelId: llmModelId,
|
|
58
64
|
history: [{ role: "user", content: question }],
|
|
59
65
|
stream: true,
|
|
60
66
|
});
|
|
61
|
-
|
|
67
|
+
console.log("▸ Response:");
|
|
62
68
|
for await (const token of result.tokenStream) {
|
|
63
69
|
process.stdout.write(token);
|
|
64
70
|
}
|
|
65
|
-
console.log("
|
|
71
|
+
console.log("");
|
|
66
72
|
await unloadModel({ modelId: llmModelId });
|
|
67
|
-
console.log("
|
|
73
|
+
console.log("▸ LLM unloaded\n");
|
|
68
74
|
}
|
|
69
75
|
catch (error) {
|
|
70
|
-
console.error("
|
|
76
|
+
console.error("✖ LLM failed:", error);
|
|
71
77
|
process.exit(1);
|
|
72
78
|
}
|
|
73
|
-
console.log("2. Translation (nmtcpp-translation plugin)");
|
|
79
|
+
console.log("▸ 2. Translation (nmtcpp-translation plugin)");
|
|
74
80
|
try {
|
|
75
81
|
const nmtModelId = await loadModel({
|
|
76
82
|
modelSrc: BERGAMOT_EN_ES,
|
|
@@ -79,9 +85,15 @@ try {
|
|
|
79
85
|
from: "en",
|
|
80
86
|
to: "es",
|
|
81
87
|
},
|
|
82
|
-
onProgress: (p) =>
|
|
88
|
+
onProgress: (p) => {
|
|
89
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
90
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
91
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
92
|
+
if (p.percentage >= 100)
|
|
93
|
+
process.stderr.write("\n");
|
|
94
|
+
},
|
|
83
95
|
});
|
|
84
|
-
console.log(
|
|
96
|
+
console.log(`▸ Model loaded: ${nmtModelId}`);
|
|
85
97
|
const text = "Hello, how are you?";
|
|
86
98
|
const result = translate({
|
|
87
99
|
modelId: nmtModelId,
|
|
@@ -90,33 +102,33 @@ try {
|
|
|
90
102
|
stream: false,
|
|
91
103
|
});
|
|
92
104
|
const translated = await result.text;
|
|
93
|
-
console.log(`
|
|
105
|
+
console.log(`"${text}" -> "${translated}"`);
|
|
94
106
|
await unloadModel({ modelId: nmtModelId });
|
|
95
|
-
console.log("
|
|
107
|
+
console.log("▸ NMT unloaded\n");
|
|
96
108
|
}
|
|
97
109
|
catch (error) {
|
|
98
|
-
console.error("
|
|
110
|
+
console.error("✖ Translation failed:", error);
|
|
99
111
|
process.exit(1);
|
|
100
112
|
}
|
|
101
|
-
console.log("3. Embeddings (llamacpp-embedding plugin NOT in config)");
|
|
102
|
-
console.log("
|
|
113
|
+
console.log("▸ 3. Embeddings (llamacpp-embedding plugin NOT in config)");
|
|
114
|
+
console.log("▸ Attempting to load an embeddings model...\n");
|
|
103
115
|
try {
|
|
104
116
|
const embedModelId = await loadModel({
|
|
105
117
|
modelSrc: GTE_LARGE_FP16,
|
|
106
118
|
});
|
|
107
119
|
await embed({ modelId: embedModelId, text: "test" });
|
|
108
|
-
console.error("
|
|
120
|
+
console.error("✖ Unexpected: embed succeeded without the plugin!");
|
|
109
121
|
process.exit(1);
|
|
110
122
|
}
|
|
111
123
|
catch (error) {
|
|
112
124
|
const message = error instanceof Error ? error.message : String(error);
|
|
113
125
|
if (message.includes("Plugin not found")) {
|
|
114
|
-
console.log("
|
|
115
|
-
console.log(
|
|
126
|
+
console.log("▸ Expected PLUGIN_NOT_FOUND error:");
|
|
127
|
+
console.log(`▸ ${message}\n`);
|
|
116
128
|
}
|
|
117
129
|
else {
|
|
118
|
-
console.error("
|
|
130
|
+
console.error("✖ Unexpected error:", error);
|
|
119
131
|
process.exit(1);
|
|
120
132
|
}
|
|
121
133
|
}
|
|
122
|
-
console.log("Done! Only the selected plugins were available.");
|
|
134
|
+
console.log("▸ Done! Only the selected plugins were available.");
|
|
@@ -5,13 +5,19 @@ try {
|
|
|
5
5
|
mode: "verbose",
|
|
6
6
|
includeServerBreakdown: true,
|
|
7
7
|
});
|
|
8
|
-
console.log("Profiler enabled:", profiler.isEnabled());
|
|
8
|
+
console.log("▸ Profiler enabled:", profiler.isEnabled());
|
|
9
9
|
const modelId = await loadModel({
|
|
10
10
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
11
|
-
onProgress: (p) =>
|
|
11
|
+
onProgress: (p) => {
|
|
12
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
13
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
14
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
15
|
+
if (p.percentage >= 100)
|
|
16
|
+
process.stderr.write("\n");
|
|
17
|
+
},
|
|
12
18
|
});
|
|
13
|
-
console.log("Model loaded:", modelId);
|
|
14
|
-
console.log("\n
|
|
19
|
+
console.log("▸ Model loaded:", modelId);
|
|
20
|
+
console.log("\n▸ Running completion...");
|
|
15
21
|
const result = completion({
|
|
16
22
|
modelId,
|
|
17
23
|
history: [{ role: "user", content: "Say hello in one sentence." }],
|
|
@@ -23,12 +29,12 @@ try {
|
|
|
23
29
|
console.log();
|
|
24
30
|
await unloadModel({ modelId });
|
|
25
31
|
// Export profiling data
|
|
26
|
-
console.log("\n
|
|
32
|
+
console.log("\n▸ Profiler Summary");
|
|
27
33
|
console.log(profiler.exportSummary());
|
|
28
|
-
console.log("\n
|
|
34
|
+
console.log("\n▸ Profiler Table");
|
|
29
35
|
console.log(profiler.exportTable());
|
|
30
36
|
const json = profiler.exportJSON();
|
|
31
|
-
console.log("\n
|
|
37
|
+
console.log("\n▸ Load Model Metrics");
|
|
32
38
|
// Filter for operation-level event (kind: "handler"), not RPC phase events
|
|
33
39
|
const loadModelEvent = json.recentEvents?.find((e) => e.op === "loadModel" && e.kind === "handler");
|
|
34
40
|
if (loadModelEvent) {
|
|
@@ -58,15 +64,15 @@ try {
|
|
|
58
64
|
];
|
|
59
65
|
console.log(" Available ops:", ops.join(", "));
|
|
60
66
|
}
|
|
61
|
-
console.log("\n
|
|
67
|
+
console.log("\n▸ Profiler JSON (structure)");
|
|
62
68
|
console.log(" aggregates:", Object.keys(json.aggregates).length, "metrics");
|
|
63
69
|
console.log(" recentEvents:", json.recentEvents?.length ?? 0, "events");
|
|
64
70
|
console.log(" config:", json.config);
|
|
65
71
|
// Disable profiling
|
|
66
72
|
profiler.disable();
|
|
67
|
-
console.log("\
|
|
73
|
+
console.log("\n▸ Profiler disabled:", !profiler.isEnabled());
|
|
68
74
|
}
|
|
69
75
|
catch (error) {
|
|
70
|
-
console.error("
|
|
76
|
+
console.error("✖", error);
|
|
71
77
|
process.exit(1);
|
|
72
78
|
}
|
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
import { embed, loadModel, unloadModel, GTE_LARGE_FP16, profiler, } from "@qvac/sdk";
|
|
2
2
|
try {
|
|
3
3
|
profiler.disable();
|
|
4
|
-
console.log("Profiler globally enabled:", profiler.isEnabled());
|
|
4
|
+
console.log("▸ Profiler globally enabled:", profiler.isEnabled());
|
|
5
5
|
const modelId = await loadModel({
|
|
6
6
|
modelSrc: GTE_LARGE_FP16,
|
|
7
|
-
onProgress: (p) =>
|
|
7
|
+
onProgress: (p) => {
|
|
8
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
9
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
10
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
11
|
+
if (p.percentage >= 100)
|
|
12
|
+
process.stderr.write("\n");
|
|
13
|
+
},
|
|
8
14
|
});
|
|
9
|
-
console.log("Model loaded:", modelId);
|
|
10
|
-
console.log("\n
|
|
15
|
+
console.log("▸ Model loaded:", modelId);
|
|
16
|
+
console.log("\n▸ Embed with per-call profiling");
|
|
11
17
|
const { embedding: embedding1 } = await embed({ modelId, text: "Profile this specific call" }, { profiling: { enabled: true, includeServerBreakdown: true } });
|
|
12
|
-
console.log("Embedding dimensions:", embedding1.length);
|
|
13
|
-
console.log("\n
|
|
18
|
+
console.log("▸ Embedding dimensions:", embedding1.length);
|
|
19
|
+
console.log("\n▸ Embed without profiling");
|
|
14
20
|
const { embedding: embedding2 } = await embed({
|
|
15
21
|
modelId,
|
|
16
22
|
text: "This call is not profiled",
|
|
17
23
|
});
|
|
18
|
-
console.log("Embedding dimensions:", embedding2.length);
|
|
19
|
-
console.log("\n
|
|
24
|
+
console.log("▸ Embedding dimensions:", embedding2.length);
|
|
25
|
+
console.log("\n▸ Embed with profiling explicitly disabled");
|
|
20
26
|
const { embedding: embedding3 } = await embed({ modelId, text: "Profiling explicitly disabled for this call" }, { profiling: { enabled: false } });
|
|
21
|
-
console.log("Embedding dimensions:", embedding3.length);
|
|
27
|
+
console.log("▸ Embedding dimensions:", embedding3.length);
|
|
22
28
|
await unloadModel({ modelId });
|
|
23
|
-
console.log("\n
|
|
29
|
+
console.log("\n▸ Profiler Summary (per-call data only)");
|
|
24
30
|
console.log(profiler.exportSummary());
|
|
25
31
|
}
|
|
26
32
|
catch (error) {
|
|
27
|
-
console.error("
|
|
33
|
+
console.error("✖", error);
|
|
28
34
|
process.exit(1);
|
|
29
35
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The Bare quickstart. Bare has no `process` global and does not spawn a worker,
|
|
2
|
+
// so two setup steps come first: install bare-process as the `process` global,
|
|
3
|
+
// then register the plugins this example uses via `plugins([...])`.
|
|
4
|
+
import bareProcess from "bare-process";
|
|
5
|
+
import { plugins, LLAMA_3_2_1B_INST_Q4_0 } from "@qvac/sdk";
|
|
6
|
+
import { llmPlugin } from "@qvac/sdk/llamacpp-completion/plugin.js";
|
|
7
|
+
globalThis.process = bareProcess;
|
|
8
|
+
const { loadModel, completion, unloadModel } = plugins([llmPlugin]);
|
|
9
|
+
// From here it is the same as the Node quickstart.
|
|
10
|
+
const modelId = await loadModel({ modelSrc: LLAMA_3_2_1B_INST_Q4_0 });
|
|
11
|
+
const history = [
|
|
12
|
+
{ role: "user", content: "Explain quantum computing in one sentence" },
|
|
13
|
+
];
|
|
14
|
+
const result = completion({ modelId, history, stream: true });
|
|
15
|
+
for await (const token of result.tokenStream) {
|
|
16
|
+
process.stdout.write(token);
|
|
17
|
+
}
|
|
18
|
+
await unloadModel({ modelId, autoClose: true });
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
// The SDK prints no logs by default. To see its client and server logs, run with
|
|
2
|
+
// QVAC_CONFIG_PATH pointing at a config that sets "loggerConsoleOutput": true
|
|
3
|
+
// (see the Quickstart docs).
|
|
1
4
|
import { loadModel, LLAMA_3_2_1B_INST_Q4_0, completion, unloadModel, } from "@qvac/sdk";
|
|
2
5
|
try {
|
|
3
6
|
// Load a model into memory
|
|
4
7
|
const modelId = await loadModel({
|
|
5
8
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
6
|
-
onProgress: (
|
|
7
|
-
|
|
9
|
+
onProgress: (p) => {
|
|
10
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
11
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
12
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
13
|
+
if (p.percentage >= 100)
|
|
14
|
+
process.stderr.write("\n");
|
|
8
15
|
},
|
|
9
16
|
});
|
|
10
17
|
// You can use the loaded model multiple times
|
|
@@ -22,6 +29,6 @@ try {
|
|
|
22
29
|
await unloadModel({ modelId });
|
|
23
30
|
}
|
|
24
31
|
catch (error) {
|
|
25
|
-
console.error("
|
|
32
|
+
console.error("✖", error);
|
|
26
33
|
process.exit(1);
|
|
27
34
|
}
|