@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
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
const SDK_EXPORT_CONDITIONS = [
|
|
5
|
+
"bare",
|
|
6
|
+
"import",
|
|
7
|
+
"module",
|
|
8
|
+
"default",
|
|
9
|
+
"node",
|
|
10
|
+
"require",
|
|
11
|
+
];
|
|
12
|
+
export function selectExportTarget(entry) {
|
|
13
|
+
if (entry == null)
|
|
14
|
+
return null;
|
|
15
|
+
if (typeof entry === "string")
|
|
16
|
+
return entry;
|
|
17
|
+
for (const condition of SDK_EXPORT_CONDITIONS) {
|
|
18
|
+
const resolved = selectExportTarget(entry[condition]);
|
|
19
|
+
if (resolved)
|
|
20
|
+
return resolved;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function readSdkExports(sdkPath) {
|
|
25
|
+
try {
|
|
26
|
+
const raw = fs.readFileSync(path.join(sdkPath, "package.json"), "utf8");
|
|
27
|
+
const pkg = JSON.parse(raw);
|
|
28
|
+
return pkg.exports ?? {};
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// bare-pack rewrites the worker's Node builtins to their bare-* equivalents
|
|
35
|
+
// (os -> bare-os, fs -> bare-fs, ...) and resolves them relative to wherever
|
|
36
|
+
// the generated entry imports the SDK from. A bare specifier resolves against
|
|
37
|
+
// the consumer project, so a hoisted/symlinked SDK (pnpm, workspaces) whose
|
|
38
|
+
// bare-* deps live in a parent node_modules becomes unreachable. Importing each
|
|
39
|
+
// SDK subpath via its resolved file under the SDK's realpath anchors that
|
|
40
|
+
// resolution next to the bare-* deps instead.
|
|
41
|
+
export function createSdkImportResolver(sdkPath, sdkName) {
|
|
42
|
+
let resolvedSdkPath = sdkPath;
|
|
43
|
+
try {
|
|
44
|
+
resolvedSdkPath = fs.realpathSync(sdkPath);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Keep sdkPath as-is if it cannot be canonicalized.
|
|
48
|
+
}
|
|
49
|
+
const exportsMap = readSdkExports(resolvedSdkPath);
|
|
50
|
+
const prefix = `${sdkName}/`;
|
|
51
|
+
return (specifier) => {
|
|
52
|
+
if (!specifier.startsWith(prefix))
|
|
53
|
+
return specifier;
|
|
54
|
+
const subpath = `./${specifier.slice(prefix.length)}`;
|
|
55
|
+
const target = selectExportTarget(exportsMap[subpath]);
|
|
56
|
+
if (!target)
|
|
57
|
+
return specifier;
|
|
58
|
+
return pathToFileURL(path.join(resolvedSdkPath, target)).href;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -19,10 +19,10 @@ const neuralFilePath = args[0];
|
|
|
19
19
|
// Feed the neural buffer in fixed-size chunks to simulate a live stream.
|
|
20
20
|
const CHUNK_SIZE = 64 * 1024;
|
|
21
21
|
try {
|
|
22
|
-
console.log("
|
|
23
|
-
console.log(
|
|
24
|
-
console.log(
|
|
25
|
-
console.log("Loading model...");
|
|
22
|
+
console.log("▸ BCI transcribeStream file test");
|
|
23
|
+
console.log(`▸ File: ${neuralFilePath}`);
|
|
24
|
+
console.log(`▸ Chunk size: ${CHUNK_SIZE} bytes`);
|
|
25
|
+
console.log("▸ Loading model...");
|
|
26
26
|
const modelId = await loadModel({
|
|
27
27
|
modelSrc: BCI_WINDOWED,
|
|
28
28
|
modelConfig: {
|
|
@@ -38,10 +38,10 @@ try {
|
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
});
|
|
41
|
-
console.log(
|
|
42
|
-
console.log("Opening live session...");
|
|
41
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
42
|
+
console.log("▸ Opening live session...");
|
|
43
43
|
const session = await bciTranscribeStream({ modelId, emit: "delta" });
|
|
44
|
-
console.log("Session open. Streaming neural signal
|
|
44
|
+
console.log("▸ Session open. Streaming neural signal...");
|
|
45
45
|
// Drain the session concurrently with writing so the sliding-window
|
|
46
46
|
// decode can make progress as chunks arrive instead of stalling.
|
|
47
47
|
const consume = (async () => {
|
|
@@ -60,18 +60,18 @@ try {
|
|
|
60
60
|
totalBytes += chunk.length;
|
|
61
61
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
62
62
|
}
|
|
63
|
-
console.log(`\n\
|
|
64
|
-
console.log("Waiting for transcription to finish
|
|
63
|
+
console.log(`\n\n▸ Neural signal streamed: ${totalBytes} bytes`);
|
|
64
|
+
console.log("▸ Waiting for transcription to finish...");
|
|
65
65
|
session.end();
|
|
66
66
|
const transcript = await consume;
|
|
67
|
-
console.log("\n
|
|
68
|
-
console.log(
|
|
69
|
-
console.log("
|
|
67
|
+
console.log("\n▸ Results");
|
|
68
|
+
console.log(transcript.trim() || "(no text received)");
|
|
69
|
+
console.log("▸ Unloading model...");
|
|
70
70
|
await unloadModel({ modelId });
|
|
71
|
-
console.log("Done.");
|
|
71
|
+
console.log("▸ Done.");
|
|
72
72
|
process.exit(0);
|
|
73
73
|
}
|
|
74
74
|
catch (error) {
|
|
75
|
-
console.error("
|
|
75
|
+
console.error("✖", error);
|
|
76
76
|
process.exit(1);
|
|
77
77
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Usage: bun run examples/bci/bci-filesystem.ts <neural-bin-file-path>
|
|
9
9
|
*/
|
|
10
|
-
import { loadModel, unloadModel, bciTranscribe, BCI_WINDOWED } from "@qvac/sdk";
|
|
10
|
+
import { loadModel, unloadModel, bciTranscribe, BCI_WINDOWED, } from "@qvac/sdk";
|
|
11
11
|
const args = process.argv.slice(2);
|
|
12
12
|
if (!args[0]) {
|
|
13
13
|
console.error("Usage: bun run examples/bci/bci-filesystem.ts <neural-bin-file-path>");
|
|
@@ -15,8 +15,8 @@ if (!args[0]) {
|
|
|
15
15
|
}
|
|
16
16
|
const neuralFilePath = args[0];
|
|
17
17
|
try {
|
|
18
|
-
console.log("
|
|
19
|
-
console.log("
|
|
18
|
+
console.log("▸ Starting BCI transcription example...");
|
|
19
|
+
console.log("▸ Loading BCI model...");
|
|
20
20
|
const modelId = await loadModel({
|
|
21
21
|
modelSrc: BCI_WINDOWED,
|
|
22
22
|
modelConfig: {
|
|
@@ -31,33 +31,37 @@ try {
|
|
|
31
31
|
day_idx: 1,
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
|
-
onProgress: (
|
|
35
|
-
|
|
34
|
+
onProgress: (p) => {
|
|
35
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
36
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
37
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
38
|
+
if (p.percentage >= 100)
|
|
39
|
+
process.stderr.write("\n");
|
|
36
40
|
},
|
|
37
41
|
});
|
|
38
|
-
console.log(
|
|
39
|
-
console.log("
|
|
42
|
+
console.log(`▸ BCI model loaded with ID: ${modelId}`);
|
|
43
|
+
console.log("▸ Transcribing neural signal...");
|
|
40
44
|
const segments = await bciTranscribe({
|
|
41
45
|
modelId,
|
|
42
46
|
neuralData: neuralFilePath,
|
|
43
47
|
metadata: true,
|
|
44
48
|
});
|
|
45
|
-
console.log("
|
|
49
|
+
console.log("▸ Transcription result:");
|
|
46
50
|
for (const segment of segments) {
|
|
47
51
|
const start = (segment.startMs / 1000).toFixed(2);
|
|
48
52
|
const end = (segment.endMs / 1000).toFixed(2);
|
|
49
53
|
console.log(` [${start}s → ${end}s] (id=${segment.id}, append=${segment.append}) ${segment.text}`);
|
|
50
54
|
}
|
|
51
|
-
console.log(
|
|
55
|
+
console.log(segments
|
|
52
56
|
.map((s) => s.text)
|
|
53
57
|
.join("")
|
|
54
|
-
.trim()
|
|
55
|
-
console.log("
|
|
58
|
+
.trim());
|
|
59
|
+
console.log("▸ Unloading BCI model...");
|
|
56
60
|
await unloadModel({ modelId });
|
|
57
|
-
console.log("
|
|
61
|
+
console.log("▸ BCI model unloaded successfully");
|
|
58
62
|
process.exit(0);
|
|
59
63
|
}
|
|
60
64
|
catch (error) {
|
|
61
|
-
console.error("
|
|
65
|
+
console.error("✖", error);
|
|
62
66
|
process.exit(1);
|
|
63
67
|
}
|
|
@@ -1,68 +1,68 @@
|
|
|
1
1
|
import { WHISPER_TINY } from "../models/registry/index.js";
|
|
2
2
|
import { downloadAsset, getModelInfo, loadModel, unloadModel } from "..";
|
|
3
3
|
const printModelStatus = (info, label) => {
|
|
4
|
-
console.log(`\n${label}`);
|
|
5
|
-
console.log(
|
|
6
|
-
console.log(
|
|
7
|
-
console.log(
|
|
8
|
-
console.log(
|
|
9
|
-
console.log(
|
|
10
|
-
console.log(
|
|
11
|
-
console.log(
|
|
12
|
-
console.log(
|
|
4
|
+
console.log(`\n▸ ${label}`);
|
|
5
|
+
console.log(`▸ Model Name: ${info.name}`);
|
|
6
|
+
console.log(`▸ Model ID: ${info.modelId}`);
|
|
7
|
+
console.log(`▸ Blob Core Key: ${info.blobCoreKey?.substring(0, 16) || "N/A"}...`);
|
|
8
|
+
console.log(`▸ Expected Size: ${(info.expectedSize / 1024 / 1024).toFixed(2)} MB`);
|
|
9
|
+
console.log(`▸ Addon: ${info.addon}`);
|
|
10
|
+
console.log(`▸ Cache Files: ${info.cacheFiles.length}`);
|
|
11
|
+
console.log(`▸ Is Cached: ${info.isCached ? "yes" : "no"}`);
|
|
12
|
+
console.log(`▸ Is Loaded: ${info.isLoaded ? "yes" : "no"}`);
|
|
13
13
|
if (info.isCached) {
|
|
14
14
|
if (info.cacheFiles.length === 1) {
|
|
15
|
-
console.log(
|
|
15
|
+
console.log(`▸ Cache Path: ${info.cacheFiles[0]?.path}`);
|
|
16
16
|
}
|
|
17
17
|
else {
|
|
18
18
|
const cachedFiles = info.cacheFiles.filter((f) => f.isCached).length;
|
|
19
|
-
console.log(
|
|
19
|
+
console.log(`▸ Cached: ${cachedFiles}/${info.cacheFiles.length}`);
|
|
20
20
|
}
|
|
21
|
-
console.log(
|
|
22
|
-
console.log(
|
|
21
|
+
console.log(`▸ Actual Size: ${(info.actualSize / 1024 / 1024).toFixed(2)} MB`);
|
|
22
|
+
console.log(`▸ Cached At: ${info.cachedAt?.toLocaleString()}`);
|
|
23
23
|
}
|
|
24
24
|
if (info.loadedInstances && info.loadedInstances.length > 0) {
|
|
25
|
-
console.log(
|
|
25
|
+
console.log(`▸ Loaded Instances: ${info.loadedInstances.length}`);
|
|
26
26
|
info.loadedInstances.forEach((instance, i) => {
|
|
27
|
-
console.log(
|
|
28
|
-
console.log(
|
|
27
|
+
console.log(`▸ ${i + 1}. Registry ID: ${instance.registryId}`);
|
|
28
|
+
console.log(`▸ Loaded At: ${instance.loadedAt.toLocaleString()}`);
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
try {
|
|
33
|
-
console.log("
|
|
33
|
+
console.log("▸ Model Cache Management Demo");
|
|
34
34
|
// 1. Check initial status
|
|
35
|
-
console.log("\
|
|
35
|
+
console.log("\n▸ 1. INITIAL STATUS CHECK");
|
|
36
36
|
const initialInfo = await getModelInfo(WHISPER_TINY);
|
|
37
37
|
printModelStatus(initialInfo, "Initial Status:");
|
|
38
38
|
// 2. Download if not cached
|
|
39
39
|
if (!initialInfo.isCached) {
|
|
40
|
-
console.log("\
|
|
41
|
-
console.log("
|
|
40
|
+
console.log("\n▸ 2. DOWNLOADING MODEL (not cached)");
|
|
41
|
+
console.log("▸ Downloading from hyperdrive...");
|
|
42
42
|
await downloadAsset({ assetSrc: WHISPER_TINY });
|
|
43
|
-
console.log("
|
|
43
|
+
console.log("▸ Download complete!");
|
|
44
44
|
const afterDownload = await getModelInfo(WHISPER_TINY);
|
|
45
45
|
printModelStatus(afterDownload, "Status After Download:");
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
48
|
-
console.log("\
|
|
49
|
-
console.log("
|
|
48
|
+
console.log("\n▸ 2. MODEL ALREADY CACHED");
|
|
49
|
+
console.log("▸ Skipping download...");
|
|
50
50
|
}
|
|
51
51
|
// 3. Load if not loaded
|
|
52
|
-
console.log("\
|
|
52
|
+
console.log("\n▸ 3. LOADING MODEL INTO MEMORY");
|
|
53
53
|
const beforeLoad = await getModelInfo(WHISPER_TINY);
|
|
54
54
|
let modelId;
|
|
55
55
|
if (!beforeLoad.isLoaded) {
|
|
56
|
-
console.log("
|
|
56
|
+
console.log("▸ Loading model into memory...");
|
|
57
57
|
modelId = await loadModel({
|
|
58
58
|
modelSrc: WHISPER_TINY,
|
|
59
59
|
});
|
|
60
|
-
console.log(
|
|
60
|
+
console.log(`▸ Model loaded! ID: ${modelId}`);
|
|
61
61
|
const afterLoad = await getModelInfo(WHISPER_TINY);
|
|
62
62
|
printModelStatus(afterLoad, "Status After Load:");
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
console.log("
|
|
65
|
+
console.log("▸ Model already loaded!");
|
|
66
66
|
const instances = beforeLoad.loadedInstances;
|
|
67
67
|
if (!instances || instances.length === 0) {
|
|
68
68
|
throw new Error("Model is loaded but no instances found");
|
|
@@ -72,25 +72,25 @@ try {
|
|
|
72
72
|
throw new Error("First instance is undefined");
|
|
73
73
|
}
|
|
74
74
|
modelId = firstInstance.registryId;
|
|
75
|
-
console.log(
|
|
75
|
+
console.log(`▸ Using existing model ID: ${modelId}`);
|
|
76
76
|
}
|
|
77
77
|
// 4. Demonstrate unload
|
|
78
|
-
console.log("\
|
|
79
|
-
console.log("
|
|
78
|
+
console.log("\n▸ 4. UNLOADING MODEL");
|
|
79
|
+
console.log("▸ Unloading model from memory...");
|
|
80
80
|
await unloadModel({ modelId });
|
|
81
|
-
console.log("
|
|
81
|
+
console.log("▸ Model unloaded!");
|
|
82
82
|
const afterUnload = await getModelInfo(WHISPER_TINY);
|
|
83
83
|
printModelStatus(afterUnload, "Status After Unload:");
|
|
84
84
|
// 5. Summary
|
|
85
|
-
console.log("\
|
|
86
|
-
console.log("
|
|
87
|
-
console.log("
|
|
88
|
-
console.log("
|
|
89
|
-
console.log("
|
|
90
|
-
console.log("\n
|
|
85
|
+
console.log("\n▸ 5. SUMMARY");
|
|
86
|
+
console.log("▸ Model Info API works correctly");
|
|
87
|
+
console.log("▸ Cache status tracked accurately");
|
|
88
|
+
console.log("▸ Loaded status reflects memory state");
|
|
89
|
+
console.log("▸ All operations completed successfully");
|
|
90
|
+
console.log("\n▸ Demo Complete\n");
|
|
91
91
|
process.exit(0);
|
|
92
92
|
}
|
|
93
93
|
catch (error) {
|
|
94
|
-
console.error("
|
|
94
|
+
console.error("✖", error);
|
|
95
95
|
process.exit(1);
|
|
96
96
|
}
|
|
@@ -50,11 +50,11 @@ try {
|
|
|
50
50
|
],
|
|
51
51
|
stream: true,
|
|
52
52
|
});
|
|
53
|
-
console.log(
|
|
53
|
+
console.log(`▸ requestId: ${run.requestId}`);
|
|
54
54
|
// Cancel after a short delay so we exercise the cancel-mid-decode path.
|
|
55
55
|
setTimeout(() => {
|
|
56
56
|
void cancel({ requestId: run.requestId });
|
|
57
|
-
console.log("
|
|
57
|
+
console.log("▸ cancel issued");
|
|
58
58
|
}, 250);
|
|
59
59
|
// Channel 1: the events stream ends normally on cancel. The
|
|
60
60
|
// `completionDone` event's `stopReason` tells you why the loop is
|
|
@@ -70,23 +70,23 @@ try {
|
|
|
70
70
|
endReason = event.stopReason;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
console.log(`\n\
|
|
73
|
+
console.log(`\n\n▸ streamed ${tokenCount} content deltas, stopReason=${endReason}`);
|
|
74
74
|
// Channel 2: promise-aggregates reject with InferenceCancelledError
|
|
75
75
|
// on cancel. The accumulated state up to the cancel point is preserved
|
|
76
76
|
// on `err.partial`.
|
|
77
77
|
try {
|
|
78
78
|
const text = await run.text;
|
|
79
|
-
console.log(
|
|
79
|
+
console.log(`▸ completed normally (${text.length} chars)`);
|
|
80
80
|
}
|
|
81
81
|
catch (err) {
|
|
82
82
|
if (err instanceof InferenceCancelledError) {
|
|
83
|
-
console.log(
|
|
84
|
-
console.log(
|
|
83
|
+
console.log(`▸ run.text rejected: cancelled (requestId=${err.requestId})`);
|
|
84
|
+
console.log(`▸ partial text length: ${(err.partial.text ?? "").length}`);
|
|
85
85
|
if (err.partial.stats?.tokensPerSecond !== undefined) {
|
|
86
|
-
console.log(
|
|
86
|
+
console.log(`▸ partial stats: ${err.partial.stats.tokensPerSecond.toFixed(1)} tok/s`);
|
|
87
87
|
}
|
|
88
88
|
if (err.partial.toolCalls && err.partial.toolCalls.length > 0) {
|
|
89
|
-
console.log(
|
|
89
|
+
console.log(`▸ partial tool calls: ${err.partial.toolCalls.length}`);
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
else {
|
|
@@ -97,6 +97,6 @@ try {
|
|
|
97
97
|
process.exit(0);
|
|
98
98
|
}
|
|
99
99
|
catch (error) {
|
|
100
|
-
console.error("
|
|
100
|
+
console.error("✖", error);
|
|
101
101
|
process.exit(1);
|
|
102
102
|
}
|
|
@@ -19,9 +19,15 @@ try {
|
|
|
19
19
|
const modelId = await loadModel({
|
|
20
20
|
modelSrc: QWEN3_600M_INST_Q4,
|
|
21
21
|
modelConfig: { ctx_size: 4096 },
|
|
22
|
-
onProgress: (p) =>
|
|
22
|
+
onProgress: (p) => {
|
|
23
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
24
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
25
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
26
|
+
if (p.percentage >= 100)
|
|
27
|
+
process.stderr.write("\n");
|
|
28
|
+
},
|
|
23
29
|
});
|
|
24
|
-
console.log(
|
|
30
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
25
31
|
const result = completion({
|
|
26
32
|
modelId,
|
|
27
33
|
history: [
|
|
@@ -34,25 +40,25 @@ try {
|
|
|
34
40
|
handleEvent(event);
|
|
35
41
|
}
|
|
36
42
|
const final = await result.final;
|
|
37
|
-
console.log("\n
|
|
38
|
-
console.log(
|
|
43
|
+
console.log("\n▸ Final result");
|
|
44
|
+
console.log(`▸ Content: ${final.contentText}`);
|
|
39
45
|
if (final.thinkingText) {
|
|
40
|
-
console.log(
|
|
46
|
+
console.log(`▸ Thinking: ${final.thinkingText}`);
|
|
41
47
|
}
|
|
42
48
|
if (final.stats) {
|
|
43
|
-
console.log(
|
|
49
|
+
console.log(`▸ ${final.stats.tokensPerSecond?.toFixed(1)} tok/s`);
|
|
44
50
|
}
|
|
45
51
|
if (final.toolCalls.length > 0) {
|
|
46
|
-
console.log(
|
|
52
|
+
console.log(`▸ Tool calls: ${final.toolCalls.map((c) => c.name).join(", ")}`);
|
|
47
53
|
}
|
|
48
54
|
if (final.stopReason) {
|
|
49
|
-
console.log(
|
|
55
|
+
console.log(`▸ Stop reason: ${final.stopReason}`);
|
|
50
56
|
}
|
|
51
|
-
console.log(
|
|
57
|
+
console.log(`▸ Raw output length: ${final.raw.fullText.length} chars`);
|
|
52
58
|
await unloadModel({ modelId, clearStorage: false });
|
|
53
59
|
}
|
|
54
60
|
catch (error) {
|
|
55
|
-
console.error("
|
|
61
|
+
console.error("✖", error);
|
|
56
62
|
process.exit(1);
|
|
57
63
|
}
|
|
58
64
|
function handleEvent(event) {
|
|
@@ -64,17 +70,17 @@ function handleEvent(event) {
|
|
|
64
70
|
process.stdout.write(`\x1b[2m${event.text}\x1b[0m`);
|
|
65
71
|
break;
|
|
66
72
|
case "toolCall":
|
|
67
|
-
console.log(`\n
|
|
73
|
+
console.log(`\n▸ Tool: ${event.call.name}(${JSON.stringify(event.call.arguments)})`);
|
|
68
74
|
break;
|
|
69
75
|
case "toolError":
|
|
70
|
-
console.
|
|
76
|
+
console.log(`\n✖ Tool error [${event.error.code}]: ${event.error.message}`);
|
|
71
77
|
break;
|
|
72
78
|
case "completionStats":
|
|
73
|
-
console.log(`\n
|
|
79
|
+
console.log(`\n▸ ${event.stats.tokensPerSecond?.toFixed(1)} tok/s`);
|
|
74
80
|
break;
|
|
75
81
|
case "completionDone":
|
|
76
82
|
if (event.stopReason === "error" && "error" in event) {
|
|
77
|
-
console.
|
|
83
|
+
console.log(`\n✖ ${event.error.message}`);
|
|
78
84
|
}
|
|
79
85
|
break;
|
|
80
86
|
case "rawDelta":
|
|
@@ -26,11 +26,17 @@ try {
|
|
|
26
26
|
const modelId = await loadModel({
|
|
27
27
|
modelSrc: QWEN3_600M_INST_Q4,
|
|
28
28
|
modelConfig: { ctx_size: 4096 },
|
|
29
|
-
onProgress: (p) =>
|
|
29
|
+
onProgress: (p) => {
|
|
30
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
31
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
32
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
33
|
+
if (p.percentage >= 100)
|
|
34
|
+
process.stderr.write("\n");
|
|
35
|
+
},
|
|
30
36
|
});
|
|
31
|
-
console.log(
|
|
37
|
+
console.log(`▸ Model loaded: ${modelId}\n`);
|
|
32
38
|
// --- Case 1: natural EOS ---
|
|
33
|
-
console.log("
|
|
39
|
+
console.log("▸ Case 1: natural EOS (no predict limit)");
|
|
34
40
|
const run1 = completion({
|
|
35
41
|
modelId,
|
|
36
42
|
history: [{ role: "user", content: "Say hi in one word." }],
|
|
@@ -41,9 +47,9 @@ try {
|
|
|
41
47
|
process.stdout.write(event.text);
|
|
42
48
|
}
|
|
43
49
|
const final1 = await run1.final;
|
|
44
|
-
console.log(`\
|
|
50
|
+
console.log(`\n▸ stopReason: ${final1.stopReason ?? "(undefined — natural EOS)"}`);
|
|
45
51
|
// --- Case 2: predict budget exhausted → stopReason = "length" ---
|
|
46
|
-
console.log("\n
|
|
52
|
+
console.log("\n▸ Case 2: predict budget hit (predict: 10)");
|
|
47
53
|
const run2 = completion({
|
|
48
54
|
modelId,
|
|
49
55
|
history: [{ role: "user", content: "Count from 1 to 100, one number per line." }],
|
|
@@ -55,11 +61,11 @@ try {
|
|
|
55
61
|
process.stdout.write(event.text);
|
|
56
62
|
}
|
|
57
63
|
const final2 = await run2.final;
|
|
58
|
-
console.log(`\
|
|
64
|
+
console.log(`\n▸ stopReason: ${final2.stopReason}`);
|
|
59
65
|
await unloadModel({ modelId, clearStorage: false });
|
|
60
66
|
process.exit(0);
|
|
61
67
|
}
|
|
62
68
|
catch (error) {
|
|
63
|
-
console.error("
|
|
69
|
+
console.error("✖", error);
|
|
64
70
|
process.exit(1);
|
|
65
71
|
}
|
|
@@ -48,15 +48,15 @@ async function runCompletion(label, modelId, prompt) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
function report(title, outcomes) {
|
|
51
|
-
console.log(`\n${title}`);
|
|
51
|
+
console.log(`\n▸ ${title}`);
|
|
52
52
|
for (const o of outcomes) {
|
|
53
53
|
if (o.ok) {
|
|
54
54
|
const preview = o.text.replace(/\s+/g, " ").slice(0, 70);
|
|
55
|
-
console.log(`
|
|
55
|
+
console.log(` ▸ ${o.label}: ${preview}${o.text.length > 70 ? "…" : ""}`);
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
const policy = o.code === 52420 ? " (rejected by policy)" : "";
|
|
59
|
-
console.log(`
|
|
59
|
+
console.log(` ✖ ${o.label}: ${o.errorName}${o.code !== undefined ? ` [${o.code}]` : ""}${policy} — ${o.message}`);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -73,10 +73,10 @@ try {
|
|
|
73
73
|
report("Part 1 — two concurrent completions on the SAME model (expect both to succeed, serialized):", sameModel);
|
|
74
74
|
const rejected = sameModel.filter((o) => !o.ok).length;
|
|
75
75
|
if (rejected === 0) {
|
|
76
|
-
console.log("
|
|
76
|
+
console.log(" ▸ Both succeeded: the second was queued behind the first and ran when the slot freed (no 52420, no addon collision).");
|
|
77
77
|
}
|
|
78
78
|
else {
|
|
79
|
-
console.log(`
|
|
79
|
+
console.log(` ▸ ${rejected}/2 failed — the FIFO admission queue should have serialized these. Check the completion policy.`);
|
|
80
80
|
}
|
|
81
81
|
// Part 2 — different models, two concurrent completions (the "parallel that works").
|
|
82
82
|
const modelB = await loadModel({
|
|
@@ -90,9 +90,9 @@ try {
|
|
|
90
90
|
report("Part 2 — two concurrent completions on DIFFERENT models (expect both succeed):", differentModels);
|
|
91
91
|
await unloadModel({ modelId: modelA, clearStorage: false });
|
|
92
92
|
await unloadModel({ modelId: modelB, clearStorage: false });
|
|
93
|
-
console.log(`\
|
|
93
|
+
console.log(`\n▸ rejected-by-policy error available for instanceof checks: ${typeof RequestRejectedByPolicyError === "function"}`);
|
|
94
94
|
}
|
|
95
95
|
catch (error) {
|
|
96
|
-
console.error("
|
|
96
|
+
console.error("✖", error);
|
|
97
97
|
process.exit(1);
|
|
98
98
|
}
|
|
@@ -2,13 +2,13 @@ import { WHISPER_TINY, loadModel, transcribe, unloadModel } from "../index";
|
|
|
2
2
|
// Parse command line arguments
|
|
3
3
|
const args = process.argv.slice(2);
|
|
4
4
|
if (!args[0]) {
|
|
5
|
-
console.error("Usage: bun run examples/config-reload.ts <audio-file-path>");
|
|
5
|
+
console.error("✖ Usage: bun run examples/config-reload.ts <audio-file-path>");
|
|
6
6
|
process.exit(1);
|
|
7
7
|
}
|
|
8
8
|
const audioFilePath = args[0];
|
|
9
9
|
try {
|
|
10
10
|
// Initial load with English language
|
|
11
|
-
console.log("Loading Whisper model with English config...");
|
|
11
|
+
console.log("▸ Loading Whisper model with English config...");
|
|
12
12
|
const modelId = await loadModel({
|
|
13
13
|
modelSrc: WHISPER_TINY,
|
|
14
14
|
modelConfig: {
|
|
@@ -16,15 +16,14 @@ try {
|
|
|
16
16
|
},
|
|
17
17
|
});
|
|
18
18
|
// Transcribe with English config
|
|
19
|
-
console.log("Transcribing audio with English config...");
|
|
19
|
+
console.log("▸ Transcribing audio with English config...");
|
|
20
20
|
const englishText = await transcribe({
|
|
21
21
|
modelId,
|
|
22
22
|
audioChunk: audioFilePath,
|
|
23
23
|
});
|
|
24
24
|
console.log(`Transcription (EN): ${englishText}`);
|
|
25
|
-
console.log();
|
|
26
25
|
// Hot reload config - change language and temperature
|
|
27
|
-
console.log("Hot reloading config (changing language and temperature)...");
|
|
26
|
+
console.log("▸ Hot reloading config (changing language and temperature)...");
|
|
28
27
|
const reloadedId = await loadModel({
|
|
29
28
|
modelId,
|
|
30
29
|
modelType: "whispercpp-transcription",
|
|
@@ -32,9 +31,9 @@ try {
|
|
|
32
31
|
language: "es", // Change to Spanish
|
|
33
32
|
},
|
|
34
33
|
});
|
|
35
|
-
console.log(
|
|
34
|
+
console.log(`▸ Config reloaded, same model ID: ${reloadedId === modelId}`);
|
|
36
35
|
// Transcribe again with updated config
|
|
37
|
-
console.log("Transcribing with updated config...");
|
|
36
|
+
console.log("▸ Transcribing with updated config...");
|
|
38
37
|
const spanishText = await transcribe({
|
|
39
38
|
modelId,
|
|
40
39
|
audioChunk: audioFilePath,
|
|
@@ -43,6 +42,6 @@ try {
|
|
|
43
42
|
await unloadModel({ modelId });
|
|
44
43
|
}
|
|
45
44
|
catch (error) {
|
|
46
|
-
console.error("
|
|
45
|
+
console.error("✖", error);
|
|
47
46
|
process.exit(1);
|
|
48
47
|
}
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
const configDir = import.meta.dirname ?? process.cwd();
|
|
19
19
|
process.env["QVAC_CONFIG_PATH"] =
|
|
20
20
|
`${configDir}/config/default/default.config.js`;
|
|
21
|
-
console.log(
|
|
21
|
+
console.log(`▸ Using config from: ${process.env["QVAC_CONFIG_PATH"]}`);
|
|
22
22
|
const { loadModel, unloadModel, completion, LLAMA_3_2_1B_INST_Q4_0 } = await import("@qvac/sdk");
|
|
23
23
|
try {
|
|
24
|
-
console.log("
|
|
24
|
+
console.log("▸ Loading model with configured settings...");
|
|
25
25
|
const modelId = await loadModel({
|
|
26
26
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
27
27
|
});
|
|
28
|
-
console.log("
|
|
28
|
+
console.log("▸ Running completion...");
|
|
29
29
|
const result = completion({
|
|
30
30
|
modelId,
|
|
31
31
|
history: [
|
|
@@ -40,7 +40,7 @@ try {
|
|
|
40
40
|
await unloadModel({ modelId });
|
|
41
41
|
}
|
|
42
42
|
catch (error) {
|
|
43
|
-
console.error("
|
|
43
|
+
console.error("✖", error);
|
|
44
44
|
process.exit(1);
|
|
45
45
|
}
|
|
46
46
|
export {};
|