@qvac/sdk 0.11.0 → 0.12.0

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 (205) hide show
  1. package/NOTICE +1427 -39
  2. package/README.md +2 -0
  3. package/dist/client/api/classify.d.ts +23 -0
  4. package/dist/client/api/classify.js +43 -0
  5. package/dist/client/api/get-model-info.d.ts +1 -1
  6. package/dist/client/api/index.d.ts +4 -0
  7. package/dist/client/api/index.js +4 -0
  8. package/dist/client/api/load-model.js +24 -1
  9. package/dist/client/api/transcribe.d.ts +3 -0
  10. package/dist/client/api/transcribe.js +13 -2
  11. package/dist/client/api/video.d.ts +64 -0
  12. package/dist/client/api/video.js +147 -0
  13. package/dist/client/api/vla-helpers.d.ts +45 -0
  14. package/dist/client/api/vla-helpers.js +130 -0
  15. package/dist/client/api/vla.d.ts +65 -0
  16. package/dist/client/api/vla.js +109 -0
  17. package/dist/client/config-loader/resolve-config.node.d.ts +16 -0
  18. package/dist/client/config-loader/resolve-config.node.js +77 -23
  19. package/dist/client/plugins-factory.d.ts +8 -0
  20. package/dist/client/plugins-factory.js +10 -0
  21. package/dist/client/rpc/bare-client.js +62 -66
  22. package/dist/client/rpc/ensure-worker-ready.d.ts +9 -0
  23. package/dist/client/rpc/ensure-worker-ready.js +17 -0
  24. package/dist/client/rpc/node-rpc-client.js +4 -1
  25. package/dist/client/rpc/rpc-error.js +14 -1
  26. package/dist/commands/bundle/bare-pack.d.ts +13 -0
  27. package/dist/commands/bundle/bare-pack.js +54 -0
  28. package/dist/commands/bundle/constants.d.ts +7 -0
  29. package/dist/commands/bundle/constants.js +23 -0
  30. package/dist/commands/bundle/entry-gen.d.ts +2 -0
  31. package/dist/commands/bundle/entry-gen.js +48 -0
  32. package/dist/commands/bundle/index.d.ts +20 -0
  33. package/dist/commands/bundle/index.js +141 -0
  34. package/dist/commands/bundle/manifest.d.ts +21 -0
  35. package/dist/commands/bundle/manifest.js +193 -0
  36. package/dist/commands/bundle/plugins.d.ts +9 -0
  37. package/dist/commands/bundle/plugins.js +51 -0
  38. package/dist/commands/index.d.ts +5 -0
  39. package/dist/commands/index.js +2 -0
  40. package/dist/commands/verify/abi.d.ts +52 -0
  41. package/dist/commands/verify/abi.js +125 -0
  42. package/dist/commands/verify/addon-source.d.ts +43 -0
  43. package/dist/commands/verify/addon-source.js +75 -0
  44. package/dist/commands/verify/bundle-source.d.ts +12 -0
  45. package/dist/commands/verify/bundle-source.js +53 -0
  46. package/dist/commands/verify/index.d.ts +59 -0
  47. package/dist/commands/verify/index.js +371 -0
  48. package/dist/commands/verify/node-modules-source.d.ts +11 -0
  49. package/dist/commands/verify/node-modules-source.js +76 -0
  50. package/dist/commands/verify/prebuilds.d.ts +15 -0
  51. package/dist/commands/verify/prebuilds.js +39 -0
  52. package/dist/examples/classification/classify-image.d.ts +2 -0
  53. package/dist/examples/classification/classify-image.js +23 -0
  54. package/dist/examples/diffusion-txt2vid.d.ts +2 -0
  55. package/dist/examples/diffusion-txt2vid.js +81 -0
  56. package/dist/examples/plugins.js +3 -7
  57. package/dist/examples/tools/llamacpp-tools-gemma4.js +2 -5
  58. package/dist/examples/tools/llamacpp-tools-qwen35.js +2 -3
  59. package/dist/examples/transcription/parakeet-ctc-filesystem.js +18 -12
  60. package/dist/examples/transcription/parakeet-microphone-record.js +7 -12
  61. package/dist/examples/transcription/parakeet-microphone-stream.d.ts +2 -0
  62. package/dist/examples/transcription/parakeet-microphone-stream.js +79 -0
  63. package/dist/examples/transcription/parakeet-sortformer-streaming.d.ts +2 -0
  64. package/dist/examples/transcription/parakeet-sortformer-streaming.js +121 -0
  65. package/dist/examples/transcription/parakeet-sortformer.js +58 -55
  66. package/dist/examples/transcription/parakeet-tdt-filesystem.js +18 -15
  67. package/dist/examples/transcription/whispercpp-microphone-conversation.js +6 -1
  68. package/dist/examples/tts/chatterbox.js +7 -16
  69. package/dist/examples/tts/llm-to-tts-streaming.js +3 -10
  70. package/dist/examples/tts/supertonic-multilingual.js +4 -12
  71. package/dist/examples/tts/supertonic.js +5 -12
  72. package/dist/examples/vla-smolvla.d.ts +2 -0
  73. package/dist/examples/vla-smolvla.js +75 -0
  74. package/dist/examples/voice-assistant/voice-assistant.js +3 -10
  75. package/dist/expo/plugins/find-in-ancestor-node-modules.d.ts +14 -0
  76. package/dist/expo/plugins/find-in-ancestor-node-modules.js +24 -0
  77. package/dist/expo/plugins/get-project-root.d.ts +22 -0
  78. package/dist/expo/plugins/get-project-root.js +23 -0
  79. package/dist/expo/plugins/index.d.ts +4 -0
  80. package/dist/expo/plugins/index.js +4 -0
  81. package/dist/expo/plugins/resolve-sdk-package-dir.d.ts +9 -2
  82. package/dist/expo/plugins/resolve-sdk-package-dir.js +38 -11
  83. package/dist/expo/plugins/withDeviceInfo.js +2 -1
  84. package/dist/expo/plugins/withMobileBundle.d.ts +2 -17
  85. package/dist/expo/plugins/withMobileBundle.js +31 -85
  86. package/dist/index.d.ts +4 -3
  87. package/dist/index.js +4 -3
  88. package/dist/models/registry/models.d.ts +3711 -368
  89. package/dist/models/registry/models.js +7066 -3562
  90. package/dist/models/update-models/naming.js +22 -8
  91. package/dist/pear/pre.js +6 -2
  92. package/dist/schemas/cancel.d.ts +5 -0
  93. package/dist/schemas/cancel.js +1 -0
  94. package/dist/schemas/classification.d.ts +53 -0
  95. package/dist/schemas/classification.js +33 -0
  96. package/dist/schemas/common.d.ts +1001 -1739
  97. package/dist/schemas/common.js +6 -1
  98. package/dist/schemas/completion-event.d.ts +3 -0
  99. package/dist/schemas/completion-event.js +1 -0
  100. package/dist/schemas/completion-stream.d.ts +1 -0
  101. package/dist/schemas/download-asset.d.ts +13 -3
  102. package/dist/schemas/engine-addon-map.d.ts +3 -0
  103. package/dist/schemas/engine-addon-map.js +18 -5
  104. package/dist/schemas/get-model-info.d.ts +4 -0
  105. package/dist/schemas/get-model-info.js +2 -0
  106. package/dist/schemas/index.d.ts +3 -0
  107. package/dist/schemas/index.js +3 -0
  108. package/dist/schemas/llamacpp-config.d.ts +12 -2
  109. package/dist/schemas/load-model.d.ts +6152 -10764
  110. package/dist/schemas/load-model.js +75 -7
  111. package/dist/schemas/model-src-utils.d.ts +22 -2
  112. package/dist/schemas/model-types.d.ts +46 -6
  113. package/dist/schemas/model-types.js +28 -5
  114. package/dist/schemas/ocr.d.ts +5 -0
  115. package/dist/schemas/plugin.d.ts +20 -5
  116. package/dist/schemas/plugin.js +21 -4
  117. package/dist/schemas/registry.d.ts +44 -0
  118. package/dist/schemas/registry.js +5 -0
  119. package/dist/schemas/reload-config.d.ts +22 -2
  120. package/dist/schemas/sdcpp-config.d.ts +316 -1
  121. package/dist/schemas/sdcpp-config.js +232 -33
  122. package/dist/schemas/sdk-config.d.ts +654 -1324
  123. package/dist/schemas/sdk-config.js +16 -1
  124. package/dist/schemas/sdk-errors-client.d.ts +5 -0
  125. package/dist/schemas/sdk-errors-client.js +26 -1
  126. package/dist/schemas/sdk-errors-server.d.ts +3 -1
  127. package/dist/schemas/sdk-errors-server.js +20 -5
  128. package/dist/schemas/text-to-speech.d.ts +79 -696
  129. package/dist/schemas/text-to-speech.js +46 -19
  130. package/dist/schemas/transcription-config.d.ts +37 -226
  131. package/dist/schemas/transcription-config.js +76 -15
  132. package/dist/schemas/transcription.d.ts +63 -11
  133. package/dist/schemas/transcription.js +56 -2
  134. package/dist/schemas/translation-config.d.ts +60 -10
  135. package/dist/schemas/vla.d.ts +87 -0
  136. package/dist/schemas/vla.js +108 -0
  137. package/dist/scripts/run-unit-tests.js +8 -2
  138. package/dist/server/bare/ops/transcribe.d.ts +2 -1
  139. package/dist/server/bare/ops/transcribe.js +59 -34
  140. package/dist/server/bare/plugins/ggml-classification/ops/classify.d.ts +6 -0
  141. package/dist/server/bare/plugins/ggml-classification/ops/classify.js +30 -0
  142. package/dist/server/bare/plugins/ggml-classification/plugin.d.ts +32 -0
  143. package/dist/server/bare/plugins/ggml-classification/plugin.js +55 -0
  144. package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.d.ts +3 -0
  145. package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.js +12 -0
  146. package/dist/server/bare/plugins/ggml-vla/ops/vla-run.d.ts +3 -0
  147. package/dist/server/bare/plugins/ggml-vla/ops/vla-run.js +75 -0
  148. package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +54 -0
  149. package/dist/server/bare/plugins/ggml-vla/plugin.js +57 -0
  150. package/dist/server/bare/plugins/index.d.ts +3 -1
  151. package/dist/server/bare/plugins/index.js +3 -1
  152. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +3 -0
  153. package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.d.ts +29 -0
  154. package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.js +65 -0
  155. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +6 -0
  156. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +26 -0
  157. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +25 -0
  158. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +5 -0
  159. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +67 -246
  160. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +66 -97
  161. package/dist/server/bare/plugins/sdcpp-generation/ops/video.d.ts +3 -0
  162. package/dist/server/bare/plugins/sdcpp-generation/ops/video.js +199 -0
  163. package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +200 -2
  164. package/dist/server/bare/plugins/sdcpp-generation/plugin.js +61 -8
  165. package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.js +2 -15
  166. package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.js +2 -1
  167. package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +75 -0
  168. package/dist/server/bare/plugins/tts-ggml/plugin.js +189 -0
  169. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +29 -4
  170. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +12 -1
  171. package/dist/server/bare/registry/model-config-utils.js +7 -0
  172. package/dist/server/bare/runtime/request-context.d.ts +1 -1
  173. package/dist/server/bare/runtime-lifecycle.js +9 -9
  174. package/dist/server/bare/types/addon-responses.d.ts +1 -0
  175. package/dist/server/env.js +4 -1
  176. package/dist/server/plugins/index.d.ts +1 -1
  177. package/dist/server/plugins/index.js +1 -1
  178. package/dist/server/plugins/registry.d.ts +1 -0
  179. package/dist/server/plugins/registry.js +5 -0
  180. package/dist/server/rpc/handler-registry.js +4 -0
  181. package/dist/server/rpc/handler-selection.d.ts +9 -0
  182. package/dist/server/rpc/handler-selection.js +14 -0
  183. package/dist/server/rpc/handler-utils.js +5 -13
  184. package/dist/server/rpc/handlers/classify.d.ts +3 -0
  185. package/dist/server/rpc/handlers/classify.js +4 -0
  186. package/dist/server/rpc/handlers/index.d.ts +2 -0
  187. package/dist/server/rpc/handlers/index.js +2 -0
  188. package/dist/server/rpc/handlers/load-model/handler.js +4 -1
  189. package/dist/server/rpc/handlers/load-model/resolve.js +9 -0
  190. package/dist/server/rpc/handlers/video-stream.d.ts +3 -0
  191. package/dist/server/rpc/handlers/video-stream.js +4 -0
  192. package/dist/server/rpc/profiling/operation-metrics.js +23 -0
  193. package/dist/server/utils/config-transform.js +1 -1
  194. package/dist/server/worker.js +14 -11
  195. package/dist/utils/errors-client.d.ts +15 -0
  196. package/dist/utils/errors-client.js +26 -0
  197. package/dist/utils/errors-server.d.ts +30 -2
  198. package/dist/utils/errors-server.js +51 -3
  199. package/package.json +66 -80
  200. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +0 -490
  201. package/dist/server/bare/plugins/onnx-tts/plugin.js +0 -272
  202. package/dist/server/bare/plugins/onnx-tts/wav-helper.d.ts +0 -14
  203. package/dist/server/bare/plugins/onnx-tts/wav-helper.js +0 -107
  204. /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.d.ts +0 -0
  205. /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.d.ts +0 -0
@@ -0,0 +1,76 @@
1
+ import { promises as fsp } from "node:fs";
2
+ import path from "node:path";
3
+ import { deduplicateAddons, readAddonPackageJson, } from "./addon-source.js";
4
+ export class InvalidNodeModulesSourceError extends Error {
5
+ nodeModulesPath;
6
+ constructor(nodeModulesPath, cause) {
7
+ const reason = cause instanceof Error ? cause.message : String(cause);
8
+ super(`node_modules at ${nodeModulesPath} could not be read.\n\n` +
9
+ ` Reason: ${reason}\n\n` +
10
+ " Run `npm install` before invoking verifyBundle against a node_modules tree.");
11
+ this.name = "InvalidNodeModulesSourceError";
12
+ this.nodeModulesPath = nodeModulesPath;
13
+ }
14
+ }
15
+ export async function collectAddonsFromNodeModules(options) {
16
+ const { nodeModulesRoot, diagnostics } = options;
17
+ const addons = [];
18
+ await walkNodeModules(nodeModulesRoot, addons, diagnostics, true);
19
+ return deduplicateAddons(addons);
20
+ }
21
+ async function walkNodeModules(nodeModulesDir, addons, diagnostics, isRoot) {
22
+ let entries;
23
+ try {
24
+ entries = await fsp.readdir(nodeModulesDir, { withFileTypes: true });
25
+ }
26
+ catch (error) {
27
+ if (isRoot)
28
+ throw new InvalidNodeModulesSourceError(nodeModulesDir, error);
29
+ return;
30
+ }
31
+ for (const entry of entries) {
32
+ if (entry.name.startsWith("."))
33
+ continue;
34
+ if (!isPackageEntry(entry))
35
+ continue;
36
+ if (entry.name.startsWith("@")) {
37
+ await walkScopeDirectory(path.join(nodeModulesDir, entry.name), addons, diagnostics);
38
+ continue;
39
+ }
40
+ await visitPackageDirectory(path.join(nodeModulesDir, entry.name), entry.name, addons, diagnostics);
41
+ }
42
+ }
43
+ async function walkScopeDirectory(scopeDir, addons, diagnostics) {
44
+ const scope = path.basename(scopeDir);
45
+ let entries;
46
+ try {
47
+ entries = await fsp.readdir(scopeDir, { withFileTypes: true });
48
+ }
49
+ catch {
50
+ return;
51
+ }
52
+ for (const entry of entries) {
53
+ if (entry.name.startsWith("."))
54
+ continue;
55
+ if (!isPackageEntry(entry))
56
+ continue;
57
+ await visitPackageDirectory(path.join(scopeDir, entry.name), `${scope}/${entry.name}`, addons, diagnostics);
58
+ }
59
+ }
60
+ function isPackageEntry(entry) {
61
+ return entry.isDirectory() || entry.isSymbolicLink();
62
+ }
63
+ async function visitPackageDirectory(packageDir, packageName, addons, diagnostics) {
64
+ const result = await readAddonPackageJson({
65
+ packageJsonPath: path.join(packageDir, "package.json"),
66
+ expectedName: packageName,
67
+ });
68
+ if (result.isAddon && result.addon) {
69
+ addons.push(result.addon);
70
+ }
71
+ else if (result.invalid !== undefined && diagnostics !== undefined) {
72
+ diagnostics.invalidPackageJsons.push(result.invalid);
73
+ }
74
+ const nestedNodeModules = path.join(packageDir, "node_modules");
75
+ await walkNodeModules(nestedNodeModules, addons, diagnostics, false);
76
+ }
@@ -0,0 +1,15 @@
1
+ import { type NativeAddon } from "./addon-source";
2
+ export interface MissingPrebuildIssue {
3
+ code: "missing-prebuild";
4
+ level: "error";
5
+ addon: string;
6
+ host: string;
7
+ message: string;
8
+ packageRoot: string;
9
+ }
10
+ export interface CheckPrebuildsOptions {
11
+ addon: NativeAddon;
12
+ hosts: string[];
13
+ }
14
+ export declare function checkPrebuilds(options: CheckPrebuildsOptions): Promise<MissingPrebuildIssue[]>;
15
+ //# sourceMappingURL=prebuilds.d.ts.map
@@ -0,0 +1,39 @@
1
+ import { promises as fsp } from "node:fs";
2
+ import path from "node:path";
3
+ import { formatAddonId } from "./addon-source.js";
4
+ export async function checkPrebuilds(options) {
5
+ const { addon, hosts } = options;
6
+ const issues = [];
7
+ for (const host of hosts) {
8
+ const hostDir = path.join(addon.packageRoot, "prebuilds", host);
9
+ const present = await hasBarePrebuild(hostDir);
10
+ if (!present) {
11
+ issues.push({
12
+ code: "missing-prebuild",
13
+ level: "error",
14
+ addon: formatAddonId(addon),
15
+ host,
16
+ packageRoot: addon.packageRoot,
17
+ message: `${formatAddonId(addon)} is missing a prebuild for ${host} ` +
18
+ `(expected ${path.join(hostDir, "*.bare")}).`,
19
+ });
20
+ }
21
+ }
22
+ return issues;
23
+ }
24
+ async function hasBarePrebuild(hostDir) {
25
+ let entries;
26
+ try {
27
+ entries = await fsp.readdir(hostDir, { withFileTypes: true });
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ for (const entry of entries) {
33
+ if (!entry.isFile() && !entry.isSymbolicLink())
34
+ continue;
35
+ if (entry.name.endsWith(".bare"))
36
+ return true;
37
+ }
38
+ return false;
39
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=classify-image.d.ts.map
@@ -0,0 +1,23 @@
1
+ import fs from "fs";
2
+ import { startQVACProvider, stopQVACProvider, loadModel, classify, unloadModel } from "@qvac/sdk";
3
+ /**
4
+ * Classify an image using the bundled MobileNetV3-Small model.
5
+ *
6
+ * The bundled model produces three classes: "food", "report", "other".
7
+ * No modelSrc is needed — the model ships inside @qvac/classification-ggml.
8
+ */
9
+ async function main() {
10
+ await startQVACProvider({});
11
+ const modelId = await loadModel({
12
+ modelType: "ggml-classification",
13
+ });
14
+ const image = fs.readFileSync("image.jpg");
15
+ const results = await classify({ modelId, image });
16
+ console.log("Classification results:");
17
+ for (const { label, confidence } of results) {
18
+ console.log(` ${label}: ${(confidence * 100).toFixed(1)}%`);
19
+ }
20
+ await unloadModel({ modelId });
21
+ await stopQVACProvider();
22
+ }
23
+ main().catch(console.error);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=diffusion-txt2vid.d.ts.map
@@ -0,0 +1,81 @@
1
+ import { loadModel, unloadModel, video, WAN2_1_T2V_1_3B_FP16, UMT5_XXL_FP16, WAN_2_1_COMFYUI_REPACKAGED_VAE, } from "@qvac/sdk";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ // Text-to-video with Wan 2.1 T2V 1.3B. Wan uses a split layout:
5
+ // a diffusion model + a UMT5-XXL text encoder + a VAE.
6
+ // This example needs powerful hardware: at least 16 GB of video memory or
7
+ // 20 GB of unified memory.
8
+ const diffusionModelSrc = process.argv[2] || WAN2_1_T2V_1_3B_FP16;
9
+ const t5XxlModelSrc = process.argv[3] || UMT5_XXL_FP16;
10
+ const vaeModelSrc = process.argv[4] || WAN_2_1_COMFYUI_REPACKAGED_VAE;
11
+ // Prompt tip: Wan 1.3B is small and has weak temporal priors. Use motion-
12
+ // explicit verbs and avoid static framing words like "standing", "still",
13
+ // or "portrait" in the positive prompt.
14
+ const prompt = process.argv[5] ||
15
+ "a colorful bird flapping its wings";
16
+ const outputDir = process.argv[6] || ".";
17
+ try {
18
+ console.log("Loading Wan 2.1 T2V model (diffusion + UMT5-XXL + VAE)...");
19
+ const modelId = await loadModel({
20
+ modelSrc: diffusionModelSrc,
21
+ modelType: "diffusion",
22
+ modelConfig: {
23
+ mode: "video",
24
+ device: "gpu",
25
+ threads: 4,
26
+ t5XxlModelSrc,
27
+ vaeModelSrc,
28
+ diffusion_fa: true,
29
+ offload_to_cpu: true,
30
+ vae_on_cpu: true,
31
+ vae_tiling: true,
32
+ },
33
+ onProgress: (p) => console.log(`Loading: ${p.percentage.toFixed(1)}%`),
34
+ });
35
+ console.log(`Model loaded: ${modelId}`);
36
+ console.log(`\nGenerating video for: "${prompt}"`);
37
+ const { progressStream, outputs, stats } = video({
38
+ modelId,
39
+ mode: "txt2vid",
40
+ prompt,
41
+ negative_prompt: "blurry, low quality, static, jittery, watermark",
42
+ width: 480,
43
+ height: 832,
44
+ // Frame count must satisfy (4*k + 1), k >= 1. Common values at 16 fps:
45
+ // 17 frames ~= 1.06s (very fast, ~6 min on M3 Ultra Metal)
46
+ // 33 frames ~= 2.06s (default in this example, ~11 min)
47
+ // 49 frames ~= 3.06s (~17 min)
48
+ // 65 frames ~= 4.06s (~22 min)
49
+ // 81 frames ~= 5.06s (Wan 1.3B native training length, best motion
50
+ // quality, ~28 min)
51
+ // Going beyond 81 can degrade quality because it exceeds the model's
52
+ // positional embeddings.
53
+ video_frames: 33,
54
+ fps: 16,
55
+ steps: 30,
56
+ cfg_scale: 6.0,
57
+ // Wan 2.1 T2V needs flow_shift=3.0 for visible motion. Higher values can
58
+ // make consecutive frames near-identical, which looks like a frozen video.
59
+ flow_shift: 3.0,
60
+ seed: 42,
61
+ vae_tiling: true,
62
+ });
63
+ for await (const { step, totalSteps } of progressStream) {
64
+ process.stdout.write(`\rStep ${step}/${totalSteps}`);
65
+ }
66
+ console.log();
67
+ const buffers = await outputs;
68
+ for (let i = 0; i < buffers.length; i++) {
69
+ const outputPath = path.join(outputDir, `wan_t2v_${i}.avi`);
70
+ fs.writeFileSync(outputPath, buffers[i]);
71
+ console.log(`Saved: ${outputPath}`);
72
+ }
73
+ console.log("\nStats:", await stats);
74
+ await unloadModel({ modelId, clearStorage: false });
75
+ console.log("Done.");
76
+ process.exit(0);
77
+ }
78
+ catch (error) {
79
+ console.error("❌ Error:", error);
80
+ process.exit(1);
81
+ }
@@ -10,7 +10,7 @@
10
10
  * 3. Embeddings -> fails (plugin not selected)
11
11
  *
12
12
  */
13
- import { execSync } from "child_process";
13
+ import { bundleSdk } from "../commands/index.js";
14
14
  import { existsSync, rmSync } from "fs";
15
15
  import path from "path";
16
16
  const configDir = import.meta.dirname ?? process.cwd();
@@ -23,14 +23,10 @@ console.log(`⚠️ This example will generate a worker bundle in ${qvacOutputD
23
23
  console.log(" If you have an existing qvac/ folder with bundled files, they will be overwritten and removed.\n");
24
24
  console.log("🔨 Generating worker bundle from plugins config...\n");
25
25
  try {
26
- execSync(`npx @qvac/cli bundle sdk --config "${configPath}" --quiet`, {
27
- cwd: projectRoot,
28
- stdio: "inherit",
29
- });
26
+ await bundleSdk({ projectRoot, configPath, quiet: true });
30
27
  }
31
28
  catch (error) {
32
- console.error("❌ Failed to generate worker bundle. Ensure @qvac/cli is installed:");
33
- console.error(" npm install -D @qvac/cli");
29
+ console.error("❌ Failed to generate worker bundle.");
34
30
  console.error("❌ Error:", error);
35
31
  process.exit(1);
36
32
  }
@@ -15,12 +15,9 @@
15
15
  * Usage:
16
16
  * bun run bare:example dist/examples/tools/llamacpp-tools-gemma4.js <model-url>
17
17
  */
18
- import { completion, loadModel, unloadModel, } from "@qvac/sdk";
18
+ import { completion, loadModel, unloadModel, GEMMA4_2B_MULTIMODAL_Q4_K_M, } from "@qvac/sdk";
19
19
  import { tools, mockExecute } from "./shared.js";
20
- // bartowski's pack tags <eos> as the EOG token (matching the base tokenizer),
21
- // ensuring generation stops correctly; unsloth's variant maps it differently.
22
- const GEMMA4_HF = "https://huggingface.co/bartowski/google_gemma-4-E2B-it-GGUF/resolve/main/google_gemma-4-E2B-it-Q4_K_M.gguf";
23
- const modelSrc = process.argv[2] ?? GEMMA4_HF;
20
+ const modelSrc = process.argv[2] ?? GEMMA4_2B_MULTIMODAL_Q4_K_M;
24
21
  let modelId;
25
22
  try {
26
23
  modelId = await loadModel({
@@ -11,10 +11,9 @@
11
11
  * Usage:
12
12
  * bun run bare:example dist/examples/tools/llamacpp-tools-qwen35.js <model-url>
13
13
  */
14
- import { completion, loadModel, unloadModel, } from "@qvac/sdk";
14
+ import { completion, loadModel, unloadModel, QWEN3_5_0_8B_MULTIMODAL_Q8_0, } from "@qvac/sdk";
15
15
  import { tools, mockExecute } from "./shared.js";
16
- const QWEN35_HF = "https://huggingface.co/unsloth/Qwen3.5-0.8B-GGUF/resolve/main/Qwen3.5-0.8B-Q8_0.gguf";
17
- const modelSrc = process.argv[2] ?? QWEN35_HF;
16
+ const modelSrc = process.argv[2] ?? QWEN3_5_0_8B_MULTIMODAL_Q8_0;
18
17
  let modelId;
19
18
  try {
20
19
  modelId = await loadModel({
@@ -1,24 +1,30 @@
1
- import { loadModel, unloadModel, transcribe, PARAKEET_CTC_FP32, PARAKEET_CTC_TOKENIZER, } from "@qvac/sdk";
1
+ /**
2
+ * Parakeet CTC transcription from a WAV file.
3
+ *
4
+ * Usage:
5
+ * bun run examples/transcription/parakeet-ctc-filesystem.ts <wav-file> [parakeet-ctc-gguf]
6
+ *
7
+ * Loads a single GGUF checkpoint (`PARAKEET_CTC_0_6B_Q8_0` by default) and
8
+ * transcribes the file with the batch `transcribe` API. Omit the model
9
+ * argument to use the registry constant.
10
+ *
11
+ * Audio should be 16 kHz mono PCM in a WAV container.
12
+ */
13
+ import { loadModel, unloadModel, transcribe, PARAKEET_CTC_0_6B_Q8_0, } from "@qvac/sdk";
2
14
  const args = process.argv.slice(2);
3
15
  if (!args[0]) {
4
16
  console.error("Usage: bun run examples/transcription/parakeet-ctc-filesystem.ts <wav-file> " +
5
- "[model.onnx] [tokenizer.json]");
6
- console.error("\nIf model paths are omitted, defaults to registry models.");
17
+ "[parakeet-ctc-gguf]");
18
+ console.error("\nIf the model path is omitted, defaults to the registry model.");
7
19
  process.exit(1);
8
20
  }
9
21
  const audioFilePath = args[0];
10
- const parakeetCtcModelSrc = args[1] ?? PARAKEET_CTC_FP32;
11
- const parakeetTokenizerSrc = args[2] ?? PARAKEET_CTC_TOKENIZER;
22
+ const parakeetModelSrc = args[1] ?? PARAKEET_CTC_0_6B_Q8_0;
12
23
  try {
13
24
  console.log("Loading Parakeet CTC model...");
14
25
  const modelId = await loadModel({
15
- modelSrc: parakeetCtcModelSrc,
26
+ modelSrc: parakeetModelSrc,
16
27
  modelType: "parakeet",
17
- modelConfig: {
18
- modelType: "ctc",
19
- parakeetCtcModelSrc,
20
- parakeetTokenizerSrc,
21
- },
22
28
  onProgress: (progress) => {
23
29
  console.log(`Download progress: ${progress.percentage.toFixed(1)}%`);
24
30
  },
@@ -33,6 +39,6 @@ try {
33
39
  console.log("Done");
34
40
  }
35
41
  catch (error) {
36
- console.error("Error:", error);
42
+ console.error("❌ Error:", error);
37
43
  process.exit(1);
38
44
  }
@@ -1,14 +1,15 @@
1
1
  /**
2
- * Microphone → Parakeet transcription using chunked `transcribe` calls.
2
+ * Microphone → Parakeet batch transcription (chunked `transcribe`).
3
3
  *
4
- * Usage: bun run examples/transcription/parakeet-microphone-record.ts
4
+ * Usage:
5
+ * bun run examples/transcription/parakeet-microphone-record.ts
5
6
  *
6
- * Captures 3-second audio chunks from the microphone and sends each to the
7
- * batch `transcribe` API. Press Ctrl+C to quit.
7
+ * Captures 3 s s16le chunks from the microphone and sends each to `transcribe`
8
+ * with the TDT model. Press Ctrl+C to stop.
8
9
  *
9
10
  * Requirements: FFmpeg installed, microphone access.
10
11
  */
11
- import { loadModel, unloadModel, transcribe, PARAKEET_TDT_ENCODER_FP32, PARAKEET_TDT_DECODER_FP32, PARAKEET_TDT_VOCAB, PARAKEET_TDT_PREPROCESSOR_FP32, } from "@qvac/sdk";
12
+ import { loadModel, unloadModel, transcribe, PARAKEET_TDT_0_6B_V3_Q8_0, } from "@qvac/sdk";
12
13
  import { spawnSync } from "child_process";
13
14
  import { startMicrophone } from "../audio/mic-input";
14
15
  const SAMPLE_RATE = 16000;
@@ -27,14 +28,8 @@ catch {
27
28
  }
28
29
  console.log("Loading Parakeet model...");
29
30
  const modelId = await loadModel({
30
- modelSrc: PARAKEET_TDT_ENCODER_FP32,
31
+ modelSrc: PARAKEET_TDT_0_6B_V3_Q8_0,
31
32
  modelType: "parakeet",
32
- modelConfig: {
33
- parakeetEncoderSrc: PARAKEET_TDT_ENCODER_FP32,
34
- parakeetDecoderSrc: PARAKEET_TDT_DECODER_FP32,
35
- parakeetVocabSrc: PARAKEET_TDT_VOCAB,
36
- parakeetPreprocessorSrc: PARAKEET_TDT_PREPROCESSOR_FP32,
37
- },
38
33
  onProgress: (p) => console.log(`Download: ${p.percentage.toFixed(1)}%`),
39
34
  });
40
35
  console.log("Model loaded.\n");
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parakeet-microphone-stream.d.ts.map
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Microphone → Parakeet duplex streaming (`transcribeStream`).
3
+ *
4
+ * Usage:
5
+ * bun run examples/transcription/parakeet-microphone-stream.ts
6
+ *
7
+ * Streams microphone audio through `transcribeStream` with
8
+ * `parakeetStreamingConfig`. Uses the EOU checkpoint so you may see
9
+ * `{ type: "endOfTurn", source: "parakeet" }` events; CTC/TDT models
10
+ * emit transcript text only. Parakeet does not yield standalone VAD events.
11
+ *
12
+ * Requirements: FFmpeg installed, microphone access.
13
+ */
14
+ import { loadModel, unloadModel, transcribeStream, PARAKEET_EOU_120M_V1_Q8_0, } from "@qvac/sdk";
15
+ import { spawnSync } from "child_process";
16
+ import { startMicrophone } from "../audio/mic-input";
17
+ const SAMPLE_RATE = 16000;
18
+ try {
19
+ const r = spawnSync("ffmpeg", ["-version"], { stdio: "ignore" });
20
+ if (r.error || r.status !== 0)
21
+ throw new Error("FFmpeg not found");
22
+ }
23
+ catch {
24
+ console.error("Error: FFmpeg is required. Install it and try again.");
25
+ process.exit(1);
26
+ }
27
+ let modelId = null;
28
+ let ffmpeg = null;
29
+ async function cleanup() {
30
+ console.log("\n\nStopping...");
31
+ ffmpeg?.kill();
32
+ if (modelId)
33
+ await unloadModel({ modelId });
34
+ console.log("Done.");
35
+ }
36
+ process.on("SIGINT", () => {
37
+ void cleanup().finally(() => process.exit(0));
38
+ });
39
+ process.on("SIGTERM", () => {
40
+ void cleanup().finally(() => process.exit(0));
41
+ });
42
+ try {
43
+ console.log("Loading Parakeet (EOU) streaming model...");
44
+ modelId = await loadModel({
45
+ modelSrc: PARAKEET_EOU_120M_V1_Q8_0,
46
+ modelType: "parakeet",
47
+ onProgress: (p) => console.log(`Download: ${p.percentage.toFixed(1)}%`),
48
+ });
49
+ console.log("Model loaded.\n");
50
+ ffmpeg = startMicrophone({ sampleRate: SAMPLE_RATE, format: "s16le" });
51
+ const session = await transcribeStream({
52
+ modelId,
53
+ parakeetStreamingConfig: {
54
+ chunkMs: 1000,
55
+ emitPartials: true,
56
+ },
57
+ });
58
+ ffmpeg.stdout.on("data", (chunk) => session.write(chunk));
59
+ console.log("Listening... speak and pause to see transcripts. End-of-turn boundaries fire when the EOU model emits an <EOU> token.\n");
60
+ for await (const event of session) {
61
+ switch (event.type) {
62
+ case "text":
63
+ if (event.text.trim()) {
64
+ process.stdout.write(`${event.text}`);
65
+ }
66
+ break;
67
+ case "endOfTurn":
68
+ console.log("\n[endOfTurn] turn boundary detected\n");
69
+ break;
70
+ }
71
+ }
72
+ await cleanup();
73
+ process.exit(0);
74
+ }
75
+ catch (error) {
76
+ console.error("Error:", error);
77
+ await cleanup();
78
+ process.exit(1);
79
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parakeet-sortformer-streaming.d.ts.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Sortformer v2.1 streaming diarization via duplex `transcribeStream` + AOSC.
3
+ *
4
+ * Usage:
5
+ * bun run examples/transcription/parakeet-sortformer-streaming.ts <wav-file> [sortformer-gguf]
6
+ *
7
+ * Streams 16 kHz mono s16le audio in real-time-paced chunks (required for parakeet
8
+ * duplex streaming). Loads v2.1 with AOSC knobs in `modelConfig`. Omit the model
9
+ * argument to use `PARAKEET_SORTFORMER_4SPK_V2_1_Q8_0`.
10
+ *
11
+ * For offline batch diarization (Sortformer + TDT), see `parakeet-sortformer.ts`.
12
+ */
13
+ import { loadModel, unloadModel, transcribeStream, PARAKEET_SORTFORMER_4SPK_V2_1_Q8_0, } from "@qvac/sdk";
14
+ import { spawn } from "child_process";
15
+ const SAMPLE_RATE = 16000;
16
+ const BYTES_PER_S16_SAMPLE = 2;
17
+ const STREAM_CHUNK_MS = 2000;
18
+ /** NeMo-port AOSC defaults for v2.1 Sortformer (`parakeet.model_variant` in GGUF). */
19
+ const SORTFORMER_V21_AOSC_LOAD_CONFIG = {
20
+ streaming: true,
21
+ streamingChunkMs: 2000,
22
+ streamingChunkRightContextMs: 560,
23
+ streamingSpkCacheEnable: true,
24
+ streamingSpkCacheLen: 188,
25
+ streamingFifoLen: 188,
26
+ streamingChunkLeftContextMs: 80,
27
+ streamingSpkCacheUpdatePeriod: 144,
28
+ };
29
+ const args = process.argv.slice(2);
30
+ if (!args[0]) {
31
+ console.error("Usage: bun run examples/transcription/parakeet-sortformer-streaming.ts <wav-file-path> [sortformer-gguf]");
32
+ console.error("\nDefaults to the v2.1 q8_0 registry model (PARAKEET_SORTFORMER_4SPK_V2_1_Q8_0).");
33
+ process.exit(1);
34
+ }
35
+ const audioFilePath = args[0];
36
+ const sortformerOverride = args[1];
37
+ const chunkBytes = Math.floor((STREAM_CHUNK_MS / 1000) * SAMPLE_RATE) * BYTES_PER_S16_SAMPLE;
38
+ let modelId = null;
39
+ async function cleanup() {
40
+ if (modelId) {
41
+ await unloadModel({ modelId });
42
+ }
43
+ }
44
+ function readS16leFromWav(wavPath) {
45
+ return new Promise((resolve, reject) => {
46
+ const chunks = [];
47
+ const proc = spawn("ffmpeg", [
48
+ "-i",
49
+ wavPath,
50
+ "-ar",
51
+ String(SAMPLE_RATE),
52
+ "-ac",
53
+ "1",
54
+ "-f",
55
+ "s16le",
56
+ "pipe:1",
57
+ ], { stdio: ["ignore", "pipe", "ignore"] });
58
+ proc.stdout.on("data", (buf) => chunks.push(buf));
59
+ proc.on("error", reject);
60
+ proc.on("close", (code) => {
61
+ if (code !== 0) {
62
+ reject(new Error(`ffmpeg exited with code ${code}`));
63
+ return;
64
+ }
65
+ const merged = Buffer.concat(chunks);
66
+ resolve(new Uint8Array(merged.buffer, merged.byteOffset, merged.byteLength));
67
+ });
68
+ });
69
+ }
70
+ const loadOptions = {
71
+ modelType: "parakeet-transcription",
72
+ modelConfig: { ...SORTFORMER_V21_AOSC_LOAD_CONFIG },
73
+ onProgress: (p) => console.log(`Download: ${p.percentage.toFixed(1)}%`),
74
+ ...(sortformerOverride
75
+ ? { modelSrc: sortformerOverride }
76
+ : { modelSrc: PARAKEET_SORTFORMER_4SPK_V2_1_Q8_0 }),
77
+ };
78
+ try {
79
+ console.log("Loading Sortformer v2.1 with streaming + AOSC (load-time config)...");
80
+ modelId = await loadModel(loadOptions);
81
+ console.log(`Model loaded: ${modelId}\n`);
82
+ const session = await transcribeStream({
83
+ modelId,
84
+ parakeetStreamingConfig: { chunkMs: STREAM_CHUNK_MS },
85
+ });
86
+ console.log(`Streaming ${audioFilePath} in ${STREAM_CHUNK_MS}ms chunks (wall-clock paced)...\n`);
87
+ const pcm = await readS16leFromWav(audioFilePath);
88
+ const trailingSilenceMs = 1500;
89
+ const trailingBytes = new Uint8Array(Math.floor((trailingSilenceMs / 1000) * SAMPLE_RATE) * BYTES_PER_S16_SAMPLE);
90
+ for (let offset = 0; offset < pcm.length; offset += chunkBytes) {
91
+ const end = Math.min(offset + chunkBytes, pcm.length);
92
+ session.write(pcm.subarray(offset, end));
93
+ if (end < pcm.length) {
94
+ await new Promise((resolve) => setTimeout(resolve, STREAM_CHUNK_MS));
95
+ }
96
+ }
97
+ for (let offset = 0; offset < trailingBytes.length; offset += chunkBytes) {
98
+ const end = Math.min(offset + chunkBytes, trailingBytes.length);
99
+ session.write(trailingBytes.subarray(offset, end));
100
+ if (end < trailingBytes.length) {
101
+ await new Promise((resolve) => setTimeout(resolve, STREAM_CHUNK_MS));
102
+ }
103
+ }
104
+ session.end();
105
+ const lines = [];
106
+ for await (const event of session) {
107
+ if (event.type === "text" && event.text.trim()) {
108
+ lines.push(event.text.trim());
109
+ console.log(event.text.trim());
110
+ }
111
+ }
112
+ console.log("\n=== Streaming diarization transcript ===");
113
+ console.log(lines.join("\n") || "(no speaker lines emitted)");
114
+ await cleanup();
115
+ process.exit(0);
116
+ }
117
+ catch (error) {
118
+ console.error("❌ Error:", error);
119
+ await cleanup();
120
+ process.exit(1);
121
+ }