@qvac/sdk 0.17.1 → 0.18.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 (154) hide show
  1. package/NOTICE +124 -64
  2. package/README.md +19 -0
  3. package/dist/client/api/audio-gen.d.ts +17 -0
  4. package/dist/client/api/audio-gen.js +17 -0
  5. package/dist/client/api/finetune.d.ts +2 -0
  6. package/dist/client/api/finetune.js +7 -1
  7. package/dist/client/api/index.d.ts +1 -1
  8. package/dist/client/api/index.js +1 -1
  9. package/dist/client/api/load-model.d.ts +8 -0
  10. package/dist/client/api/transcribe.d.ts +19 -2
  11. package/dist/client/api/transcribe.js +66 -27
  12. package/dist/client/api/translate.d.ts +1 -0
  13. package/dist/client/api/translate.js +40 -19
  14. package/dist/client/api/vla.d.ts +42 -1
  15. package/dist/client/api/vla.js +50 -1
  16. package/dist/commands/bundle/entry-gen.d.ts +4 -0
  17. package/dist/commands/bundle/entry-gen.js +6 -0
  18. package/dist/commands/bundle/index.js +19 -12
  19. package/dist/examples/asr/parakeet-indic-conformer-filesystem.d.ts +2 -0
  20. package/dist/examples/asr/parakeet-indic-conformer-filesystem.js +52 -0
  21. package/dist/examples/audiogen/generate-cover.d.ts +2 -0
  22. package/dist/examples/audiogen/generate-cover.js +100 -0
  23. package/dist/examples/llamacpp-fallback.d.ts +2 -0
  24. package/dist/examples/llamacpp-fallback.js +34 -0
  25. package/dist/examples/multi-job-completion.d.ts +28 -0
  26. package/dist/examples/multi-job-completion.js +128 -0
  27. package/dist/examples/profiling/basic.js +32 -1
  28. package/dist/examples/system-resources.d.ts +2 -0
  29. package/dist/examples/system-resources.js +86 -0
  30. package/dist/examples/tts/audio8.d.ts +2 -0
  31. package/dist/examples/tts/audio8.js +54 -0
  32. package/dist/examples/tts/cosyvoice3.d.ts +2 -0
  33. package/dist/examples/tts/cosyvoice3.js +52 -0
  34. package/dist/examples/vla-groot.js +92 -49
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.js +2 -2
  37. package/dist/models/registry/models.d.ts +782 -6
  38. package/dist/models/registry/models.js +2664 -1859
  39. package/dist/schemas/audio-gen.d.ts +103 -0
  40. package/dist/schemas/audio-gen.js +135 -4
  41. package/dist/schemas/common.d.ts +550 -11
  42. package/dist/schemas/constants-registry.d.ts +18 -4
  43. package/dist/schemas/constants-registry.js +16 -3
  44. package/dist/schemas/index.d.ts +1 -1
  45. package/dist/schemas/index.js +1 -1
  46. package/dist/schemas/llamacpp-config.d.ts +10 -10
  47. package/dist/schemas/llamacpp-config.js +12 -5
  48. package/dist/schemas/load-model.d.ts +3678 -323
  49. package/dist/schemas/load-model.js +21 -3
  50. package/dist/schemas/sdk-config.d.ts +60 -24
  51. package/dist/schemas/sdk-errors-server.d.ts +1 -0
  52. package/dist/schemas/sdk-errors-server.js +5 -0
  53. package/dist/schemas/text-to-speech.d.ts +1086 -110
  54. package/dist/schemas/text-to-speech.js +194 -4
  55. package/dist/schemas/tools.d.ts +0 -16
  56. package/dist/schemas/tools.js +0 -15
  57. package/dist/schemas/transcription-config.d.ts +2 -0
  58. package/dist/schemas/transcription-config.js +10 -4
  59. package/dist/schemas/transcription.d.ts +3 -0
  60. package/dist/schemas/vla.d.ts +83 -0
  61. package/dist/schemas/vla.js +105 -2
  62. package/dist/scripts/link-workspace-inference.d.ts +2 -0
  63. package/dist/scripts/link-workspace-inference.js +31 -0
  64. package/dist/server/bare/ops/cancel.d.ts +1 -1
  65. package/dist/server/bare/ops/cancel.js +1 -1
  66. package/dist/server/bare/ops/kv-cache-retention.js +11 -0
  67. package/dist/server/bare/ops/kv-cache-utils.d.ts +1 -1
  68. package/dist/server/bare/ops/kv-cache-utils.js +40 -12
  69. package/dist/server/bare/ops/transcribe.d.ts +2 -2
  70. package/dist/server/bare/ops/transcribe.js +54 -48
  71. package/dist/server/bare/ops/translate-stats.d.ts +5 -0
  72. package/dist/server/bare/ops/translate-stats.js +11 -0
  73. package/dist/server/bare/ops/translate.js +66 -38
  74. package/dist/server/bare/ops/unload-model.js +30 -24
  75. package/dist/server/bare/plugins/audiogen-ggml/ops/audio-gen-input.d.ts +20 -0
  76. package/dist/server/bare/plugins/audiogen-ggml/ops/audio-gen-input.js +153 -0
  77. package/dist/server/bare/plugins/audiogen-ggml/ops/audio-gen-stream.js +52 -1
  78. package/dist/server/bare/plugins/audiogen-ggml/plugin.d.ts +28 -0
  79. package/dist/server/bare/plugins/ggml-ocr/plugin.js +3 -1
  80. package/dist/server/bare/plugins/ggml-vla/ops/vla-set-embodiment.d.ts +3 -0
  81. package/dist/server/bare/plugins/ggml-vla/ops/vla-set-embodiment.js +9 -0
  82. package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +37 -0
  83. package/dist/server/bare/plugins/ggml-vla/plugin.js +21 -4
  84. package/dist/server/bare/plugins/llamacpp-completion/ops/batch-completion-stream.js +16 -15
  85. package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.d.ts +1 -1
  86. package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.js +2 -2
  87. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.d.ts +6 -0
  88. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.js +10 -0
  89. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +1 -0
  90. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +131 -123
  91. package/dist/server/bare/plugins/llamacpp-completion/ops/finetune.js +110 -20
  92. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.d.ts +49 -23
  93. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.js +308 -143
  94. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +1 -0
  95. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +2 -2
  96. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +6 -6
  97. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +55 -36
  98. package/dist/server/bare/plugins/llamacpp-completion/transform.js +1 -7
  99. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +2 -3
  100. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +6 -5
  101. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +27 -16
  102. package/dist/server/bare/plugins/tts-ggml/ops/parler-options.js +23 -3
  103. package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +302 -4
  104. package/dist/server/bare/plugins/tts-ggml/plugin.js +131 -0
  105. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +48 -39
  106. package/dist/server/bare/registry/model-registry.d.ts +1 -0
  107. package/dist/server/bare/runtime/request-registry-singleton.js +29 -15
  108. package/dist/server/bare/runtime/request-registry.d.ts +27 -0
  109. package/dist/server/bare/runtime/request-registry.js +246 -76
  110. package/dist/server/bare/types/addon-responses.d.ts +4 -12
  111. package/dist/server/rpc/handlers/load-model/handler.js +2 -2
  112. package/dist/server/rpc/handlers/load-model/resolve-session.d.ts +1 -1
  113. package/dist/server/rpc/handlers/load-model/resolve-session.js +3 -3
  114. package/dist/server/rpc/handlers/load-model/resolve.d.ts +12 -2
  115. package/dist/server/rpc/handlers/load-model/resolve.js +90 -12
  116. package/dist/server/utils/audio/decoder.d.ts +37 -1
  117. package/dist/server/utils/audio/decoder.js +81 -51
  118. package/dist/server/utils/config-transform.d.ts +3 -0
  119. package/dist/server/utils/config-transform.js +6 -0
  120. package/dist/server/utils/index.d.ts +0 -1
  121. package/dist/server/utils/index.js +0 -1
  122. package/dist/server/utils/shard-utils.d.ts +1 -0
  123. package/dist/server/utils/shard-utils.js +14 -0
  124. package/dist/server/utils/tool-integration.d.ts +3 -10
  125. package/dist/server/utils/tool-integration.js +3 -12
  126. package/dist/utils/errors-server.d.ts +3 -0
  127. package/dist/utils/errors-server.js +5 -0
  128. package/package.json +12 -14
  129. package/dist/examples/llamacpp-dynamic-tools.d.ts +0 -2
  130. package/dist/examples/llamacpp-dynamic-tools.js +0 -152
  131. package/dist/models/update-models/codegen.d.ts +0 -3
  132. package/dist/models/update-models/codegen.js +0 -196
  133. package/dist/models/update-models/companions.d.ts +0 -30
  134. package/dist/models/update-models/companions.js +0 -296
  135. package/dist/models/update-models/history.d.ts +0 -24
  136. package/dist/models/update-models/history.js +0 -107
  137. package/dist/models/update-models/index.d.ts +0 -2
  138. package/dist/models/update-models/index.js +0 -123
  139. package/dist/models/update-models/naming.d.ts +0 -4
  140. package/dist/models/update-models/naming.js +0 -396
  141. package/dist/models/update-models/processing.d.ts +0 -8
  142. package/dist/models/update-models/processing.js +0 -65
  143. package/dist/models/update-models/registry.d.ts +0 -5
  144. package/dist/models/update-models/registry.js +0 -87
  145. package/dist/models/update-models/shards.d.ts +0 -4
  146. package/dist/models/update-models/shards.js +0 -57
  147. package/dist/models/update-models/types.d.ts +0 -88
  148. package/dist/models/update-models/types.js +0 -1
  149. package/dist/models/update-models/utils.d.ts +0 -3
  150. package/dist/models/update-models/utils.js +0 -21
  151. package/dist/server/bare/plugins/llamacpp-completion/ops/batch-cancelled.d.ts +0 -23
  152. package/dist/server/bare/plugins/llamacpp-completion/ops/batch-cancelled.js +0 -30
  153. package/dist/server/utils/expand-gguf-shards.d.ts +0 -3
  154. package/dist/server/utils/expand-gguf-shards.js +0 -22
@@ -77,6 +77,37 @@ export const TTS_PARLER_EMOTIONS = [
77
77
  'sad',
78
78
  'surprise'
79
79
  ];
80
+ // Canonical cross-engine pace vocabulary (@qvac/tts-ggml `PACES`, unified in
81
+ // QVAC-23154). `moderate` is the neutral pace: on CosyVoice3 it disengages the
82
+ // pace conditioning channel entirely (plain zero-shot synthesis).
83
+ export const TTS_PACES = ['slow', 'moderate', 'fast'];
84
+ // CosyVoice3 supports a subset of the cross-engine emotion vocabulary and the
85
+ // full canonical pace vocabulary.
86
+ export const TTS_COSYVOICE3_EMOTIONS = ['anger', 'happy', 'neutral', 'sad'];
87
+ // CosyVoice3 structured-instruct control vocabulary (@qvac/tts-ggml
88
+ // `CosyvoiceInstruct`). Exactly one control renders per synthesis, resolved by
89
+ // precedence dialect > volume > style.
90
+ export const TTS_COSYVOICE3_INSTRUCT_DIALECTS = [
91
+ 'cantonese',
92
+ 'northeastern',
93
+ 'gansu',
94
+ 'guizhou',
95
+ 'henan',
96
+ 'hubei',
97
+ 'hunan',
98
+ 'jiangxi',
99
+ 'minnan',
100
+ 'ningxia',
101
+ 'shanxi',
102
+ 'shaanxi',
103
+ 'shandong',
104
+ 'shanghai',
105
+ 'sichuan',
106
+ 'tianjin',
107
+ 'yunnan'
108
+ ];
109
+ export const TTS_COSYVOICE3_INSTRUCT_VOLUMES = ['loud', 'soft'];
110
+ export const TTS_COSYVOICE3_INSTRUCT_STYLES = ['peppa', 'robot'];
80
111
  // Supertonic languages not already present in the Chatterbox set, used to keep
81
112
  // TTS_LANGUAGES a true union across engines without duplicates.
82
113
  const TTS_SUPERTONIC_ONLY_LANGUAGES = [
@@ -103,6 +134,8 @@ export const TTS_LANGUAGES = [
103
134
  const ttsChatterboxLanguageSchema = z.enum(TTS_CHATTERBOX_LANGUAGES);
104
135
  const ttsSupertonicLanguageSchema = z.enum(TTS_SUPERTONIC_LANGUAGES);
105
136
  const ttsParlerEmotionSchema = z.enum(TTS_PARLER_EMOTIONS);
137
+ const ttsCosyvoice3EmotionSchema = z.enum(TTS_COSYVOICE3_EMOTIONS);
138
+ const ttsPaceSchema = z.enum(TTS_PACES);
106
139
  const ttsIntegerSchema = z.number().int();
107
140
  const ttsNonNegativeIntegerSchema = ttsIntegerSchema.nonnegative();
108
141
  const ttsPositiveIntegerSchema = ttsIntegerSchema.positive();
@@ -120,7 +153,9 @@ const ttsParlerDescriptionFieldsShape = {
120
153
  voice: z.string().min(1).optional(),
121
154
  emotion: ttsParlerEmotionSchema.optional(),
122
155
  pitch: z.string().min(1).optional(),
123
- pace: z.string().min(1).optional(),
156
+ // Canonical cross-engine vocabulary since @qvac/tts-ggml 0.7 (QVAC-23154);
157
+ // free-form pace strings are rejected natively.
158
+ pace: ttsPaceSchema.optional(),
124
159
  expressivity: z.string().min(1).optional(),
125
160
  noise: z.string().min(1).optional(),
126
161
  reverb: z.string().min(1).optional(),
@@ -211,10 +246,102 @@ export const ttsParlerRuntimeConfigSchema = z
211
246
  normalizeNumbers: z.boolean().optional()
212
247
  })
213
248
  .superRefine(refineParlerRuntimeConfig);
249
+ // CosyVoice3 structured instruct: a raw string passes through to the engine as
250
+ // the exact instruction text (advanced escape hatch); the object form renders
251
+ // exactly one trained control by precedence dialect > volume > style.
252
+ // The string branch trims first: the addon trims too, so a whitespace-only
253
+ // instruction would otherwise silently degrade to zero-shot synthesis.
254
+ const ttsCosyvoice3InstructSchema = z.union([
255
+ z.string().trim().min(1),
256
+ z
257
+ .object({
258
+ dialect: z.enum(TTS_COSYVOICE3_INSTRUCT_DIALECTS).optional(),
259
+ volume: z.enum(TTS_COSYVOICE3_INSTRUCT_VOLUMES).optional(),
260
+ style: z.enum(TTS_COSYVOICE3_INSTRUCT_STYLES).optional()
261
+ })
262
+ .strict()
263
+ .refine((value) => value.dialect !== undefined || value.volume !== undefined || value.style !== undefined, { message: 'instruct requires at least one of dialect, volume, or style.' })
264
+ ]);
265
+ // CosyVoice3 is trained on one instruction per synthesis: at most one of
266
+ // `emotion`, a non-moderate `pace`, or `instruct` may be engaged at once
267
+ // (`pace: 'moderate'` disengages the pace channel).
268
+ function refineCosyvoice3ConditioningControls(config, ctx) {
269
+ const engaged = [];
270
+ if (config.emotion !== undefined)
271
+ engaged.push('emotion');
272
+ if (config.pace !== undefined && config.pace !== 'moderate')
273
+ engaged.push('pace');
274
+ if (config.instruct !== undefined)
275
+ engaged.push('instruct');
276
+ if (engaged.length > 1) {
277
+ ctx.addIssue({
278
+ code: 'custom',
279
+ path: [engaged[1]],
280
+ message: `CosyVoice3 accepts one conditioning control per synthesis; got ${engaged.join(', ')}. ` +
281
+ 'Set exactly one (pace "moderate" disengages the pace channel).'
282
+ });
283
+ }
284
+ }
285
+ function refineCosyvoice3NativeStreamingRate(config, ctx) {
286
+ const nativeStreamingEnabled = (config.streamChunkTokens ?? 0) > 0;
287
+ if (nativeStreamingEnabled &&
288
+ config.outputSampleRate !== undefined &&
289
+ config.outputSampleRate !== 24000) {
290
+ ctx.addIssue({
291
+ code: 'custom',
292
+ path: ['outputSampleRate'],
293
+ message: 'CosyVoice3 native streaming emits at 24000 Hz; omit outputSampleRate, use 24000, ' +
294
+ 'enable the LavaSR enhancer (which resamples seam-free), or disable native streaming.'
295
+ });
296
+ }
297
+ }
298
+ function refineCosyvoice3RuntimeConfig(config, ctx) {
299
+ refineCosyvoice3ConditioningControls(config, ctx);
300
+ refineCosyvoice3NativeStreamingRate(config, ctx);
301
+ }
302
+ const ttsCosyvoice3RuntimeConfigShape = {
303
+ ttsEngine: z.literal('cosyvoice3'),
304
+ emotion: ttsCosyvoice3EmotionSchema.optional(),
305
+ pace: ttsPaceSchema.optional(),
306
+ instruct: ttsCosyvoice3InstructSchema.optional(),
307
+ useGPU: z.boolean().optional(),
308
+ outputSampleRate: ttsOutputSampleRateSchema.optional(),
309
+ streamChunkTokens: ttsNonNegativeInt32Schema.optional(),
310
+ streamFirstChunkTokens: ttsNonNegativeInt32Schema.optional(),
311
+ threads: ttsPositiveInt32Schema.optional(),
312
+ nGpuLayers: ttsInt32Schema.optional(),
313
+ seed: ttsInt32Schema.optional()
314
+ };
315
+ export const ttsCosyvoice3RuntimeConfigSchema = z
316
+ .object(ttsCosyvoice3RuntimeConfigShape)
317
+ .superRefine(refineCosyvoice3RuntimeConfig);
318
+ const ttsAudio8RuntimeConfigShape = {
319
+ ttsEngine: z.literal('audio8'),
320
+ // Transcript of the load-time reference recording (zero-shot voice cloning).
321
+ // Paired with `referenceAudioSrc` on the load config; kept on the runtime
322
+ // config because it survives artifact resolution as plain data.
323
+ // Trimmed for the same reason as the CosyVoice3 instruct string: a
324
+ // whitespace-only transcript would reach the engine as a non-empty value.
325
+ referenceText: z.string().trim().min(1).optional(),
326
+ greedy: z.boolean().optional(),
327
+ temperature: z.number().nonnegative().optional(),
328
+ topK: ttsNonNegativeInt32Schema.optional(),
329
+ topP: z.number().positive().max(1).optional(),
330
+ // Codec frames on Audio8's ~46 ms grid (~21.5 frames/s); 0 = engine default.
331
+ maxFrames: ttsNonNegativeInt32Schema.optional(),
332
+ useGPU: z.boolean().optional(),
333
+ outputSampleRate: ttsOutputSampleRateSchema.optional(),
334
+ threads: ttsPositiveInt32Schema.optional(),
335
+ nGpuLayers: ttsInt32Schema.optional(),
336
+ seed: ttsInt32Schema.optional()
337
+ };
338
+ export const ttsAudio8RuntimeConfigSchema = z.object(ttsAudio8RuntimeConfigShape);
214
339
  export const ttsRuntimeConfigSchema = z.discriminatedUnion('ttsEngine', [
215
340
  ttsChatterboxRuntimeConfigSchema,
216
341
  ttsSupertonicRuntimeConfigSchema,
217
- ttsParlerRuntimeConfigSchema
342
+ ttsParlerRuntimeConfigSchema,
343
+ ttsCosyvoice3RuntimeConfigSchema,
344
+ ttsAudio8RuntimeConfigSchema
218
345
  ]);
219
346
  // Optional LavaSR post-processing model sources, shared across engines. Supply
220
347
  // the enhancer GGUF to bandwidth-extend the output to 48 kHz, and/or the
@@ -237,6 +364,65 @@ export const ttsSupertonicLoadConfigSchema = ttsSupertonicRuntimeConfigSchema.ex
237
364
  ...ttsLavasrLoadFieldsShape
238
365
  });
239
366
  export const ttsParlerLoadConfigSchema = ttsParlerRuntimeConfigSchema;
367
+ function refineCosyvoice3LoadConfig(config, ctx) {
368
+ refineCosyvoice3ConditioningControls(config, ctx);
369
+ // With the LavaSR enhancer active the addon resamples seam-free, so the
370
+ // 24 kHz native-streaming restriction only applies without it.
371
+ if (config.lavasrEnhancerModelSrc === undefined) {
372
+ refineCosyvoice3NativeStreamingRate(config, ctx);
373
+ }
374
+ if (config.lavasrDenoiserModelSrc !== undefined && (config.streamChunkTokens ?? 0) > 0) {
375
+ ctx.addIssue({
376
+ code: 'custom',
377
+ path: ['lavasrDenoiserModelSrc'],
378
+ message: 'The LavaSR denoiser is batch-only; disable native streaming (streamChunkTokens) to use it.'
379
+ });
380
+ }
381
+ }
382
+ // CosyVoice3 loads from a model *directory* (LLM/flow/HiFT GGUFs plus
383
+ // voice.gguf, vocab.json and merges.txt). The primary `modelSrc` is the LLM
384
+ // GGUF, whose registry companion set co-locates the remaining files, so the
385
+ // load config only adds the optional LavaSR post-processing sources.
386
+ export const ttsCosyvoice3LoadConfigSchema = z
387
+ .object({
388
+ ...ttsCosyvoice3RuntimeConfigShape,
389
+ ...ttsLavasrLoadFieldsShape
390
+ })
391
+ .superRefine(refineCosyvoice3LoadConfig);
392
+ function refineAudio8LoadConfig(config, ctx) {
393
+ if (config.referenceAudioSrc !== undefined && config.referenceText === undefined) {
394
+ ctx.addIssue({
395
+ code: 'custom',
396
+ path: ['referenceText'],
397
+ message: 'referenceText (the transcript of the reference recording) is required with referenceAudioSrc.'
398
+ });
399
+ }
400
+ if (config.referenceText !== undefined && config.referenceAudioSrc === undefined) {
401
+ ctx.addIssue({
402
+ code: 'custom',
403
+ path: ['referenceAudioSrc'],
404
+ message: 'referenceAudioSrc is required when referenceText is set.'
405
+ });
406
+ }
407
+ if (config.referenceAudioSrc !== undefined && config.audio8CodecEncoderModelSrc === undefined) {
408
+ ctx.addIssue({
409
+ code: 'custom',
410
+ path: ['audio8CodecEncoderModelSrc'],
411
+ message: 'Voice cloning requires the Audio8 codec encoder GGUF (audio8CodecEncoderModelSrc).'
412
+ });
413
+ }
414
+ }
415
+ // Audio8 loads from explicit per-component GGUFs: the primary `modelSrc` is
416
+ // the DualAR LM, the codec decoder is required, and the codec encoder is only
417
+ // needed for zero-shot voice cloning (reference audio + transcript).
418
+ export const ttsAudio8LoadConfigSchema = z
419
+ .object({
420
+ ...ttsAudio8RuntimeConfigShape,
421
+ audio8CodecDecoderModelSrc: modelSrcInputSchema,
422
+ audio8CodecEncoderModelSrc: modelSrcInputSchema.optional(),
423
+ referenceAudioSrc: modelSrcInputSchema.optional()
424
+ })
425
+ .superRefine(refineAudio8LoadConfig);
240
426
  function refineChatterboxTokenizerAssets(data, ctx) {
241
427
  if (data.ttsEngine !== 'chatterbox')
242
428
  return;
@@ -259,7 +445,9 @@ export const ttsLoadConfigSchema = z
259
445
  .discriminatedUnion('ttsEngine', [
260
446
  ttsChatterboxLoadConfigSchema,
261
447
  ttsSupertonicLoadConfigSchema,
262
- ttsParlerLoadConfigSchema
448
+ ttsParlerLoadConfigSchema,
449
+ ttsCosyvoice3LoadConfigSchema,
450
+ ttsAudio8LoadConfigSchema
263
451
  ])
264
452
  .superRefine(refineChatterboxTokenizerAssets);
265
453
  // === Legacy ONNX modelConfig fields (deprecated) ===
@@ -296,7 +484,9 @@ export const ttsConfigSchema = z
296
484
  .discriminatedUnion('ttsEngine', [
297
485
  ttsChatterboxLoadConfigSchema.extend(legacyTtsOnnxFieldsShape).strict(),
298
486
  ttsSupertonicLoadConfigSchema.extend(legacyTtsOnnxFieldsShape).strict(),
299
- ttsParlerLoadConfigSchema.strict()
487
+ ttsParlerLoadConfigSchema.strict(),
488
+ ttsCosyvoice3LoadConfigSchema.strict(),
489
+ ttsAudio8LoadConfigSchema.strict()
300
490
  ])
301
491
  .superRefine(refineChatterboxTokenizerAssets);
302
492
  const ttsClientParamsShape = {
@@ -1,20 +1,4 @@
1
1
  import { z } from 'zod';
2
- /**
3
- * `static` (default) — tools are prepended once after the system message and
4
- * shared across the chat session.
5
- * `dynamic` — tools are anchored after the last user message and trimmed
6
- * from the kv-cache once the tool-call chain resolves, so each user prompt
7
- * can carry its own tool set without poisoning the cache.
8
- *
9
- * Implementation detail: maps to the addon's `tools_compact` boolean. The
10
- * SDK uses the higher-level `static`/`dynamic` naming so the addon-side
11
- * mapping can change without breaking the public API.
12
- */
13
- export declare const TOOLS_MODE: {
14
- readonly static: "static";
15
- readonly dynamic: "dynamic";
16
- };
17
- export type ToolsMode = (typeof TOOLS_MODE)[keyof typeof TOOLS_MODE];
18
2
  export declare const toolSchema: z.ZodObject<{
19
3
  type: z.ZodLiteral<"function">;
20
4
  name: z.ZodString;
@@ -1,19 +1,4 @@
1
1
  import { z } from 'zod';
2
- /**
3
- * `static` (default) — tools are prepended once after the system message and
4
- * shared across the chat session.
5
- * `dynamic` — tools are anchored after the last user message and trimmed
6
- * from the kv-cache once the tool-call chain resolves, so each user prompt
7
- * can carry its own tool set without poisoning the cache.
8
- *
9
- * Implementation detail: maps to the addon's `tools_compact` boolean. The
10
- * SDK uses the higher-level `static`/`dynamic` naming so the addon-side
11
- * mapping can change without breaking the public API.
12
- */
13
- export const TOOLS_MODE = {
14
- static: 'static',
15
- dynamic: 'dynamic'
16
- };
17
2
  const jsonSchemaEnumValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
18
3
  export const toolSchema = z.object({
19
4
  type: z.literal('function'),
@@ -120,6 +120,7 @@ export declare const parakeetRuntimeConfigSchema: z.ZodObject<{
120
120
  streamingEnergyVad: z.ZodOptional<z.ZodBoolean>;
121
121
  streamingLeftContextMs: z.ZodOptional<z.ZodNumber>;
122
122
  streamingRightLookaheadMs: z.ZodOptional<z.ZodNumber>;
123
+ language: z.ZodOptional<z.ZodString>;
123
124
  streamingSpkCacheEnable: z.ZodOptional<z.ZodBoolean>;
124
125
  streamingSpkCacheLen: z.ZodOptional<z.ZodNumber>;
125
126
  streamingFifoLen: z.ZodOptional<z.ZodNumber>;
@@ -144,6 +145,7 @@ export declare const parakeetConfigSchema: z.ZodObject<{
144
145
  streamingEnergyVad: z.ZodOptional<z.ZodBoolean>;
145
146
  streamingLeftContextMs: z.ZodOptional<z.ZodNumber>;
146
147
  streamingRightLookaheadMs: z.ZodOptional<z.ZodNumber>;
148
+ language: z.ZodOptional<z.ZodString>;
147
149
  streamingSpkCacheEnable: z.ZodOptional<z.ZodBoolean>;
148
150
  streamingSpkCacheLen: z.ZodOptional<z.ZodNumber>;
149
151
  streamingFifoLen: z.ZodOptional<z.ZodNumber>;
@@ -104,6 +104,12 @@ export const parakeetRuntimeConfigSchema = z.object({
104
104
  streamingEnergyVad: z.boolean().optional(),
105
105
  streamingLeftContextMs: z.number().int().nonnegative().optional(),
106
106
  streamingRightLookaheadMs: z.number().int().nonnegative().optional(),
107
+ /**
108
+ * Multilingual CTC language id (e.g. `"hi"`, `"ta"`). Required for Indic
109
+ * Conformer GGUFs that advertise `parakeet.ctc.lang_*` ranges; ignored on
110
+ * monolingual CTC such as English `parakeet-ctc-0.6b`.
111
+ */
112
+ language: z.string().optional(),
107
113
  // === AOSC (Audio-Online Speaker Cache; v2.1+ Sortformer only) =========
108
114
  // Auto-enabled when the loaded GGUF carries
109
115
  // `parakeet.model_variant == "sortformer-streaming-v2.1-aosc"`. Ignored
@@ -117,10 +123,10 @@ export const parakeetRuntimeConfigSchema = z.object({
117
123
  backendsDir: z.string().optional(),
118
124
  openclCacheDir: z.string().optional()
119
125
  });
120
- // Parakeet's load-time config currently has no fields beyond the
121
- // runtime knobs (single GGUF model is supplied via the top-level
122
- // `modelSrc` of `loadModel`). The alias is retained so consumers can
123
- // keep importing `ParakeetConfig` / `parakeetConfigSchema`.
126
+ // Parakeet's load-time config is the runtime knobs (single GGUF model is
127
+ // supplied via the top-level `modelSrc` of `loadModel`). The alias is
128
+ // retained so consumers can keep importing `ParakeetConfig` /
129
+ // `parakeetConfigSchema`.
124
130
  export const parakeetConfigSchema = parakeetRuntimeConfigSchema;
125
131
  // === Parakeet legacy ONNX modelConfig fields (deprecated) ===
126
132
  //
@@ -225,12 +225,14 @@ export type TranscribeStreamClientParams = {
225
225
  parakeetStreamingConfig?: ParakeetStreamingRunConfig;
226
226
  };
227
227
  export interface TranscribeStreamSession {
228
+ stats: Promise<TranscribeStats | undefined>;
228
229
  write(audioChunk: Uint8Array): void;
229
230
  end(): void;
230
231
  destroy(): void;
231
232
  [Symbol.asyncIterator](): AsyncIterator<string>;
232
233
  }
233
234
  export interface TranscribeStreamMetadataSession {
235
+ stats: Promise<TranscribeStats | undefined>;
234
236
  write(audioChunk: Uint8Array): void;
235
237
  end(): void;
236
238
  destroy(): void;
@@ -252,6 +254,7 @@ export type TranscribeStreamEvent = {
252
254
  type: 'endOfTurn';
253
255
  } & EndOfTurnEvent);
254
256
  export interface TranscribeStreamConversationSession {
257
+ stats: Promise<TranscribeStats | undefined>;
255
258
  write(audioChunk: Uint8Array): void;
256
259
  end(): void;
257
260
  destroy(): void;
@@ -1,10 +1,56 @@
1
1
  import { z } from 'zod';
2
+ /**
3
+ * How a GR00T embodiment is named when selecting one: a tag string, its
4
+ * numeric `cat_id` (0..31), or an object carrying either plus an optional
5
+ * camera-count override. Mirrors the addon's `VlaEmbodimentSelector`.
6
+ *
7
+ * On the load path (`config.embodiment`) an object naming neither `tag` nor
8
+ * `catId` is allowed — the GGUF's default embodiment is used, with only the
9
+ * `numCameras` override applied.
10
+ */
11
+ export declare const vlaEmbodimentSelectorSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
12
+ tag: z.ZodOptional<z.ZodString>;
13
+ catId: z.ZodOptional<z.ZodNumber>;
14
+ numCameras: z.ZodOptional<z.ZodNumber>;
15
+ }, z.core.$strip>]>;
16
+ export type VlaEmbodimentSelector = z.input<typeof vlaEmbodimentSelectorSchema>;
17
+ /**
18
+ * The selector shape `vlaSetEmbodiment` accepts: a switch must name an
19
+ * embodiment, so the neither-tag-nor-catId object form is rejected here
20
+ * (matching the addon's `setEmbodiment` validation).
21
+ */
22
+ export declare const vlaEmbodimentSelectionSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
23
+ tag: z.ZodOptional<z.ZodString>;
24
+ catId: z.ZodOptional<z.ZodNumber>;
25
+ numCameras: z.ZodOptional<z.ZodNumber>;
26
+ }, z.core.$strip>]>;
27
+ /**
28
+ * The static type matching `vlaEmbodimentSelectionSchema`. Hand-written
29
+ * because zod refinements don't narrow the inferred type — `z.input` of the
30
+ * schema would still allow the load-path-only `{ numCameras }` / `{}`
31
+ * spellings that the switch schema rejects at runtime. The `never` fields
32
+ * encode "exactly one of tag / catId" structurally.
33
+ */
34
+ export type VlaEmbodimentSelection = string | number | {
35
+ tag: string;
36
+ catId?: never;
37
+ numCameras?: number;
38
+ } | {
39
+ catId: number;
40
+ tag?: never;
41
+ numCameras?: number;
42
+ };
2
43
  export declare const vlaConfigSchema: z.ZodObject<{
3
44
  backend: z.ZodOptional<z.ZodEnum<{
4
45
  cpu: "cpu";
5
46
  auto: "auto";
6
47
  }>>;
7
48
  verbosity: z.ZodOptional<z.ZodNumber>;
49
+ embodiment: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
50
+ tag: z.ZodOptional<z.ZodString>;
51
+ catId: z.ZodOptional<z.ZodNumber>;
52
+ numCameras: z.ZodOptional<z.ZodNumber>;
53
+ }, z.core.$strip>]>>;
8
54
  }, z.core.$strip>;
9
55
  export type VlaConfig = z.input<typeof vlaConfigSchema>;
10
56
  export declare const vlaHparamsSchema: z.ZodObject<{
@@ -24,6 +70,8 @@ export declare const vlaHparamsSchema: z.ZodObject<{
24
70
  patches: "patches";
25
71
  }>>;
26
72
  imagePatchElems: z.ZodOptional<z.ZodNumber>;
73
+ selectedEmbodimentTag: z.ZodOptional<z.ZodString>;
74
+ selectedEmbodimentCatId: z.ZodOptional<z.ZodNumber>;
27
75
  }, z.core.$strip>;
28
76
  export type VlaHparams = z.infer<typeof vlaHparamsSchema>;
29
77
  export declare const vlaStatsSchema: z.ZodObject<{
@@ -88,10 +136,45 @@ export declare const vlaHparamsResponseSchema: z.ZodObject<{
88
136
  patches: "patches";
89
137
  }>>;
90
138
  imagePatchElems: z.ZodOptional<z.ZodNumber>;
139
+ selectedEmbodimentTag: z.ZodOptional<z.ZodString>;
140
+ selectedEmbodimentCatId: z.ZodOptional<z.ZodNumber>;
91
141
  }, z.core.$strip>;
92
142
  backendName: z.ZodNullable<z.ZodString>;
93
143
  }, z.core.$strip>;
94
144
  export type VlaHparamsResponse = z.infer<typeof vlaHparamsResponseSchema>;
145
+ export declare const vlaSetEmbodimentRequestSchema: z.ZodObject<{
146
+ type: z.ZodLiteral<"vlaSetEmbodiment">;
147
+ modelId: z.ZodString;
148
+ embodiment: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
149
+ tag: z.ZodOptional<z.ZodString>;
150
+ catId: z.ZodOptional<z.ZodNumber>;
151
+ numCameras: z.ZodOptional<z.ZodNumber>;
152
+ }, z.core.$strip>]>;
153
+ }, z.core.$strip>;
154
+ export type VlaSetEmbodimentRequest = z.input<typeof vlaSetEmbodimentRequestSchema>;
155
+ export declare const vlaSetEmbodimentResponseSchema: z.ZodObject<{
156
+ hparams: z.ZodObject<{
157
+ chunkSize: z.ZodNumber;
158
+ actionDim: z.ZodNumber;
159
+ maxActionDim: z.ZodNumber;
160
+ maxStateDim: z.ZodNumber;
161
+ tokenizerMaxLength: z.ZodNumber;
162
+ visionImageSize: z.ZodNumber;
163
+ numCameras: z.ZodOptional<z.ZodNumber>;
164
+ stateInputMode: z.ZodOptional<z.ZodEnum<{
165
+ discrete: "discrete";
166
+ continuous: "continuous";
167
+ }>>;
168
+ imageInputMode: z.ZodOptional<z.ZodEnum<{
169
+ pixels: "pixels";
170
+ patches: "patches";
171
+ }>>;
172
+ imagePatchElems: z.ZodOptional<z.ZodNumber>;
173
+ selectedEmbodimentTag: z.ZodOptional<z.ZodString>;
174
+ selectedEmbodimentCatId: z.ZodOptional<z.ZodNumber>;
175
+ }, z.core.$strip>;
176
+ }, z.core.$strip>;
177
+ export type VlaSetEmbodimentResponse = z.infer<typeof vlaSetEmbodimentResponseSchema>;
95
178
  export interface VlaClientRunParams {
96
179
  modelId: string;
97
180
  images: Float32Array[];
@@ -1,6 +1,73 @@
1
1
  import { z } from 'zod';
2
2
  const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
3
3
  // ============================================
4
+ // Embodiment selection (GR00T only)
5
+ // ============================================
6
+ // Bounds mirrored from @qvac/vla-ggml: a cat_id indexes GR00T's
7
+ // CategorySpecificLinear bank whose category dim the architecture fixes at 32,
8
+ // and the native resolver caps camera counts at 64.
9
+ const MAX_EMBODIMENT_CAT_ID = 31;
10
+ const MAX_NUM_CAMERAS = 64;
11
+ // Sanity bound, not an addon contract — the addon only requires non-empty.
12
+ // Real tags are short snake_case identifiers (longest known: 37 chars); the
13
+ // cap stops a garbage or hostile string from travelling into the native
14
+ // resolver while leaving ample headroom for legitimate tags.
15
+ const MAX_EMBODIMENT_TAG_LENGTH = 256;
16
+ const embodimentTagSchema = z
17
+ .string()
18
+ .min(1)
19
+ .max(MAX_EMBODIMENT_TAG_LENGTH)
20
+ .describe("Embodiment tag string as stored in the GGUF (e.g. 'libero_sim').");
21
+ const embodimentCatIdSchema = z
22
+ .number()
23
+ .int()
24
+ .min(0)
25
+ .max(MAX_EMBODIMENT_CAT_ID)
26
+ .describe("The embodiment's numeric `cat_id` (0..31).");
27
+ const embodimentObjectSchema = z
28
+ .object({
29
+ tag: embodimentTagSchema.optional(),
30
+ catId: embodimentCatIdSchema.optional(),
31
+ numCameras: z
32
+ .number()
33
+ .int()
34
+ .min(1)
35
+ .max(MAX_NUM_CAMERAS)
36
+ .optional()
37
+ .describe('Overrides the camera count stored in the GGUF for the selected ' +
38
+ 'embodiment. Required to select an embodiment whose count was ' +
39
+ 'unknown at conversion time.')
40
+ })
41
+ .refine((value) => value.tag === undefined || value.catId === undefined, {
42
+ message: 'embodiment accepts either tag or catId, not both'
43
+ });
44
+ /**
45
+ * How a GR00T embodiment is named when selecting one: a tag string, its
46
+ * numeric `cat_id` (0..31), or an object carrying either plus an optional
47
+ * camera-count override. Mirrors the addon's `VlaEmbodimentSelector`.
48
+ *
49
+ * On the load path (`config.embodiment`) an object naming neither `tag` nor
50
+ * `catId` is allowed — the GGUF's default embodiment is used, with only the
51
+ * `numCameras` override applied.
52
+ */
53
+ export const vlaEmbodimentSelectorSchema = z.union([
54
+ embodimentTagSchema,
55
+ embodimentCatIdSchema,
56
+ embodimentObjectSchema
57
+ ]);
58
+ /**
59
+ * The selector shape `vlaSetEmbodiment` accepts: a switch must name an
60
+ * embodiment, so the neither-tag-nor-catId object form is rejected here
61
+ * (matching the addon's `setEmbodiment` validation).
62
+ */
63
+ export const vlaEmbodimentSelectionSchema = z.union([
64
+ embodimentTagSchema,
65
+ embodimentCatIdSchema,
66
+ embodimentObjectSchema.refine((value) => value.tag !== undefined || value.catId !== undefined, {
67
+ message: 'embodiment must name a tag or a catId'
68
+ })
69
+ ]);
70
+ // ============================================
4
71
  // Load-time config
5
72
  // ============================================
6
73
  export const vlaConfigSchema = z.object({
@@ -14,7 +81,13 @@ export const vlaConfigSchema = z.object({
14
81
  .number()
15
82
  .int()
16
83
  .optional()
17
- .describe('Native log verbosity forwarded to the addon (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG).')
84
+ .describe('Native log verbosity forwarded to the addon (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG).'),
85
+ embodiment: vlaEmbodimentSelectorSchema
86
+ .optional()
87
+ .describe('GR00T only: which embodiment of a multi-embodiment GGUF to activate at ' +
88
+ 'load — a tag string, a numeric `cat_id` (0..31), or `{ tag | catId, ' +
89
+ "numCameras }`. Omitted = the GGUF's default embodiment. Rejected by " +
90
+ 'the addon for non-GR00T models.')
18
91
  });
19
92
  // ============================================
20
93
  // Hparams (returned by the addon after load)
@@ -57,7 +130,23 @@ export const vlaHparamsSchema = z.object({
57
130
  .optional()
58
131
  .describe("For patch-input models (`imageInputMode === 'patches'`), the exact " +
59
132
  'per-camera patch buffer length each `images` entry must have. Absent ' +
60
- 'for pixel-input models.')
133
+ 'for pixel-input models.'),
134
+ selectedEmbodimentTag: z
135
+ .string()
136
+ .optional()
137
+ .describe('GR00T only: the embodiment tag resolved at load / after ' +
138
+ '`vlaSetEmbodiment`. Absent for SmolVLA / π₀.₅. Present is not the ' +
139
+ 'same as switchable — a single-embodiment GGUF reports its baked tag ' +
140
+ 'and still rejects `vlaSetEmbodiment`.'),
141
+ selectedEmbodimentCatId: z
142
+ .number()
143
+ .int()
144
+ .min(0)
145
+ .max(MAX_EMBODIMENT_CAT_ID)
146
+ .optional()
147
+ .describe("The resolved embodiment's numeric `cat_id` — the value to pass back " +
148
+ 'to select the same embodiment by id. Absent when no embodiment was ' +
149
+ 'resolved (SmolVLA / π₀.₅).')
61
150
  });
62
151
  // ============================================
63
152
  // Stats
@@ -149,3 +238,17 @@ export const vlaHparamsResponseSchema = z.object({
149
238
  hparams: vlaHparamsSchema,
150
239
  backendName: z.string().nullable()
151
240
  });
241
+ // ============================================
242
+ // Set-embodiment request / response (plugin handler)
243
+ // ============================================
244
+ export const vlaSetEmbodimentRequestSchema = z.object({
245
+ type: z.literal('vlaSetEmbodiment'),
246
+ modelId: z.string(),
247
+ embodiment: vlaEmbodimentSelectionSchema.describe('The embodiment to switch the loaded GR00T model to — a tag string, a ' +
248
+ 'numeric `cat_id` (0..31), or `{ tag | catId, numCameras }`. Must name ' +
249
+ 'a tag or a catId.')
250
+ });
251
+ export const vlaSetEmbodimentResponseSchema = z.object({
252
+ hparams: vlaHparamsSchema.describe('The refreshed hparams after the switch — `numCameras`, `actionDim` and ' +
253
+ 'the `selectedEmbodiment*` fields follow the newly active embodiment.')
254
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=link-workspace-inference.d.ts.map
@@ -0,0 +1,31 @@
1
+ // Overrides the SDK's @qvac/inference dependency with the in-monorepo sibling
2
+ // for the "workspace" pod-check leg, so the SDK builds and tests against the
3
+ // engine at the same commit.
4
+ import { readFileSync, writeFileSync } from 'fs';
5
+ import { join, resolve, dirname } from 'path';
6
+ import { spawnSync } from 'child_process';
7
+ import { fileURLToPath } from 'url';
8
+ const sdkDir = resolve(dirname(fileURLToPath(import.meta.url)), '..');
9
+ const inferenceDir = resolve(sdkDir, '..', 'inference');
10
+ function declaresInference() {
11
+ const pkg = JSON.parse(readFileSync(join(sdkDir, 'package.json'), 'utf8'));
12
+ return Boolean(pkg.dependencies?.['@qvac/inference']);
13
+ }
14
+ function run(command, args, cwd) {
15
+ const { status, error } = spawnSync(command, args, { cwd, stdio: 'inherit' });
16
+ if (error)
17
+ throw error;
18
+ if (status !== 0)
19
+ process.exit(status ?? 1);
20
+ }
21
+ if (!declaresInference()) {
22
+ console.log('[link-workspace-inference] @qvac/inference is not a dependency; skipping');
23
+ process.exit(0);
24
+ }
25
+ run('bun', ['install'], inferenceDir);
26
+ run('bun', ['run', 'build'], inferenceDir);
27
+ const manifestPath = join(sdkDir, 'package.json');
28
+ const pkg = JSON.parse(readFileSync(manifestPath, 'utf8'));
29
+ pkg.dependencies['@qvac/inference'] = 'file:../inference';
30
+ writeFileSync(manifestPath, `${JSON.stringify(pkg, null, 2)}\n`);
31
+ run('bun', ['install'], sdkDir);
@@ -5,7 +5,7 @@ import type { RequestKind } from '../../../server/bare/runtime/index.js';
5
5
  * optionally a `kind`). Maps onto `RequestRegistry.cancel({ modelId })`
6
6
  * — the registry walks active contexts and aborts each one's signal,
7
7
  * which each handler has wired to its own addon-level / async unwind
8
- * via the registry's `await using ctx = registry.begin(...)` block.
8
+ * via the registry's `await using ctx = await registry.begin(...)` block.
9
9
  *
10
10
  * Kept as a stable surface alongside the new `cancel({ requestId })`
11
11
  * path: the caller may not have a `requestId` to hand (model unload,
@@ -9,7 +9,7 @@ const logger = getServerLogger();
9
9
  * optionally a `kind`). Maps onto `RequestRegistry.cancel({ modelId })`
10
10
  * — the registry walks active contexts and aborts each one's signal,
11
11
  * which each handler has wired to its own addon-level / async unwind
12
- * via the registry's `await using ctx = registry.begin(...)` block.
12
+ * via the registry's `await using ctx = await registry.begin(...)` block.
13
13
  *
14
14
  * Kept as a stable surface alongside the new `cancel({ requestId })`
15
15
  * path: the caller may not have a `requestId` to hand (model unload,