@tryhamster/gerbil 1.0.0-rc.0 → 1.0.0-rc.10

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 (114) hide show
  1. package/README.md +79 -14
  2. package/dist/auto-update-S9s5-g0C.mjs +3 -0
  3. package/dist/browser/index.d.ts +1009 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/browser/index.js +2492 -0
  6. package/dist/browser/index.js.map +1 -0
  7. package/dist/{chrome-backend-C5Un08O4.mjs → chrome-backend-CORwaIyC.mjs} +514 -73
  8. package/dist/chrome-backend-CORwaIyC.mjs.map +1 -0
  9. package/dist/{chrome-backend-CtwPENIW.mjs → chrome-backend-DIKYoWj-.mjs} +1 -1
  10. package/dist/cli.mjs +3359 -647
  11. package/dist/cli.mjs.map +1 -1
  12. package/dist/frameworks/express.d.mts +1 -1
  13. package/dist/frameworks/express.mjs +3 -4
  14. package/dist/frameworks/express.mjs.map +1 -1
  15. package/dist/frameworks/fastify.d.mts +1 -1
  16. package/dist/frameworks/fastify.mjs +2 -3
  17. package/dist/frameworks/fastify.mjs.map +1 -1
  18. package/dist/frameworks/hono.d.mts +1 -1
  19. package/dist/frameworks/hono.mjs +2 -3
  20. package/dist/frameworks/hono.mjs.map +1 -1
  21. package/dist/frameworks/next.d.mts +2 -2
  22. package/dist/frameworks/next.mjs +2 -3
  23. package/dist/frameworks/next.mjs.map +1 -1
  24. package/dist/frameworks/react.d.mts +1 -1
  25. package/dist/frameworks/trpc.d.mts +1 -1
  26. package/dist/frameworks/trpc.mjs +2 -3
  27. package/dist/frameworks/trpc.mjs.map +1 -1
  28. package/dist/gerbil-DJGqq7BX.mjs +4 -0
  29. package/dist/gerbil-DoDGHe6Z.mjs +1631 -0
  30. package/dist/gerbil-DoDGHe6Z.mjs.map +1 -0
  31. package/dist/gerbil-qOTe1nl2.d.mts +431 -0
  32. package/dist/gerbil-qOTe1nl2.d.mts.map +1 -0
  33. package/dist/index.d.mts +411 -9
  34. package/dist/index.d.mts.map +1 -1
  35. package/dist/index.mjs +7 -6
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/integrations/ai-sdk.d.mts +122 -4
  38. package/dist/integrations/ai-sdk.d.mts.map +1 -1
  39. package/dist/integrations/ai-sdk.mjs +238 -11
  40. package/dist/integrations/ai-sdk.mjs.map +1 -1
  41. package/dist/integrations/langchain.d.mts +132 -2
  42. package/dist/integrations/langchain.d.mts.map +1 -1
  43. package/dist/integrations/langchain.mjs +175 -8
  44. package/dist/integrations/langchain.mjs.map +1 -1
  45. package/dist/integrations/llamaindex.d.mts +1 -1
  46. package/dist/integrations/llamaindex.mjs +2 -3
  47. package/dist/integrations/llamaindex.mjs.map +1 -1
  48. package/dist/integrations/mcp-client.mjs +4 -4
  49. package/dist/integrations/mcp-client.mjs.map +1 -1
  50. package/dist/integrations/mcp.d.mts +2 -2
  51. package/dist/integrations/mcp.d.mts.map +1 -1
  52. package/dist/integrations/mcp.mjs +5 -6
  53. package/dist/kokoro-BNTb6egA.mjs +20210 -0
  54. package/dist/kokoro-BNTb6egA.mjs.map +1 -0
  55. package/dist/kokoro-CMOGDSgT.js +20212 -0
  56. package/dist/kokoro-CMOGDSgT.js.map +1 -0
  57. package/dist/{mcp-R8kRLIKb.mjs → mcp-kzDDWIoS.mjs} +10 -37
  58. package/dist/mcp-kzDDWIoS.mjs.map +1 -0
  59. package/dist/microphone-DaMZFRuR.mjs +3 -0
  60. package/dist/{one-liner-BUQR0nqq.mjs → one-liner-DxnNs_JK.mjs} +2 -2
  61. package/dist/{one-liner-BUQR0nqq.mjs.map → one-liner-DxnNs_JK.mjs.map} +1 -1
  62. package/dist/repl-DGUw4fCc.mjs +9 -0
  63. package/dist/skills/index.d.mts +305 -14
  64. package/dist/skills/index.d.mts.map +1 -1
  65. package/dist/skills/index.mjs +5 -6
  66. package/dist/skills-DulrOPeP.mjs +1435 -0
  67. package/dist/skills-DulrOPeP.mjs.map +1 -0
  68. package/dist/stt-1WIefHwc.mjs +3 -0
  69. package/dist/stt-CG_7KB_0.mjs +434 -0
  70. package/dist/stt-CG_7KB_0.mjs.map +1 -0
  71. package/dist/stt-Dne6SENv.js +434 -0
  72. package/dist/stt-Dne6SENv.js.map +1 -0
  73. package/dist/{tools-BsiEE6f2.mjs → tools-Bi1P7Xoy.mjs} +6 -7
  74. package/dist/{tools-BsiEE6f2.mjs.map → tools-Bi1P7Xoy.mjs.map} +1 -1
  75. package/dist/transformers.web-DiD1gTwk.js +44695 -0
  76. package/dist/transformers.web-DiD1gTwk.js.map +1 -0
  77. package/dist/transformers.web-u34VxRFM.js +3 -0
  78. package/dist/tts-B1pZMlDv.mjs +3 -0
  79. package/dist/tts-C2FzKuSx.js +725 -0
  80. package/dist/tts-C2FzKuSx.js.map +1 -0
  81. package/dist/tts-CyHhcLtN.mjs +731 -0
  82. package/dist/tts-CyHhcLtN.mjs.map +1 -0
  83. package/dist/types-CiTc7ez3.d.mts +353 -0
  84. package/dist/types-CiTc7ez3.d.mts.map +1 -0
  85. package/dist/{utils-7vXqtq2Q.mjs → utils-CZBZ8dgR.mjs} +1 -1
  86. package/dist/{utils-7vXqtq2Q.mjs.map → utils-CZBZ8dgR.mjs.map} +1 -1
  87. package/docs/ai-sdk.md +137 -21
  88. package/docs/browser.md +241 -2
  89. package/docs/memory.md +72 -0
  90. package/docs/stt.md +494 -0
  91. package/docs/tts.md +569 -0
  92. package/docs/vision.md +396 -0
  93. package/package.json +21 -22
  94. package/dist/auto-update-BbNHbSU1.mjs +0 -3
  95. package/dist/browser/index.d.mts +0 -262
  96. package/dist/browser/index.d.mts.map +0 -1
  97. package/dist/browser/index.mjs +0 -755
  98. package/dist/browser/index.mjs.map +0 -1
  99. package/dist/chrome-backend-C5Un08O4.mjs.map +0 -1
  100. package/dist/gerbil-BfnsFWRE.mjs +0 -644
  101. package/dist/gerbil-BfnsFWRE.mjs.map +0 -1
  102. package/dist/gerbil-BjW-z7Fq.mjs +0 -5
  103. package/dist/gerbil-DZ1k3ChC.d.mts +0 -138
  104. package/dist/gerbil-DZ1k3ChC.d.mts.map +0 -1
  105. package/dist/mcp-R8kRLIKb.mjs.map +0 -1
  106. package/dist/models-DKULvhOr.mjs +0 -136
  107. package/dist/models-DKULvhOr.mjs.map +0 -1
  108. package/dist/models-De2-_GmQ.d.mts +0 -22
  109. package/dist/models-De2-_GmQ.d.mts.map +0 -1
  110. package/dist/skills-D3CEpgDc.mjs +0 -630
  111. package/dist/skills-D3CEpgDc.mjs.map +0 -1
  112. package/dist/types-BS1N92Jt.d.mts +0 -183
  113. package/dist/types-BS1N92Jt.d.mts.map +0 -1
  114. /package/dist/{chunk-Ct1HF2bE.mjs → chunk-CkXuGtQK.mjs} +0 -0
@@ -1,5 +1,5 @@
1
- import { c as GerbilModelSettings, f as ModelConfig, l as GerbilProviderSettings } from "../types-BS1N92Jt.mjs";
2
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2CallWarning, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2StreamPart, LanguageModelV2Usage } from "@ai-sdk/provider";
1
+ import { b as STTModelConfig, g as ModelConfig, l as GerbilModelSettings, u as GerbilProviderSettings } from "../types-CiTc7ez3.mjs";
2
+ import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2CallWarning, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2StreamPart, LanguageModelV2Usage, SpeechModelV2, SpeechModelV2CallOptions, SpeechModelV2CallWarning, TranscriptionModelV2, TranscriptionModelV2CallOptions, TranscriptionModelV2CallWarning } from "@ai-sdk/provider";
3
3
 
4
4
  //#region src/integrations/ai-sdk.d.ts
5
5
 
@@ -38,11 +38,85 @@ declare class GerbilLanguageModel implements LanguageModelV2 {
38
38
  };
39
39
  }>;
40
40
  }
41
+ /** Settings for Gerbil speech model */
42
+ interface GerbilSpeechSettings {
43
+ /** Default voice ID (default: "af_heart") */
44
+ voice?: string;
45
+ /** Speech speed multiplier (default: 1.0) */
46
+ speed?: number;
47
+ }
48
+ declare class GerbilSpeechModel implements SpeechModelV2 {
49
+ readonly specificationVersion: "v2";
50
+ readonly provider = "gerbil";
51
+ readonly modelId: string;
52
+ private instance;
53
+ private readonly settings;
54
+ private loadPromise;
55
+ constructor(modelId: string, settings?: GerbilSpeechSettings);
56
+ private ensureLoaded;
57
+ doGenerate(options: SpeechModelV2CallOptions): Promise<{
58
+ audio: Uint8Array;
59
+ warnings: SpeechModelV2CallWarning[];
60
+ request?: {
61
+ body?: unknown;
62
+ };
63
+ response: {
64
+ timestamp: Date;
65
+ modelId: string;
66
+ };
67
+ }>;
68
+ /**
69
+ * Convert Float32Array audio to WAV format Uint8Array
70
+ */
71
+ private float32ToWav;
72
+ }
73
+ /** Settings for Gerbil transcription model */
74
+ interface GerbilTranscriptionSettings {
75
+ /** Default language code (ISO-639-1) for transcription */
76
+ language?: string;
77
+ }
78
+ declare class GerbilTranscriptionModel implements TranscriptionModelV2 {
79
+ readonly specificationVersion: "v2";
80
+ readonly provider = "gerbil";
81
+ readonly modelId: string;
82
+ private instance;
83
+ private readonly settings;
84
+ private loadPromise;
85
+ constructor(modelId: string, settings?: GerbilTranscriptionSettings);
86
+ private ensureLoaded;
87
+ doGenerate(options: TranscriptionModelV2CallOptions): Promise<{
88
+ text: string;
89
+ segments: Array<{
90
+ text: string;
91
+ startSecond: number;
92
+ endSecond: number;
93
+ }>;
94
+ language: string | undefined;
95
+ durationInSeconds: number | undefined;
96
+ warnings: TranscriptionModelV2CallWarning[];
97
+ request?: {
98
+ body?: string;
99
+ };
100
+ response: {
101
+ timestamp: Date;
102
+ modelId: string;
103
+ };
104
+ }>;
105
+ }
41
106
  type GerbilProvider = {
42
107
  (modelId: string, settings?: GerbilModelSettings): GerbilLanguageModel;
43
108
  languageModel(modelId: string, settings?: GerbilModelSettings): GerbilLanguageModel;
109
+ speech(modelId?: string, settings?: GerbilSpeechSettings): GerbilSpeechModel;
110
+ transcription(modelId?: string, settings?: GerbilTranscriptionSettings): GerbilTranscriptionModel;
44
111
  listModels(): ModelConfig[];
45
112
  getModel(modelId: string): ModelConfig | undefined;
113
+ listVoices(): Array<{
114
+ id: string;
115
+ name: string;
116
+ gender: string;
117
+ language: string;
118
+ }>;
119
+ listTranscriptionModels(): STTModelConfig[];
46
120
  };
47
121
  /**
48
122
  * Create a Gerbil provider
@@ -51,17 +125,31 @@ type GerbilProvider = {
51
125
  * ```ts
52
126
  * const local = createGerbil({ device: "gpu", dtype: "q4" });
53
127
  *
128
+ * // Text generation
54
129
  * const { text } = await generateText({
55
130
  * model: local("qwen3-0.6b"),
56
131
  * prompt: "Hello",
57
132
  * });
133
+ *
134
+ * // Speech generation
135
+ * const audio = await generateSpeech({
136
+ * model: local.speech(),
137
+ * text: "Hello world!",
138
+ * voice: "af_heart",
139
+ * });
140
+ *
141
+ * // Transcription
142
+ * const transcript = await transcribe({
143
+ * model: local.transcription(),
144
+ * audio: audioBuffer,
145
+ * });
58
146
  * ```
59
147
  */
60
148
  declare function createGerbil(options?: GerbilProviderSettings): GerbilProvider;
61
149
  /**
62
150
  * Default Gerbil provider
63
151
  *
64
- * @example
152
+ * @example Text Generation
65
153
  * ```ts
66
154
  * import { generateText } from "ai";
67
155
  * import { gerbil } from "gerbil/ai";
@@ -71,8 +159,38 @@ declare function createGerbil(options?: GerbilProviderSettings): GerbilProvider;
71
159
  * prompt: "Hello",
72
160
  * });
73
161
  * ```
162
+ *
163
+ * @example Speech Generation
164
+ * ```ts
165
+ * import { experimental_generateSpeech as generateSpeech } from "ai";
166
+ * import { gerbil } from "gerbil/ai";
167
+ *
168
+ * const audio = await generateSpeech({
169
+ * model: gerbil.speech(),
170
+ * text: "Hello world!",
171
+ * voice: "af_heart", // Or "bf_emma", "am_fenrir", etc.
172
+ * });
173
+ *
174
+ * // Access audio data
175
+ * const audioData = audio.audioData; // Uint8Array (WAV format)
176
+ * ```
177
+ *
178
+ * @example Transcription
179
+ * ```ts
180
+ * import { experimental_transcribe as transcribe } from "ai";
181
+ * import { gerbil } from "gerbil/ai";
182
+ * import { readFile } from "fs/promises";
183
+ *
184
+ * const transcript = await transcribe({
185
+ * model: gerbil.transcription(), // whisper-tiny.en by default
186
+ * audio: await readFile("audio.wav"),
187
+ * });
188
+ *
189
+ * console.log(transcript.text);
190
+ * console.log(transcript.segments); // Timestamped segments
191
+ * ```
74
192
  */
75
193
  declare const gerbil: GerbilProvider;
76
194
  //#endregion
77
- export { GerbilProvider, createGerbil, gerbil as default, gerbil };
195
+ export { GerbilProvider, GerbilSpeechSettings, GerbilTranscriptionSettings, createGerbil, gerbil as default, gerbil };
78
196
  //# sourceMappingURL=ai-sdk.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-sdk.d.mts","names":[],"sources":["../../src/integrations/ai-sdk.ts"],"sourcesContent":[],"mappings":";;;;;cA0CM,mBAAA,YAA+B,eAqIe,CAAA;EArIf,SAAA,oBAAA,EAAA,IAAA;EAAe,SAAA,QAAA,GAAA,QAAA;EAmNxC,SAAA,OAAA,EAAc,MAAA;EACK,SAAA,aAAA,EA9ML,MA8MK,CAAA,MAAA,EA9MU,MA8MV,EAAA,CAAA;EAAsB,QAAA,QAAA;EACT,iBAAA,QAAA;EAAsB,iBAAA,gBAAA;EAClD,QAAA,WAAA;EACa,WAAA,CAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAxMf,mBAwMe,EAAA,gBAAA,EAvMP,sBAuMO;EAAW,QAAA,YAAA;EAgBxB,QAAA,aAAY;EA4Bf,QAAA,eAAM;sBA7KS,6BAA0B;;;;;;;;;;;;oBA+C5B,6BAA0B;;;;;;;;;;KA8ExC,cAAA;+BACmB,sBAAsB;4CACT,sBAAsB;gBAClD;6BACa;;;;;;;;;;;;;;;iBAgBb,YAAA,WAAsB,yBAA8B;;;;;;;;;;;;;;;cA4BvD,QAAM"}
1
+ {"version":3,"file":"ai-sdk.d.mts","names":[],"sources":["../../src/integrations/ai-sdk.ts"],"sourcesContent":[],"mappings":";;;;;cAwDM,mBAAA,YAA+B,eAsJe,CAAA;EAtJf,SAAA,oBAAA,EAAA,IAAA;EAAe,SAAA,QAAA,GAAA,QAAA;EAsOnC,SAAA,OAAA,EAAA,MAAoB;EAO/B,SAAA,aAAkB,EAvOE,MAuOF,CAAA,MAAA,EAvOiB,MAuOjB,EAAA,CAAA;EASiB,QAAA,QAAA;EAoBb,iBAAA,QAAA;EACjB,iBAAA,gBAAA;EACG,QAAA,WAAA;EAEa,WAAA,CAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EA/Pb,mBA+Pa,EAAA,gBAAA,EA9PL,sBA8PK;EAJ4B,QAAA,YAAA;EA7BpB,QAAA,aAAA;EAAa,QAAA,eAAA;EAoI/B,UAAA,CAAA,OAAA,EA3QW,0BA2QgB,CAAA,EA3QU,OA2QV,CAAA;IAKtC,OAAA,wBAAyB,EAAA;IASU,YAAA,6BAAA;IAoBb,KAAA,sBAAA;IAEd,OAAA,EAAA;MAOA,IAAA,EAAA;QAGG,KAAA,EAAA,MAAA;QAZ6C,MAAA,EAAA,MAAA;MA7BpB,CAAA;IAAoB,CAAA;IAiHlD,QAAA,4BAAc,EAAA;EACK,CAAA,CAAA;EAAsB,QAAA,CAAA,OAAA,EAlV3B,0BAkV2B,CAAA,EAlVD,OAkVC,CAAA;IACT,MAAA,gBAAA,0BAAA,CAAA;IAAsB,OAAA,EAAA;MAC5B,IAAA,EAAA;QAAuB,KAAA,EAAA,MAAA;QAChB,MAAA,EAAA,MAAA;MAA8B,CAAA;IAC3D,CAAA;EACa,CAAA,CAAA;;;AAEc,UAzQ1B,oBAAA,CAyQ0B;EA8B3B;EA4EH,KAAA,CAAA,EAAA,MAAuB;;;;cA5W9B,iBAAA,YAA6B;;;;;;;0CASM;;sBAoBb,2BAA2B;WAC5C;cACG;;;;;iBAEa;;;;;;;;;;UAmGV,2BAAA;;;;cAKX,wBAAA,YAAoC;;;;;;;0CASD;;sBAoBb,kCAAkC;;cAEhD;;;;;;;cAOA;;;;;iBAGG;;;;;KAwEL,cAAA;+BACmB,sBAAsB;4CACT,sBAAsB;sCAC5B,uBAAuB;6CAChB,8BAA8B;gBAC3D;6BACa;gBACb;;;;;;6BACa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8Bb,YAAA,WAAsB,yBAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4EvD,QAAM"}
@@ -1,11 +1,12 @@
1
- import { t as BUILTIN_MODELS } from "../models-DKULvhOr.mjs";
2
- import "../utils-7vXqtq2Q.mjs";
3
- import { t as Gerbil } from "../gerbil-BfnsFWRE.mjs";
1
+ import { n as BUILTIN_MODELS, t as Gerbil } from "../gerbil-DoDGHe6Z.mjs";
2
+ import "../utils-CZBZ8dgR.mjs";
3
+ import { t as WHISPER_MODELS } from "../stt-CG_7KB_0.mjs";
4
+ import { t as KOKORO_VOICES } from "../tts-CyHhcLtN.mjs";
4
5
 
5
6
  //#region src/integrations/ai-sdk.ts
6
7
  let idCounter = 0;
7
8
  function generateId() {
8
- return `gerbil-${Date.now()}-${++idCounter}`;
9
+ return `gerbil-${Date.now()}-${idCounter += 1}`;
9
10
  }
10
11
  var GerbilLanguageModel = class {
11
12
  specificationVersion = "v2";
@@ -38,15 +39,27 @@ var GerbilLanguageModel = class {
38
39
  convertPrompt(prompt) {
39
40
  let system;
40
41
  let user = "";
42
+ const images = [];
41
43
  for (const msg of prompt) if (msg.role === "system") system = msg.content;
42
44
  else if (msg.role === "user") {
43
45
  for (const part of msg.content) if (part.type === "text") user += part.text;
46
+ else if (part.type === "image") {
47
+ const imgPart = part;
48
+ if (imgPart.image instanceof URL) images.push({ source: imgPart.image.toString() });
49
+ else if (typeof imgPart.image === "string") images.push({ source: imgPart.image });
50
+ else if (imgPart.image instanceof Uint8Array) {
51
+ const base64 = btoa(String.fromCharCode(...imgPart.image));
52
+ const mimeType = imgPart.mimeType || "image/png";
53
+ images.push({ source: `data:${mimeType};base64,${base64}` });
54
+ }
55
+ }
44
56
  } else if (msg.role === "assistant") {
45
57
  for (const part of msg.content) if (part.type === "text") user += `\n\nAssistant: ${part.text}`;
46
58
  } else if (msg.role === "tool") for (const part of msg.content) user += `\n\nTool (${part.toolName}): ${JSON.stringify(part)}`;
47
59
  return {
48
60
  system,
49
- user
61
+ user,
62
+ images
50
63
  };
51
64
  }
52
65
  mapFinishReason(reason) {
@@ -58,7 +71,7 @@ var GerbilLanguageModel = class {
58
71
  async doGenerate(options) {
59
72
  const warnings = [];
60
73
  const g = await this.ensureLoaded();
61
- const { system, user } = this.convertPrompt(options.prompt);
74
+ const { system, user, images } = this.convertPrompt(options.prompt);
62
75
  const result = await g.generate(user, {
63
76
  maxTokens: options.maxOutputTokens,
64
77
  temperature: options.temperature,
@@ -66,7 +79,8 @@ var GerbilLanguageModel = class {
66
79
  topK: options.topK,
67
80
  system,
68
81
  thinking: this.settings.thinking,
69
- stopSequences: options.stopSequences
82
+ stopSequences: options.stopSequences,
83
+ images: images.length > 0 ? images : void 0
70
84
  });
71
85
  const content = [];
72
86
  if (result.thinking) content.push({
@@ -96,7 +110,7 @@ var GerbilLanguageModel = class {
96
110
  async doStream(options) {
97
111
  const warnings = [];
98
112
  const g = await this.ensureLoaded();
99
- const { system, user } = this.convertPrompt(options.prompt);
113
+ const { system, user, images } = this.convertPrompt(options.prompt);
100
114
  const streamGen = g.stream(user, {
101
115
  maxTokens: options.maxOutputTokens,
102
116
  temperature: options.temperature,
@@ -104,7 +118,8 @@ var GerbilLanguageModel = class {
104
118
  topK: options.topK,
105
119
  system,
106
120
  thinking: this.settings.thinking,
107
- stopSequences: options.stopSequences
121
+ stopSequences: options.stopSequences,
122
+ images: images.length > 0 ? images : void 0
108
123
  });
109
124
  let tokens = 0;
110
125
  const textId = generateId();
@@ -120,7 +135,7 @@ var GerbilLanguageModel = class {
120
135
  id: textId
121
136
  });
122
137
  for await (const chunk of streamGen) {
123
- tokens++;
138
+ tokens += 1;
124
139
  controller.enqueue({
125
140
  type: "text-delta",
126
141
  id: textId,
@@ -156,6 +171,163 @@ var GerbilLanguageModel = class {
156
171
  };
157
172
  }
158
173
  };
174
+ var GerbilSpeechModel = class {
175
+ specificationVersion = "v2";
176
+ provider = "gerbil";
177
+ modelId;
178
+ instance = null;
179
+ settings;
180
+ loadPromise = null;
181
+ constructor(modelId, settings = {}) {
182
+ this.modelId = modelId;
183
+ this.settings = settings;
184
+ }
185
+ async ensureLoaded() {
186
+ if (this.instance?.isTTSLoaded()) return this.instance;
187
+ if (this.loadPromise) {
188
+ await this.loadPromise;
189
+ return this.instance;
190
+ }
191
+ this.instance = new Gerbil();
192
+ this.loadPromise = this.instance.ensureTTSLoaded();
193
+ await this.loadPromise;
194
+ return this.instance;
195
+ }
196
+ async doGenerate(options) {
197
+ const warnings = [];
198
+ const g = await this.ensureLoaded();
199
+ let voice = options.voice || this.settings.voice || "af_heart";
200
+ if (!KOKORO_VOICES.find((v) => v.id === voice)) {
201
+ warnings.push({
202
+ type: "unsupported-setting",
203
+ setting: "voice",
204
+ details: `Unknown voice "${voice}", using default "af_heart"`
205
+ });
206
+ voice = "af_heart";
207
+ }
208
+ const speed = options.speed ?? this.settings.speed ?? 1;
209
+ if (options.outputFormat && options.outputFormat !== "wav" && options.outputFormat !== "raw") warnings.push({
210
+ type: "unsupported-setting",
211
+ setting: "outputFormat",
212
+ details: `Gerbil TTS only supports "wav" and "raw" formats, got "${options.outputFormat}"`
213
+ });
214
+ if (options.instructions) warnings.push({
215
+ type: "unsupported-setting",
216
+ setting: "instructions",
217
+ details: "Gerbil TTS does not support instructions parameter"
218
+ });
219
+ const result = await g.speak(options.text, {
220
+ voice,
221
+ speed
222
+ });
223
+ return {
224
+ audio: this.float32ToWav(result.audio, result.sampleRate),
225
+ warnings,
226
+ request: { body: {
227
+ text: options.text,
228
+ voice,
229
+ speed
230
+ } },
231
+ response: {
232
+ timestamp: /* @__PURE__ */ new Date(),
233
+ modelId: this.modelId
234
+ }
235
+ };
236
+ }
237
+ /**
238
+ * Convert Float32Array audio to WAV format Uint8Array
239
+ */
240
+ float32ToWav(audio, sampleRate) {
241
+ const buffer = /* @__PURE__ */ new ArrayBuffer(44 + audio.length * 2);
242
+ const view = new DataView(buffer);
243
+ const writeString = (offset, str) => {
244
+ for (let i = 0; i < str.length; i++) view.setUint8(offset + i, str.charCodeAt(i));
245
+ };
246
+ writeString(0, "RIFF");
247
+ view.setUint32(4, 36 + audio.length * 2, true);
248
+ writeString(8, "WAVE");
249
+ writeString(12, "fmt ");
250
+ view.setUint32(16, 16, true);
251
+ view.setUint16(20, 1, true);
252
+ view.setUint16(22, 1, true);
253
+ view.setUint32(24, sampleRate, true);
254
+ view.setUint32(28, sampleRate * 2, true);
255
+ view.setUint16(32, 2, true);
256
+ view.setUint16(34, 16, true);
257
+ writeString(36, "data");
258
+ view.setUint32(40, audio.length * 2, true);
259
+ for (let i = 0; i < audio.length; i++) {
260
+ const s = Math.max(-1, Math.min(1, audio[i]));
261
+ view.setInt16(44 + i * 2, Math.round(s * 32767), true);
262
+ }
263
+ return new Uint8Array(buffer);
264
+ }
265
+ };
266
+ var GerbilTranscriptionModel = class {
267
+ specificationVersion = "v2";
268
+ provider = "gerbil";
269
+ modelId;
270
+ instance = null;
271
+ settings;
272
+ loadPromise = null;
273
+ constructor(modelId, settings = {}) {
274
+ this.modelId = modelId;
275
+ this.settings = settings;
276
+ }
277
+ async ensureLoaded() {
278
+ if (this.instance?.isSTTLoaded()) return this.instance;
279
+ if (this.loadPromise) {
280
+ await this.loadPromise;
281
+ return this.instance;
282
+ }
283
+ this.instance = new Gerbil();
284
+ this.loadPromise = this.instance.loadSTT(this.modelId);
285
+ await this.loadPromise;
286
+ return this.instance;
287
+ }
288
+ async doGenerate(options) {
289
+ const warnings = [];
290
+ const g = await this.ensureLoaded();
291
+ let audioData;
292
+ if (typeof options.audio === "string") {
293
+ const binaryString = atob(options.audio);
294
+ audioData = new Uint8Array(binaryString.length);
295
+ for (let i = 0; i < binaryString.length; i++) audioData[i] = binaryString.charCodeAt(i);
296
+ } else audioData = options.audio;
297
+ const mediaType = options.mediaType?.toLowerCase() || "";
298
+ if (mediaType && !mediaType.includes("wav") && !mediaType.includes("wave")) warnings.push({
299
+ type: "unsupported-setting",
300
+ setting: "mediaType",
301
+ details: `Gerbil STT natively supports WAV format. Got "${options.mediaType}". Audio may not decode correctly.`
302
+ });
303
+ const language = (options.providerOptions?.gerbil)?.language || this.settings.language;
304
+ const result = await g.transcribe(audioData, {
305
+ language,
306
+ timestamps: true
307
+ });
308
+ const segments = (result.segments || []).map((seg) => ({
309
+ text: seg.text,
310
+ startSecond: seg.start,
311
+ endSecond: seg.end
312
+ }));
313
+ return {
314
+ text: result.text,
315
+ segments,
316
+ language: result.language,
317
+ durationInSeconds: result.duration,
318
+ warnings,
319
+ request: { body: JSON.stringify({
320
+ model: this.modelId,
321
+ mediaType: options.mediaType,
322
+ language
323
+ }) },
324
+ response: {
325
+ timestamp: /* @__PURE__ */ new Date(),
326
+ modelId: this.modelId
327
+ }
328
+ };
329
+ }
330
+ };
159
331
  /**
160
332
  * Create a Gerbil provider
161
333
  *
@@ -163,24 +335,49 @@ var GerbilLanguageModel = class {
163
335
  * ```ts
164
336
  * const local = createGerbil({ device: "gpu", dtype: "q4" });
165
337
  *
338
+ * // Text generation
166
339
  * const { text } = await generateText({
167
340
  * model: local("qwen3-0.6b"),
168
341
  * prompt: "Hello",
169
342
  * });
343
+ *
344
+ * // Speech generation
345
+ * const audio = await generateSpeech({
346
+ * model: local.speech(),
347
+ * text: "Hello world!",
348
+ * voice: "af_heart",
349
+ * });
350
+ *
351
+ * // Transcription
352
+ * const transcript = await transcribe({
353
+ * model: local.transcription(),
354
+ * audio: audioBuffer,
355
+ * });
170
356
  * ```
171
357
  */
172
358
  function createGerbil(options = {}) {
173
359
  const createModel = (modelId, settings = {}) => new GerbilLanguageModel(modelId, settings, options);
360
+ const createSpeechModel = (modelId = "kokoro-82m", settings = {}) => new GerbilSpeechModel(modelId, settings);
361
+ const createTranscriptionModel = (modelId = "whisper-tiny.en", settings = {}) => new GerbilTranscriptionModel(modelId, settings);
174
362
  const provider = ((modelId, settings) => createModel(modelId, settings ?? {}));
175
363
  provider.languageModel = createModel;
364
+ provider.speech = createSpeechModel;
365
+ provider.transcription = createTranscriptionModel;
176
366
  provider.listModels = () => Object.values(BUILTIN_MODELS);
177
367
  provider.getModel = (id) => BUILTIN_MODELS[id];
368
+ provider.listVoices = () => KOKORO_VOICES.map((v) => ({
369
+ id: v.id,
370
+ name: v.name,
371
+ gender: v.gender,
372
+ language: v.language
373
+ }));
374
+ provider.listTranscriptionModels = () => WHISPER_MODELS;
178
375
  return provider;
179
376
  }
180
377
  /**
181
378
  * Default Gerbil provider
182
379
  *
183
- * @example
380
+ * @example Text Generation
184
381
  * ```ts
185
382
  * import { generateText } from "ai";
186
383
  * import { gerbil } from "gerbil/ai";
@@ -190,6 +387,36 @@ function createGerbil(options = {}) {
190
387
  * prompt: "Hello",
191
388
  * });
192
389
  * ```
390
+ *
391
+ * @example Speech Generation
392
+ * ```ts
393
+ * import { experimental_generateSpeech as generateSpeech } from "ai";
394
+ * import { gerbil } from "gerbil/ai";
395
+ *
396
+ * const audio = await generateSpeech({
397
+ * model: gerbil.speech(),
398
+ * text: "Hello world!",
399
+ * voice: "af_heart", // Or "bf_emma", "am_fenrir", etc.
400
+ * });
401
+ *
402
+ * // Access audio data
403
+ * const audioData = audio.audioData; // Uint8Array (WAV format)
404
+ * ```
405
+ *
406
+ * @example Transcription
407
+ * ```ts
408
+ * import { experimental_transcribe as transcribe } from "ai";
409
+ * import { gerbil } from "gerbil/ai";
410
+ * import { readFile } from "fs/promises";
411
+ *
412
+ * const transcript = await transcribe({
413
+ * model: gerbil.transcription(), // whisper-tiny.en by default
414
+ * audio: await readFile("audio.wav"),
415
+ * });
416
+ *
417
+ * console.log(transcript.text);
418
+ * console.log(transcript.segments); // Timestamped segments
419
+ * ```
193
420
  */
194
421
  const gerbil = createGerbil();
195
422
  var ai_sdk_default = gerbil;
@@ -1 +1 @@
1
- {"version":3,"file":"ai-sdk.mjs","names":["system: string | undefined","warnings: LanguageModelV2CallWarning[]","content: LanguageModelV2Content[]","usage: LanguageModelV2Usage"],"sources":["../../src/integrations/ai-sdk.ts"],"sourcesContent":["/**\n * Gerbil AI SDK Provider (V2 Specification)\n *\n * Compatible with AI SDK v5+\n *\n * @example\n * ```ts\n * import { generateText, streamText } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n *\n * const { text } = await generateText({\n * model: gerbil(\"qwen3-0.6b\"),\n * prompt: \"Hello world\",\n * });\n * ```\n */\n\nimport type {\n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2CallWarning,\n LanguageModelV2Content,\n LanguageModelV2FinishReason,\n LanguageModelV2Prompt,\n LanguageModelV2StreamPart,\n LanguageModelV2Usage,\n} from \"@ai-sdk/provider\";\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport { BUILTIN_MODELS } from \"../core/models.js\";\nimport type { GerbilModelSettings, GerbilProviderSettings, ModelConfig } from \"../core/types.js\";\n\n// Simple ID generator\nlet idCounter = 0;\nfunction generateId(): string {\n return `gerbil-${Date.now()}-${++idCounter}`;\n}\n\n// ============================================\n// Language Model Implementation (V2 Spec)\n// ============================================\n\nclass GerbilLanguageModel implements LanguageModelV2 {\n readonly specificationVersion = \"v2\" as const;\n readonly provider = \"gerbil\";\n readonly modelId: string;\n\n // Gerbil runs locally, no URL support needed\n readonly supportedUrls: Record<string, RegExp[]> = {};\n\n private instance: Gerbil | null = null;\n private readonly settings: GerbilModelSettings;\n private readonly providerSettings: GerbilProviderSettings;\n private loadPromise: Promise<void> | null = null;\n\n constructor(\n modelId: string,\n settings: GerbilModelSettings,\n providerSettings: GerbilProviderSettings,\n ) {\n this.modelId = modelId;\n this.settings = settings;\n this.providerSettings = providerSettings;\n }\n\n private async ensureLoaded(): Promise<Gerbil> {\n if (this.instance?.isLoaded()) {\n return this.instance;\n }\n if (this.loadPromise) {\n await this.loadPromise;\n return this.instance!;\n }\n\n this.instance = new Gerbil();\n this.loadPromise = this.instance.loadModel(this.modelId, {\n device: this.settings.device ?? this.providerSettings.device ?? \"auto\",\n dtype: this.settings.dtype ?? this.providerSettings.dtype ?? \"q4\",\n });\n await this.loadPromise;\n return this.instance;\n }\n\n private convertPrompt(prompt: LanguageModelV2Prompt): {\n system?: string;\n user: string;\n } {\n let system: string | undefined;\n let user = \"\";\n\n for (const msg of prompt) {\n if (msg.role === \"system\") {\n system = msg.content;\n } else if (msg.role === \"user\") {\n for (const part of msg.content) {\n if (part.type === \"text\") {\n user += part.text;\n }\n }\n } else if (msg.role === \"assistant\") {\n for (const part of msg.content) {\n if (part.type === \"text\") {\n user += `\\n\\nAssistant: ${part.text}`;\n }\n }\n } else if (msg.role === \"tool\") {\n for (const part of msg.content) {\n user += `\\n\\nTool (${part.toolName}): ${JSON.stringify(part)}`;\n }\n }\n }\n\n return { system, user };\n }\n\n private mapFinishReason(reason: string): LanguageModelV2FinishReason {\n if (reason === \"stop\") {\n return \"stop\";\n }\n if (reason === \"length\") {\n return \"length\";\n }\n if (reason === \"error\") {\n return \"error\";\n }\n return \"other\";\n }\n\n async doGenerate(options: LanguageModelV2CallOptions) {\n const warnings: LanguageModelV2CallWarning[] = [];\n const g = await this.ensureLoaded();\n const { system, user } = this.convertPrompt(options.prompt);\n\n const result = await g.generate(user, {\n maxTokens: options.maxOutputTokens,\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n system,\n thinking: this.settings.thinking,\n stopSequences: options.stopSequences,\n });\n\n // Build V2 content array\n const content: LanguageModelV2Content[] = [];\n\n // Add reasoning if thinking mode was enabled\n if (result.thinking) {\n content.push({\n type: \"reasoning\",\n text: result.thinking,\n });\n }\n\n // Add main text response\n content.push({\n type: \"text\",\n text: result.text,\n });\n\n const usage: LanguageModelV2Usage = {\n inputTokens: 0,\n outputTokens: result.tokensGenerated,\n totalTokens: result.tokensGenerated,\n };\n\n return {\n content,\n finishReason: this.mapFinishReason(result.finishReason),\n usage,\n request: { body: { model: this.modelId, prompt: user } },\n warnings,\n };\n }\n\n async doStream(options: LanguageModelV2CallOptions) {\n const warnings: LanguageModelV2CallWarning[] = [];\n const g = await this.ensureLoaded();\n const { system, user } = this.convertPrompt(options.prompt);\n\n const streamGen = g.stream(user, {\n maxTokens: options.maxOutputTokens,\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n system,\n thinking: this.settings.thinking,\n stopSequences: options.stopSequences,\n });\n\n let tokens = 0;\n const textId = generateId();\n\n const stream = new ReadableStream<LanguageModelV2StreamPart>({\n async start(controller) {\n try {\n // V2: Send stream-start event first\n controller.enqueue({\n type: \"stream-start\",\n warnings,\n });\n\n // V2: Send text-start before text deltas\n controller.enqueue({\n type: \"text-start\",\n id: textId,\n });\n\n for await (const chunk of streamGen) {\n tokens++;\n // V2: Use 'text-delta' with id and delta\n controller.enqueue({\n type: \"text-delta\",\n id: textId,\n delta: chunk,\n });\n }\n\n // V2: Send text-end after all deltas\n controller.enqueue({\n type: \"text-end\",\n id: textId,\n });\n\n // V2: Send finish event\n controller.enqueue({\n type: \"finish\",\n finishReason: \"stop\",\n usage: {\n inputTokens: 0,\n outputTokens: tokens,\n totalTokens: tokens,\n },\n });\n controller.close();\n } catch (error) {\n controller.enqueue({ type: \"error\", error });\n controller.close();\n }\n },\n });\n\n return {\n stream,\n request: { body: { model: this.modelId, prompt: user } },\n };\n }\n}\n\n// ============================================\n// Provider Factory\n// ============================================\n\nexport type GerbilProvider = {\n (modelId: string, settings?: GerbilModelSettings): GerbilLanguageModel;\n languageModel(modelId: string, settings?: GerbilModelSettings): GerbilLanguageModel;\n listModels(): ModelConfig[];\n getModel(modelId: string): ModelConfig | undefined;\n};\n\n/**\n * Create a Gerbil provider\n *\n * @example\n * ```ts\n * const local = createGerbil({ device: \"gpu\", dtype: \"q4\" });\n *\n * const { text } = await generateText({\n * model: local(\"qwen3-0.6b\"),\n * prompt: \"Hello\",\n * });\n * ```\n */\nexport function createGerbil(options: GerbilProviderSettings = {}): GerbilProvider {\n const createModel = (modelId: string, settings: GerbilModelSettings = {}) =>\n new GerbilLanguageModel(modelId, settings, options);\n\n const provider = ((modelId: string, settings?: GerbilModelSettings) =>\n createModel(modelId, settings ?? {})) as GerbilProvider;\n\n provider.languageModel = createModel;\n provider.listModels = () => Object.values(BUILTIN_MODELS);\n provider.getModel = (id: string) => BUILTIN_MODELS[id];\n\n return provider;\n}\n\n/**\n * Default Gerbil provider\n *\n * @example\n * ```ts\n * import { generateText } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n *\n * const { text } = await generateText({\n * model: gerbil(\"qwen3-0.6b\"),\n * prompt: \"Hello\",\n * });\n * ```\n */\nexport const gerbil = createGerbil();\n\nexport default gerbil;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ai-sdk.mjs","names":["system: string | undefined","images: ImageInput[]","warnings: LanguageModelV2CallWarning[]","content: LanguageModelV2Content[]","usage: LanguageModelV2Usage","warnings: SpeechModelV2CallWarning[]","warnings: TranscriptionModelV2CallWarning[]","audioData: Uint8Array"],"sources":["../../src/integrations/ai-sdk.ts"],"sourcesContent":["/**\n * Gerbil AI SDK Provider (V2 Specification)\n *\n * Compatible with AI SDK v5+\n *\n * @example\n * ```ts\n * import { generateText, streamText } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n *\n * const { text } = await generateText({\n * model: gerbil(\"qwen3-0.6b\"),\n * prompt: \"Hello world\",\n * });\n * ```\n */\n\nimport type {\n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2CallWarning,\n LanguageModelV2Content,\n LanguageModelV2FinishReason,\n LanguageModelV2Prompt,\n LanguageModelV2StreamPart,\n LanguageModelV2Usage,\n SpeechModelV2,\n SpeechModelV2CallOptions,\n SpeechModelV2CallWarning,\n TranscriptionModelV2,\n TranscriptionModelV2CallOptions,\n TranscriptionModelV2CallWarning,\n} from \"@ai-sdk/provider\";\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport { BUILTIN_MODELS } from \"../core/models.js\";\nimport { WHISPER_MODELS } from \"../core/stt.js\";\nimport { KOKORO_VOICES } from \"../core/tts.js\";\nimport type {\n GerbilModelSettings,\n GerbilProviderSettings,\n ImageInput,\n ModelConfig,\n STTModelConfig,\n} from \"../core/types.js\";\n\n// Simple ID generator\nlet idCounter = 0;\nfunction generateId(): string {\n return `gerbil-${Date.now()}-${(idCounter += 1)}`;\n}\n\n// ============================================\n// Language Model Implementation (V2 Spec)\n// ============================================\n\nclass GerbilLanguageModel implements LanguageModelV2 {\n readonly specificationVersion = \"v2\" as const;\n readonly provider = \"gerbil\";\n readonly modelId: string;\n\n // Gerbil runs locally, no URL support needed\n readonly supportedUrls: Record<string, RegExp[]> = {};\n\n private instance: Gerbil | null = null;\n private readonly settings: GerbilModelSettings;\n private readonly providerSettings: GerbilProviderSettings;\n private loadPromise: Promise<void> | null = null;\n\n constructor(\n modelId: string,\n settings: GerbilModelSettings,\n providerSettings: GerbilProviderSettings,\n ) {\n this.modelId = modelId;\n this.settings = settings;\n this.providerSettings = providerSettings;\n }\n\n private async ensureLoaded(): Promise<Gerbil> {\n if (this.instance?.isLoaded()) {\n return this.instance;\n }\n if (this.loadPromise) {\n await this.loadPromise;\n return this.instance!;\n }\n\n this.instance = new Gerbil();\n this.loadPromise = this.instance.loadModel(this.modelId, {\n device: this.settings.device ?? this.providerSettings.device ?? \"auto\",\n dtype: this.settings.dtype ?? this.providerSettings.dtype ?? \"q4\",\n });\n await this.loadPromise;\n return this.instance;\n }\n\n private convertPrompt(prompt: LanguageModelV2Prompt): {\n system?: string;\n user: string;\n images: ImageInput[];\n } {\n let system: string | undefined;\n let user = \"\";\n const images: ImageInput[] = [];\n\n for (const msg of prompt) {\n if (msg.role === \"system\") {\n system = msg.content;\n } else if (msg.role === \"user\") {\n for (const part of msg.content) {\n if (part.type === \"text\") {\n user += part.text;\n } else if ((part as any).type === \"image\") {\n // AI SDK v5 image part - can be URL, base64, or Uint8Array\n const imgPart = part as any;\n if (imgPart.image instanceof URL) {\n images.push({ source: imgPart.image.toString() });\n } else if (typeof imgPart.image === \"string\") {\n // base64 or URL string\n images.push({ source: imgPart.image });\n } else if (imgPart.image instanceof Uint8Array) {\n // Convert Uint8Array to base64 data URI\n const base64 = btoa(String.fromCharCode(...imgPart.image));\n const mimeType = imgPart.mimeType || \"image/png\";\n images.push({ source: `data:${mimeType};base64,${base64}` });\n }\n }\n }\n } else if (msg.role === \"assistant\") {\n for (const part of msg.content) {\n if (part.type === \"text\") {\n user += `\\n\\nAssistant: ${part.text}`;\n }\n }\n } else if (msg.role === \"tool\") {\n for (const part of msg.content) {\n user += `\\n\\nTool (${part.toolName}): ${JSON.stringify(part)}`;\n }\n }\n }\n\n return { system, user, images };\n }\n\n private mapFinishReason(reason: string): LanguageModelV2FinishReason {\n if (reason === \"stop\") {\n return \"stop\";\n }\n if (reason === \"length\") {\n return \"length\";\n }\n if (reason === \"error\") {\n return \"error\";\n }\n return \"other\";\n }\n\n async doGenerate(options: LanguageModelV2CallOptions) {\n const warnings: LanguageModelV2CallWarning[] = [];\n const g = await this.ensureLoaded();\n const { system, user, images } = this.convertPrompt(options.prompt);\n\n const result = await g.generate(user, {\n maxTokens: options.maxOutputTokens,\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n system,\n thinking: this.settings.thinking,\n stopSequences: options.stopSequences,\n images: images.length > 0 ? images : undefined,\n });\n\n // Build V2 content array\n const content: LanguageModelV2Content[] = [];\n\n // Add reasoning if thinking mode was enabled\n if (result.thinking) {\n content.push({\n type: \"reasoning\",\n text: result.thinking,\n });\n }\n\n // Add main text response\n content.push({\n type: \"text\",\n text: result.text,\n });\n\n const usage: LanguageModelV2Usage = {\n inputTokens: 0,\n outputTokens: result.tokensGenerated,\n totalTokens: result.tokensGenerated,\n };\n\n return {\n content,\n finishReason: this.mapFinishReason(result.finishReason),\n usage,\n request: { body: { model: this.modelId, prompt: user } },\n warnings,\n };\n }\n\n async doStream(options: LanguageModelV2CallOptions) {\n const warnings: LanguageModelV2CallWarning[] = [];\n const g = await this.ensureLoaded();\n const { system, user, images } = this.convertPrompt(options.prompt);\n\n const streamGen = g.stream(user, {\n maxTokens: options.maxOutputTokens,\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n system,\n thinking: this.settings.thinking,\n stopSequences: options.stopSequences,\n images: images.length > 0 ? images : undefined,\n });\n\n let tokens = 0;\n const textId = generateId();\n\n const stream = new ReadableStream<LanguageModelV2StreamPart>({\n async start(controller) {\n try {\n // V2: Send stream-start event first\n controller.enqueue({\n type: \"stream-start\",\n warnings,\n });\n\n // V2: Send text-start before text deltas\n controller.enqueue({\n type: \"text-start\",\n id: textId,\n });\n\n for await (const chunk of streamGen) {\n tokens += 1;\n // V2: Use 'text-delta' with id and delta\n controller.enqueue({\n type: \"text-delta\",\n id: textId,\n delta: chunk,\n });\n }\n\n // V2: Send text-end after all deltas\n controller.enqueue({\n type: \"text-end\",\n id: textId,\n });\n\n // V2: Send finish event\n controller.enqueue({\n type: \"finish\",\n finishReason: \"stop\",\n usage: {\n inputTokens: 0,\n outputTokens: tokens,\n totalTokens: tokens,\n },\n });\n controller.close();\n } catch (error) {\n controller.enqueue({ type: \"error\", error });\n controller.close();\n }\n },\n });\n\n return {\n stream,\n request: { body: { model: this.modelId, prompt: user } },\n };\n }\n}\n\n// ============================================\n// Speech Model Implementation (V2 Spec)\n// ============================================\n\n/** Settings for Gerbil speech model */\nexport interface GerbilSpeechSettings {\n /** Default voice ID (default: \"af_heart\") */\n voice?: string;\n /** Speech speed multiplier (default: 1.0) */\n speed?: number;\n}\n\nclass GerbilSpeechModel implements SpeechModelV2 {\n readonly specificationVersion = \"v2\" as const;\n readonly provider = \"gerbil\";\n readonly modelId: string;\n\n private instance: Gerbil | null = null;\n private readonly settings: GerbilSpeechSettings;\n private loadPromise: Promise<void> | null = null;\n\n constructor(modelId: string, settings: GerbilSpeechSettings = {}) {\n this.modelId = modelId;\n this.settings = settings;\n }\n\n private async ensureLoaded(): Promise<Gerbil> {\n if (this.instance?.isTTSLoaded()) {\n return this.instance;\n }\n if (this.loadPromise) {\n await this.loadPromise;\n return this.instance!;\n }\n\n this.instance = new Gerbil();\n this.loadPromise = this.instance.ensureTTSLoaded();\n await this.loadPromise;\n return this.instance;\n }\n\n async doGenerate(options: SpeechModelV2CallOptions): Promise<{\n audio: Uint8Array;\n warnings: SpeechModelV2CallWarning[];\n request?: { body?: unknown };\n response: { timestamp: Date; modelId: string };\n }> {\n const warnings: SpeechModelV2CallWarning[] = [];\n const g = await this.ensureLoaded();\n\n // Determine voice - use options.voice, fall back to settings, then default\n let voice = options.voice || this.settings.voice || \"af_heart\";\n\n // Validate voice exists\n const validVoice = KOKORO_VOICES.find((v) => v.id === voice);\n if (!validVoice) {\n warnings.push({\n type: \"unsupported-setting\",\n setting: \"voice\",\n details: `Unknown voice \"${voice}\", using default \"af_heart\"`,\n });\n voice = \"af_heart\";\n }\n\n // Determine speed\n const speed = options.speed ?? this.settings.speed ?? 1.0;\n\n // Handle unsupported options\n if (options.outputFormat && options.outputFormat !== \"wav\" && options.outputFormat !== \"raw\") {\n warnings.push({\n type: \"unsupported-setting\",\n setting: \"outputFormat\",\n details: `Gerbil TTS only supports \"wav\" and \"raw\" formats, got \"${options.outputFormat}\"`,\n });\n }\n\n if (options.instructions) {\n warnings.push({\n type: \"unsupported-setting\",\n setting: \"instructions\",\n details: \"Gerbil TTS does not support instructions parameter\",\n });\n }\n\n // Generate speech\n const result = await g.speak(options.text, { voice, speed });\n\n // Convert Float32Array to WAV format Uint8Array\n const audioData = this.float32ToWav(result.audio, result.sampleRate);\n\n return {\n audio: audioData,\n warnings,\n request: { body: { text: options.text, voice, speed } },\n response: {\n timestamp: new Date(),\n modelId: this.modelId,\n },\n };\n }\n\n /**\n * Convert Float32Array audio to WAV format Uint8Array\n */\n private float32ToWav(audio: Float32Array, sampleRate: number): Uint8Array {\n const buffer = new ArrayBuffer(44 + audio.length * 2);\n const view = new DataView(buffer);\n\n // WAV header\n const writeString = (offset: number, str: string) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n };\n\n writeString(0, \"RIFF\");\n view.setUint32(4, 36 + audio.length * 2, true);\n writeString(8, \"WAVE\");\n writeString(12, \"fmt \");\n view.setUint32(16, 16, true); // Subchunk1Size\n view.setUint16(20, 1, true); // AudioFormat (PCM)\n view.setUint16(22, 1, true); // NumChannels (mono)\n view.setUint32(24, sampleRate, true); // SampleRate\n view.setUint32(28, sampleRate * 2, true); // ByteRate\n view.setUint16(32, 2, true); // BlockAlign\n view.setUint16(34, 16, true); // BitsPerSample\n writeString(36, \"data\");\n view.setUint32(40, audio.length * 2, true);\n\n // Audio data (convert float32 to int16)\n for (let i = 0; i < audio.length; i++) {\n const s = Math.max(-1, Math.min(1, audio[i]));\n view.setInt16(44 + i * 2, Math.round(s * 32767), true);\n }\n\n return new Uint8Array(buffer);\n }\n}\n\n// ============================================\n// Transcription Model Implementation (V2 Spec)\n// ============================================\n\n/** Settings for Gerbil transcription model */\nexport interface GerbilTranscriptionSettings {\n /** Default language code (ISO-639-1) for transcription */\n language?: string;\n}\n\nclass GerbilTranscriptionModel implements TranscriptionModelV2 {\n readonly specificationVersion = \"v2\" as const;\n readonly provider = \"gerbil\";\n readonly modelId: string;\n\n private instance: Gerbil | null = null;\n private readonly settings: GerbilTranscriptionSettings;\n private loadPromise: Promise<void> | null = null;\n\n constructor(modelId: string, settings: GerbilTranscriptionSettings = {}) {\n this.modelId = modelId;\n this.settings = settings;\n }\n\n private async ensureLoaded(): Promise<Gerbil> {\n if (this.instance?.isSTTLoaded()) {\n return this.instance;\n }\n if (this.loadPromise) {\n await this.loadPromise;\n return this.instance!;\n }\n\n this.instance = new Gerbil();\n this.loadPromise = this.instance.loadSTT(this.modelId);\n await this.loadPromise;\n return this.instance;\n }\n\n async doGenerate(options: TranscriptionModelV2CallOptions): Promise<{\n text: string;\n segments: Array<{\n text: string;\n startSecond: number;\n endSecond: number;\n }>;\n language: string | undefined;\n durationInSeconds: number | undefined;\n warnings: TranscriptionModelV2CallWarning[];\n request?: { body?: string };\n response: {\n timestamp: Date;\n modelId: string;\n };\n }> {\n const warnings: TranscriptionModelV2CallWarning[] = [];\n const g = await this.ensureLoaded();\n\n // Convert audio to Uint8Array\n let audioData: Uint8Array;\n if (typeof options.audio === \"string\") {\n // Base64 encoded - decode it\n const binaryString = atob(options.audio);\n audioData = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n audioData[i] = binaryString.charCodeAt(i);\n }\n } else {\n audioData = options.audio;\n }\n\n // Check media type - we only support WAV natively\n const mediaType = options.mediaType?.toLowerCase() || \"\";\n if (mediaType && !mediaType.includes(\"wav\") && !mediaType.includes(\"wave\")) {\n warnings.push({\n type: \"unsupported-setting\",\n setting: \"mediaType\",\n details: `Gerbil STT natively supports WAV format. Got \"${options.mediaType}\". Audio may not decode correctly.`,\n });\n }\n\n // Determine language from provider options or settings\n const providerOpts = options.providerOptions?.gerbil as Record<string, unknown> | undefined;\n const language = (providerOpts?.language as string) || this.settings.language;\n\n // Transcribe with timestamps to get segments\n const result = await g.transcribe(audioData, {\n language,\n timestamps: true,\n });\n\n // Map segments to V2 format\n const segments = (result.segments || []).map((seg) => ({\n text: seg.text,\n startSecond: seg.start,\n endSecond: seg.end,\n }));\n\n return {\n text: result.text,\n segments,\n language: result.language,\n durationInSeconds: result.duration,\n warnings,\n request: {\n body: JSON.stringify({\n model: this.modelId,\n mediaType: options.mediaType,\n language,\n }),\n },\n response: {\n timestamp: new Date(),\n modelId: this.modelId,\n },\n };\n }\n}\n\n// ============================================\n// Provider Factory\n// ============================================\n\nexport type GerbilProvider = {\n (modelId: string, settings?: GerbilModelSettings): GerbilLanguageModel;\n languageModel(modelId: string, settings?: GerbilModelSettings): GerbilLanguageModel;\n speech(modelId?: string, settings?: GerbilSpeechSettings): GerbilSpeechModel;\n transcription(modelId?: string, settings?: GerbilTranscriptionSettings): GerbilTranscriptionModel;\n listModels(): ModelConfig[];\n getModel(modelId: string): ModelConfig | undefined;\n listVoices(): Array<{ id: string; name: string; gender: string; language: string }>;\n listTranscriptionModels(): STTModelConfig[];\n};\n\n/**\n * Create a Gerbil provider\n *\n * @example\n * ```ts\n * const local = createGerbil({ device: \"gpu\", dtype: \"q4\" });\n *\n * // Text generation\n * const { text } = await generateText({\n * model: local(\"qwen3-0.6b\"),\n * prompt: \"Hello\",\n * });\n *\n * // Speech generation\n * const audio = await generateSpeech({\n * model: local.speech(),\n * text: \"Hello world!\",\n * voice: \"af_heart\",\n * });\n *\n * // Transcription\n * const transcript = await transcribe({\n * model: local.transcription(),\n * audio: audioBuffer,\n * });\n * ```\n */\nexport function createGerbil(options: GerbilProviderSettings = {}): GerbilProvider {\n const createModel = (modelId: string, settings: GerbilModelSettings = {}) =>\n new GerbilLanguageModel(modelId, settings, options);\n\n const createSpeechModel = (modelId = \"kokoro-82m\", settings: GerbilSpeechSettings = {}) =>\n new GerbilSpeechModel(modelId, settings);\n\n const createTranscriptionModel = (\n modelId = \"whisper-tiny.en\",\n settings: GerbilTranscriptionSettings = {},\n ) => new GerbilTranscriptionModel(modelId, settings);\n\n const provider = ((modelId: string, settings?: GerbilModelSettings) =>\n createModel(modelId, settings ?? {})) as GerbilProvider;\n\n provider.languageModel = createModel;\n provider.speech = createSpeechModel;\n provider.transcription = createTranscriptionModel;\n provider.listModels = () => Object.values(BUILTIN_MODELS);\n provider.getModel = (id: string) => BUILTIN_MODELS[id];\n provider.listVoices = () =>\n KOKORO_VOICES.map((v) => ({\n id: v.id,\n name: v.name,\n gender: v.gender,\n language: v.language,\n }));\n provider.listTranscriptionModels = () => WHISPER_MODELS;\n\n return provider;\n}\n\n/**\n * Default Gerbil provider\n *\n * @example Text Generation\n * ```ts\n * import { generateText } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n *\n * const { text } = await generateText({\n * model: gerbil(\"qwen3-0.6b\"),\n * prompt: \"Hello\",\n * });\n * ```\n *\n * @example Speech Generation\n * ```ts\n * import { experimental_generateSpeech as generateSpeech } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n *\n * const audio = await generateSpeech({\n * model: gerbil.speech(),\n * text: \"Hello world!\",\n * voice: \"af_heart\", // Or \"bf_emma\", \"am_fenrir\", etc.\n * });\n *\n * // Access audio data\n * const audioData = audio.audioData; // Uint8Array (WAV format)\n * ```\n *\n * @example Transcription\n * ```ts\n * import { experimental_transcribe as transcribe } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n * import { readFile } from \"fs/promises\";\n *\n * const transcript = await transcribe({\n * model: gerbil.transcription(), // whisper-tiny.en by default\n * audio: await readFile(\"audio.wav\"),\n * });\n *\n * console.log(transcript.text);\n * console.log(transcript.segments); // Timestamped segments\n * ```\n */\nexport const gerbil = createGerbil();\n\nexport default gerbil;\n"],"mappings":"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"}