@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
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
import { modelRegistryList, modelRegistrySearch, modelRegistryGetModel, ModelType, close, } from "@qvac/sdk";
|
|
2
2
|
try {
|
|
3
|
-
console.log("QVAC Model Registry Query Examples\n");
|
|
3
|
+
console.log("▸ QVAC Model Registry Query Examples\n");
|
|
4
4
|
// List all available models
|
|
5
|
-
console.log("Listing all models in QVAC model registry...");
|
|
5
|
+
console.log("▸ Listing all models in QVAC model registry...");
|
|
6
6
|
const allModels = await modelRegistryList();
|
|
7
|
-
console.log(
|
|
7
|
+
console.log(`▸ Found ${allModels.length} models in registry\n`);
|
|
8
8
|
// Show first 5 models as sample
|
|
9
|
-
console.log("
|
|
9
|
+
console.log("▸ Sample models:");
|
|
10
10
|
allModels.slice(0, 5).forEach((model) => {
|
|
11
11
|
console.log(` - ${model.name} (${model.addon}, ${model.engine}, ${formatSize(model.expectedSize)})`);
|
|
12
12
|
});
|
|
13
13
|
console.log();
|
|
14
14
|
// Search with text filter
|
|
15
|
-
console.log('Searching for "whisper" models...');
|
|
15
|
+
console.log('▸ Searching for "whisper" models...');
|
|
16
16
|
const whisperModels = await modelRegistrySearch({ filter: "whisper" });
|
|
17
|
-
console.log(
|
|
17
|
+
console.log(`▸ Found ${whisperModels.length} whisper-related models\n`);
|
|
18
18
|
// Search by engine (using canonical ModelType enum)
|
|
19
|
-
console.log(
|
|
19
|
+
console.log(`▸ Searching by engine (${ModelType.llamacppEmbedding})...`);
|
|
20
20
|
const embedModels = await modelRegistrySearch({
|
|
21
21
|
engine: ModelType.llamacppEmbedding,
|
|
22
22
|
});
|
|
23
|
-
console.log(
|
|
23
|
+
console.log(`▸ Found ${embedModels.length} embedding models`);
|
|
24
24
|
embedModels.slice(0, 3).forEach((model) => {
|
|
25
25
|
console.log(` - ${model.name} (${model.quantization})`);
|
|
26
26
|
});
|
|
27
27
|
console.log();
|
|
28
28
|
// Search by quantization
|
|
29
|
-
console.log("Searching for Q4 quantized models...");
|
|
29
|
+
console.log("▸ Searching for Q4 quantized models...");
|
|
30
30
|
const q4Models = await modelRegistrySearch({ quantization: "q4" });
|
|
31
|
-
console.log(
|
|
31
|
+
console.log(`▸ Found ${q4Models.length} Q4 quantized models`);
|
|
32
32
|
q4Models.slice(0, 3).forEach((model) => {
|
|
33
33
|
console.log(` - ${model.name}`);
|
|
34
34
|
});
|
|
35
35
|
console.log();
|
|
36
36
|
// Search by addon/model type
|
|
37
|
-
console.log("Searching for transcription models...");
|
|
37
|
+
console.log("▸ Searching for transcription models...");
|
|
38
38
|
const transcriptionModels = await modelRegistrySearch({
|
|
39
39
|
addon: "whisper",
|
|
40
40
|
});
|
|
41
|
-
console.log(
|
|
41
|
+
console.log(`▸ Found ${transcriptionModels.length} transcription models`);
|
|
42
42
|
transcriptionModels.slice(0, 3).forEach((model) => {
|
|
43
43
|
console.log(` - ${model.name}`);
|
|
44
44
|
});
|
|
45
45
|
console.log();
|
|
46
46
|
// Combined search: engine + quantization
|
|
47
|
-
console.log("Searching for Q4 LLM models...");
|
|
47
|
+
console.log("▸ Searching for Q4 LLM models...");
|
|
48
48
|
const q4LlmModels = await modelRegistrySearch({
|
|
49
49
|
engine: ModelType.llamacppCompletion,
|
|
50
50
|
quantization: "q4",
|
|
51
51
|
});
|
|
52
|
-
console.log(
|
|
52
|
+
console.log(`▸ Found ${q4LlmModels.length} Q4 LLM models`);
|
|
53
53
|
q4LlmModels.slice(0, 3).forEach((model) => {
|
|
54
54
|
console.log(` - ${model.name} (${model.quantization})`);
|
|
55
55
|
});
|
|
@@ -57,7 +57,7 @@ try {
|
|
|
57
57
|
// Get specific model (if we have at least one model)
|
|
58
58
|
const sampleModel = allModels[0];
|
|
59
59
|
if (sampleModel) {
|
|
60
|
-
console.log(
|
|
60
|
+
console.log(`▸ Getting specific model: ${sampleModel.registrySource}/${sampleModel.registryPath}`);
|
|
61
61
|
const model = await modelRegistryGetModel(sampleModel.registryPath, sampleModel.registrySource);
|
|
62
62
|
console.log(" Model details:");
|
|
63
63
|
console.log(` - Name: ${model.name}`);
|
|
@@ -68,12 +68,12 @@ try {
|
|
|
68
68
|
console.log(` - Checksum: ${model.sha256Checksum.slice(0, 16)}...`);
|
|
69
69
|
console.log();
|
|
70
70
|
}
|
|
71
|
-
console.log("QVAC model registry query examples completed successfully!");
|
|
71
|
+
console.log("▸ QVAC model registry query examples completed successfully!");
|
|
72
72
|
void close();
|
|
73
73
|
process.exit(0);
|
|
74
74
|
}
|
|
75
75
|
catch (error) {
|
|
76
|
-
console.error("
|
|
76
|
+
console.error("✖", error);
|
|
77
77
|
process.exit(1);
|
|
78
78
|
}
|
|
79
79
|
function formatSize(bytes) {
|
|
@@ -2,20 +2,24 @@ import { LLAMA_3_2_1B_INST_Q4_0, downloadAsset } from "@qvac/sdk";
|
|
|
2
2
|
await downloadAsset({
|
|
3
3
|
assetSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
4
4
|
seed: true,
|
|
5
|
-
onProgress: (
|
|
6
|
-
|
|
5
|
+
onProgress: (p) => {
|
|
6
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
7
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
8
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
9
|
+
if (p.percentage >= 100)
|
|
10
|
+
process.stderr.write("\n");
|
|
7
11
|
},
|
|
8
12
|
})
|
|
9
13
|
.then(() => {
|
|
10
|
-
console.log("
|
|
11
|
-
console.log("
|
|
14
|
+
console.log("▸ Model loaded and seeding started!");
|
|
15
|
+
console.log("▸ Seeding service is running... Press Ctrl+C to stop");
|
|
12
16
|
})
|
|
13
17
|
.catch((error) => {
|
|
14
|
-
console.error("
|
|
18
|
+
console.error("✖", error);
|
|
15
19
|
process.exit(1);
|
|
16
20
|
});
|
|
17
21
|
process.on("SIGINT", () => {
|
|
18
|
-
console.log("\n
|
|
22
|
+
console.log("\n▸ Seeding service stopped");
|
|
19
23
|
process.exit(0);
|
|
20
24
|
});
|
|
21
25
|
process.stdin.resume();
|
|
@@ -3,14 +3,18 @@ try {
|
|
|
3
3
|
// Load a model
|
|
4
4
|
const modelId = await loadModel({
|
|
5
5
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
6
|
-
onProgress: (
|
|
7
|
-
|
|
6
|
+
onProgress: (p) => {
|
|
7
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
8
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
9
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
10
|
+
if (p.percentage >= 100)
|
|
11
|
+
process.stderr.write("\n");
|
|
8
12
|
},
|
|
9
13
|
});
|
|
10
|
-
console.log("
|
|
11
|
-
console.log(
|
|
14
|
+
console.log("▸ Model loaded\n");
|
|
15
|
+
console.log(`▸ Lifecycle state: ${await state()}\n`);
|
|
12
16
|
// Run a completion before suspending
|
|
13
|
-
console.log("
|
|
17
|
+
console.log("▸ Completion before suspend");
|
|
14
18
|
const result1 = completion({
|
|
15
19
|
modelId,
|
|
16
20
|
history: [{ role: "user", content: "Say hello in one word" }],
|
|
@@ -19,11 +23,11 @@ try {
|
|
|
19
23
|
for await (const token of result1.tokenStream) {
|
|
20
24
|
process.stdout.write(token);
|
|
21
25
|
}
|
|
22
|
-
console.log("
|
|
26
|
+
console.log("");
|
|
23
27
|
// Suspend all networking and storage (e.g. app going to background)
|
|
24
|
-
console.log("
|
|
28
|
+
console.log("▸ Suspending...");
|
|
25
29
|
await suspend();
|
|
26
|
-
console.log(
|
|
30
|
+
console.log(`▸ Lifecycle state: ${await state()}\n`);
|
|
27
31
|
try {
|
|
28
32
|
await completion({
|
|
29
33
|
modelId,
|
|
@@ -34,21 +38,21 @@ try {
|
|
|
34
38
|
catch (error) {
|
|
35
39
|
const name = error.name;
|
|
36
40
|
if (name === "LIFECYCLE_OPERATION_BLOCKED") {
|
|
37
|
-
console.log(
|
|
41
|
+
console.log(`▸ Operation blocked while suspended (${name})`);
|
|
38
42
|
}
|
|
39
43
|
else {
|
|
40
44
|
throw error;
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
// Simulate time in background
|
|
44
|
-
console.log("\n
|
|
48
|
+
console.log("\n▸ Simulating 3 seconds in background...");
|
|
45
49
|
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
46
50
|
// Resume when returning to foreground
|
|
47
|
-
console.log("
|
|
51
|
+
console.log("▸ Resuming...");
|
|
48
52
|
await resume();
|
|
49
|
-
console.log(
|
|
53
|
+
console.log(`▸ Lifecycle state: ${await state()}\n`);
|
|
50
54
|
// Run another completion after resuming
|
|
51
|
-
console.log("
|
|
55
|
+
console.log("▸ Completion after resume");
|
|
52
56
|
const result2 = completion({
|
|
53
57
|
modelId,
|
|
54
58
|
history: [{ role: "user", content: "Say goodbye in one word" }],
|
|
@@ -57,12 +61,12 @@ try {
|
|
|
57
61
|
for await (const token of result2.tokenStream) {
|
|
58
62
|
process.stdout.write(token);
|
|
59
63
|
}
|
|
60
|
-
console.log("
|
|
64
|
+
console.log("");
|
|
61
65
|
await unloadModel({ modelId });
|
|
62
|
-
console.log("
|
|
66
|
+
console.log("▸ Model unloaded");
|
|
63
67
|
process.exit(0);
|
|
64
68
|
}
|
|
65
69
|
catch (error) {
|
|
66
|
-
console.error("
|
|
70
|
+
console.error("✖", error);
|
|
67
71
|
process.exit(1);
|
|
68
72
|
}
|
|
@@ -7,9 +7,15 @@ try {
|
|
|
7
7
|
ctx_size: 4096,
|
|
8
8
|
tools: true,
|
|
9
9
|
},
|
|
10
|
-
onProgress: (
|
|
10
|
+
onProgress: (p) => {
|
|
11
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
12
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
13
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
14
|
+
if (p.percentage >= 100)
|
|
15
|
+
process.stderr.write("\n");
|
|
16
|
+
},
|
|
11
17
|
});
|
|
12
|
-
console.log(
|
|
18
|
+
console.log(`▸ Model loaded successfully! Model ID: ${modelId}`);
|
|
13
19
|
const history = [
|
|
14
20
|
{
|
|
15
21
|
role: "system",
|
|
@@ -20,8 +26,8 @@ try {
|
|
|
20
26
|
content: "What's the weather in Tokyo and my horoscope for Aquarius?",
|
|
21
27
|
},
|
|
22
28
|
];
|
|
23
|
-
console.log("\n
|
|
24
|
-
console.log("(Streaming with tool definitions in prompt)\n");
|
|
29
|
+
console.log("\n▸ AI Response:");
|
|
30
|
+
console.log("▸ (Streaming with tool definitions in prompt)\n");
|
|
25
31
|
const result = completion({ modelId, history, stream: true, tools });
|
|
26
32
|
const tokensTask = (async () => {
|
|
27
33
|
for await (const token of result.tokenStream) {
|
|
@@ -30,38 +36,38 @@ try {
|
|
|
30
36
|
})();
|
|
31
37
|
const toolsTask = (async () => {
|
|
32
38
|
for await (const evt of result.toolCallStream) {
|
|
33
|
-
console.log(`\n\n
|
|
34
|
-
console.log(
|
|
39
|
+
console.log(`\n\n▸ Tool Call Detected: ${evt.call.name}(${JSON.stringify(evt.call.arguments)})`);
|
|
40
|
+
console.log(`▸ ID: ${evt.call.id}`);
|
|
35
41
|
}
|
|
36
42
|
})();
|
|
37
43
|
await Promise.all([tokensTask, toolsTask]);
|
|
38
44
|
const stats = await result.stats;
|
|
39
45
|
const toolCalls = await result.toolCalls;
|
|
40
|
-
console.log("\n\n
|
|
46
|
+
console.log("\n\n▸ Parsed Tool Calls:");
|
|
41
47
|
if (toolCalls.length > 0) {
|
|
42
48
|
for (const call of toolCalls) {
|
|
43
|
-
console.log(
|
|
49
|
+
console.log(`▸ ${call.name}(${JSON.stringify(call.arguments)})`);
|
|
44
50
|
const schema = toolSchemas[call.name];
|
|
45
51
|
if (schema) {
|
|
46
52
|
const validated = schema.safeParse(call.arguments);
|
|
47
53
|
if (validated.success) {
|
|
48
|
-
console.log(
|
|
54
|
+
console.log(`▸ Arguments validated with Zod`);
|
|
49
55
|
}
|
|
50
56
|
else {
|
|
51
|
-
console.log(
|
|
57
|
+
console.log(`✖ Validation failed:`, validated.error);
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
else {
|
|
57
|
-
console.log("
|
|
63
|
+
console.log("▸ No tool calls detected in response");
|
|
58
64
|
}
|
|
59
|
-
console.log("\n
|
|
65
|
+
console.log("\n▸ Performance Stats:", stats);
|
|
60
66
|
if (toolCalls.length > 0) {
|
|
61
|
-
console.log("\n\n
|
|
67
|
+
console.log("\n\n▸ Simulating Tool Execution...");
|
|
62
68
|
const toolResults = toolCalls.map((call) => {
|
|
63
69
|
const result = mockExecute(call.name, call.arguments);
|
|
64
|
-
console.log(
|
|
70
|
+
console.log(`▸ ${call.name}: ${result}`);
|
|
65
71
|
return { toolCallId: call.id, result };
|
|
66
72
|
});
|
|
67
73
|
history.push({
|
|
@@ -74,7 +80,7 @@ try {
|
|
|
74
80
|
content: toolResult.result,
|
|
75
81
|
});
|
|
76
82
|
}
|
|
77
|
-
console.log("\n\n
|
|
83
|
+
console.log("\n\n▸ Follow-up Response with Tool Results:");
|
|
78
84
|
const followUpResult = completion({
|
|
79
85
|
modelId,
|
|
80
86
|
history,
|
|
@@ -85,12 +91,12 @@ try {
|
|
|
85
91
|
process.stdout.write(token);
|
|
86
92
|
}
|
|
87
93
|
const followUpStats = await followUpResult.stats;
|
|
88
|
-
console.log("\n\n
|
|
94
|
+
console.log("\n\n▸ Follow-up Stats:", followUpStats);
|
|
89
95
|
}
|
|
90
|
-
console.log("\n\n
|
|
96
|
+
console.log("\n\n▸ Completed!");
|
|
91
97
|
await unloadModel({ modelId, clearStorage: false });
|
|
92
98
|
}
|
|
93
99
|
catch (error) {
|
|
94
|
-
console.error("
|
|
100
|
+
console.error("✖", error);
|
|
95
101
|
process.exit(1);
|
|
96
102
|
}
|
|
@@ -24,9 +24,15 @@ try {
|
|
|
24
24
|
modelSrc,
|
|
25
25
|
modelType: "llamacpp-completion",
|
|
26
26
|
modelConfig: { ctx_size: 4096, tools: true },
|
|
27
|
-
onProgress: (
|
|
27
|
+
onProgress: (p) => {
|
|
28
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
29
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
30
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
31
|
+
if (p.percentage >= 100)
|
|
32
|
+
process.stderr.write("\n");
|
|
33
|
+
},
|
|
28
34
|
});
|
|
29
|
-
console.log(
|
|
35
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
30
36
|
const history = [
|
|
31
37
|
{
|
|
32
38
|
role: "system",
|
|
@@ -46,27 +52,27 @@ try {
|
|
|
46
52
|
const toolsTask = (async () => {
|
|
47
53
|
for await (const evt of result.toolCallStream) {
|
|
48
54
|
if (evt.type === "toolCall") {
|
|
49
|
-
console.log(`\n
|
|
55
|
+
console.log(`\n▸ ${evt.call.name}(${JSON.stringify(evt.call.arguments)})`);
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
58
|
})();
|
|
53
59
|
await Promise.all([tokensTask, toolsTask]);
|
|
54
60
|
const toolCalls = await result.toolCalls;
|
|
55
|
-
console.log("\n\
|
|
61
|
+
console.log("\n\n▸ Final tool calls:");
|
|
56
62
|
if (toolCalls.length > 0) {
|
|
57
63
|
for (const call of toolCalls) {
|
|
58
|
-
console.log(
|
|
64
|
+
console.log(`▸ ${call.name}(${JSON.stringify(call.arguments)})`);
|
|
59
65
|
const toolResult = mockExecute(call.name, call.arguments);
|
|
60
|
-
console.log(
|
|
66
|
+
console.log(`▸ result: ${toolResult}`);
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
69
|
else {
|
|
64
|
-
console.log("
|
|
70
|
+
console.log("▸ (none)");
|
|
65
71
|
}
|
|
66
72
|
await unloadModel({ modelId, clearStorage: false });
|
|
67
73
|
}
|
|
68
74
|
catch (error) {
|
|
69
|
-
console.error("
|
|
75
|
+
console.error("✖", error);
|
|
70
76
|
if (modelId)
|
|
71
77
|
await unloadModel({ modelId, clearStorage: false }).catch(() => { });
|
|
72
78
|
process.exit(1);
|
|
@@ -15,9 +15,15 @@ try {
|
|
|
15
15
|
modelId = await loadModel({
|
|
16
16
|
modelSrc: GPT_OSS_20B_INST_Q4_K_M,
|
|
17
17
|
modelConfig: { ctx_size: 4096, tools: true },
|
|
18
|
-
onProgress: (
|
|
18
|
+
onProgress: (p) => {
|
|
19
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
20
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
21
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
22
|
+
if (p.percentage >= 100)
|
|
23
|
+
process.stderr.write("\n");
|
|
24
|
+
},
|
|
19
25
|
});
|
|
20
|
-
console.log(
|
|
26
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
21
27
|
const history = [
|
|
22
28
|
{
|
|
23
29
|
role: "system",
|
|
@@ -29,20 +35,20 @@ try {
|
|
|
29
35
|
},
|
|
30
36
|
];
|
|
31
37
|
for (let turn = 1; turn <= MAX_TURNS; turn++) {
|
|
32
|
-
console.log(`\n========== TURN ${turn} ==========`);
|
|
38
|
+
console.log(`\n▸ ========== TURN ${turn} ==========`);
|
|
33
39
|
const result = completion({ modelId, history, tools, stream: true });
|
|
34
40
|
for await (const token of result.tokenStream) {
|
|
35
41
|
process.stdout.write(token);
|
|
36
42
|
}
|
|
37
43
|
console.log();
|
|
38
44
|
const final = await result.final;
|
|
39
|
-
console.log(`\n--- TURN ${turn} SUMMARY ---`);
|
|
40
|
-
console.log(
|
|
45
|
+
console.log(`\n▸ --- TURN ${turn} SUMMARY ---`);
|
|
46
|
+
console.log(`▸ [sdk toolCalls] ${final.toolCalls.length}`);
|
|
41
47
|
for (const call of final.toolCalls) {
|
|
42
|
-
console.log(
|
|
48
|
+
console.log(`▸ ${call.name}(${JSON.stringify(call.arguments)})`);
|
|
43
49
|
}
|
|
44
50
|
if (final.toolCalls.length === 0) {
|
|
45
|
-
console.log(`\n
|
|
51
|
+
console.log(`\n▸ Final response received — exiting loop.`);
|
|
46
52
|
break;
|
|
47
53
|
}
|
|
48
54
|
// Raw, not result.text — GPT-OSS needs its own framed output in history
|
|
@@ -51,31 +57,31 @@ try {
|
|
|
51
57
|
history.push({ role: "assistant", content: assistantContent });
|
|
52
58
|
for (const call of final.toolCalls) {
|
|
53
59
|
const toolResult = mockExecute(call.name, call.arguments);
|
|
54
|
-
console.log(
|
|
60
|
+
console.log(`▸ mock-executed ${call.name}: ${toolResult}`);
|
|
55
61
|
history.push({ role: "tool", content: toolResult });
|
|
56
62
|
}
|
|
57
63
|
if (turn === MAX_TURNS) {
|
|
58
|
-
console.log(`\n
|
|
64
|
+
console.log(`\n▸ MAX_TURNS (${MAX_TURNS}) reached — stopping.`);
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
|
-
console.log(`\n========== HISTORY ==========`);
|
|
67
|
+
console.log(`\n▸ ========== HISTORY ==========`);
|
|
62
68
|
for (const msg of history) {
|
|
63
69
|
const preview = msg.content.slice(0, 120).replace(/\n/g, "\\n");
|
|
64
|
-
console.log(
|
|
70
|
+
console.log(`▸ [${msg.role}] ${preview}${msg.content.length > 120 ? "…" : ""}`);
|
|
65
71
|
}
|
|
66
72
|
}
|
|
67
73
|
catch (error) {
|
|
68
|
-
console.error("
|
|
74
|
+
console.error("✖", error);
|
|
69
75
|
process.exit(1);
|
|
70
76
|
}
|
|
71
77
|
finally {
|
|
72
78
|
if (modelId) {
|
|
73
79
|
try {
|
|
74
80
|
await unloadModel({ modelId, clearStorage: false });
|
|
75
|
-
console.log(`\n[unload] done`);
|
|
81
|
+
console.log(`\n▸ [unload] done`);
|
|
76
82
|
}
|
|
77
83
|
catch (unloadError) {
|
|
78
|
-
console.error("[unload] failed:", unloadError);
|
|
84
|
+
console.error("✖ [unload] failed:", unloadError);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
}
|
|
@@ -6,9 +6,15 @@ try {
|
|
|
6
6
|
modelSrc: LFM_TOOL_HF,
|
|
7
7
|
modelType: "llamacpp-completion",
|
|
8
8
|
modelConfig: { ctx_size: 4096, tools: true },
|
|
9
|
-
onProgress: (
|
|
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");
|
|
15
|
+
},
|
|
10
16
|
});
|
|
11
|
-
console.log(
|
|
17
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
12
18
|
const history = [
|
|
13
19
|
{
|
|
14
20
|
role: "system",
|
|
@@ -19,7 +25,7 @@ try {
|
|
|
19
25
|
content: "What's the weather in Tokyo and my horoscope for Aquarius?",
|
|
20
26
|
},
|
|
21
27
|
];
|
|
22
|
-
console.log("\n
|
|
28
|
+
console.log("\n▸ Streaming...\n");
|
|
23
29
|
const result = completion({ modelId, history, stream: true, tools });
|
|
24
30
|
const tokensTask = (async () => {
|
|
25
31
|
for await (const token of result.tokenStream) {
|
|
@@ -28,23 +34,23 @@ try {
|
|
|
28
34
|
})();
|
|
29
35
|
const toolsTask = (async () => {
|
|
30
36
|
for await (const evt of result.toolCallStream) {
|
|
31
|
-
console.log(`\n
|
|
37
|
+
console.log(`\n▸ ${evt.call.name}(${JSON.stringify(evt.call.arguments)})`);
|
|
32
38
|
}
|
|
33
39
|
})();
|
|
34
40
|
await Promise.all([tokensTask, toolsTask]);
|
|
35
41
|
const toolCalls = await result.toolCalls;
|
|
36
|
-
console.log("\n\n
|
|
42
|
+
console.log("\n\n▸ Final tool calls:");
|
|
37
43
|
if (toolCalls.length > 0) {
|
|
38
44
|
for (const call of toolCalls) {
|
|
39
|
-
console.log(
|
|
45
|
+
console.log(`▸ ${call.name}(${JSON.stringify(call.arguments)})`);
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
else {
|
|
43
|
-
console.log("
|
|
49
|
+
console.log("▸ (none)");
|
|
44
50
|
}
|
|
45
51
|
await unloadModel({ modelId });
|
|
46
52
|
}
|
|
47
53
|
catch (error) {
|
|
48
|
-
console.error("
|
|
54
|
+
console.error("✖", error);
|
|
49
55
|
process.exit(1);
|
|
50
56
|
}
|
|
@@ -20,9 +20,15 @@ try {
|
|
|
20
20
|
modelSrc,
|
|
21
21
|
modelType: "llamacpp-completion",
|
|
22
22
|
modelConfig: { ctx_size: 4096, tools: true },
|
|
23
|
-
onProgress: (
|
|
23
|
+
onProgress: (p) => {
|
|
24
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
25
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
26
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
27
|
+
if (p.percentage >= 100)
|
|
28
|
+
process.stderr.write("\n");
|
|
29
|
+
},
|
|
24
30
|
});
|
|
25
|
-
console.log(
|
|
31
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
26
32
|
const history = [
|
|
27
33
|
{
|
|
28
34
|
role: "system",
|
|
@@ -42,27 +48,27 @@ try {
|
|
|
42
48
|
const toolsTask = (async () => {
|
|
43
49
|
for await (const evt of result.toolCallStream) {
|
|
44
50
|
if (evt.type === "toolCall") {
|
|
45
|
-
console.log(`\n
|
|
51
|
+
console.log(`\n▸ ${evt.call.name}(${JSON.stringify(evt.call.arguments)})`);
|
|
46
52
|
}
|
|
47
53
|
}
|
|
48
54
|
})();
|
|
49
55
|
await Promise.all([tokensTask, toolsTask]);
|
|
50
56
|
const toolCalls = await result.toolCalls;
|
|
51
|
-
console.log("\n\
|
|
57
|
+
console.log("\n\n▸ Final tool calls:");
|
|
52
58
|
if (toolCalls.length > 0) {
|
|
53
59
|
for (const call of toolCalls) {
|
|
54
|
-
console.log(
|
|
60
|
+
console.log(`▸ ${call.name}(${JSON.stringify(call.arguments)})`);
|
|
55
61
|
const toolResult = mockExecute(call.name, call.arguments);
|
|
56
|
-
console.log(
|
|
62
|
+
console.log(`▸ result: ${toolResult}`);
|
|
57
63
|
}
|
|
58
64
|
}
|
|
59
65
|
else {
|
|
60
|
-
console.log("
|
|
66
|
+
console.log("▸ (none)");
|
|
61
67
|
}
|
|
62
68
|
await unloadModel({ modelId, clearStorage: false });
|
|
63
69
|
}
|
|
64
70
|
catch (error) {
|
|
65
|
-
console.error("
|
|
71
|
+
console.error("✖", error);
|
|
66
72
|
if (modelId)
|
|
67
73
|
await unloadModel({ modelId, clearStorage: false }).catch(() => { });
|
|
68
74
|
process.exit(1);
|
|
@@ -21,24 +21,27 @@ if (!args[0]) {
|
|
|
21
21
|
const audioFilePath = args[0];
|
|
22
22
|
const parakeetModelSrc = args[1] ?? PARAKEET_CTC_0_6B_Q8_0;
|
|
23
23
|
try {
|
|
24
|
-
console.log("Loading Parakeet CTC model...");
|
|
24
|
+
console.log("▸ Loading Parakeet CTC model...");
|
|
25
25
|
const modelId = await loadModel({
|
|
26
26
|
modelSrc: parakeetModelSrc,
|
|
27
27
|
modelType: "parakeet-transcription",
|
|
28
|
-
onProgress: (
|
|
29
|
-
|
|
28
|
+
onProgress: (p) => {
|
|
29
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
30
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
31
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
32
|
+
if (p.percentage >= 100)
|
|
33
|
+
process.stderr.write("\n");
|
|
30
34
|
},
|
|
31
35
|
});
|
|
32
|
-
console.log(
|
|
33
|
-
console.log("Transcribing audio...");
|
|
36
|
+
console.log(`▸ Parakeet CTC model loaded with ID: ${modelId}`);
|
|
37
|
+
console.log("▸ Transcribing audio...");
|
|
34
38
|
const text = await transcribe({ modelId, audioChunk: audioFilePath });
|
|
35
|
-
console.log("Transcription result:");
|
|
36
39
|
console.log(text);
|
|
37
|
-
console.log("Unloading model...");
|
|
40
|
+
console.log("▸ Unloading model...");
|
|
38
41
|
await unloadModel({ modelId });
|
|
39
|
-
console.log("Done");
|
|
42
|
+
console.log("▸ Done");
|
|
40
43
|
}
|
|
41
44
|
catch (error) {
|
|
42
|
-
console.error("
|
|
45
|
+
console.error("✖", error);
|
|
43
46
|
process.exit(1);
|
|
44
47
|
}
|
|
@@ -23,22 +23,28 @@ try {
|
|
|
23
23
|
throw new Error("FFmpeg not found");
|
|
24
24
|
}
|
|
25
25
|
catch {
|
|
26
|
-
console.error("FFmpeg is required. Install it and try again.");
|
|
26
|
+
console.error("✖ FFmpeg is required. Install it and try again.");
|
|
27
27
|
process.exit(1);
|
|
28
28
|
}
|
|
29
|
-
console.log("Loading Parakeet model...");
|
|
29
|
+
console.log("▸ Loading Parakeet model...");
|
|
30
30
|
const modelId = await loadModel({
|
|
31
31
|
modelSrc: PARAKEET_TDT_0_6B_V3_Q8_0,
|
|
32
|
-
onProgress: (p) =>
|
|
32
|
+
onProgress: (p) => {
|
|
33
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
34
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
35
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
36
|
+
if (p.percentage >= 100)
|
|
37
|
+
process.stderr.write("\n");
|
|
38
|
+
},
|
|
33
39
|
});
|
|
34
|
-
console.log("Model loaded
|
|
40
|
+
console.log("▸ Model loaded.");
|
|
35
41
|
const ffmpeg = startMicrophone({
|
|
36
42
|
sampleRate: SAMPLE_RATE,
|
|
37
43
|
format: "s16le",
|
|
38
44
|
});
|
|
39
45
|
let buffer = Buffer.alloc(0);
|
|
40
46
|
let processing = false;
|
|
41
|
-
console.log("Listening... speak and pause to see transcriptions
|
|
47
|
+
console.log("▸ Listening... speak and pause to see transcriptions.");
|
|
42
48
|
ffmpeg.stdout.on("data", (chunk) => {
|
|
43
49
|
buffer = Buffer.concat([buffer, chunk]);
|
|
44
50
|
if (buffer.length >= CHUNK_SIZE && !processing) {
|
|
@@ -49,11 +55,11 @@ ffmpeg.stdout.on("data", (chunk) => {
|
|
|
49
55
|
try {
|
|
50
56
|
const text = await transcribe({ modelId, audioChunk });
|
|
51
57
|
if (text.trim() && !text.includes("[No speech detected]")) {
|
|
52
|
-
console.log(
|
|
58
|
+
console.log(text.trim());
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
catch (err) {
|
|
56
|
-
console.error("
|
|
62
|
+
console.error("✖", err instanceof Error ? err.message : err);
|
|
57
63
|
}
|
|
58
64
|
finally {
|
|
59
65
|
processing = false;
|
|
@@ -62,10 +68,10 @@ ffmpeg.stdout.on("data", (chunk) => {
|
|
|
62
68
|
}
|
|
63
69
|
});
|
|
64
70
|
async function cleanup() {
|
|
65
|
-
console.log("\n
|
|
71
|
+
console.log("\n▸ Stopping...");
|
|
66
72
|
ffmpeg.kill();
|
|
67
73
|
await unloadModel({ modelId });
|
|
68
|
-
console.log("Done.");
|
|
74
|
+
console.log("▸ Done.");
|
|
69
75
|
}
|
|
70
76
|
process.on("SIGINT", () => void cleanup());
|
|
71
77
|
process.on("SIGTERM", () => void cleanup());
|