@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.
Files changed (226) hide show
  1. package/NOTICE +95 -1151
  2. package/README.md +1 -2
  3. package/bare-imports.json +0 -5
  4. package/dist/client/api/bci-transcribe.js +2 -1
  5. package/dist/client/api/download-asset.js +2 -1
  6. package/dist/client/api/finetune.js +6 -5
  7. package/dist/client/api/index.d.ts +1 -0
  8. package/dist/client/api/index.js +1 -0
  9. package/dist/client/api/load-model.d.ts +11 -8
  10. package/dist/client/api/load-model.js +6 -6
  11. package/dist/client/api/subscribe-logs.d.ts +28 -0
  12. package/dist/client/api/subscribe-logs.js +43 -0
  13. package/dist/client/api/text-to-speech.js +2 -1
  14. package/dist/client/config-loader/config-utils.js +2 -4
  15. package/dist/client/config-loader/resolve-config.bare.js +4 -3
  16. package/dist/client/parse-input.d.ts +3 -0
  17. package/dist/client/parse-input.js +14 -0
  18. package/dist/client/rpc/expo-rpc-client.js +2 -11
  19. package/dist/client/rpc/node-rpc-client.js +8 -2
  20. package/dist/client/rpc/rpc-client.js +39 -7
  21. package/dist/commands/bundle/constants.js +2 -1
  22. package/dist/commands/bundle/entry-gen.d.ts +1 -1
  23. package/dist/commands/bundle/entry-gen.js +6 -6
  24. package/dist/commands/bundle/index.js +3 -1
  25. package/dist/commands/bundle/resolve-sdk-import.d.ts +6 -0
  26. package/dist/commands/bundle/resolve-sdk-import.js +60 -0
  27. package/dist/examples/bci/bci-filesystem-streaming.js +14 -14
  28. package/dist/examples/bci/bci-filesystem.js +17 -13
  29. package/dist/examples/cache-management.js +38 -38
  30. package/dist/examples/cancel-by-request-id.js +9 -9
  31. package/dist/examples/completion-events.js +20 -14
  32. package/dist/examples/completion-stop-reason.js +13 -7
  33. package/dist/examples/concurrent-completion-collision.js +7 -7
  34. package/dist/examples/config-reload.js +7 -8
  35. package/dist/examples/default-config-usage.js +4 -4
  36. package/dist/examples/delegated-inference/composite.js +14 -10
  37. package/dist/examples/delegated-inference/consumer-profiled.js +13 -13
  38. package/dist/examples/delegated-inference/consumer.js +16 -12
  39. package/dist/examples/delegated-inference/provider.js +12 -12
  40. package/dist/examples/diffusion-esrgan-upscale.js +19 -15
  41. package/dist/examples/diffusion-flux2-klein-img2img.js +16 -11
  42. package/dist/examples/diffusion-flux2-klein.js +14 -9
  43. package/dist/examples/diffusion-img2img.js +9 -10
  44. package/dist/examples/diffusion-img2vid.js +17 -12
  45. package/dist/examples/diffusion-simple.js +1 -1
  46. package/dist/examples/diffusion-txt2img.js +14 -9
  47. package/dist/examples/diffusion-txt2vid.js +15 -10
  48. package/dist/examples/download-with-blind-relays.js +16 -21
  49. package/dist/examples/download-with-cancel.js +15 -16
  50. package/dist/examples/embed-multi-gpu.js +3 -4
  51. package/dist/examples/embed-p2p.js +11 -7
  52. package/dist/examples/finetune/llamacpp-finetune.js +7 -7
  53. package/dist/examples/kv-cache-cleanup.js +35 -35
  54. package/dist/examples/kv-cache-custom-key.js +24 -24
  55. package/dist/examples/kv-cache-example.js +9 -9
  56. package/dist/examples/llamacpp-cache.js +18 -14
  57. package/dist/examples/llamacpp-dynamic-tools.js +15 -9
  58. package/dist/examples/llamacpp-filesystem.js +15 -9
  59. package/dist/examples/llamacpp-http.js +12 -10
  60. package/dist/examples/llamacpp-multi-gpu.js +4 -4
  61. package/dist/examples/llamacpp-multimodal.js +13 -9
  62. package/dist/examples/llamacpp-p2p.js +8 -4
  63. package/dist/examples/llamacpp-sharded.js +5 -5
  64. package/dist/examples/llamacpp-structured-output.js +15 -9
  65. package/dist/examples/logging-file-transport.js +3 -3
  66. package/dist/examples/logging-global.d.ts +2 -0
  67. package/dist/examples/logging-global.js +34 -0
  68. package/dist/examples/logging-streaming.js +7 -10
  69. package/dist/examples/mcp-websearch.js +24 -18
  70. package/dist/examples/multi-model-demo.js +17 -11
  71. package/dist/examples/ocr-fasttext.js +14 -16
  72. package/dist/examples/parallel-download.js +7 -7
  73. package/dist/examples/plugins.js +40 -28
  74. package/dist/examples/profiling/basic.js +16 -10
  75. package/dist/examples/profiling/per-call.js +17 -11
  76. package/dist/examples/quickstart.bare.d.ts +2 -0
  77. package/dist/examples/quickstart.bare.js +18 -0
  78. package/dist/examples/quickstart.js +10 -3
  79. package/dist/examples/rag/rag-chromadb.js +18 -14
  80. package/dist/examples/rag/rag-hyperdb/cancellation.js +17 -14
  81. package/dist/examples/rag/rag-hyperdb/ingest.js +14 -12
  82. package/dist/examples/rag/rag-hyperdb/pipeline.js +19 -17
  83. package/dist/examples/rag/rag-hyperdb/workspaces.js +31 -27
  84. package/dist/examples/rag/rag-lancedb.js +12 -8
  85. package/dist/examples/rag/rag-sqlite.js +11 -7
  86. package/dist/examples/registry-query.js +17 -17
  87. package/dist/examples/seed-p2p.js +10 -6
  88. package/dist/examples/suspend-resume.js +20 -16
  89. package/dist/examples/tools/llamacpp-native-tools.js +24 -18
  90. package/dist/examples/tools/llamacpp-tools-gemma4.js +14 -8
  91. package/dist/examples/tools/llamacpp-tools-harmony-multiturn.js +20 -14
  92. package/dist/examples/tools/llamacpp-tools-pythonic.js +14 -8
  93. package/dist/examples/tools/llamacpp-tools-qwen35.js +14 -8
  94. package/dist/examples/transcription/parakeet-ctc-filesystem.js +12 -9
  95. package/dist/examples/transcription/parakeet-microphone-record.js +15 -9
  96. package/dist/examples/transcription/parakeet-microphone-stream.js +15 -9
  97. package/dist/examples/transcription/parakeet-sortformer-streaming.js +12 -6
  98. package/dist/examples/transcription/parakeet-sortformer.js +3 -5
  99. package/dist/examples/transcription/parakeet-tdt-filesystem.js +13 -10
  100. package/dist/examples/transcription/whispercpp-filesystem-streaming.js +16 -17
  101. package/dist/examples/transcription/whispercpp-filesystem.js +14 -10
  102. package/dist/examples/transcription/whispercpp-microphone-conversation.js +10 -10
  103. package/dist/examples/transcription/whispercpp-microphone-record.js +6 -6
  104. package/dist/examples/transcription/whispercpp-prompt.js +14 -10
  105. package/dist/examples/translation/translation-bergamot-batch.js +11 -7
  106. package/dist/examples/translation/translation-bergamot-pivot.js +13 -9
  107. package/dist/examples/translation/translation-bergamot.js +8 -4
  108. package/dist/examples/translation/translation-indic.js +8 -4
  109. package/dist/examples/translation/translation-llm-afriquegemma.js +7 -3
  110. package/dist/examples/translation/translation-llm-context.js +8 -4
  111. package/dist/examples/translation/translation-llm.js +7 -3
  112. package/dist/examples/translation/translation-stream.js +4 -4
  113. package/dist/examples/tts/chatterbox.js +19 -11
  114. package/dist/examples/tts/llm-to-tts-streaming.js +27 -14
  115. package/dist/examples/tts/supertonic-multilingual.js +18 -14
  116. package/dist/examples/tts/supertonic.js +19 -15
  117. package/dist/examples/tts/utils.js +1 -1
  118. package/dist/examples/vla-pi05.js +18 -14
  119. package/dist/examples/vla-smolvla.js +18 -14
  120. package/dist/examples/voice-assistant/voice-assistant.js +12 -12
  121. package/dist/index.d.ts +3 -4
  122. package/dist/index.js +3 -4
  123. package/dist/logging/client-logger.js +2 -1
  124. package/dist/logging/index.d.ts +1 -1
  125. package/dist/logging/index.js +1 -1
  126. package/dist/logging/namespaces.d.ts +1 -0
  127. package/dist/logging/namespaces.js +2 -0
  128. package/dist/logging/server-logger.js +1 -4
  129. package/dist/logging/utils.js +6 -1
  130. package/dist/models/registry/index.d.ts +17 -0
  131. package/dist/models/registry/index.js +20 -1
  132. package/dist/models/registry/models.d.ts +1062 -38
  133. package/dist/models/registry/models.js +3546 -2490
  134. package/dist/pear/pre.js +2 -2
  135. package/dist/schemas/bci-config.d.ts +37 -0
  136. package/dist/schemas/bci-config.js +2 -0
  137. package/dist/schemas/bci.d.ts +2 -0
  138. package/dist/schemas/common.d.ts +171 -94
  139. package/dist/schemas/completion-stream.d.ts +6 -3
  140. package/dist/schemas/completion-stream.js +10 -2
  141. package/dist/schemas/download-asset.d.ts +5 -5
  142. package/dist/schemas/engine-addon-map.d.ts +1 -1
  143. package/dist/schemas/engine-addon-map.js +6 -3
  144. package/dist/schemas/error.js +6 -1
  145. package/dist/schemas/llamacpp-config.d.ts +27 -8
  146. package/dist/schemas/llamacpp-config.js +19 -2
  147. package/dist/schemas/load-model.d.ts +4170 -570
  148. package/dist/schemas/load-model.js +85 -26
  149. package/dist/schemas/logging-stream.js +7 -1
  150. package/dist/schemas/model-src-utils.d.ts +6 -6
  151. package/dist/schemas/model-types.d.ts +14 -15
  152. package/dist/schemas/model-types.js +10 -11
  153. package/dist/schemas/ocr.d.ts +10 -8
  154. package/dist/schemas/ocr.js +8 -6
  155. package/dist/schemas/plugin.d.ts +6 -5
  156. package/dist/schemas/plugin.js +4 -4
  157. package/dist/schemas/rag.d.ts +4 -4
  158. package/dist/schemas/registry.d.ts +8 -8
  159. package/dist/schemas/registry.js +1 -1
  160. package/dist/schemas/reload-config.d.ts +6 -6
  161. package/dist/schemas/sdcpp-config.d.ts +12 -12
  162. package/dist/schemas/sdk-config.d.ts +171 -117
  163. package/dist/schemas/sdk-config.js +5 -5
  164. package/dist/schemas/sdk-errors-client.d.ts +1 -0
  165. package/dist/schemas/sdk-errors-client.js +7 -2
  166. package/dist/schemas/text-to-speech.d.ts +157 -13
  167. package/dist/schemas/text-to-speech.js +70 -7
  168. package/dist/schemas/transcription-config.d.ts +5 -1
  169. package/dist/schemas/transcription-config.js +2 -0
  170. package/dist/schemas/transcription.d.ts +3 -0
  171. package/dist/schemas/transcription.js +2 -1
  172. package/dist/schemas/translate.d.ts +6 -6
  173. package/dist/schemas/translate.js +2 -3
  174. package/dist/schemas/translation-config.d.ts +20 -20
  175. package/dist/server/bare/hyperswarm.js +3 -3
  176. package/dist/server/bare/ops/transcribe.js +46 -15
  177. package/dist/server/bare/plugins/bci-whispercpp-transcription/args.d.ts +3 -0
  178. package/dist/server/bare/plugins/bci-whispercpp-transcription/args.js +13 -0
  179. package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.d.ts +41 -0
  180. package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.js +6 -11
  181. package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.d.ts +75 -0
  182. package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.js +11 -0
  183. package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.d.ts +16 -10
  184. package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.js +25 -18
  185. package/dist/server/bare/plugins/index.d.ts +1 -1
  186. package/dist/server/bare/plugins/index.js +1 -1
  187. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.d.ts +10 -0
  188. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.js +29 -0
  189. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +4 -22
  190. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +15 -7
  191. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +7 -7
  192. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +2 -0
  193. package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +10 -10
  194. package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +14 -8
  195. package/dist/server/bare/plugins/tts-ggml/plugin.js +12 -0
  196. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +3 -1
  197. package/dist/server/bare/registry/logging-stream-registry.d.ts +4 -2
  198. package/dist/server/bare/registry/logging-stream-registry.js +12 -7
  199. package/dist/server/bare/registry/model-config-utils.js +2 -2
  200. package/dist/server/bare/registry/registry-client.js +1 -1
  201. package/dist/server/bare/runtime-lifecycle.d.ts +9 -0
  202. package/dist/server/bare/runtime-lifecycle.js +24 -0
  203. package/dist/server/bare/types/addon-responses.d.ts +1 -0
  204. package/dist/server/env.js +7 -10
  205. package/dist/server/plugins/registry.js +2 -4
  206. package/dist/server/rpc/handlers/load-model/handler.js +2 -4
  207. package/dist/server/rpc/handlers/load-model/http.js +253 -51
  208. package/dist/server/rpc/handlers/logging-stream.js +4 -2
  209. package/dist/server/rpc/handlers/plugin-invoke.js +5 -16
  210. package/dist/server/utils/completion-normalizer.js +13 -4
  211. package/dist/server/utils/worker-lock.js +5 -5
  212. package/dist/server/worker-core.d.ts +1 -1
  213. package/dist/server/worker-core.js +28 -18
  214. package/dist/utils/errors-client.d.ts +3 -0
  215. package/dist/utils/errors-client.js +5 -0
  216. package/dist/utils/errors-server.d.ts +2 -0
  217. package/dist/utils/errors-server.js +3 -0
  218. package/dist/utils/zod-error.d.ts +3 -0
  219. package/dist/utils/zod-error.js +4 -0
  220. package/package.json +21 -24
  221. package/dist/polyfills/bare-globals.d.ts +0 -2
  222. package/dist/polyfills/bare-globals.js +0 -4
  223. package/dist/polyfills/bare-globals.noop.d.ts +0 -2
  224. package/dist/polyfills/bare-globals.noop.js +0 -1
  225. /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.d.ts +0 -0
  226. /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("=== BCI transcribeStream file test ===");
23
- console.log(`File: ${neuralFilePath}`);
24
- console.log(`Chunk size: ${CHUNK_SIZE} bytes\n`);
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(`Model loaded: ${modelId}\n`);
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...\n");
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\nNeural signal streamed: ${totalBytes} bytes`);
64
- console.log("Waiting for transcription to finish...\n");
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=== Results ===");
68
- console.log(`Transcript: ${transcript.trim() || "(no text received)"}`);
69
- console.log("\nUnloading model...");
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("❌ Error:", 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("🧠 Starting BCI transcription example...");
19
- console.log("📥 Loading BCI model...");
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: (progress) => {
35
- console.log(progress);
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(`✅ BCI model loaded with ID: ${modelId}`);
39
- console.log("🧠 Transcribing neural signal...");
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("📝 Transcription result:");
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(`\nFull transcript: ${segments
55
+ console.log(segments
52
56
  .map((s) => s.text)
53
57
  .join("")
54
- .trim()}`);
55
- console.log("🧹 Unloading BCI model...");
58
+ .trim());
59
+ console.log("▸ Unloading BCI model...");
56
60
  await unloadModel({ modelId });
57
- console.log("✅ BCI model unloaded successfully");
61
+ console.log("▸ BCI model unloaded successfully");
58
62
  process.exit(0);
59
63
  }
60
64
  catch (error) {
61
- console.error("❌ Error:", 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(` 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 ? "✅" : "❌"}`);
12
- console.log(` Is Loaded: ${info.isLoaded ? "✅" : "❌"}`);
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(` Cache Path: ${info.cacheFiles[0]?.path}`);
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(` Cached: ${cachedFiles}/${info.cacheFiles.length}`);
19
+ console.log(`▸ Cached: ${cachedFiles}/${info.cacheFiles.length}`);
20
20
  }
21
- console.log(` Actual Size: ${(info.actualSize / 1024 / 1024).toFixed(2)} MB`);
22
- console.log(` Cached At: ${info.cachedAt?.toLocaleString()}`);
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(` Loaded Instances: ${info.loadedInstances.length}`);
25
+ console.log(`▸ Loaded Instances: ${info.loadedInstances.length}`);
26
26
  info.loadedInstances.forEach((instance, i) => {
27
- console.log(` ${i + 1}. Registry ID: ${instance.registryId}`);
28
- console.log(` Loaded At: ${instance.loadedAt.toLocaleString()}`);
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("=== Model Cache Management Demo ===");
33
+ console.log("▸ Model Cache Management Demo");
34
34
  // 1. Check initial status
35
- console.log("\n1️⃣ INITIAL STATUS CHECK");
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("\n2️⃣ DOWNLOADING MODEL (not cached)");
41
- console.log(" Downloading from hyperdrive...");
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(" ✅ Download complete!");
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("\n2️⃣ MODEL ALREADY CACHED");
49
- console.log(" Skipping download...");
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("\n3️⃣ LOADING MODEL INTO MEMORY");
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(" Loading model into memory...");
56
+ console.log("▸ Loading model into memory...");
57
57
  modelId = await loadModel({
58
58
  modelSrc: WHISPER_TINY,
59
59
  });
60
- console.log(` ✅ Model loaded! ID: ${modelId}`);
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(" Model already loaded!");
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(` Using existing model ID: ${modelId}`);
75
+ console.log(`▸ Using existing model ID: ${modelId}`);
76
76
  }
77
77
  // 4. Demonstrate unload
78
- console.log("\n4️⃣ UNLOADING MODEL");
79
- console.log(" Unloading model from memory...");
78
+ console.log("\n▸ 4. UNLOADING MODEL");
79
+ console.log("▸ Unloading model from memory...");
80
80
  await unloadModel({ modelId });
81
- console.log(" ✅ Model unloaded!");
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("\n5️⃣ 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");
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("❌ Error:", 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(`requestId: ${run.requestId}`);
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("(cancel issued)");
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\nstreamed ${tokenCount} content deltas, stopReason=${endReason}.`);
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(`completed normally (${text.length} chars).`);
79
+ console.log(`▸ completed normally (${text.length} chars)`);
80
80
  }
81
81
  catch (err) {
82
82
  if (err instanceof InferenceCancelledError) {
83
- console.log(`run.text rejected: cancelled (requestId=${err.requestId})`);
84
- console.log(`partial text length: ${(err.partial.text ?? "").length}`);
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(`partial stats: ${err.partial.stats.tokensPerSecond.toFixed(1)} tok/s`);
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(`partial tool calls: ${err.partial.toolCalls.length}`);
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("Error:", 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) => console.log(`Loading: ${p.percentage.toFixed(1)}%`),
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(`✅ Model loaded: ${modelId}\n`);
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\n--- Final Result ---");
38
- console.log(`Content: ${final.contentText}\n`);
43
+ console.log("\n▸ Final result");
44
+ console.log(`▸ Content: ${final.contentText}`);
39
45
  if (final.thinkingText) {
40
- console.log(`Thinking: ${final.thinkingText}\n`);
46
+ console.log(`▸ Thinking: ${final.thinkingText}`);
41
47
  }
42
48
  if (final.stats) {
43
- console.log(`Stats: ${final.stats.tokensPerSecond?.toFixed(1)} tok/s`);
49
+ console.log(`▸ ${final.stats.tokensPerSecond?.toFixed(1)} tok/s`);
44
50
  }
45
51
  if (final.toolCalls.length > 0) {
46
- console.log(`Tool calls: ${final.toolCalls.map((c) => c.name).join(", ")}`);
52
+ console.log(`▸ Tool calls: ${final.toolCalls.map((c) => c.name).join(", ")}`);
47
53
  }
48
54
  if (final.stopReason) {
49
- console.log(`Stop reason: ${final.stopReason}`);
55
+ console.log(`▸ Stop reason: ${final.stopReason}`);
50
56
  }
51
- console.log(`Raw output length: ${final.raw.fullText.length} chars`);
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("❌ Error:", 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→ Tool: ${event.call.name}(${JSON.stringify(event.call.arguments)})`);
73
+ console.log(`\n▸ Tool: ${event.call.name}(${JSON.stringify(event.call.arguments)})`);
68
74
  break;
69
75
  case "toolError":
70
- console.warn(`\n⚠ Tool error [${event.error.code}]: ${event.error.message}`);
76
+ console.log(`\n✖ Tool error [${event.error.code}]: ${event.error.message}`);
71
77
  break;
72
78
  case "completionStats":
73
- console.log(`\n📊 ${event.stats.tokensPerSecond?.toFixed(1)} tok/s`);
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.error(`\n❌ ${event.error.message}`);
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) => console.log(`Loading: ${p.percentage.toFixed(1)}%`),
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(`✅ Model loaded: ${modelId}\n`);
37
+ console.log(`▸ Model loaded: ${modelId}\n`);
32
38
  // --- Case 1: natural EOS ---
33
- console.log("=== Case 1: natural EOS (no predict limit) ===");
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(`\nstopReason: ${final1.stopReason ?? "(undefined — natural EOS)"}`);
50
+ console.log(`\n▸ stopReason: ${final1.stopReason ?? "(undefined — natural EOS)"}`);
45
51
  // --- Case 2: predict budget exhausted → stopReason = "length" ---
46
- console.log("\n=== Case 2: predict budget hit (predict: 10) ===");
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(`\nstopReason: ${final2.stopReason}`);
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("❌ Error:", 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(` ✅ ${o.label}: ${preview}${o.text.length > 70 ? "…" : ""}`);
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(` ❌ ${o.label}: ${o.errorName}${o.code !== undefined ? ` [${o.code}]` : ""}${policy} — ${o.message}`);
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(" → Both succeeded: the second was queued behind the first and ran when the slot freed (no 52420, no addon collision).");
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(` ⚠️ ${rejected}/2 failed — the FIFO admission queue should have serialized these. Check the completion policy.`);
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(`\nrejected-by-policy error available for instanceof checks: ${typeof RequestRejectedByPolicyError === "function"}`);
93
+ console.log(`\n▸ rejected-by-policy error available for instanceof checks: ${typeof RequestRejectedByPolicyError === "function"}`);
94
94
  }
95
95
  catch (error) {
96
- console.error("❌ Error:", 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(`Config reloaded, same model ID: ${reloadedId === modelId}`);
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("❌ Error:", 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(`🔍 Using config from: ${process.env["QVAC_CONFIG_PATH"]}`);
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("🚀 Loading model with configured settings...\n");
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("\n💬 Running completion...\n");
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("❌ Error:", error);
43
+ console.error("✖", error);
44
44
  process.exit(1);
45
45
  }
46
46
  export {};