@tryhamster/gerbil 1.1.3 → 1.2.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 (55) hide show
  1. package/dist/{architectures-wan0swXu.mjs → architectures-Ol7yUmKf.mjs} +128 -68
  2. package/dist/architectures-Ol7yUmKf.mjs.map +1 -0
  3. package/dist/cli.mjs +8 -8
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/{defaults-9komdrbY.mjs → defaults-bJcmOaRG.mjs} +2 -2
  6. package/dist/defaults-bJcmOaRG.mjs.map +1 -0
  7. package/dist/frameworks/express.mjs +1 -1
  8. package/dist/frameworks/fastify.mjs +1 -1
  9. package/dist/frameworks/hono.mjs +1 -1
  10. package/dist/frameworks/next.d.mts +2 -2
  11. package/dist/frameworks/next.mjs +1 -1
  12. package/dist/frameworks/trpc.mjs +1 -1
  13. package/dist/gerbil-0M50i8TK.mjs +4 -0
  14. package/dist/{gerbil-CQspp8fS.mjs → gerbil-DW1VioGN.mjs} +2 -2
  15. package/dist/{gerbil-CQspp8fS.mjs.map → gerbil-DW1VioGN.mjs.map} +1 -1
  16. package/dist/{gerbil-DZbWbIm2.d.mts → gerbil-DkilSf1Q.d.mts} +2 -2
  17. package/dist/{gerbil-DZbWbIm2.d.mts.map → gerbil-DkilSf1Q.d.mts.map} +1 -1
  18. package/dist/gpu/hooks.d.mts +24 -7
  19. package/dist/gpu/hooks.d.mts.map +1 -1
  20. package/dist/gpu/hooks.mjs +14 -7
  21. package/dist/gpu/hooks.mjs.map +1 -1
  22. package/dist/gpu/index.d.mts +2 -2
  23. package/dist/gpu/index.mjs +5 -5
  24. package/dist/{gpu-BYCQ5aTI.mjs → gpu-DR6EG0K-.mjs} +93 -24
  25. package/dist/gpu-DR6EG0K-.mjs.map +1 -0
  26. package/dist/index-Dgmb2kE3.d.mts.map +1 -1
  27. package/dist/{index-CKszv3lt.d.mts → index-HVS7yeLx.d.mts} +232 -133
  28. package/dist/index-HVS7yeLx.d.mts.map +1 -0
  29. package/dist/index.d.mts +2 -2
  30. package/dist/index.mjs +6 -6
  31. package/dist/integrations/ai-sdk.mjs +1 -1
  32. package/dist/integrations/langchain.mjs +1 -1
  33. package/dist/integrations/llamaindex.mjs +1 -1
  34. package/dist/integrations/mcp.d.mts +2 -2
  35. package/dist/integrations/mcp.mjs +4 -4
  36. package/dist/{mcp-CszII8GJ.mjs → mcp-8Tn3U-EE.mjs} +3 -3
  37. package/dist/{mcp-CszII8GJ.mjs.map → mcp-8Tn3U-EE.mjs.map} +1 -1
  38. package/dist/moonshine-stt-B3YtKcEE.mjs +4 -0
  39. package/dist/{moonshine-stt-DDUm5WfP.mjs → moonshine-stt-DSz3VW_0.mjs} +56 -6
  40. package/dist/{moonshine-stt-DDUm5WfP.mjs.map → moonshine-stt-DSz3VW_0.mjs.map} +1 -1
  41. package/dist/{one-liner-DVche8Eg.mjs → one-liner-BK9wqRYw.mjs} +2 -2
  42. package/dist/{one-liner-DVche8Eg.mjs.map → one-liner-BK9wqRYw.mjs.map} +1 -1
  43. package/dist/repl-B62rx3DS.mjs +9 -0
  44. package/dist/skills/index.d.mts +2 -2
  45. package/dist/skills/index.mjs +3 -3
  46. package/dist/{skills-BQI-VSn2.mjs → skills-BF3FVv8_.mjs} +2 -2
  47. package/dist/{skills-BQI-VSn2.mjs.map → skills-BF3FVv8_.mjs.map} +1 -1
  48. package/package.json +1 -1
  49. package/dist/architectures-wan0swXu.mjs.map +0 -1
  50. package/dist/defaults-9komdrbY.mjs.map +0 -1
  51. package/dist/gerbil-tHnYb9nZ.mjs +0 -4
  52. package/dist/gpu-BYCQ5aTI.mjs.map +0 -1
  53. package/dist/index-CKszv3lt.d.mts.map +0 -1
  54. package/dist/moonshine-stt-BtR-KiSP.mjs +0 -4
  55. package/dist/repl-BYJA2U7t.mjs +0 -9
@@ -1,6 +1,6 @@
1
- import { n as resolveDefaultRepo, t as DEFAULT_MODELS } from "../defaults-9komdrbY.mjs";
2
- import { C as parseKaniConfig, _ as generateNanoCodecDecoderGraph, a as generateMoonshineEncoderGraph, f as audioTokensToCodes, g as generateKaniTtsGraph, i as generateMoonshineDecoderGraph, o as moonshineEncoderFrames, r as MOONSHINE_REMAINING_WORK, s as parseMoonshineConfig } from "../architectures-wan0swXu.mjs";
3
- import { C as generateGemma4VisionGraph, S as dequantizeMLXProjection, T as resolveGemma4VisionInfo, _ as smartResize, a as buildGemma4PosEmbeds, b as generateQwen3_5VisionGraph, c as buildMRoPECosSin, d as buildPositionIds, f as buildRotaryCosSin, g as preprocessImageGemma4, h as preprocessImage, i as buildGemma4PoolMatrix, l as buildMRoPEPositionIds, m as mropeFreqDims, n as GEMMA4_IMAGE_PROCESSOR, o as buildGemma4RotaryCosSin, p as buildVisionPositionTensors, r as QWEN3_5_IMAGE_PROCESSOR, s as buildGemma4VisionPositionTensors, t as WebGPUEngine, u as buildPosEmbeds, v as VisionExecutor, w as patchGemma4VisionClips, x as dequantizeGemma4VisionProjection, y as KaniTTS } from "../gpu-BYCQ5aTI.mjs";
4
- import { a as loadMoonshine, g as initGPU, i as loadModel, n as MoonshineEncoderExecutor, r as loadKaniTTS, s as Executor, t as MoonshineSTT } from "../moonshine-stt-DDUm5WfP.mjs";
1
+ import { n as resolveDefaultRepo, t as DEFAULT_MODELS } from "../defaults-bJcmOaRG.mjs";
2
+ import { a as generateMoonshineEncoderGraph, h as generateNanoCodecDecoderGraph, i as generateMoonshineDecoderGraph, m as generateKaniTtsGraph, o as moonshineEncoderFrames, r as MOONSHINE_REMAINING_WORK, s as parseMoonshineConfig, u as audioTokensToCodes, x as parseKaniConfig } from "../architectures-Ol7yUmKf.mjs";
3
+ import { C as generateGemma4VisionGraph, S as dequantizeMLXProjection, T as resolveGemma4VisionInfo, _ as smartResize, a as buildGemma4PosEmbeds, b as generateQwen3_5VisionGraph, c as buildMRoPECosSin, d as buildPositionIds, f as buildRotaryCosSin, g as preprocessImageGemma4, h as preprocessImage, i as buildGemma4PoolMatrix, l as buildMRoPEPositionIds, m as mropeFreqDims, n as GEMMA4_IMAGE_PROCESSOR, o as buildGemma4RotaryCosSin, p as buildVisionPositionTensors, r as QWEN3_5_IMAGE_PROCESSOR, s as buildGemma4VisionPositionTensors, t as WebGPUEngine, u as buildPosEmbeds, v as VisionExecutor, w as patchGemma4VisionClips, x as dequantizeGemma4VisionProjection, y as KaniTTS } from "../gpu-DR6EG0K-.mjs";
4
+ import { _ as initGPU, a as loadMoonshine, c as Executor, i as loadModel, n as MoonshineEncoderExecutor, o as quantizeKaniBackbone, r as loadKaniTTS, t as MoonshineSTT } from "../moonshine-stt-DSz3VW_0.mjs";
5
5
 
6
- export { DEFAULT_MODELS, Executor, GEMMA4_IMAGE_PROCESSOR, KaniTTS, MOONSHINE_REMAINING_WORK, MoonshineEncoderExecutor, MoonshineSTT, QWEN3_5_IMAGE_PROCESSOR, VisionExecutor, WebGPUEngine, audioTokensToCodes, buildGemma4PoolMatrix, buildGemma4PosEmbeds, buildGemma4RotaryCosSin, buildGemma4VisionPositionTensors, buildMRoPECosSin, buildMRoPEPositionIds, buildPosEmbeds, buildPositionIds, buildRotaryCosSin, buildVisionPositionTensors, dequantizeGemma4VisionProjection, dequantizeMLXProjection, generateGemma4VisionGraph, generateKaniTtsGraph, generateMoonshineDecoderGraph, generateMoonshineEncoderGraph, generateNanoCodecDecoderGraph, generateQwen3_5VisionGraph, initGPU, loadKaniTTS, loadModel, loadMoonshine, moonshineEncoderFrames, mropeFreqDims, parseKaniConfig, parseMoonshineConfig, patchGemma4VisionClips, preprocessImage, preprocessImageGemma4, resolveDefaultRepo, resolveGemma4VisionInfo, smartResize };
6
+ export { DEFAULT_MODELS, Executor, GEMMA4_IMAGE_PROCESSOR, KaniTTS, MOONSHINE_REMAINING_WORK, MoonshineEncoderExecutor, MoonshineSTT, QWEN3_5_IMAGE_PROCESSOR, VisionExecutor, WebGPUEngine, audioTokensToCodes, buildGemma4PoolMatrix, buildGemma4PosEmbeds, buildGemma4RotaryCosSin, buildGemma4VisionPositionTensors, buildMRoPECosSin, buildMRoPEPositionIds, buildPosEmbeds, buildPositionIds, buildRotaryCosSin, buildVisionPositionTensors, dequantizeGemma4VisionProjection, dequantizeMLXProjection, generateGemma4VisionGraph, generateKaniTtsGraph, generateMoonshineDecoderGraph, generateMoonshineEncoderGraph, generateNanoCodecDecoderGraph, generateQwen3_5VisionGraph, initGPU, loadKaniTTS, loadModel, loadMoonshine, moonshineEncoderFrames, mropeFreqDims, parseKaniConfig, parseMoonshineConfig, patchGemma4VisionClips, preprocessImage, preprocessImageGemma4, quantizeKaniBackbone, resolveDefaultRepo, resolveGemma4VisionInfo, smartResize };
@@ -1,6 +1,6 @@
1
- import { n as resolveDefaultRepo } from "./defaults-9komdrbY.mjs";
2
- import { C as parseKaniConfig, E as GEMMA4_VIS_KEYS, T as DTYPE_BYTES, _ as generateNanoCodecDecoderGraph, b as kaniLayerAlpha, d as KANI_START_OF_HUMAN, f as audioTokensToCodes, g as generateKaniTtsGraph, m as computeKaniPositions, p as buildKaniLayerCosSin, u as KANI_END_OF_HUMAN, v as kaniAttentionLayerIndices, w as CANONICAL_KEYS, x as kaniSinTensor, y as kaniCosTensor } from "./architectures-wan0swXu.mjs";
3
- import { _ as verifyGPU, c as KERNEL_REGISTRY, d as createBindGroup, f as createStorageBuffer, g as initGPU, h as getOrCreatePipeline, i as loadModel, l as MATMUL_BIAS_F16C_SPEC, m as destroyBuffers, o as remapPrunedToken, p as createUniformBuffer, r as loadKaniTTS, s as Executor, u as clearPipelineCache } from "./moonshine-stt-DDUm5WfP.mjs";
1
+ import { n as resolveDefaultRepo, t as DEFAULT_MODELS } from "./defaults-bJcmOaRG.mjs";
2
+ import { E as GEMMA4_VIS_KEYS, T as DTYPE_BYTES, _ as kaniCosTensor, c as KANI_END_OF_HUMAN, d as buildKaniLayerCosSin, f as computeKaniPositions, g as kaniAttentionLayerIndices, h as generateNanoCodecDecoderGraph, l as KANI_START_OF_HUMAN, m as generateKaniTtsGraph, u as audioTokensToCodes, v as kaniLayerAlpha, w as CANONICAL_KEYS, x as parseKaniConfig, y as kaniSinTensor } from "./architectures-Ol7yUmKf.mjs";
3
+ import { _ as initGPU, c as Executor, d as clearPipelineCache, f as createBindGroup, g as getOrCreatePipeline, h as destroyBuffers, i as loadModel, l as KERNEL_REGISTRY, m as createUniformBuffer, o as quantizeKaniBackbone, p as createStorageBuffer, r as loadKaniTTS, s as remapPrunedToken, u as MATMUL_BIAS_F16C_SPEC, v as verifyGPU } from "./moonshine-stt-DSz3VW_0.mjs";
4
4
 
5
5
  //#region src/gpu/architectures/gemma4_vision.ts
6
6
  /**
@@ -802,6 +802,19 @@ function nucleusSample(probs, ids, topP) {
802
802
  }
803
803
  return ids[order[0]];
804
804
  }
805
+ /**
806
+ * In-place top-k filter over a probability array: keep only the `k` highest, zero
807
+ * the rest, and renormalize. No-op when k <= 0 or k >= length (keep everything).
808
+ */
809
+ function applyTopK(scores, k) {
810
+ const n = scores.length;
811
+ if (k <= 0 || k >= n) return;
812
+ const order = Array.from({ length: n }, (_, i) => i).sort((a, b) => scores[b] - scores[a]);
813
+ let keepSum = 0;
814
+ for (let r = 0; r < k; r++) keepSum += scores[order[r]];
815
+ for (let r = k; r < n; r++) scores[order[r]] = 0;
816
+ if (keepSum > 0) for (let i = 0; i < n; i++) scores[i] /= keepSum;
817
+ }
805
818
  /** In-place softmax of `scores`. */
806
819
  function softmaxInPlace(scores) {
807
820
  let maxV = Number.NEGATIVE_INFINITY;
@@ -829,14 +842,23 @@ var KaniTTS = class KaniTTS {
829
842
  headDim;
830
843
  ropeBase;
831
844
  _destroyed = false;
832
- architecture = "KaniTTS2ForCausalLM";
833
- constructor(ctx, loaded, maxSeqLen) {
845
+ /** Accent/voice tags the loaded checkpoint advertises (empty = single voice). */
846
+ voiceTags;
847
+ /** The loaded checkpoint's architecture string ("KaniTTS2ForCausalLM" or "Lfm2ForCausalLM"). */
848
+ architecture;
849
+ /** The selected backbone precision ("q4" or "f32"). */
850
+ dtype;
851
+ constructor(ctx, loaded, maxSeqLen, dtype) {
834
852
  this.ctx = ctx;
835
853
  this.loaded = loaded;
836
854
  this.tokenizer = loaded.tokenizer;
837
855
  this.rawConfig = loaded.rawConfig;
838
856
  this.cfg = parseKaniConfig(loaded.rawConfig);
839
857
  this.maxSeqLen = maxSeqLen;
858
+ this.dtype = loaded.preQuantized ? "q4" : dtype;
859
+ this.architecture = (loaded.rawConfig.architectures ?? [])[0] ?? "Lfm2ForCausalLM";
860
+ const langSettings = loaded.rawConfig.language_settings;
861
+ this.voiceTags = Array.isArray(langSettings?.language_tags_list) ? langSettings.language_tags_list.filter((v) => typeof v === "string") : [];
840
862
  const hidden = this.rawConfig.hidden_size;
841
863
  const heads = this.rawConfig.num_attention_heads;
842
864
  this.headDim = this.rawConfig.head_dim ?? Math.floor(hidden / heads);
@@ -852,13 +874,26 @@ var KaniTTS = class KaniTTS {
852
874
  }
853
875
  this.layerAlpha.set(layer, alpha);
854
876
  }
855
- const graph = generateKaniTtsGraph(this.rawConfig);
856
- this.backboneExec = new Executor(ctx, graph, {
877
+ this.backboneExec = this.buildBackbone(ctx, loaded, maxSeqLen);
878
+ }
879
+ /**
880
+ * Build the codec-LM backbone graph, quantize it when q4, and upload its weights
881
+ * into a fresh Executor. For a pre-quantized (gerbil-int4) checkpoint the linear
882
+ * projections already carry `.q`/`.scales`/`.zeros`, so quantizeKaniBackbone is an
883
+ * idempotent no-op (it skips any projection whose `.q` is already present) and the
884
+ * int4 weights are uploaded verbatim — no on-device re-quantization.
885
+ */
886
+ buildBackbone(ctx, loaded, maxSeqLen) {
887
+ const useQ4 = this.dtype === "q4";
888
+ const graph = generateKaniTtsGraph(this.rawConfig, useQ4 ? "q4" : void 0);
889
+ if (useQ4) quantizeKaniBackbone(graph, loaded.backboneWeights);
890
+ const exec = new Executor(ctx, graph, {
857
891
  maxSeqLen,
858
892
  kvMode: "f32"
859
893
  });
860
- this.backboneExec.uploadWeightsMap(selectGraphWeights(graph, loaded.backboneWeights));
861
- this.backboneExec.initBindGroups();
894
+ exec.uploadWeightsMap(selectGraphWeights(graph, loaded.backboneWeights));
895
+ exec.initBindGroups();
896
+ return exec;
862
897
  }
863
898
  static async create(options = {}) {
864
899
  const ctx = await initGPU();
@@ -871,7 +906,7 @@ var KaniTTS = class KaniTTS {
871
906
  onProgress: options.onProgress
872
907
  });
873
908
  const ctxLen = loaded.rawConfig.max_position_embeddings ?? 4096;
874
- return new KaniTTS(ctx, loaded, Math.min(options.maxSeqLen ?? 2048, ctxLen));
909
+ return new KaniTTS(ctx, loaded, Math.min(options.maxSeqLen ?? 2048, ctxLen), options.dtype ?? "q4");
875
910
  }
876
911
  /** Write per-layer cos/sin for token rows [rowStart, rowStart+positions.length). */
877
912
  writeCosSin(positions, rowStart) {
@@ -889,6 +924,20 @@ var KaniTTS = class KaniTTS {
889
924
  }
890
925
  }
891
926
  /**
927
+ * Accent/voice tags the loaded checkpoint supports. Multi-accent KaniTTS2
928
+ * checkpoints (kani-tts-2-en) return e.g. ["en_us","en_nyork","en_glasg", …];
929
+ * the plain LFM2 family (the Apache default) returns [] (one trained voice,
930
+ * selectable only by fine-tuning the backbone — there is no runtime voice/
931
+ * speaker-prompt knob, and zero-shot cloning is not wired).
932
+ */
933
+ availableVoices() {
934
+ return [...this.voiceTags];
935
+ }
936
+ /** NanoCodec's fixed output sample rate (Hz). Not selectable — see SpeakResult. */
937
+ get sampleRate() {
938
+ return KANI_SAMPLE_RATE;
939
+ }
940
+ /**
892
941
  * Synthesize speech for `text`. Returns 22 kHz mono PCM.
893
942
  *
894
943
  * Pipeline: build the [SOH]+text+[EOT,EOH] prompt → prefill the codec-LM →
@@ -899,12 +948,13 @@ var KaniTTS = class KaniTTS {
899
948
  if (this._destroyed) throw new Error("KaniTTS has been destroyed.");
900
949
  const temperature = opts.temperature ?? 1;
901
950
  const topP = opts.topP ?? .95;
951
+ const topK = opts.topK ?? 0;
902
952
  const repetitionPenalty = opts.repetitionPenalty ?? 1.1;
903
- const tag = opts.languageTag ?? "en_us";
904
953
  const maxNewTokens = Math.min(opts.maxNewTokens ?? DEFAULT_MAX_NEW_TOKENS, this.maxSeqLen);
954
+ const promptText = this.voiceTags.length > 0 ? `${(opts.languageTag ?? this.voiceTags[0]).trim()}: ${text}` : text;
905
955
  const prompt = [
906
956
  KANI_START_OF_HUMAN,
907
- ...this.tokenizer.encode(`${tag.trim()}: ${text}`),
957
+ ...this.tokenizer.encode(promptText),
908
958
  KANI_END_OF_TEXT,
909
959
  KANI_END_OF_HUMAN
910
960
  ];
@@ -917,6 +967,7 @@ var KaniTTS = class KaniTTS {
917
967
  const { audioTokens, finished } = await this.runDecodeLoop(prompt, logits, {
918
968
  temperature,
919
969
  topP,
970
+ topK,
920
971
  repetitionPenalty,
921
972
  maxNewTokens,
922
973
  maxFrames: opts.maxFrames ?? Number.POSITIVE_INFINITY
@@ -953,6 +1004,7 @@ var KaniTTS = class KaniTTS {
953
1004
  const nextToken = inSpeech ? this.sampleAudioToken(logits, audioTokens.length % this.cfg.tokensPerFrame, {
954
1005
  temperature: p.temperature,
955
1006
  topP: p.topP,
1007
+ topK: p.topK,
956
1008
  repetitionPenalty: p.repetitionPenalty,
957
1009
  previous: seq
958
1010
  }) : this.argmax(logits);
@@ -994,7 +1046,8 @@ var KaniTTS = class KaniTTS {
994
1046
  /**
995
1047
  * Sample one audio token for codebook position `codebook`, constrained to that
996
1048
  * codebook's valid window [audio_tokens_start + 4032*c, +4032). Allows end_of_speech
997
- * only at codebook 0 (frame boundary). Applies temperature, top-p, rep-penalty.
1049
+ * only at codebook 0 (frame boundary). Applies repetition penalty, temperature,
1050
+ * optional top-k, then top-p nucleus sampling.
998
1051
  */
999
1052
  sampleAudioToken(logits, codebook, p) {
1000
1053
  const winStart = this.cfg.audioTokensStart + this.cfg.codebookSize * codebook;
@@ -1012,6 +1065,7 @@ var KaniTTS = class KaniTTS {
1012
1065
  scores[i] = s / p.temperature;
1013
1066
  }
1014
1067
  softmaxInPlace(scores);
1068
+ applyTopK(scores, p.topK);
1015
1069
  return nucleusSample(scores, ids, p.topP);
1016
1070
  }
1017
1071
  /**
@@ -3069,29 +3123,44 @@ var WebGPUEngine = class WebGPUEngine {
3069
3123
  throw new Error(`generateObject failed after ${attemptsMax} attempt(s): ${lastError}. Last output: ${JSON.stringify(lastText.slice(0, 200))}`);
3070
3124
  }
3071
3125
  /**
3072
- * Text-to-speech: text → 22 kHz PCM via Kani-TTS-2 (LFM2-350M codec-LM + NVIDIA
3126
+ * Text-to-speech: text → 22 kHz PCM via KaniTTS (LFM2-350M codec-LM + NVIDIA
3073
3127
  * NeMo NanoCodec). Returns `{ pcm: Float32Array, sampleRate: 22050 }`.
3074
3128
  *
3075
3129
  * Runs the full pipeline: the codec-LM backbone autoregressively emits NanoCodec
3076
- * audio tokens (4 per frame, frame-level positions + learnable per-layer RoPE),
3077
- * then the bit-exact NanoCodec decoder (FSQ + causal HiFi-GAN) turns the codes
3078
- * into PCM. The heavy lifting lives in {@link KaniTTS} (src/gpu/kani-tts.ts); this
3079
- * lazily constructs that engine on first use (downloading the NanoCodec codec
3080
- * checkpoint alongside the backbone).
3130
+ * audio tokens (4 per frame), then the bit-exact NanoCodec decoder (FSQ + causal
3131
+ * HiFi-GAN) turns the codes into PCM. The heavy lifting lives in {@link KaniTTS}
3132
+ * (src/gpu/kani-tts.ts); this lazily constructs that engine on first use
3133
+ * (downloading the NanoCodec codec checkpoint alongside the backbone).
3081
3134
  *
3082
- * Requires a Kani-TTS-2 checkpoint (architecture "KaniTTS2ForCausalLM").
3135
+ * The default checkpoint is the Apache-2.0 `nineninesix/kani-tts-450m-0.2-ft`
3136
+ * (plain `Lfm2ForCausalLM` backbone); the earlier `KaniTTS2ForCausalLM`
3137
+ * checkpoints (multi-accent) also work. The codec-LM backbone defaults to INT4
3138
+ * (`dtype: "q4"`) — pass `dtype: "f32"` for full precision.
3083
3139
  */
3084
3140
  async speak(text, options = {}) {
3085
3141
  this.checkDestroyed();
3086
- if (this._architecture !== "KaniTTS2ForCausalLM") throw new Error(`speak() requires a Kani-TTS-2 model (architecture "KaniTTS2ForCausalLM"), loaded engine is "${this._architecture}".`);
3142
+ const repo = this._createOptions.repo ?? "";
3143
+ if (!(this._architecture === "KaniTTS2ForCausalLM" || /kani-tts/i.test(repo) || /\btts\b/i.test(repo))) throw new Error(`speak() requires a Kani-TTS checkpoint (e.g. "${DEFAULT_MODELS.tts}"), loaded engine is "${this._architecture}" (repo "${repo}").`);
3087
3144
  if (!this._kaniTTS) this._kaniTTS = await KaniTTS.create({
3088
3145
  repo: this._createOptions.repo,
3089
3146
  revision: this._createOptions.revision,
3090
3147
  hfToken: this._createOptions.hfToken,
3091
3148
  cacheDir: this._createOptions.cacheDir,
3092
- maxSeqLen: this.maxSeqLen
3149
+ maxSeqLen: this.maxSeqLen,
3150
+ dtype: options.dtype
3151
+ });
3152
+ return this._kaniTTS.speak(text, {
3153
+ languageTag: options.voice ?? options.languageTag,
3154
+ temperature: options.temperature,
3155
+ topP: options.topP,
3156
+ topK: options.topK,
3157
+ repetitionPenalty: options.repetitionPenalty,
3158
+ maxFrames: options.maxFrames
3093
3159
  });
3094
- return this._kaniTTS.speak(text, options);
3160
+ }
3161
+ /** Accent/voice tags the lazily-built TTS engine supports ([] = single voice). */
3162
+ ttsVoices() {
3163
+ return this._kaniTTS?.availableVoices() ?? [];
3095
3164
  }
3096
3165
  /**
3097
3166
  * Describe an image: image-in → text-out. Runs the vision encoder, splices the
@@ -3799,4 +3868,4 @@ var WebGPUEngine = class WebGPUEngine {
3799
3868
 
3800
3869
  //#endregion
3801
3870
  export { generateGemma4VisionGraph as C, dequantizeMLXProjection as S, resolveGemma4VisionInfo as T, smartResize as _, buildGemma4PosEmbeds as a, generateQwen3_5VisionGraph as b, buildMRoPECosSin as c, buildPositionIds as d, buildRotaryCosSin as f, preprocessImageGemma4 as g, preprocessImage as h, buildGemma4PoolMatrix as i, buildMRoPEPositionIds as l, mropeFreqDims as m, GEMMA4_IMAGE_PROCESSOR as n, buildGemma4RotaryCosSin as o, buildVisionPositionTensors as p, QWEN3_5_IMAGE_PROCESSOR as r, buildGemma4VisionPositionTensors as s, WebGPUEngine as t, buildPosEmbeds as u, VisionExecutor as v, patchGemma4VisionClips as w, dequantizeGemma4VisionProjection as x, KaniTTS as y };
3802
- //# sourceMappingURL=gpu-BYCQ5aTI.mjs.map
3871
+ //# sourceMappingURL=gpu-DR6EG0K-.mjs.map