@tryhamster/gerbil 1.0.0-rc.9 → 1.0.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 (179) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +318 -104
  3. package/dist/architectures-C1I5V3Dt.mjs +6070 -0
  4. package/dist/architectures-C1I5V3Dt.mjs.map +1 -0
  5. package/dist/browser/index.d.ts +276 -590
  6. package/dist/browser/index.d.ts.map +1 -1
  7. package/dist/browser/index.js +592 -2334
  8. package/dist/browser/index.js.map +1 -1
  9. package/dist/cli.mjs +625 -1098
  10. package/dist/cli.mjs.map +1 -1
  11. package/dist/defaults-9komdrbY.mjs +24 -0
  12. package/dist/defaults-9komdrbY.mjs.map +1 -0
  13. package/dist/frameworks/express.d.mts +1 -3
  14. package/dist/frameworks/express.d.mts.map +1 -1
  15. package/dist/frameworks/express.mjs +7 -7
  16. package/dist/frameworks/express.mjs.map +1 -1
  17. package/dist/frameworks/fastify.d.mts +1 -1
  18. package/dist/frameworks/fastify.d.mts.map +1 -1
  19. package/dist/frameworks/fastify.mjs +3 -3
  20. package/dist/frameworks/fastify.mjs.map +1 -1
  21. package/dist/frameworks/hono.d.mts +1 -1
  22. package/dist/frameworks/hono.d.mts.map +1 -1
  23. package/dist/frameworks/hono.mjs +4 -4
  24. package/dist/frameworks/hono.mjs.map +1 -1
  25. package/dist/frameworks/next.d.mts +3 -2
  26. package/dist/frameworks/next.d.mts.map +1 -1
  27. package/dist/frameworks/next.mjs +4 -4
  28. package/dist/frameworks/next.mjs.map +1 -1
  29. package/dist/frameworks/react.d.mts +1 -1
  30. package/dist/frameworks/trpc.d.mts +1 -1
  31. package/dist/frameworks/trpc.d.mts.map +1 -1
  32. package/dist/frameworks/trpc.mjs +4 -4
  33. package/dist/frameworks/trpc.mjs.map +1 -1
  34. package/dist/gerbil-BetB5xb0.d.mts +488 -0
  35. package/dist/gerbil-BetB5xb0.d.mts.map +1 -0
  36. package/dist/gerbil-CTZUa8EZ.mjs +4 -0
  37. package/dist/gerbil-DNniplr4.mjs +1656 -0
  38. package/dist/gerbil-DNniplr4.mjs.map +1 -0
  39. package/dist/gpu/hooks.d.mts +640 -0
  40. package/dist/gpu/hooks.d.mts.map +1 -0
  41. package/dist/gpu/hooks.mjs +1369 -0
  42. package/dist/gpu/hooks.mjs.map +1 -0
  43. package/dist/gpu/index.d.mts +2 -0
  44. package/dist/gpu/index.mjs +6 -0
  45. package/dist/gpu-DFuglcEx.mjs +3790 -0
  46. package/dist/gpu-DFuglcEx.mjs.map +1 -0
  47. package/dist/index-Dgmb2kE3.d.mts +245 -0
  48. package/dist/index-Dgmb2kE3.d.mts.map +1 -0
  49. package/dist/index-DukkJRMj.d.mts +2114 -0
  50. package/dist/index-DukkJRMj.d.mts.map +1 -0
  51. package/dist/index.d.mts +22 -487
  52. package/dist/index.d.mts.map +1 -1
  53. package/dist/index.mjs +13 -8
  54. package/dist/index.mjs.map +1 -1
  55. package/dist/indexeddb-store-BWIMtxxH.mjs +103 -0
  56. package/dist/indexeddb-store-BWIMtxxH.mjs.map +1 -0
  57. package/dist/indexeddb-store-ClH12Xnl.mjs +4 -0
  58. package/dist/integrations/ai-sdk.d.mts +75 -6
  59. package/dist/integrations/ai-sdk.d.mts.map +1 -1
  60. package/dist/integrations/ai-sdk.mjs +131 -15
  61. package/dist/integrations/ai-sdk.mjs.map +1 -1
  62. package/dist/integrations/langchain.d.mts +1 -1
  63. package/dist/integrations/langchain.d.mts.map +1 -1
  64. package/dist/integrations/langchain.mjs +5 -5
  65. package/dist/integrations/langchain.mjs.map +1 -1
  66. package/dist/integrations/llamaindex.d.mts +1 -1
  67. package/dist/integrations/llamaindex.d.mts.map +1 -1
  68. package/dist/integrations/llamaindex.mjs +5 -5
  69. package/dist/integrations/llamaindex.mjs.map +1 -1
  70. package/dist/integrations/mcp-client.mjs +3 -3
  71. package/dist/integrations/mcp-client.mjs.map +1 -1
  72. package/dist/integrations/mcp.d.mts +3 -2
  73. package/dist/integrations/mcp.d.mts.map +1 -1
  74. package/dist/integrations/mcp.mjs +5 -5
  75. package/dist/{mcp-BvbriaBy.mjs → mcp-D2vvH1Xc.mjs} +4 -4
  76. package/dist/mcp-D2vvH1Xc.mjs.map +1 -0
  77. package/dist/memory/index.d.mts +3 -0
  78. package/dist/memory/index.mjs +6 -0
  79. package/dist/memory-D1P7Tmda.mjs +4 -0
  80. package/dist/memory-DVN0MnIG.mjs +132 -0
  81. package/dist/memory-DVN0MnIG.mjs.map +1 -0
  82. package/dist/memory-Dj0J1v88.mjs +294 -0
  83. package/dist/memory-Dj0J1v88.mjs.map +1 -0
  84. package/dist/moonshine-stt-17dpP1kr.mjs +4 -0
  85. package/dist/moonshine-stt-4ojLtMq7.mjs +11962 -0
  86. package/dist/moonshine-stt-4ojLtMq7.mjs.map +1 -0
  87. package/dist/{one-liner-s-lD8rCC.mjs → one-liner-JhdIPxzF.mjs} +14 -16
  88. package/dist/one-liner-JhdIPxzF.mjs.map +1 -0
  89. package/dist/repl-BDRkwPGX.mjs +9 -0
  90. package/dist/skills/index.d.mts +270 -320
  91. package/dist/skills/index.d.mts.map +1 -1
  92. package/dist/skills/index.mjs +5 -5
  93. package/dist/{skills-CD3Orlex.mjs → skills-CU694Dc8.mjs} +187 -32
  94. package/dist/skills-CU694Dc8.mjs.map +1 -0
  95. package/dist/{tools-Bi1P7Xoy.mjs → tools-DQ1mPUw5.mjs} +34 -22
  96. package/dist/tools-DQ1mPUw5.mjs.map +1 -0
  97. package/dist/types-DQBe2lFo.d.mts +165 -0
  98. package/dist/types-DQBe2lFo.d.mts.map +1 -0
  99. package/dist/{types-CiTc7ez3.d.mts → types-LlyYILII.d.mts} +112 -14
  100. package/dist/types-LlyYILII.d.mts.map +1 -0
  101. package/dist/{utils-CZBZ8dgR.mjs → utils-DKO55ZmZ.mjs} +1 -1
  102. package/dist/{utils-CZBZ8dgR.mjs.map → utils-DKO55ZmZ.mjs.map} +1 -1
  103. package/dist/vector-B0panuy6.mjs +95 -0
  104. package/dist/vector-B0panuy6.mjs.map +1 -0
  105. package/docs/PROJECT-STATE.md +321 -0
  106. package/docs/adding-a-model-family.md +280 -0
  107. package/docs/ai-sdk.md +70 -61
  108. package/docs/architecture/overview.md +17 -7
  109. package/docs/browser.md +203 -8
  110. package/docs/embeddings.md +156 -0
  111. package/docs/gerbil-site-native-migration.md +217 -0
  112. package/docs/gpu-engine/architectures.md +398 -0
  113. package/docs/gpu-engine/ir.md +372 -0
  114. package/docs/gpu-engine/kernels.md +718 -0
  115. package/docs/gpu-engine/paper.html +1759 -0
  116. package/docs/gpu-engine/paper.md +2109 -0
  117. package/docs/gpu-engine/safetensors.md +312 -0
  118. package/docs/gpu-engine/tokenizer.md +302 -0
  119. package/docs/memory-rag.md +91 -0
  120. package/docs/metal-safari-intel.md +190 -0
  121. package/docs/mobile-failure-diagnosis.md +124 -0
  122. package/docs/mobile.md +99 -0
  123. package/docs/observability.md +230 -0
  124. package/docs/onnx-removal-plan.md +339 -0
  125. package/docs/research/autoresearch-portable.md +904 -0
  126. package/docs/research/dispatch-reduction-hivemind.md +84 -0
  127. package/docs/research/ios-safari-model-caching.md +117 -0
  128. package/docs/research/mobile-webgpu-speed-fusion.md +135 -0
  129. package/docs/research/native-stt-model-selection.md +49 -0
  130. package/docs/research/native-tts-model-selection.md +90 -0
  131. package/docs/research/native-vs-chromium-decision.md +152 -0
  132. package/docs/research/nemotron-mamba2-inference.md +910 -0
  133. package/docs/research/qwen35-multimodal.md +293 -0
  134. package/docs/research/qwen36-gemma4-targets.md +337 -0
  135. package/docs/research/sota-embedding-models.md +179 -0
  136. package/docs/research/sota-mobile-models-2026.md +263 -0
  137. package/docs/research/sota-modality-models.md +202 -0
  138. package/docs/research/tps-baselines.md +71 -0
  139. package/docs/research/webgpu-m4-reference.md +104 -0
  140. package/docs/site-update-plan.md +155 -0
  141. package/docs/structured-output.md +123 -0
  142. package/docs/stt.md +63 -446
  143. package/docs/tts.md +77 -499
  144. package/docs/vision.md +100 -338
  145. package/package.json +22 -7
  146. package/dist/chrome-backend-CORwaIyC.mjs +0 -1212
  147. package/dist/chrome-backend-CORwaIyC.mjs.map +0 -1
  148. package/dist/chrome-backend-DIKYoWj-.mjs +0 -3
  149. package/dist/gerbil-CJ3ifloF.mjs +0 -4
  150. package/dist/gerbil-Dw4Qj77e.mjs +0 -1631
  151. package/dist/gerbil-Dw4Qj77e.mjs.map +0 -1
  152. package/dist/gerbil-qOTe1nl2.d.mts +0 -431
  153. package/dist/gerbil-qOTe1nl2.d.mts.map +0 -1
  154. package/dist/kokoro-BNTb6egA.mjs +0 -20210
  155. package/dist/kokoro-BNTb6egA.mjs.map +0 -1
  156. package/dist/kokoro-CMOGDSgT.js +0 -20212
  157. package/dist/kokoro-CMOGDSgT.js.map +0 -1
  158. package/dist/mcp-BvbriaBy.mjs.map +0 -1
  159. package/dist/one-liner-s-lD8rCC.mjs.map +0 -1
  160. package/dist/repl-DveXw36T.mjs +0 -9
  161. package/dist/skills-CD3Orlex.mjs.map +0 -1
  162. package/dist/stt-Bu-E23Sc.js +0 -433
  163. package/dist/stt-Bu-E23Sc.js.map +0 -1
  164. package/dist/stt-CpLYbGFd.mjs +0 -433
  165. package/dist/stt-CpLYbGFd.mjs.map +0 -1
  166. package/dist/stt-DRPLEEHB.mjs +0 -3
  167. package/dist/tools-Bi1P7Xoy.mjs.map +0 -1
  168. package/dist/transformers.web-DiD1gTwk.js +0 -44695
  169. package/dist/transformers.web-DiD1gTwk.js.map +0 -1
  170. package/dist/transformers.web-u34VxRFM.js +0 -3
  171. package/dist/tts-CqroPaSK.js +0 -724
  172. package/dist/tts-CqroPaSK.js.map +0 -1
  173. package/dist/tts-DXgsKGCe.mjs +0 -3
  174. package/dist/tts-DeGANMNV.mjs +0 -730
  175. package/dist/tts-DeGANMNV.mjs.map +0 -1
  176. package/dist/types-CiTc7ez3.d.mts.map +0 -1
  177. /package/dist/{auto-update-S9s5-g0C.mjs → auto-update-BVaLXcDE.mjs} +0 -0
  178. /package/dist/{chunk-CkXuGtQK.mjs → chunk-B9cbKln6.mjs} +0 -0
  179. /package/dist/{microphone-DaMZFRuR.mjs → microphone-Bqmoz9_K.mjs} +0 -0
@@ -1 +1 @@
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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"}
1
+ {"version":3,"file":"ai-sdk.mjs","names":["NATIVE_VOICES: VoiceInfo[]","NATIVE_TRANSCRIPTION_MODELS: STTModelConfig[]","system: string | undefined","images: ImageInput[]","warnings: LanguageModelV2CallWarning[]","content: LanguageModelV2Content[]","usage: LanguageModelV2Usage","warnings: SpeechModelV2CallWarning[]","warnings: TranscriptionModelV2CallWarning[]","audioData: Uint8Array","embeddings: number[][]"],"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.5-0.8b\"),\n * prompt: \"Hello world\",\n * });\n * ```\n */\n\nimport type {\n EmbeddingModelV2,\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 type {\n GerbilModelSettings,\n GerbilProviderSettings,\n ImageInput,\n ModelConfig,\n STTModelConfig,\n VoiceInfo,\n} from \"../core/types.js\";\n\n// Native speech/transcription model lists. Gerbil's native engine uses\n// Kani-TTS-2 for speech (single neutral voice) and Moonshine for transcription.\n// These small constants replace the retired ONNX Kokoro/Whisper tables.\nconst NATIVE_VOICES: VoiceInfo[] = [\n {\n id: \"default\",\n name: \"Default\",\n gender: \"neutral\",\n language: \"en-us\",\n description: \"Kani-TTS-2 native voice\",\n },\n];\n\nconst NATIVE_TRANSCRIPTION_MODELS: STTModelConfig[] = [\n {\n id: \"moonshine-base\",\n repo: \"UsefulSensors/moonshine-base\",\n description: \"Moonshine native WebGPU STT\",\n size: \"61M\",\n multilingual: false,\n languages: [\"en\"],\n sampleRate: 16000,\n },\n];\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 || \"default\";\n\n // Validate voice exists\n const validVoice = NATIVE_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`,\n });\n voice = \"default\";\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// Embedding Model Implementation (V2 Spec)\n// ============================================\n\n/** Settings for Gerbil embedding model */\nexport interface GerbilEmbeddingSettings {\n /** Normalize embeddings (default: true) */\n normalize?: boolean;\n}\n\n/** Default embedding models */\nexport const EMBEDDING_MODELS = [\n {\n id: \"all-MiniLM-L6-v2\",\n repo: \"Xenova/all-MiniLM-L6-v2\",\n description: \"MiniLM L6 v2 - Fast, 384 dimensions\",\n dimensions: 384,\n },\n {\n id: \"bge-small-en-v1.5\",\n repo: \"Xenova/bge-small-en-v1.5\",\n description: \"BGE Small EN v1.5 - High quality, 384 dimensions\",\n dimensions: 384,\n },\n {\n id: \"gte-small\",\n repo: \"Xenova/gte-small\",\n description: \"GTE Small - General text embeddings, 384 dimensions\",\n dimensions: 384,\n },\n];\n\nclass GerbilEmbeddingModel implements EmbeddingModelV2<string> {\n readonly specificationVersion = \"v2\" as const;\n readonly provider = \"gerbil\";\n readonly modelId: string;\n readonly maxEmbeddingsPerCall = Infinity;\n readonly supportsParallelCalls = false;\n\n private instance: Gerbil | null = null;\n private readonly settings: GerbilEmbeddingSettings;\n private loadPromise: Promise<void> | null = null;\n\n constructor(modelId: string, settings: GerbilEmbeddingSettings = {}) {\n this.modelId = modelId;\n this.settings = settings;\n }\n\n private getRepo(): string {\n const model = EMBEDDING_MODELS.find((m) => m.id === this.modelId);\n return model?.repo || this.modelId;\n }\n\n private async ensureLoaded(): Promise<Gerbil> {\n if (this.instance) {\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 // Embedding models load lazily on first embed() call\n return this.instance;\n }\n\n async doEmbed(options: { values: string[]; abortSignal?: AbortSignal }): Promise<{\n embeddings: number[][];\n usage?: { tokens: number };\n }> {\n const g = await this.ensureLoaded();\n\n const embeddings: number[][] = [];\n let totalTokens = 0;\n\n for (const value of options.values) {\n if (options.abortSignal?.aborted) {\n throw new Error(\"Embedding aborted\");\n }\n\n const result = await g.embed(value, {\n model: this.getRepo(),\n normalize: this.settings.normalize,\n });\n\n embeddings.push(result.vector);\n // Approximate token count (1 token ≈ 4 chars)\n totalTokens += Math.ceil(value.length / 4);\n }\n\n return {\n embeddings,\n usage: { tokens: totalTokens },\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 embedding(modelId?: string, settings?: GerbilEmbeddingSettings): GerbilEmbeddingModel;\n listModels(): ModelConfig[];\n getModel(modelId: string): ModelConfig | undefined;\n listVoices(): Array<{ id: string; name: string; gender: string; language: string }>;\n listTranscriptionModels(): STTModelConfig[];\n listEmbeddingModels(): typeof EMBEDDING_MODELS;\n /**\n * Preload a model (download without initializing)\n *\n * @param modelId - Model to preload\n * @param options.keepLoaded - Keep model in memory for instant generateText() calls\n */\n preload(\n modelId: string,\n options?: {\n onProgress?: (info: { status: string; progress?: number }) => void;\n keepLoaded?: boolean;\n },\n ): Promise<void>;\n /** Check if a model is cached */\n isCached(modelId: string): Promise<boolean>;\n};\n\n/**\n * Create a Gerbil provider\n *\n * @example\n * ```ts\n * const local = createGerbil({ device: \"webgpu\", dtype: \"q4\" });\n *\n * // Text generation\n * const { text } = await generateText({\n * model: local(\"qwen3.5-0.8b\"),\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 // Cache model instances so preload + generateText share the same loaded model\n const modelCache = new Map<string, GerbilLanguageModel>();\n\n const createModel = (modelId: string, settings: GerbilModelSettings = {}) => {\n // Return cached instance if available (for keepLoaded support)\n const cached = modelCache.get(modelId);\n if (cached) return cached;\n\n return new GerbilLanguageModel(modelId, settings, options);\n };\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 createEmbeddingModel = (\n modelId = \"all-MiniLM-L6-v2\",\n settings: GerbilEmbeddingSettings = {},\n ) => new GerbilEmbeddingModel(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.embedding = createEmbeddingModel;\n provider.listModels = () => Object.values(BUILTIN_MODELS);\n provider.getModel = (id: string) => BUILTIN_MODELS[id];\n provider.listVoices = () =>\n NATIVE_VOICES.map((v) => ({\n id: v.id,\n name: v.name,\n gender: v.gender,\n language: v.language,\n }));\n provider.listTranscriptionModels = () => NATIVE_TRANSCRIPTION_MODELS;\n provider.listEmbeddingModels = () => EMBEDDING_MODELS;\n\n // Preload and cache checking\n provider.preload = async (modelId, opts) => {\n const keepLoaded = (opts as any)?.keepLoaded ?? false;\n\n if (keepLoaded) {\n // Create model instance, load it, and cache for later gerbil() calls\n const model = new GerbilLanguageModel(modelId, {}, options);\n await (model as any).ensureLoaded(); // Trigger load\n modelCache.set(modelId, model);\n } else {\n // Just download to disk cache\n const g = new Gerbil();\n await g.preloadModel(modelId, opts);\n }\n };\n\n provider.isCached = async (modelId) => {\n // Check memory cache first\n if (modelCache.has(modelId)) return true;\n // Then check disk cache\n const g = new Gerbil();\n return g.isModelCached(modelId);\n };\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.5-0.8b\"),\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 *\n * @example Embeddings\n * ```ts\n * import { embed, embedMany } from \"ai\";\n * import { gerbil } from \"gerbil/ai\";\n *\n * // Single embedding\n * const { embedding } = await embed({\n * model: gerbil.embedding(), // all-MiniLM-L6-v2 by default\n * value: \"Hello world\",\n * });\n *\n * // Multiple embeddings\n * const { embeddings } = await embedMany({\n * model: gerbil.embedding(),\n * values: [\"Hello\", \"World\", \"How are you?\"],\n * });\n * ```\n */\nexport const gerbil = createGerbil();\n\nexport default gerbil;\n"],"mappings":";;;;AAiDA,MAAMA,gBAA6B,CACjC;CACE,IAAI;CACJ,MAAM;CACN,QAAQ;CACR,UAAU;CACV,aAAa;CACd,CACF;AAED,MAAMC,8BAAgD,CACpD;CACE,IAAI;CACJ,MAAM;CACN,aAAa;CACb,MAAM;CACN,cAAc;CACd,WAAW,CAAC,KAAK;CACjB,YAAY;CACb,CACF;AAGD,IAAI,YAAY;AAChB,SAAS,aAAqB;AAC5B,QAAO,UAAU,KAAK,KAAK,CAAC,GAAI,aAAa;;AAO/C,IAAM,sBAAN,MAAqD;CACnD,AAAS,uBAAuB;CAChC,AAAS,WAAW;CACpB,AAAS;CAGT,AAAS,gBAA0C,EAAE;CAErD,AAAQ,WAA0B;CAClC,AAAiB;CACjB,AAAiB;CACjB,AAAQ,cAAoC;CAE5C,YACE,SACA,UACA,kBACA;AACA,OAAK,UAAU;AACf,OAAK,WAAW;AAChB,OAAK,mBAAmB;;CAG1B,MAAc,eAAgC;AAC5C,MAAI,KAAK,UAAU,UAAU,CAC3B,QAAO,KAAK;AAEd,MAAI,KAAK,aAAa;AACpB,SAAM,KAAK;AACX,UAAO,KAAK;;AAGd,OAAK,WAAW,IAAI,QAAQ;AAC5B,OAAK,cAAc,KAAK,SAAS,UAAU,KAAK,SAAS;GACvD,QAAQ,KAAK,SAAS,UAAU,KAAK,iBAAiB,UAAU;GAChE,OAAO,KAAK,SAAS,SAAS,KAAK,iBAAiB,SAAS;GAC9D,CAAC;AACF,QAAM,KAAK;AACX,SAAO,KAAK;;CAGd,AAAQ,cAAc,QAIpB;EACA,IAAIC;EACJ,IAAI,OAAO;EACX,MAAMC,SAAuB,EAAE;AAE/B,OAAK,MAAM,OAAO,OAChB,KAAI,IAAI,SAAS,SACf,UAAS,IAAI;WACJ,IAAI,SAAS,QACtB;QAAK,MAAM,QAAQ,IAAI,QACrB,KAAI,KAAK,SAAS,OAChB,SAAQ,KAAK;YACH,KAAa,SAAS,SAAS;IAEzC,MAAM,UAAU;AAChB,QAAI,QAAQ,iBAAiB,IAC3B,QAAO,KAAK,EAAE,QAAQ,QAAQ,MAAM,UAAU,EAAE,CAAC;aACxC,OAAO,QAAQ,UAAU,SAElC,QAAO,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC;aAC7B,QAAQ,iBAAiB,YAAY;KAE9C,MAAM,SAAS,KAAK,OAAO,aAAa,GAAG,QAAQ,MAAM,CAAC;KAC1D,MAAM,WAAW,QAAQ,YAAY;AACrC,YAAO,KAAK,EAAE,QAAQ,QAAQ,SAAS,UAAU,UAAU,CAAC;;;aAIzD,IAAI,SAAS,aACtB;QAAK,MAAM,QAAQ,IAAI,QACrB,KAAI,KAAK,SAAS,OAChB,SAAQ,kBAAkB,KAAK;aAG1B,IAAI,SAAS,OACtB,MAAK,MAAM,QAAQ,IAAI,QACrB,SAAQ,aAAa,KAAK,SAAS,KAAK,KAAK,UAAU,KAAK;AAKlE,SAAO;GAAE;GAAQ;GAAM;GAAQ;;CAGjC,AAAQ,gBAAgB,QAA6C;AACnE,MAAI,WAAW,OACb,QAAO;AAET,MAAI,WAAW,SACb,QAAO;AAET,MAAI,WAAW,QACb,QAAO;AAET,SAAO;;CAGT,MAAM,WAAW,SAAqC;EACpD,MAAMC,WAAyC,EAAE;EACjD,MAAM,IAAI,MAAM,KAAK,cAAc;EACnC,MAAM,EAAE,QAAQ,MAAM,WAAW,KAAK,cAAc,QAAQ,OAAO;EAEnE,MAAM,SAAS,MAAM,EAAE,SAAS,MAAM;GACpC,WAAW,QAAQ;GACnB,aAAa,QAAQ;GACrB,MAAM,QAAQ;GACd,MAAM,QAAQ;GACd;GACA,UAAU,KAAK,SAAS;GACxB,eAAe,QAAQ;GACvB,QAAQ,OAAO,SAAS,IAAI,SAAS;GACtC,CAAC;EAGF,MAAMC,UAAoC,EAAE;AAG5C,MAAI,OAAO,SACT,SAAQ,KAAK;GACX,MAAM;GACN,MAAM,OAAO;GACd,CAAC;AAIJ,UAAQ,KAAK;GACX,MAAM;GACN,MAAM,OAAO;GACd,CAAC;EAEF,MAAMC,QAA8B;GAClC,aAAa;GACb,cAAc,OAAO;GACrB,aAAa,OAAO;GACrB;AAED,SAAO;GACL;GACA,cAAc,KAAK,gBAAgB,OAAO,aAAa;GACvD;GACA,SAAS,EAAE,MAAM;IAAE,OAAO,KAAK;IAAS,QAAQ;IAAM,EAAE;GACxD;GACD;;CAGH,MAAM,SAAS,SAAqC;EAClD,MAAMF,WAAyC,EAAE;EACjD,MAAM,IAAI,MAAM,KAAK,cAAc;EACnC,MAAM,EAAE,QAAQ,MAAM,WAAW,KAAK,cAAc,QAAQ,OAAO;EAEnE,MAAM,YAAY,EAAE,OAAO,MAAM;GAC/B,WAAW,QAAQ;GACnB,aAAa,QAAQ;GACrB,MAAM,QAAQ;GACd,MAAM,QAAQ;GACd;GACA,UAAU,KAAK,SAAS;GACxB,eAAe,QAAQ;GACvB,QAAQ,OAAO,SAAS,IAAI,SAAS;GACtC,CAAC;EAEF,IAAI,SAAS;EACb,MAAM,SAAS,YAAY;AAmD3B,SAAO;GACL,QAlDa,IAAI,eAA0C,EAC3D,MAAM,MAAM,YAAY;AACtB,QAAI;AAEF,gBAAW,QAAQ;MACjB,MAAM;MACN;MACD,CAAC;AAGF,gBAAW,QAAQ;MACjB,MAAM;MACN,IAAI;MACL,CAAC;AAEF,gBAAW,MAAM,SAAS,WAAW;AACnC,gBAAU;AAEV,iBAAW,QAAQ;OACjB,MAAM;OACN,IAAI;OACJ,OAAO;OACR,CAAC;;AAIJ,gBAAW,QAAQ;MACjB,MAAM;MACN,IAAI;MACL,CAAC;AAGF,gBAAW,QAAQ;MACjB,MAAM;MACN,cAAc;MACd,OAAO;OACL,aAAa;OACb,cAAc;OACd,aAAa;OACd;MACF,CAAC;AACF,gBAAW,OAAO;aACX,OAAO;AACd,gBAAW,QAAQ;MAAE,MAAM;MAAS;MAAO,CAAC;AAC5C,gBAAW,OAAO;;MAGvB,CAAC;GAIA,SAAS,EAAE,MAAM;IAAE,OAAO,KAAK;IAAS,QAAQ;IAAM,EAAE;GACzD;;;AAgBL,IAAM,oBAAN,MAAiD;CAC/C,AAAS,uBAAuB;CAChC,AAAS,WAAW;CACpB,AAAS;CAET,AAAQ,WAA0B;CAClC,AAAiB;CACjB,AAAQ,cAAoC;CAE5C,YAAY,SAAiB,WAAiC,EAAE,EAAE;AAChE,OAAK,UAAU;AACf,OAAK,WAAW;;CAGlB,MAAc,eAAgC;AAC5C,MAAI,KAAK,UAAU,aAAa,CAC9B,QAAO,KAAK;AAEd,MAAI,KAAK,aAAa;AACpB,SAAM,KAAK;AACX,UAAO,KAAK;;AAGd,OAAK,WAAW,IAAI,QAAQ;AAC5B,OAAK,cAAc,KAAK,SAAS,iBAAiB;AAClD,QAAM,KAAK;AACX,SAAO,KAAK;;CAGd,MAAM,WAAW,SAKd;EACD,MAAMG,WAAuC,EAAE;EAC/C,MAAM,IAAI,MAAM,KAAK,cAAc;EAGnC,IAAI,QAAQ,QAAQ,SAAS,KAAK,SAAS,SAAS;AAIpD,MAAI,CADe,cAAc,MAAM,MAAM,EAAE,OAAO,MAAM,EAC3C;AACf,YAAS,KAAK;IACZ,MAAM;IACN,SAAS;IACT,SAAS,kBAAkB,MAAM;IAClC,CAAC;AACF,WAAQ;;EAIV,MAAM,QAAQ,QAAQ,SAAS,KAAK,SAAS,SAAS;AAGtD,MAAI,QAAQ,gBAAgB,QAAQ,iBAAiB,SAAS,QAAQ,iBAAiB,MACrF,UAAS,KAAK;GACZ,MAAM;GACN,SAAS;GACT,SAAS,0DAA0D,QAAQ,aAAa;GACzF,CAAC;AAGJ,MAAI,QAAQ,aACV,UAAS,KAAK;GACZ,MAAM;GACN,SAAS;GACT,SAAS;GACV,CAAC;EAIJ,MAAM,SAAS,MAAM,EAAE,MAAM,QAAQ,MAAM;GAAE;GAAO;GAAO,CAAC;AAK5D,SAAO;GACL,OAHgB,KAAK,aAAa,OAAO,OAAO,OAAO,WAAW;GAIlE;GACA,SAAS,EAAE,MAAM;IAAE,MAAM,QAAQ;IAAM;IAAO;IAAO,EAAE;GACvD,UAAU;IACR,2BAAW,IAAI,MAAM;IACrB,SAAS,KAAK;IACf;GACF;;;;;CAMH,AAAQ,aAAa,OAAqB,YAAgC;EACxE,MAAM,yBAAS,IAAI,YAAY,KAAK,MAAM,SAAS,EAAE;EACrD,MAAM,OAAO,IAAI,SAAS,OAAO;EAGjC,MAAM,eAAe,QAAgB,QAAgB;AACnD,QAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC9B,MAAK,SAAS,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC;;AAIhD,cAAY,GAAG,OAAO;AACtB,OAAK,UAAU,GAAG,KAAK,MAAM,SAAS,GAAG,KAAK;AAC9C,cAAY,GAAG,OAAO;AACtB,cAAY,IAAI,OAAO;AACvB,OAAK,UAAU,IAAI,IAAI,KAAK;AAC5B,OAAK,UAAU,IAAI,GAAG,KAAK;AAC3B,OAAK,UAAU,IAAI,GAAG,KAAK;AAC3B,OAAK,UAAU,IAAI,YAAY,KAAK;AACpC,OAAK,UAAU,IAAI,aAAa,GAAG,KAAK;AACxC,OAAK,UAAU,IAAI,GAAG,KAAK;AAC3B,OAAK,UAAU,IAAI,IAAI,KAAK;AAC5B,cAAY,IAAI,OAAO;AACvB,OAAK,UAAU,IAAI,MAAM,SAAS,GAAG,KAAK;AAG1C,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,GAAG,CAAC;AAC7C,QAAK,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,MAAM,EAAE,KAAK;;AAGxD,SAAO,IAAI,WAAW,OAAO;;;AAcjC,IAAM,2BAAN,MAA+D;CAC7D,AAAS,uBAAuB;CAChC,AAAS,WAAW;CACpB,AAAS;CAET,AAAQ,WAA0B;CAClC,AAAiB;CACjB,AAAQ,cAAoC;CAE5C,YAAY,SAAiB,WAAwC,EAAE,EAAE;AACvE,OAAK,UAAU;AACf,OAAK,WAAW;;CAGlB,MAAc,eAAgC;AAC5C,MAAI,KAAK,UAAU,aAAa,CAC9B,QAAO,KAAK;AAEd,MAAI,KAAK,aAAa;AACpB,SAAM,KAAK;AACX,UAAO,KAAK;;AAGd,OAAK,WAAW,IAAI,QAAQ;AAC5B,OAAK,cAAc,KAAK,SAAS,QAAQ,KAAK,QAAQ;AACtD,QAAM,KAAK;AACX,SAAO,KAAK;;CAGd,MAAM,WAAW,SAed;EACD,MAAMC,WAA8C,EAAE;EACtD,MAAM,IAAI,MAAM,KAAK,cAAc;EAGnC,IAAIC;AACJ,MAAI,OAAO,QAAQ,UAAU,UAAU;GAErC,MAAM,eAAe,KAAK,QAAQ,MAAM;AACxC,eAAY,IAAI,WAAW,aAAa,OAAO;AAC/C,QAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,IACvC,WAAU,KAAK,aAAa,WAAW,EAAE;QAG3C,aAAY,QAAQ;EAItB,MAAM,YAAY,QAAQ,WAAW,aAAa,IAAI;AACtD,MAAI,aAAa,CAAC,UAAU,SAAS,MAAM,IAAI,CAAC,UAAU,SAAS,OAAO,CACxE,UAAS,KAAK;GACZ,MAAM;GACN,SAAS;GACT,SAAS,iDAAiD,QAAQ,UAAU;GAC7E,CAAC;EAKJ,MAAM,YADe,QAAQ,iBAAiB,SACd,YAAuB,KAAK,SAAS;EAGrE,MAAM,SAAS,MAAM,EAAE,WAAW,WAAW;GAC3C;GACA,YAAY;GACb,CAAC;EAGF,MAAM,YAAY,OAAO,YAAY,EAAE,EAAE,KAAK,SAAS;GACrD,MAAM,IAAI;GACV,aAAa,IAAI;GACjB,WAAW,IAAI;GAChB,EAAE;AAEH,SAAO;GACL,MAAM,OAAO;GACb;GACA,UAAU,OAAO;GACjB,mBAAmB,OAAO;GAC1B;GACA,SAAS,EACP,MAAM,KAAK,UAAU;IACnB,OAAO,KAAK;IACZ,WAAW,QAAQ;IACnB;IACD,CAAC,EACH;GACD,UAAU;IACR,2BAAW,IAAI,MAAM;IACrB,SAAS,KAAK;IACf;GACF;;;;AAeL,MAAa,mBAAmB;CAC9B;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,YAAY;EACb;CACD;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,YAAY;EACb;CACD;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,YAAY;EACb;CACF;AAED,IAAM,uBAAN,MAA+D;CAC7D,AAAS,uBAAuB;CAChC,AAAS,WAAW;CACpB,AAAS;CACT,AAAS,uBAAuB;CAChC,AAAS,wBAAwB;CAEjC,AAAQ,WAA0B;CAClC,AAAiB;CACjB,AAAQ,cAAoC;CAE5C,YAAY,SAAiB,WAAoC,EAAE,EAAE;AACnE,OAAK,UAAU;AACf,OAAK,WAAW;;CAGlB,AAAQ,UAAkB;AAExB,SADc,iBAAiB,MAAM,MAAM,EAAE,OAAO,KAAK,QAAQ,EACnD,QAAQ,KAAK;;CAG7B,MAAc,eAAgC;AAC5C,MAAI,KAAK,SACP,QAAO,KAAK;AAEd,MAAI,KAAK,aAAa;AACpB,SAAM,KAAK;AACX,UAAO,KAAK;;AAGd,OAAK,WAAW,IAAI,QAAQ;AAE5B,SAAO,KAAK;;CAGd,MAAM,QAAQ,SAGX;EACD,MAAM,IAAI,MAAM,KAAK,cAAc;EAEnC,MAAMC,aAAyB,EAAE;EACjC,IAAI,cAAc;AAElB,OAAK,MAAM,SAAS,QAAQ,QAAQ;AAClC,OAAI,QAAQ,aAAa,QACvB,OAAM,IAAI,MAAM,oBAAoB;GAGtC,MAAM,SAAS,MAAM,EAAE,MAAM,OAAO;IAClC,OAAO,KAAK,SAAS;IACrB,WAAW,KAAK,SAAS;IAC1B,CAAC;AAEF,cAAW,KAAK,OAAO,OAAO;AAE9B,kBAAe,KAAK,KAAK,MAAM,SAAS,EAAE;;AAG5C,SAAO;GACL;GACA,OAAO,EAAE,QAAQ,aAAa;GAC/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DL,SAAgB,aAAa,UAAkC,EAAE,EAAkB;CAEjF,MAAM,6BAAa,IAAI,KAAkC;CAEzD,MAAM,eAAe,SAAiB,WAAgC,EAAE,KAAK;EAE3E,MAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,MAAI,OAAQ,QAAO;AAEnB,SAAO,IAAI,oBAAoB,SAAS,UAAU,QAAQ;;CAG5D,MAAM,qBAAqB,UAAU,cAAc,WAAiC,EAAE,KACpF,IAAI,kBAAkB,SAAS,SAAS;CAE1C,MAAM,4BACJ,UAAU,mBACV,WAAwC,EAAE,KACvC,IAAI,yBAAyB,SAAS,SAAS;CAEpD,MAAM,wBACJ,UAAU,oBACV,WAAoC,EAAE,KACnC,IAAI,qBAAqB,SAAS,SAAS;CAEhD,MAAM,aAAa,SAAiB,aAClC,YAAY,SAAS,YAAY,EAAE,CAAC;AAEtC,UAAS,gBAAgB;AACzB,UAAS,SAAS;AAClB,UAAS,gBAAgB;AACzB,UAAS,YAAY;AACrB,UAAS,mBAAmB,OAAO,OAAO,eAAe;AACzD,UAAS,YAAY,OAAe,eAAe;AACnD,UAAS,mBACP,cAAc,KAAK,OAAO;EACxB,IAAI,EAAE;EACN,MAAM,EAAE;EACR,QAAQ,EAAE;EACV,UAAU,EAAE;EACb,EAAE;AACL,UAAS,gCAAgC;AACzC,UAAS,4BAA4B;AAGrC,UAAS,UAAU,OAAO,SAAS,SAAS;AAG1C,MAFoB,MAAc,cAAc,OAEhC;GAEd,MAAM,QAAQ,IAAI,oBAAoB,SAAS,EAAE,EAAE,QAAQ;AAC3D,SAAO,MAAc,cAAc;AACnC,cAAW,IAAI,SAAS,MAAM;QAI9B,OADU,IAAI,QAAQ,CACd,aAAa,SAAS,KAAK;;AAIvC,UAAS,WAAW,OAAO,YAAY;AAErC,MAAI,WAAW,IAAI,QAAQ,CAAE,QAAO;AAGpC,SADU,IAAI,QAAQ,CACb,cAAc,QAAQ;;AAGjC,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiET,MAAa,SAAS,cAAc;AAEpC,qBAAe"}
@@ -1,4 +1,4 @@
1
- import { O as TranscribeOptions, S as SpeakOptions, c as GerbilConfig, d as ImageInput, o as GenerateOptions } from "../types-CiTc7ez3.mjs";
1
+ import { I as TranscribeOptions, d as GerbilConfig, k as SpeakOptions, l as GenerateOptions, m as ImageInput } from "../types-LlyYILII.mjs";
2
2
 
3
3
  //#region src/integrations/langchain.d.ts
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"langchain.d.mts","names":[],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA0T8B,cA1PjB,SAAA,CA0PiB;EAAR,iBAAA,KAAA;EAAO,iBAAA,OAAA;EAS5B,WAAA,CAAA,MAAA,CAAA,EA/PqB,YA+PrB,GA/PoC,eA+PpC;;;;;mCAnPwC,kBAAkB;;;;;;;;;;;;2CAmB/C,wBACE,kBACT;;;;mCASqC,kBAAkB;;;;qCAQjB,kBAAkB;;;;oBAWnC;wBAMI;yBAIC;+BAIM;;;;;;;;;cAWxB,gBAAA;;;;;4BAOqB;uCAMW;;;;;;;;;;;;;;;;;;;;cAyBhC,SAAA;;;;;;;;;;;;gCAuBC,eACT;WAAiB;;;;;;;sCAkBR,eACT;aAA0B;;;;;;;gBAWT,QAClB;;;;;;;;;;;;;;;;;;;;;;;;cAwBS,SAAA;;;;;;;;;;;;oBAsBF,aAAa,wBACV,oBACT;;;;eAIU;;;;;;;;;gBAeO,QAAQ;;;;;;cAS7B"}
1
+ {"version":3,"file":"langchain.d.mts","names":[],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA2T8B,cA1PjB,SAAA,CA0PiB;EAAR,iBAAA,KAAA;EAAO,iBAAA,OAAA;EAS5B,WAAA,CAAA,MAAA,CAAA,EA/PqB,YA+PrB,GA/PoC,eA+PpC;;;;;mCAnPwC,kBAAkB;;;;;;;;;;;;2CAmB/C,wBACE,kBACT;;;;mCASqC,kBAAkB;;;;qCAQjB,kBAAkB;;;;oBAWnC;wBAMI;yBAIC;+BAIM;;;;;;;;;cAWxB,gBAAA;;;;;4BAOqB;uCAMW;;;;;;;;;;;;;;;;;;;;cAyBhC,SAAA;;;;;;;;;;;;gCAuBC,eACT;WAAiB;;;;;;;sCAkBR,eACT;aAA0B;;;;;;;gBAWT,QAClB;;;;;;;;;;;;;;;;;;;;;;;;cAwBS,SAAA;;;;;;;;;;;;oBAsBF,aAAa,wBACV,oBACT;;;;eAIU;;;;;;;;;gBAeO,QAAQ;;;;;;cAS7B"}
@@ -1,5 +1,5 @@
1
- import { t as Gerbil } from "../gerbil-Dw4Qj77e.mjs";
2
- import "../utils-CZBZ8dgR.mjs";
1
+ import { r as DEFAULT_MODEL, t as Gerbil } from "../gerbil-DNniplr4.mjs";
2
+ import "../utils-DKO55ZmZ.mjs";
3
3
 
4
4
  //#region src/integrations/langchain.ts
5
5
  /**
@@ -8,7 +8,7 @@ import "../utils-CZBZ8dgR.mjs";
8
8
  * @example Text Generation
9
9
  * ```ts
10
10
  * import { GerbilLLM } from "gerbil/langchain";
11
- * const llm = new GerbilLLM({ model: "qwen3-0.6b" });
11
+ * const llm = new GerbilLLM({ model: "qwen3.5-0.8b" });
12
12
  * const result = await llm.invoke("Hello!");
13
13
  * ```
14
14
  *
@@ -53,7 +53,7 @@ var GerbilLLM = class {
53
53
  model;
54
54
  options;
55
55
  constructor(config = {}) {
56
- this.model = config.model || "qwen3-0.6b";
56
+ this.model = config.model || DEFAULT_MODEL;
57
57
  this.options = config;
58
58
  }
59
59
  get _llmType() {
@@ -125,7 +125,7 @@ var GerbilLLM = class {
125
125
  var GerbilEmbeddings = class {
126
126
  model;
127
127
  constructor(config = {}) {
128
- this.model = config.model || "qwen3-0.6b";
128
+ this.model = config.model || DEFAULT_MODEL;
129
129
  }
130
130
  async embedQuery(text) {
131
131
  return (await (await getInstance(this.model)).embed(text)).vector;
@@ -1 +1 @@
1
- {"version":3,"file":"langchain.mjs","names":["instance: Gerbil | null","loadPromise: Promise<void> | null","results: string[]"],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":["/**\n * Gerbil LangChain Integration\n *\n * @example Text Generation\n * ```ts\n * import { GerbilLLM } from \"gerbil/langchain\";\n * const llm = new GerbilLLM({ model: \"qwen3-0.6b\" });\n * const result = await llm.invoke(\"Hello!\");\n * ```\n *\n * @example Embeddings\n * ```ts\n * import { GerbilEmbeddings } from \"gerbil/langchain\";\n * const embeddings = new GerbilEmbeddings();\n * const vectors = await embeddings.embedDocuments([\"Hello\", \"World\"]);\n * ```\n *\n * @example Text-to-Speech\n * ```ts\n * import { GerbilTTS } from \"gerbil/langchain\";\n * const tts = new GerbilTTS({ voice: \"af_heart\" });\n * const audio = await tts.speak(\"Hello world!\");\n * ```\n *\n * @example Speech-to-Text\n * ```ts\n * import { GerbilSTT } from \"gerbil/langchain\";\n * const stt = new GerbilSTT({ model: \"whisper-tiny.en\" });\n * const text = await stt.transcribe(audioBuffer);\n * ```\n */\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport type {\n GenerateOptions,\n GerbilConfig,\n ImageInput,\n SpeakOptions,\n TranscribeOptions,\n} from \"../core/types.js\";\n\n// Singleton Gerbil instance\nlet instance: Gerbil | null = null;\nlet loadPromise: Promise<void> | null = null;\n\nasync function getInstance(model: string): Promise<Gerbil> {\n if (!instance) {\n instance = new Gerbil();\n }\n if (!(instance.isLoaded() || loadPromise)) {\n loadPromise = instance.loadModel(model);\n }\n if (loadPromise) {\n await loadPromise;\n loadPromise = null;\n }\n return instance;\n}\n\n/**\n * Gerbil LLM for LangChain\n *\n * Supports text generation with optional vision (images) input.\n */\nexport class GerbilLLM {\n private readonly model: string;\n private readonly options: GenerateOptions;\n\n constructor(config: GerbilConfig & GenerateOptions = {}) {\n this.model = config.model || \"qwen3-0.6b\";\n this.options = config;\n }\n\n get _llmType(): string {\n return \"gerbil\";\n }\n\n /**\n * Generate text from a prompt\n */\n async invoke(prompt: string, options?: GenerateOptions): Promise<string> {\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, { ...this.options, ...options });\n return result.text;\n }\n\n /**\n * Generate text with images (vision)\n *\n * @example\n * ```ts\n * const llm = new GerbilLLM({ model: \"ministral-3b\" });\n * const result = await llm.invokeWithImages(\"Describe this image\", [\n * { source: \"https://example.com/photo.jpg\" }\n * ]);\n * ```\n */\n async invokeWithImages(\n prompt: string,\n images: ImageInput[],\n options?: GenerateOptions,\n ): Promise<string> {\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, { ...this.options, ...options, images });\n return result.text;\n }\n\n /**\n * Stream text generation\n */\n async *stream(prompt: string, options?: GenerateOptions): AsyncGenerator<string> {\n const g = await getInstance(this.model);\n yield* g.stream(prompt, { ...this.options, ...options });\n }\n\n /**\n * Batch generate text for multiple prompts\n */\n async batch(prompts: string[], options?: GenerateOptions): Promise<string[]> {\n const results: string[] = [];\n for (const prompt of prompts) {\n results.push(await this.invoke(prompt, options));\n }\n return results;\n }\n\n /**\n * Check if the model supports vision input\n */\n async supportsVision(): Promise<boolean> {\n const g = await getInstance(this.model);\n return g.supportsVision();\n }\n\n // LangChain compatibility methods\n async call(prompt: string): Promise<string> {\n return this.invoke(prompt);\n }\n\n async predict(text: string): Promise<string> {\n return this.invoke(text);\n }\n\n async generate(prompts: string[]): Promise<{ generations: { text: string }[][] }> {\n const results = await this.batch(prompts);\n return {\n generations: results.map((text) => [{ text }]),\n };\n }\n}\n\n/**\n * Gerbil Embeddings for LangChain\n */\nexport class GerbilEmbeddings {\n private readonly model: string;\n\n constructor(config: { model?: string } = {}) {\n this.model = config.model || \"qwen3-0.6b\";\n }\n\n async embedQuery(text: string): Promise<number[]> {\n const g = await getInstance(this.model);\n const result = await g.embed(text);\n return result.vector;\n }\n\n async embedDocuments(documents: string[]): Promise<number[][]> {\n const g = await getInstance(this.model);\n const results = await g.embedBatch(documents);\n return results.map((r) => r.vector);\n }\n}\n\n/**\n * Gerbil Text-to-Speech for LangChain\n *\n * Note: LangChain doesn't have a standard TTS interface, so this is a\n * utility class for use in LangChain pipelines.\n *\n * @example\n * ```ts\n * import { GerbilTTS } from \"gerbil/langchain\";\n *\n * const tts = new GerbilTTS({ voice: \"af_heart\" });\n * const result = await tts.speak(\"Hello world!\");\n * // result.audio = Float32Array, result.sampleRate = 24000\n *\n * // List voices\n * const voices = await tts.listVoices();\n * ```\n */\nexport class GerbilTTS {\n private readonly voice: string;\n private readonly speed: number;\n private gerbil: Gerbil | null = null;\n\n constructor(config: { voice?: string; speed?: number } = {}) {\n this.voice = config.voice || \"af_heart\";\n this.speed = config.speed || 1.0;\n }\n\n private async getInstance(): Promise<Gerbil> {\n if (!this.gerbil) {\n this.gerbil = new Gerbil();\n }\n await this.gerbil.ensureTTSLoaded();\n return this.gerbil;\n }\n\n /**\n * Generate speech from text\n */\n async speak(\n text: string,\n options?: SpeakOptions,\n ): Promise<{ audio: Float32Array; sampleRate: number; duration: number }> {\n const g = await this.getInstance();\n const result = await g.speak(text, {\n voice: options?.voice || this.voice,\n speed: options?.speed || this.speed,\n });\n return {\n audio: result.audio,\n sampleRate: result.sampleRate,\n duration: result.duration,\n };\n }\n\n /**\n * Stream speech generation for long text\n */\n async *speakStream(\n text: string,\n options?: SpeakOptions,\n ): AsyncGenerator<{ samples: Float32Array; index: number; isFinal: boolean }> {\n const g = await this.getInstance();\n yield* g.speakStream(text, {\n voice: options?.voice || this.voice,\n speed: options?.speed || this.speed,\n });\n }\n\n /**\n * List available voices\n */\n async listVoices(): Promise<\n Array<{ id: string; name: string; gender: string; language: string }>\n > {\n const g = await this.getInstance();\n return g.listVoices();\n }\n}\n\n/**\n * Gerbil Speech-to-Text for LangChain\n *\n * Note: LangChain doesn't have a standard STT interface, so this is a\n * utility class for use in LangChain pipelines.\n *\n * @example\n * ```ts\n * import { GerbilSTT } from \"gerbil/langchain\";\n * import { readFileSync } from \"fs\";\n *\n * const stt = new GerbilSTT({ model: \"whisper-tiny.en\" });\n * const audio = new Uint8Array(readFileSync(\"audio.wav\"));\n * const result = await stt.transcribe(audio);\n * console.log(result.text);\n * ```\n */\nexport class GerbilSTT {\n private readonly model: string;\n private gerbil: Gerbil | null = null;\n\n constructor(config: { model?: string } = {}) {\n this.model = config.model || \"whisper-tiny.en\";\n }\n\n private async getInstance(): Promise<Gerbil> {\n if (!this.gerbil) {\n this.gerbil = new Gerbil();\n }\n await this.gerbil.loadSTT(this.model);\n return this.gerbil;\n }\n\n /**\n * Transcribe audio to text\n *\n * @param audio - WAV file as Uint8Array or Float32Array at 16kHz\n */\n async transcribe(\n audio: Uint8Array | Float32Array,\n options?: TranscribeOptions,\n ): Promise<{\n text: string;\n language?: string;\n duration?: number;\n segments?: Array<{ text: string; start: number; end: number }>;\n }> {\n const g = await this.getInstance();\n const result = await g.transcribe(audio, options);\n return {\n text: result.text,\n language: result.language,\n duration: result.duration,\n segments: result.segments,\n };\n }\n\n /**\n * List available STT models\n */\n async listModels(): Promise<Array<{ id: string; size: string; multilingual: boolean }>> {\n const g = await this.getInstance();\n const models = await g.listSTTModels();\n return models.map((m) => ({\n id: m.id,\n size: m.size,\n multilingual: m.multilingual,\n }));\n }\n}\n\nexport default { GerbilLLM, GerbilEmbeddings, GerbilTTS, GerbilSTT };\n"],"mappings":"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"}
1
+ {"version":3,"file":"langchain.mjs","names":["instance: Gerbil | null","loadPromise: Promise<void> | null","results: string[]"],"sources":["../../src/integrations/langchain.ts"],"sourcesContent":["/**\n * Gerbil LangChain Integration\n *\n * @example Text Generation\n * ```ts\n * import { GerbilLLM } from \"gerbil/langchain\";\n * const llm = new GerbilLLM({ model: \"qwen3.5-0.8b\" });\n * const result = await llm.invoke(\"Hello!\");\n * ```\n *\n * @example Embeddings\n * ```ts\n * import { GerbilEmbeddings } from \"gerbil/langchain\";\n * const embeddings = new GerbilEmbeddings();\n * const vectors = await embeddings.embedDocuments([\"Hello\", \"World\"]);\n * ```\n *\n * @example Text-to-Speech\n * ```ts\n * import { GerbilTTS } from \"gerbil/langchain\";\n * const tts = new GerbilTTS({ voice: \"af_heart\" });\n * const audio = await tts.speak(\"Hello world!\");\n * ```\n *\n * @example Speech-to-Text\n * ```ts\n * import { GerbilSTT } from \"gerbil/langchain\";\n * const stt = new GerbilSTT({ model: \"whisper-tiny.en\" });\n * const text = await stt.transcribe(audioBuffer);\n * ```\n */\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport { DEFAULT_MODEL } from \"../core/models.js\";\nimport type {\n GenerateOptions,\n GerbilConfig,\n ImageInput,\n SpeakOptions,\n TranscribeOptions,\n} from \"../core/types.js\";\n\n// Singleton Gerbil instance\nlet instance: Gerbil | null = null;\nlet loadPromise: Promise<void> | null = null;\n\nasync function getInstance(model: string): Promise<Gerbil> {\n if (!instance) {\n instance = new Gerbil();\n }\n if (!(instance.isLoaded() || loadPromise)) {\n loadPromise = instance.loadModel(model);\n }\n if (loadPromise) {\n await loadPromise;\n loadPromise = null;\n }\n return instance;\n}\n\n/**\n * Gerbil LLM for LangChain\n *\n * Supports text generation with optional vision (images) input.\n */\nexport class GerbilLLM {\n private readonly model: string;\n private readonly options: GenerateOptions;\n\n constructor(config: GerbilConfig & GenerateOptions = {}) {\n this.model = config.model || DEFAULT_MODEL;\n this.options = config;\n }\n\n get _llmType(): string {\n return \"gerbil\";\n }\n\n /**\n * Generate text from a prompt\n */\n async invoke(prompt: string, options?: GenerateOptions): Promise<string> {\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, { ...this.options, ...options });\n return result.text;\n }\n\n /**\n * Generate text with images (vision)\n *\n * @example\n * ```ts\n * const llm = new GerbilLLM({ model: \"ministral-3b\" });\n * const result = await llm.invokeWithImages(\"Describe this image\", [\n * { source: \"https://example.com/photo.jpg\" }\n * ]);\n * ```\n */\n async invokeWithImages(\n prompt: string,\n images: ImageInput[],\n options?: GenerateOptions,\n ): Promise<string> {\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, { ...this.options, ...options, images });\n return result.text;\n }\n\n /**\n * Stream text generation\n */\n async *stream(prompt: string, options?: GenerateOptions): AsyncGenerator<string> {\n const g = await getInstance(this.model);\n yield* g.stream(prompt, { ...this.options, ...options });\n }\n\n /**\n * Batch generate text for multiple prompts\n */\n async batch(prompts: string[], options?: GenerateOptions): Promise<string[]> {\n const results: string[] = [];\n for (const prompt of prompts) {\n results.push(await this.invoke(prompt, options));\n }\n return results;\n }\n\n /**\n * Check if the model supports vision input\n */\n async supportsVision(): Promise<boolean> {\n const g = await getInstance(this.model);\n return g.supportsVision();\n }\n\n // LangChain compatibility methods\n async call(prompt: string): Promise<string> {\n return this.invoke(prompt);\n }\n\n async predict(text: string): Promise<string> {\n return this.invoke(text);\n }\n\n async generate(prompts: string[]): Promise<{ generations: { text: string }[][] }> {\n const results = await this.batch(prompts);\n return {\n generations: results.map((text) => [{ text }]),\n };\n }\n}\n\n/**\n * Gerbil Embeddings for LangChain\n */\nexport class GerbilEmbeddings {\n private readonly model: string;\n\n constructor(config: { model?: string } = {}) {\n this.model = config.model || DEFAULT_MODEL;\n }\n\n async embedQuery(text: string): Promise<number[]> {\n const g = await getInstance(this.model);\n const result = await g.embed(text);\n return result.vector;\n }\n\n async embedDocuments(documents: string[]): Promise<number[][]> {\n const g = await getInstance(this.model);\n const results = await g.embedBatch(documents);\n return results.map((r) => r.vector);\n }\n}\n\n/**\n * Gerbil Text-to-Speech for LangChain\n *\n * Note: LangChain doesn't have a standard TTS interface, so this is a\n * utility class for use in LangChain pipelines.\n *\n * @example\n * ```ts\n * import { GerbilTTS } from \"gerbil/langchain\";\n *\n * const tts = new GerbilTTS({ voice: \"af_heart\" });\n * const result = await tts.speak(\"Hello world!\");\n * // result.audio = Float32Array, result.sampleRate = 24000\n *\n * // List voices\n * const voices = await tts.listVoices();\n * ```\n */\nexport class GerbilTTS {\n private readonly voice: string;\n private readonly speed: number;\n private gerbil: Gerbil | null = null;\n\n constructor(config: { voice?: string; speed?: number } = {}) {\n this.voice = config.voice || \"af_heart\";\n this.speed = config.speed || 1.0;\n }\n\n private async getInstance(): Promise<Gerbil> {\n if (!this.gerbil) {\n this.gerbil = new Gerbil();\n }\n await this.gerbil.ensureTTSLoaded();\n return this.gerbil;\n }\n\n /**\n * Generate speech from text\n */\n async speak(\n text: string,\n options?: SpeakOptions,\n ): Promise<{ audio: Float32Array; sampleRate: number; duration: number }> {\n const g = await this.getInstance();\n const result = await g.speak(text, {\n voice: options?.voice || this.voice,\n speed: options?.speed || this.speed,\n });\n return {\n audio: result.audio,\n sampleRate: result.sampleRate,\n duration: result.duration,\n };\n }\n\n /**\n * Stream speech generation for long text\n */\n async *speakStream(\n text: string,\n options?: SpeakOptions,\n ): AsyncGenerator<{ samples: Float32Array; index: number; isFinal: boolean }> {\n const g = await this.getInstance();\n yield* g.speakStream(text, {\n voice: options?.voice || this.voice,\n speed: options?.speed || this.speed,\n });\n }\n\n /**\n * List available voices\n */\n async listVoices(): Promise<\n Array<{ id: string; name: string; gender: string; language: string }>\n > {\n const g = await this.getInstance();\n return g.listVoices();\n }\n}\n\n/**\n * Gerbil Speech-to-Text for LangChain\n *\n * Note: LangChain doesn't have a standard STT interface, so this is a\n * utility class for use in LangChain pipelines.\n *\n * @example\n * ```ts\n * import { GerbilSTT } from \"gerbil/langchain\";\n * import { readFileSync } from \"fs\";\n *\n * const stt = new GerbilSTT({ model: \"whisper-tiny.en\" });\n * const audio = new Uint8Array(readFileSync(\"audio.wav\"));\n * const result = await stt.transcribe(audio);\n * console.log(result.text);\n * ```\n */\nexport class GerbilSTT {\n private readonly model: string;\n private gerbil: Gerbil | null = null;\n\n constructor(config: { model?: string } = {}) {\n this.model = config.model || \"whisper-tiny.en\";\n }\n\n private async getInstance(): Promise<Gerbil> {\n if (!this.gerbil) {\n this.gerbil = new Gerbil();\n }\n await this.gerbil.loadSTT(this.model);\n return this.gerbil;\n }\n\n /**\n * Transcribe audio to text\n *\n * @param audio - WAV file as Uint8Array or Float32Array at 16kHz\n */\n async transcribe(\n audio: Uint8Array | Float32Array,\n options?: TranscribeOptions,\n ): Promise<{\n text: string;\n language?: string;\n duration?: number;\n segments?: Array<{ text: string; start: number; end: number }>;\n }> {\n const g = await this.getInstance();\n const result = await g.transcribe(audio, options);\n return {\n text: result.text,\n language: result.language,\n duration: result.duration,\n segments: result.segments,\n };\n }\n\n /**\n * List available STT models\n */\n async listModels(): Promise<Array<{ id: string; size: string; multilingual: boolean }>> {\n const g = await this.getInstance();\n const models = await g.listSTTModels();\n return models.map((m) => ({\n id: m.id,\n size: m.size,\n multilingual: m.multilingual,\n }));\n }\n}\n\nexport default { GerbilLLM, GerbilEmbeddings, GerbilTTS, GerbilSTT };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,IAAIA,WAA0B;AAC9B,IAAIC,cAAoC;AAExC,eAAe,YAAY,OAAgC;AACzD,KAAI,CAAC,SACH,YAAW,IAAI,QAAQ;AAEzB,KAAI,EAAE,SAAS,UAAU,IAAI,aAC3B,eAAc,SAAS,UAAU,MAAM;AAEzC,KAAI,aAAa;AACf,QAAM;AACN,gBAAc;;AAEhB,QAAO;;;;;;;AAQT,IAAa,YAAb,MAAuB;CACrB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAyC,EAAE,EAAE;AACvD,OAAK,QAAQ,OAAO,SAAS;AAC7B,OAAK,UAAU;;CAGjB,IAAI,WAAmB;AACrB,SAAO;;;;;CAMT,MAAM,OAAO,QAAgB,SAA4C;AAGvE,UADe,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,SAAS,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS,CAAC,EAC1D;;;;;;;;;;;;;CAchB,MAAM,iBACJ,QACA,QACA,SACiB;AAGjB,UADe,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,SAAS,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS;GAAQ,CAAC,EAClE;;;;;CAMhB,OAAO,OAAO,QAAgB,SAAmD;AAE/E,UADU,MAAM,YAAY,KAAK,MAAM,EAC9B,OAAO,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS,CAAC;;;;;CAM1D,MAAM,MAAM,SAAmB,SAA8C;EAC3E,MAAMC,UAAoB,EAAE;AAC5B,OAAK,MAAM,UAAU,QACnB,SAAQ,KAAK,MAAM,KAAK,OAAO,QAAQ,QAAQ,CAAC;AAElD,SAAO;;;;;CAMT,MAAM,iBAAmC;AAEvC,UADU,MAAM,YAAY,KAAK,MAAM,EAC9B,gBAAgB;;CAI3B,MAAM,KAAK,QAAiC;AAC1C,SAAO,KAAK,OAAO,OAAO;;CAG5B,MAAM,QAAQ,MAA+B;AAC3C,SAAO,KAAK,OAAO,KAAK;;CAG1B,MAAM,SAAS,SAAmE;AAEhF,SAAO,EACL,cAFc,MAAM,KAAK,MAAM,QAAQ,EAElB,KAAK,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,EAC/C;;;;;;AAOL,IAAa,mBAAb,MAA8B;CAC5B,AAAiB;CAEjB,YAAY,SAA6B,EAAE,EAAE;AAC3C,OAAK,QAAQ,OAAO,SAAS;;CAG/B,MAAM,WAAW,MAAiC;AAGhD,UADe,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,MAAM,KAAK,EACpB;;CAGhB,MAAM,eAAe,WAA0C;AAG7D,UADgB,OADN,MAAM,YAAY,KAAK,MAAM,EACf,WAAW,UAAU,EAC9B,KAAK,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;AAsBvC,IAAa,YAAb,MAAuB;CACrB,AAAiB;CACjB,AAAiB;CACjB,AAAQ,SAAwB;CAEhC,YAAY,SAA6C,EAAE,EAAE;AAC3D,OAAK,QAAQ,OAAO,SAAS;AAC7B,OAAK,QAAQ,OAAO,SAAS;;CAG/B,MAAc,cAA+B;AAC3C,MAAI,CAAC,KAAK,OACR,MAAK,SAAS,IAAI,QAAQ;AAE5B,QAAM,KAAK,OAAO,iBAAiB;AACnC,SAAO,KAAK;;;;;CAMd,MAAM,MACJ,MACA,SACwE;EAExE,MAAM,SAAS,OADL,MAAM,KAAK,aAAa,EACX,MAAM,MAAM;GACjC,OAAO,SAAS,SAAS,KAAK;GAC9B,OAAO,SAAS,SAAS,KAAK;GAC/B,CAAC;AACF,SAAO;GACL,OAAO,OAAO;GACd,YAAY,OAAO;GACnB,UAAU,OAAO;GAClB;;;;;CAMH,OAAO,YACL,MACA,SAC4E;AAE5E,UADU,MAAM,KAAK,aAAa,EACzB,YAAY,MAAM;GACzB,OAAO,SAAS,SAAS,KAAK;GAC9B,OAAO,SAAS,SAAS,KAAK;GAC/B,CAAC;;;;;CAMJ,MAAM,aAEJ;AAEA,UADU,MAAM,KAAK,aAAa,EACzB,YAAY;;;;;;;;;;;;;;;;;;;;AAqBzB,IAAa,YAAb,MAAuB;CACrB,AAAiB;CACjB,AAAQ,SAAwB;CAEhC,YAAY,SAA6B,EAAE,EAAE;AAC3C,OAAK,QAAQ,OAAO,SAAS;;CAG/B,MAAc,cAA+B;AAC3C,MAAI,CAAC,KAAK,OACR,MAAK,SAAS,IAAI,QAAQ;AAE5B,QAAM,KAAK,OAAO,QAAQ,KAAK,MAAM;AACrC,SAAO,KAAK;;;;;;;CAQd,MAAM,WACJ,OACA,SAMC;EAED,MAAM,SAAS,OADL,MAAM,KAAK,aAAa,EACX,WAAW,OAAO,QAAQ;AACjD,SAAO;GACL,MAAM,OAAO;GACb,UAAU,OAAO;GACjB,UAAU,OAAO;GACjB,UAAU,OAAO;GAClB;;;;;CAMH,MAAM,aAAkF;AAGtF,UADe,OADL,MAAM,KAAK,aAAa,EACX,eAAe,EACxB,KAAK,OAAO;GACxB,IAAI,EAAE;GACN,MAAM,EAAE;GACR,cAAc,EAAE;GACjB,EAAE;;;AAIP,wBAAe;CAAE;CAAW;CAAkB;CAAW;CAAW"}
@@ -1,4 +1,4 @@
1
- import { c as GerbilConfig, o as GenerateOptions } from "../types-CiTc7ez3.mjs";
1
+ import { d as GerbilConfig, l as GenerateOptions } from "../types-LlyYILII.mjs";
2
2
 
3
3
  //#region src/integrations/llamaindex.d.ts
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"llamaindex.d.mts","names":[],"sources":["../../src/integrations/llamaindex.ts"],"sourcesContent":[],"mappings":";;;;AAuGC;;;cA9DY,SAAA;;;uBAIS,eAAe;qCAKM,kBAAkB;;;;;;QAQxD;;;;;mCAYqC,kBAAkB;;;;;;;cAW/C,eAAA;;;;;kCAO2B;sCAMI;oCAMF;;cAGzC;oBAAA;0BAAA"}
1
+ {"version":3,"file":"llamaindex.d.mts","names":[],"sources":["../../src/integrations/llamaindex.ts"],"sourcesContent":[],"mappings":";;;;AAwGC;;;cA9DY,SAAA;;;uBAIS,eAAe;qCAKM,kBAAkB;;;;;;QAQxD;;;;;mCAYqC,kBAAkB;;;;;;;cAW/C,eAAA;;;;;kCAO2B;sCAMI;oCAMF;;cAGzC;oBAAA;0BAAA"}
@@ -1,5 +1,5 @@
1
- import { t as Gerbil } from "../gerbil-Dw4Qj77e.mjs";
2
- import "../utils-CZBZ8dgR.mjs";
1
+ import { r as DEFAULT_MODEL, t as Gerbil } from "../gerbil-DNniplr4.mjs";
2
+ import "../utils-DKO55ZmZ.mjs";
3
3
 
4
4
  //#region src/integrations/llamaindex.ts
5
5
  /**
@@ -9,7 +9,7 @@ import "../utils-CZBZ8dgR.mjs";
9
9
  * ```ts
10
10
  * import { GerbilLLM, GerbilEmbedding } from "gerbil/llamaindex";
11
11
  *
12
- * const llm = new GerbilLLM({ model: "qwen3-0.6b" });
12
+ * const llm = new GerbilLLM({ model: "qwen3.5-0.8b" });
13
13
  * const embedModel = new GerbilEmbedding();
14
14
  *
15
15
  * const index = await VectorStoreIndex.fromDocuments(documents, {
@@ -36,7 +36,7 @@ var GerbilLLM = class {
36
36
  model;
37
37
  options;
38
38
  constructor(config = {}) {
39
- this.model = config.model || "qwen3-0.6b";
39
+ this.model = config.model || DEFAULT_MODEL;
40
40
  this.options = config;
41
41
  }
42
42
  async complete(prompt, options) {
@@ -63,7 +63,7 @@ var GerbilLLM = class {
63
63
  var GerbilEmbedding = class {
64
64
  model;
65
65
  constructor(config = {}) {
66
- this.model = config.model || "qwen3-0.6b";
66
+ this.model = config.model || DEFAULT_MODEL;
67
67
  }
68
68
  async getTextEmbedding(text) {
69
69
  return (await (await getInstance(this.model)).embed(text)).vector;
@@ -1 +1 @@
1
- {"version":3,"file":"llamaindex.mjs","names":["instance: Gerbil | null","loadPromise: Promise<void> | null"],"sources":["../../src/integrations/llamaindex.ts"],"sourcesContent":["/**\n * Gerbil LlamaIndex Integration\n *\n * @example\n * ```ts\n * import { GerbilLLM, GerbilEmbedding } from \"gerbil/llamaindex\";\n *\n * const llm = new GerbilLLM({ model: \"qwen3-0.6b\" });\n * const embedModel = new GerbilEmbedding();\n *\n * const index = await VectorStoreIndex.fromDocuments(documents, {\n * llm,\n * embedModel,\n * });\n * ```\n */\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport type { GenerateOptions, GerbilConfig } from \"../core/types.js\";\n\n// Singleton Gerbil instance\nlet instance: Gerbil | null = null;\nlet loadPromise: Promise<void> | null = null;\n\nasync function getInstance(model: string): Promise<Gerbil> {\n if (!instance) {\n instance = new Gerbil();\n }\n if (!(instance.isLoaded() || loadPromise)) {\n loadPromise = instance.loadModel(model);\n }\n if (loadPromise) {\n await loadPromise;\n loadPromise = null;\n }\n return instance;\n}\n\n/**\n * Gerbil LLM for LlamaIndex\n */\nexport class GerbilLLM {\n private readonly model: string;\n private readonly options: GenerateOptions;\n\n constructor(config: GerbilConfig & GenerateOptions = {}) {\n this.model = config.model || \"qwen3-0.6b\";\n this.options = config;\n }\n\n async complete(prompt: string, options?: GenerateOptions): Promise<{ text: string }> {\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, { ...this.options, ...options });\n return { text: result.text };\n }\n\n async chat(\n messages: { role: string; content: string }[],\n ): Promise<{ message: { content: string } }> {\n // Convert chat messages to a single prompt\n const prompt = messages.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, this.options);\n\n return {\n message: { content: result.text },\n };\n }\n\n async *stream(prompt: string, options?: GenerateOptions): AsyncGenerator<{ delta: string }> {\n const g = await getInstance(this.model);\n for await (const chunk of g.stream(prompt, { ...this.options, ...options })) {\n yield { delta: chunk };\n }\n }\n}\n\n/**\n * Gerbil Embedding Model for LlamaIndex\n */\nexport class GerbilEmbedding {\n private readonly model: string;\n\n constructor(config: { model?: string } = {}) {\n this.model = config.model || \"qwen3-0.6b\";\n }\n\n async getTextEmbedding(text: string): Promise<number[]> {\n const g = await getInstance(this.model);\n const result = await g.embed(text);\n return result.vector;\n }\n\n async getTextEmbeddings(texts: string[]): Promise<number[][]> {\n const g = await getInstance(this.model);\n const results = await g.embedBatch(texts);\n return results.map((r) => r.vector);\n }\n\n async getQueryEmbedding(query: string): Promise<number[]> {\n return this.getTextEmbedding(query);\n }\n}\n\nexport default { GerbilLLM, GerbilEmbedding };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,IAAIA,WAA0B;AAC9B,IAAIC,cAAoC;AAExC,eAAe,YAAY,OAAgC;AACzD,KAAI,CAAC,SACH,YAAW,IAAI,QAAQ;AAEzB,KAAI,EAAE,SAAS,UAAU,IAAI,aAC3B,eAAc,SAAS,UAAU,MAAM;AAEzC,KAAI,aAAa;AACf,QAAM;AACN,gBAAc;;AAEhB,QAAO;;;;;AAMT,IAAa,YAAb,MAAuB;CACrB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAyC,EAAE,EAAE;AACvD,OAAK,QAAQ,OAAO,SAAS;AAC7B,OAAK,UAAU;;CAGjB,MAAM,SAAS,QAAgB,SAAsD;AAGnF,SAAO,EAAE,OADM,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,SAAS,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS,CAAC,EAClD,MAAM;;CAG9B,MAAM,KACJ,UAC2C;EAE3C,MAAM,SAAS,SAAS,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,UAAU,CAAC,KAAK,KAAK;AAKxE,SAAO,EACL,SAAS,EAAE,UAHE,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,SAAS,QAAQ,KAAK,QAAQ,EAGxB,MAAM,EAClC;;CAGH,OAAO,OAAO,QAAgB,SAA8D;EAC1F,MAAM,IAAI,MAAM,YAAY,KAAK,MAAM;AACvC,aAAW,MAAM,SAAS,EAAE,OAAO,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS,CAAC,CACzE,OAAM,EAAE,OAAO,OAAO;;;;;;AAQ5B,IAAa,kBAAb,MAA6B;CAC3B,AAAiB;CAEjB,YAAY,SAA6B,EAAE,EAAE;AAC3C,OAAK,QAAQ,OAAO,SAAS;;CAG/B,MAAM,iBAAiB,MAAiC;AAGtD,UADe,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,MAAM,KAAK,EACpB;;CAGhB,MAAM,kBAAkB,OAAsC;AAG5D,UADgB,OADN,MAAM,YAAY,KAAK,MAAM,EACf,WAAW,MAAM,EAC1B,KAAK,MAAM,EAAE,OAAO;;CAGrC,MAAM,kBAAkB,OAAkC;AACxD,SAAO,KAAK,iBAAiB,MAAM;;;AAIvC,yBAAe;CAAE;CAAW;CAAiB"}
1
+ {"version":3,"file":"llamaindex.mjs","names":["instance: Gerbil | null","loadPromise: Promise<void> | null"],"sources":["../../src/integrations/llamaindex.ts"],"sourcesContent":["/**\n * Gerbil LlamaIndex Integration\n *\n * @example\n * ```ts\n * import { GerbilLLM, GerbilEmbedding } from \"gerbil/llamaindex\";\n *\n * const llm = new GerbilLLM({ model: \"qwen3.5-0.8b\" });\n * const embedModel = new GerbilEmbedding();\n *\n * const index = await VectorStoreIndex.fromDocuments(documents, {\n * llm,\n * embedModel,\n * });\n * ```\n */\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport { DEFAULT_MODEL } from \"../core/models.js\";\nimport type { GenerateOptions, GerbilConfig } from \"../core/types.js\";\n\n// Singleton Gerbil instance\nlet instance: Gerbil | null = null;\nlet loadPromise: Promise<void> | null = null;\n\nasync function getInstance(model: string): Promise<Gerbil> {\n if (!instance) {\n instance = new Gerbil();\n }\n if (!(instance.isLoaded() || loadPromise)) {\n loadPromise = instance.loadModel(model);\n }\n if (loadPromise) {\n await loadPromise;\n loadPromise = null;\n }\n return instance;\n}\n\n/**\n * Gerbil LLM for LlamaIndex\n */\nexport class GerbilLLM {\n private readonly model: string;\n private readonly options: GenerateOptions;\n\n constructor(config: GerbilConfig & GenerateOptions = {}) {\n this.model = config.model || DEFAULT_MODEL;\n this.options = config;\n }\n\n async complete(prompt: string, options?: GenerateOptions): Promise<{ text: string }> {\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, { ...this.options, ...options });\n return { text: result.text };\n }\n\n async chat(\n messages: { role: string; content: string }[],\n ): Promise<{ message: { content: string } }> {\n // Convert chat messages to a single prompt\n const prompt = messages.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n\n const g = await getInstance(this.model);\n const result = await g.generate(prompt, this.options);\n\n return {\n message: { content: result.text },\n };\n }\n\n async *stream(prompt: string, options?: GenerateOptions): AsyncGenerator<{ delta: string }> {\n const g = await getInstance(this.model);\n for await (const chunk of g.stream(prompt, { ...this.options, ...options })) {\n yield { delta: chunk };\n }\n }\n}\n\n/**\n * Gerbil Embedding Model for LlamaIndex\n */\nexport class GerbilEmbedding {\n private readonly model: string;\n\n constructor(config: { model?: string } = {}) {\n this.model = config.model || DEFAULT_MODEL;\n }\n\n async getTextEmbedding(text: string): Promise<number[]> {\n const g = await getInstance(this.model);\n const result = await g.embed(text);\n return result.vector;\n }\n\n async getTextEmbeddings(texts: string[]): Promise<number[][]> {\n const g = await getInstance(this.model);\n const results = await g.embedBatch(texts);\n return results.map((r) => r.vector);\n }\n\n async getQueryEmbedding(query: string): Promise<number[]> {\n return this.getTextEmbedding(query);\n }\n}\n\nexport default { GerbilLLM, GerbilEmbedding };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,IAAIA,WAA0B;AAC9B,IAAIC,cAAoC;AAExC,eAAe,YAAY,OAAgC;AACzD,KAAI,CAAC,SACH,YAAW,IAAI,QAAQ;AAEzB,KAAI,EAAE,SAAS,UAAU,IAAI,aAC3B,eAAc,SAAS,UAAU,MAAM;AAEzC,KAAI,aAAa;AACf,QAAM;AACN,gBAAc;;AAEhB,QAAO;;;;;AAMT,IAAa,YAAb,MAAuB;CACrB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAyC,EAAE,EAAE;AACvD,OAAK,QAAQ,OAAO,SAAS;AAC7B,OAAK,UAAU;;CAGjB,MAAM,SAAS,QAAgB,SAAsD;AAGnF,SAAO,EAAE,OADM,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,SAAS,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS,CAAC,EAClD,MAAM;;CAG9B,MAAM,KACJ,UAC2C;EAE3C,MAAM,SAAS,SAAS,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,UAAU,CAAC,KAAK,KAAK;AAKxE,SAAO,EACL,SAAS,EAAE,UAHE,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,SAAS,QAAQ,KAAK,QAAQ,EAGxB,MAAM,EAClC;;CAGH,OAAO,OAAO,QAAgB,SAA8D;EAC1F,MAAM,IAAI,MAAM,YAAY,KAAK,MAAM;AACvC,aAAW,MAAM,SAAS,EAAE,OAAO,QAAQ;GAAE,GAAG,KAAK;GAAS,GAAG;GAAS,CAAC,CACzE,OAAM,EAAE,OAAO,OAAO;;;;;;AAQ5B,IAAa,kBAAb,MAA6B;CAC3B,AAAiB;CAEjB,YAAY,SAA6B,EAAE,EAAE;AAC3C,OAAK,QAAQ,OAAO,SAAS;;CAG/B,MAAM,iBAAiB,MAAiC;AAGtD,UADe,OADL,MAAM,YAAY,KAAK,MAAM,EAChB,MAAM,KAAK,EACpB;;CAGhB,MAAM,kBAAkB,OAAsC;AAG5D,UADgB,OADN,MAAM,YAAY,KAAK,MAAM,EACf,WAAW,MAAM,EAC1B,KAAK,MAAM,EAAE,OAAO;;CAGrC,MAAM,kBAAkB,OAAkC;AACxD,SAAO,KAAK,iBAAiB,MAAM;;;AAIvC,yBAAe;CAAE;CAAW;CAAiB"}
@@ -1,5 +1,5 @@
1
- import "../utils-CZBZ8dgR.mjs";
2
- import { t as defineTool } from "../tools-Bi1P7Xoy.mjs";
1
+ import "../utils-DKO55ZmZ.mjs";
2
+ import { t as defineTool } from "../tools-DQ1mPUw5.mjs";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/integrations/mcp-client.ts
@@ -451,7 +451,7 @@ defineTool({
451
451
  parameters: z.object({
452
452
  server: z.string().describe("The MCP server name (e.g., 'filesystem', 'browser')"),
453
453
  tool: z.string().describe("The tool name to call"),
454
- args: z.record(z.any()).optional().describe("Arguments to pass to the tool")
454
+ args: z.record(z.string(), z.any()).optional().describe("Arguments to pass to the tool")
455
455
  }),
456
456
  execute: async ({ server, tool, args }) => {
457
457
  const hub = getMCPHub();
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-client.mjs","names":["result: any","tools: Array<{ server: string; tool: MCPTool }>","shape: Record<string, z.ZodType<any>>","zodType: z.ZodType<any>","defaultHub: MCPHub | null","byServer: Record<string, string[]>"],"sources":["../../src/integrations/mcp-client.ts"],"sourcesContent":["/**\n * Gerbil MCP Client\n *\n * Connect to external MCP servers and use their tools.\n * Uses the official @modelcontextprotocol/sdk for protocol compliance.\n *\n * @example\n * ```typescript\n * import { MCPClient, MCPHub } from \"gerbil/mcp-client\";\n *\n * // Connect to a single server\n * const client = new MCPClient({\n * name: \"filesystem\",\n * command: \"uvx\",\n * args: [\"mcp-server-filesystem\", \"/tmp\"]\n * });\n * await client.connect();\n * const tools = await client.listTools();\n * const result = await client.callTool(\"read_file\", { path: \"/tmp/test.txt\" });\n *\n * // Or use the hub for multiple servers\n * const hub = new MCPHub();\n * await hub.addServer(\"filesystem\", { command: \"uvx\", args: [\"mcp-server-filesystem\", \"/tmp\"] });\n * await hub.addServer(\"browser\", { command: \"npx\", args: [\"-y\", \"@anthropic/mcp-server-puppeteer\"] });\n *\n * // All tools from all servers are available\n * const allTools = hub.getAllTools();\n * ```\n */\n\nimport { z } from \"zod\";\nimport { defineTool } from \"../core/tools.js\";\n\n// ============================================\n// Types\n// ============================================\n\nexport type MCPServerConfig = {\n /** Command to run the MCP server */\n command: string;\n\n /** Arguments for the command */\n args?: string[];\n\n /** Environment variables */\n env?: Record<string, string>;\n\n /** Working directory */\n cwd?: string;\n\n /** Timeout for requests (ms, default: 30000) */\n timeout?: number;\n};\n\nexport type MCPTool = {\n name: string;\n description?: string;\n inputSchema?: {\n type: string;\n properties?: Record<string, any>;\n required?: string[];\n };\n};\n\nexport type MCPResource = {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n};\n\n// ============================================\n// MCP Client (uses official SDK)\n// ============================================\n\n/**\n * Client for a single MCP server.\n *\n * Uses @modelcontextprotocol/sdk when available, falls back to\n * a minimal stdio implementation otherwise.\n */\nexport class MCPClient {\n private readonly config: MCPServerConfig;\n private client: any = null;\n private transport: any = null;\n private connected = false;\n private _tools: MCPTool[] = [];\n private _resources: MCPResource[] = [];\n private readonly serverName: string;\n private useFallback = false;\n\n // Fallback implementation state\n private fallbackProcess: any = null;\n private fallbackRequestId = 0;\n private readonly fallbackPending = new Map<\n number,\n { resolve: (v: any) => void; reject: (e: Error) => void }\n >();\n private fallbackBuffer = \"\";\n\n constructor(config: MCPServerConfig & { name?: string }) {\n this.config = {\n timeout: 30_000,\n ...config,\n };\n this.serverName = config.name || \"mcp\";\n }\n\n /**\n * Connect to the MCP server\n */\n async connect(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n try {\n // Try to use official SDK\n const sdk = await this.loadSDK();\n if (sdk) {\n await this.connectWithSDK(sdk);\n } else {\n // Fallback to minimal implementation\n await this.connectFallback();\n }\n\n this.connected = true;\n await this.refreshCapabilities();\n } catch (e) {\n this.connected = false;\n throw e;\n }\n }\n\n /**\n * Try to load the official MCP SDK\n * Uses dynamic import to avoid bundling issues when SDK is not installed\n */\n private async loadSDK(): Promise<any | null> {\n try {\n // Use Function constructor to create truly dynamic imports\n // This prevents TypeScript/bundlers from trying to resolve the module\n const importDynamic = new Function(\"modulePath\", \"return import(modulePath)\");\n const clientModule = await importDynamic(\"@modelcontextprotocol/sdk/client\");\n const stdioModule = await importDynamic(\"@modelcontextprotocol/sdk/client/stdio\");\n return {\n Client: clientModule.Client,\n StdioClientTransport: stdioModule.StdioClientTransport,\n };\n } catch {\n // SDK not installed - use fallback\n return null;\n }\n }\n\n /**\n * Connect using the official SDK\n */\n private async connectWithSDK(sdk: any): Promise<void> {\n const { Client, StdioClientTransport } = sdk;\n\n this.transport = new StdioClientTransport({\n command: this.config.command,\n args: this.config.args || [],\n env: this.config.env,\n });\n\n this.client = new Client({ name: \"gerbil\", version: \"1.0.0\" }, { capabilities: {} });\n\n await this.client.connect(this.transport);\n }\n\n /**\n * Fallback: Connect without SDK using raw stdio\n */\n private async connectFallback(): Promise<void> {\n this.useFallback = true;\n\n const { spawn } = await import(\"node:child_process\");\n\n this.fallbackProcess = spawn(this.config.command, this.config.args || [], {\n cwd: this.config.cwd,\n env: { ...process.env, ...this.config.env },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n this.fallbackProcess.stdout?.on(\"data\", (data: Buffer) => {\n this.fallbackBuffer += data.toString();\n this.processFallbackBuffer();\n });\n\n this.fallbackProcess.on(\"error\", (err: Error) => {\n this.connected = false;\n throw new Error(`MCP server error: ${err.message}`);\n });\n\n this.fallbackProcess.on(\"exit\", (code: number) => {\n this.connected = false;\n for (const [_, req] of this.fallbackPending) {\n req.reject(new Error(`MCP server exited with code ${code}`));\n }\n this.fallbackPending.clear();\n });\n\n // Initialize\n await this.fallbackRequest(\"initialize\", {\n protocolVersion: \"2024-11-05\",\n capabilities: {},\n clientInfo: { name: \"gerbil\", version: \"0.1.0\" },\n });\n\n // Send initialized notification\n this.fallbackNotify(\"notifications/initialized\", {});\n }\n\n private processFallbackBuffer(): void {\n const lines = this.fallbackBuffer.split(\"\\n\");\n this.fallbackBuffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) {\n continue;\n }\n try {\n const response = JSON.parse(line);\n if (response.id !== undefined) {\n const pending = this.fallbackPending.get(response.id);\n if (pending) {\n this.fallbackPending.delete(response.id);\n if (response.error) {\n pending.reject(new Error(response.error.message));\n } else {\n pending.resolve(response.result);\n }\n }\n }\n } catch {}\n }\n }\n\n private fallbackRequest(method: string, params?: any): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!this.fallbackProcess?.stdin) {\n reject(new Error(\"Not connected\"));\n return;\n }\n\n const id = (this.fallbackRequestId += 1);\n const request = { jsonrpc: \"2.0\", id, method, params };\n\n const timeout = setTimeout(() => {\n this.fallbackPending.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, this.config.timeout);\n\n this.fallbackPending.set(id, {\n resolve: (v) => {\n clearTimeout(timeout);\n resolve(v);\n },\n reject: (e) => {\n clearTimeout(timeout);\n reject(e);\n },\n });\n\n this.fallbackProcess.stdin.write(`${JSON.stringify(request)}\\n`);\n });\n }\n\n private fallbackNotify(method: string, params?: any): void {\n if (!this.fallbackProcess?.stdin) {\n return;\n }\n this.fallbackProcess.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", method, params })}\\n`);\n }\n\n /**\n * Disconnect from the MCP server\n */\n async disconnect(): Promise<void> {\n if (!this.connected) {\n return;\n }\n\n if (this.useFallback && this.fallbackProcess) {\n this.fallbackProcess.kill(\"SIGTERM\");\n this.fallbackProcess = null;\n } else if (this.client) {\n await this.client.close();\n this.client = null;\n this.transport = null;\n }\n\n this.connected = false;\n this._tools = [];\n this._resources = [];\n }\n\n /**\n * Refresh tools and resources from the server\n */\n async refreshCapabilities(): Promise<void> {\n try {\n if (this.useFallback) {\n const result = await this.fallbackRequest(\"tools/list\", {});\n this._tools = result.tools || [];\n } else if (this.client) {\n const result = await this.client.listTools();\n this._tools = result.tools || [];\n }\n } catch {\n this._tools = [];\n }\n\n try {\n if (this.useFallback) {\n const result = await this.fallbackRequest(\"resources/list\", {});\n this._resources = result.resources || [];\n } else if (this.client) {\n const result = await this.client.listResources();\n this._resources = result.resources || [];\n }\n } catch {\n this._resources = [];\n }\n }\n\n /**\n * List available tools\n */\n listTools(): MCPTool[] {\n return this._tools;\n }\n\n /**\n * List available resources\n */\n listResources(): MCPResource[] {\n return this._resources;\n }\n\n /**\n * Call a tool\n */\n async callTool(name: string, args: Record<string, any> = {}): Promise<any> {\n let result: any;\n\n if (this.useFallback) {\n result = await this.fallbackRequest(\"tools/call\", {\n name,\n arguments: args,\n });\n } else if (this.client) {\n result = await this.client.callTool({ name, arguments: args });\n } else {\n throw new Error(\"Not connected\");\n }\n\n // MCP returns content array\n if (result.content && Array.isArray(result.content)) {\n return result.content.map((c: any) => c.text || JSON.stringify(c)).join(\"\\n\");\n }\n\n return result;\n }\n\n /**\n * Read a resource\n */\n async readResource(uri: string): Promise<string> {\n let result: any;\n\n if (this.useFallback) {\n result = await this.fallbackRequest(\"resources/read\", { uri });\n } else if (this.client) {\n result = await this.client.readResource({ uri });\n } else {\n throw new Error(\"Not connected\");\n }\n\n if (result.contents && Array.isArray(result.contents)) {\n return result.contents.map((c: any) => c.text || c.blob || \"\").join(\"\\n\");\n }\n\n return typeof result === \"string\" ? result : JSON.stringify(result);\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Get server name\n */\n getName(): string {\n return this.serverName;\n }\n}\n\n// ============================================\n// MCP Hub (manage multiple servers)\n// ============================================\n\n/**\n * Hub for managing multiple MCP server connections\n */\nexport class MCPHub {\n private readonly clients = new Map<string, MCPClient>();\n private readonly toolPrefix = \"mcp\";\n\n /**\n * Add and connect to an MCP server\n */\n async addServer(name: string, config: MCPServerConfig): Promise<MCPClient> {\n // Disconnect existing if same name\n if (this.clients.has(name)) {\n await this.removeServer(name);\n }\n\n const client = new MCPClient({ ...config, name });\n await client.connect();\n this.clients.set(name, client);\n\n // Register tools from this server\n this.registerServerTools(name, client);\n\n return client;\n }\n\n /**\n * Remove and disconnect an MCP server\n */\n async removeServer(name: string): Promise<void> {\n const client = this.clients.get(name);\n if (client) {\n await client.disconnect();\n this.clients.delete(name);\n }\n }\n\n /**\n * Get a specific client\n */\n getClient(name: string): MCPClient | undefined {\n return this.clients.get(name);\n }\n\n /**\n * List connected servers\n */\n listServers(): string[] {\n return Array.from(this.clients.keys());\n }\n\n /**\n * Get all tools from all servers\n */\n getAllTools(): Array<{ server: string; tool: MCPTool }> {\n const tools: Array<{ server: string; tool: MCPTool }> = [];\n\n for (const [serverName, client] of this.clients) {\n for (const tool of client.listTools()) {\n tools.push({ server: serverName, tool });\n }\n }\n\n return tools;\n }\n\n /**\n * Call a tool from any connected server\n * Tool name format: \"server_name:tool_name\" or just \"tool_name\" (searches all)\n */\n async callTool(toolName: string, args: Record<string, any> = {}): Promise<any> {\n // Check if prefixed with server name\n if (toolName.includes(\":\")) {\n const [serverName, actualToolName] = toolName.split(\":\", 2);\n const client = this.clients.get(serverName);\n if (!client) {\n throw new Error(`MCP server \"${serverName}\" not connected`);\n }\n return client.callTool(actualToolName, args);\n }\n\n // Search all servers for the tool\n for (const [_, client] of this.clients) {\n const tools = client.listTools();\n if (tools.some((t) => t.name === toolName)) {\n return client.callTool(toolName, args);\n }\n }\n\n throw new Error(`Tool \"${toolName}\" not found in any connected MCP server`);\n }\n\n /**\n * Disconnect all servers\n */\n async disconnectAll(): Promise<void> {\n for (const [name] of this.clients) {\n await this.removeServer(name);\n }\n }\n\n /**\n * Register tools from an MCP server into Gerbil's tool registry\n */\n private registerServerTools(serverName: string, client: MCPClient): void {\n const tools = client.listTools();\n\n for (const tool of tools) {\n // Create a Gerbil tool that wraps the MCP tool\n const gerbilToolName = `${this.toolPrefix}_${serverName}_${tool.name}`;\n\n // Build Zod schema from MCP input schema\n const zodSchema = this.mcpSchemaToZod(tool.inputSchema);\n\n defineTool({\n name: gerbilToolName,\n description: `[MCP:${serverName}] ${tool.description || tool.name}`,\n parameters: zodSchema,\n execute: async (params) => {\n const result = await client.callTool(tool.name, params);\n return typeof result === \"string\" ? result : JSON.stringify(result);\n },\n });\n }\n }\n\n /**\n * Convert MCP JSON Schema to Zod schema (simplified)\n */\n private mcpSchemaToZod(schema?: MCPTool[\"inputSchema\"]): z.ZodType<any> {\n if (!schema || schema.type !== \"object\") {\n return z.object({}).passthrough();\n }\n\n const shape: Record<string, z.ZodType<any>> = {};\n const properties = schema.properties || {};\n const required = new Set(schema.required || []);\n\n for (const [key, prop] of Object.entries(properties)) {\n let zodType: z.ZodType<any>;\n\n switch ((prop as any).type) {\n case \"string\":\n zodType = z.string();\n if ((prop as any).description) {\n zodType = zodType.describe((prop as any).description);\n }\n break;\n case \"number\":\n case \"integer\":\n zodType = z.number();\n break;\n case \"boolean\":\n zodType = z.boolean();\n break;\n case \"array\":\n zodType = z.array(z.any());\n break;\n default:\n zodType = z.any();\n }\n\n if (!required.has(key)) {\n zodType = zodType.optional();\n }\n\n shape[key] = zodType;\n }\n\n return z.object(shape).passthrough();\n }\n}\n\n// ============================================\n// Convenience functions\n// ============================================\n\nlet defaultHub: MCPHub | null = null;\n\n/**\n * Get the default MCP hub (singleton)\n */\nexport function getMCPHub(): MCPHub {\n if (!defaultHub) {\n defaultHub = new MCPHub();\n }\n return defaultHub;\n}\n\n/**\n * Connect to an MCP server\n */\nexport async function connectMCP(name: string, config: MCPServerConfig): Promise<MCPClient> {\n return getMCPHub().addServer(name, config);\n}\n\n/**\n * Disconnect from an MCP server\n */\nexport async function disconnectMCP(name: string): Promise<void> {\n return getMCPHub().removeServer(name);\n}\n\n/**\n * Call an MCP tool\n */\nexport async function callMCPTool(toolName: string, args?: Record<string, any>): Promise<any> {\n return getMCPHub().callTool(toolName, args);\n}\n\n// ============================================\n// Built-in MCP tools for chat\n// ============================================\n\n/**\n * Tool for the LLM to call MCP tools\n */\ndefineTool({\n name: \"mcp_call\",\n description:\n \"Call a tool from a connected MCP server. Use this when you need to interact with external tools like file systems, browsers, databases, etc.\",\n parameters: z.object({\n server: z.string().describe(\"The MCP server name (e.g., 'filesystem', 'browser')\"),\n tool: z.string().describe(\"The tool name to call\"),\n args: z.record(z.any()).optional().describe(\"Arguments to pass to the tool\"),\n }),\n execute: async ({ server, tool, args }) => {\n const hub = getMCPHub();\n const client = hub.getClient(server);\n\n if (!client) {\n const servers = hub.listServers();\n if (servers.length === 0) {\n return \"No MCP servers are connected. Use the MCP settings to connect to servers first.\";\n }\n return `Server \"${server}\" not found. Available servers: ${servers.join(\", \")}`;\n }\n\n try {\n const result = await client.callTool(tool, args || {});\n return typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n } catch (e) {\n return `Error calling ${server}:${tool}: ${e}`;\n }\n },\n});\n\n/**\n * Tool to list available MCP tools\n */\ndefineTool({\n name: \"mcp_list\",\n description: \"List all tools available from connected MCP servers\",\n parameters: z.object({\n server: z.string().optional().describe(\"Filter by server name (optional)\"),\n }),\n execute: async ({ server }) => {\n const hub = getMCPHub();\n\n if (server) {\n const client = hub.getClient(server);\n if (!client) {\n return `Server \"${server}\" not connected`;\n }\n const tools = client.listTools();\n return tools.map((t) => `- ${t.name}: ${t.description || \"(no description)\"}`).join(\"\\n\");\n }\n\n const allTools = hub.getAllTools();\n if (allTools.length === 0) {\n return \"No MCP servers connected. Connect to MCP servers to use external tools.\";\n }\n\n const byServer: Record<string, string[]> = {};\n for (const { server: s, tool } of allTools) {\n if (!byServer[s]) {\n byServer[s] = [];\n }\n byServer[s].push(` - ${tool.name}: ${tool.description || \"(no description)\"}`);\n }\n\n return Object.entries(byServer)\n .map(([s, tools]) => `[${s}]\\n${tools.join(\"\\n\")}`)\n .join(\"\\n\\n\");\n },\n});\n\nexport default {\n MCPClient,\n MCPHub,\n getMCPHub,\n connectMCP,\n disconnectMCP,\n callMCPTool,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp-client.mjs","names":["result: any","tools: Array<{ server: string; tool: MCPTool }>","shape: Record<string, z.ZodType<any>>","zodType: z.ZodType<any>","defaultHub: MCPHub | null","byServer: Record<string, string[]>"],"sources":["../../src/integrations/mcp-client.ts"],"sourcesContent":["/**\n * Gerbil MCP Client\n *\n * Connect to external MCP servers and use their tools.\n * Uses the official @modelcontextprotocol/sdk for protocol compliance.\n *\n * @example\n * ```typescript\n * import { MCPClient, MCPHub } from \"gerbil/mcp-client\";\n *\n * // Connect to a single server\n * const client = new MCPClient({\n * name: \"filesystem\",\n * command: \"uvx\",\n * args: [\"mcp-server-filesystem\", \"/tmp\"]\n * });\n * await client.connect();\n * const tools = await client.listTools();\n * const result = await client.callTool(\"read_file\", { path: \"/tmp/test.txt\" });\n *\n * // Or use the hub for multiple servers\n * const hub = new MCPHub();\n * await hub.addServer(\"filesystem\", { command: \"uvx\", args: [\"mcp-server-filesystem\", \"/tmp\"] });\n * await hub.addServer(\"browser\", { command: \"npx\", args: [\"-y\", \"@anthropic/mcp-server-puppeteer\"] });\n *\n * // All tools from all servers are available\n * const allTools = hub.getAllTools();\n * ```\n */\n\nimport { z } from \"zod\";\nimport { defineTool } from \"../core/tools.js\";\n\n// ============================================\n// Types\n// ============================================\n\nexport type MCPServerConfig = {\n /** Command to run the MCP server */\n command: string;\n\n /** Arguments for the command */\n args?: string[];\n\n /** Environment variables */\n env?: Record<string, string>;\n\n /** Working directory */\n cwd?: string;\n\n /** Timeout for requests (ms, default: 30000) */\n timeout?: number;\n};\n\nexport type MCPTool = {\n name: string;\n description?: string;\n inputSchema?: {\n type: string;\n properties?: Record<string, any>;\n required?: string[];\n };\n};\n\nexport type MCPResource = {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n};\n\n// ============================================\n// MCP Client (uses official SDK)\n// ============================================\n\n/**\n * Client for a single MCP server.\n *\n * Uses @modelcontextprotocol/sdk when available, falls back to\n * a minimal stdio implementation otherwise.\n */\nexport class MCPClient {\n private readonly config: MCPServerConfig;\n private client: any = null;\n private transport: any = null;\n private connected = false;\n private _tools: MCPTool[] = [];\n private _resources: MCPResource[] = [];\n private readonly serverName: string;\n private useFallback = false;\n\n // Fallback implementation state\n private fallbackProcess: any = null;\n private fallbackRequestId = 0;\n private readonly fallbackPending = new Map<\n number,\n { resolve: (v: any) => void; reject: (e: Error) => void }\n >();\n private fallbackBuffer = \"\";\n\n constructor(config: MCPServerConfig & { name?: string }) {\n this.config = {\n timeout: 30_000,\n ...config,\n };\n this.serverName = config.name || \"mcp\";\n }\n\n /**\n * Connect to the MCP server\n */\n async connect(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n try {\n // Try to use official SDK\n const sdk = await this.loadSDK();\n if (sdk) {\n await this.connectWithSDK(sdk);\n } else {\n // Fallback to minimal implementation\n await this.connectFallback();\n }\n\n this.connected = true;\n await this.refreshCapabilities();\n } catch (e) {\n this.connected = false;\n throw e;\n }\n }\n\n /**\n * Try to load the official MCP SDK\n * Uses dynamic import to avoid bundling issues when SDK is not installed\n */\n private async loadSDK(): Promise<any | null> {\n try {\n // Use Function constructor to create truly dynamic imports\n // This prevents TypeScript/bundlers from trying to resolve the module\n const importDynamic = new Function(\"modulePath\", \"return import(modulePath)\");\n const clientModule = await importDynamic(\"@modelcontextprotocol/sdk/client\");\n const stdioModule = await importDynamic(\"@modelcontextprotocol/sdk/client/stdio\");\n return {\n Client: clientModule.Client,\n StdioClientTransport: stdioModule.StdioClientTransport,\n };\n } catch {\n // SDK not installed - use fallback\n return null;\n }\n }\n\n /**\n * Connect using the official SDK\n */\n private async connectWithSDK(sdk: any): Promise<void> {\n const { Client, StdioClientTransport } = sdk;\n\n this.transport = new StdioClientTransport({\n command: this.config.command,\n args: this.config.args || [],\n env: this.config.env,\n });\n\n this.client = new Client({ name: \"gerbil\", version: \"1.0.0\" }, { capabilities: {} });\n\n await this.client.connect(this.transport);\n }\n\n /**\n * Fallback: Connect without SDK using raw stdio\n */\n private async connectFallback(): Promise<void> {\n this.useFallback = true;\n\n const { spawn } = await import(\"node:child_process\");\n\n this.fallbackProcess = spawn(this.config.command, this.config.args || [], {\n cwd: this.config.cwd,\n env: { ...process.env, ...this.config.env },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n this.fallbackProcess.stdout?.on(\"data\", (data: Buffer) => {\n this.fallbackBuffer += data.toString();\n this.processFallbackBuffer();\n });\n\n this.fallbackProcess.on(\"error\", (err: Error) => {\n this.connected = false;\n throw new Error(`MCP server error: ${err.message}`);\n });\n\n this.fallbackProcess.on(\"exit\", (code: number) => {\n this.connected = false;\n for (const [_, req] of this.fallbackPending) {\n req.reject(new Error(`MCP server exited with code ${code}`));\n }\n this.fallbackPending.clear();\n });\n\n // Initialize\n await this.fallbackRequest(\"initialize\", {\n protocolVersion: \"2024-11-05\",\n capabilities: {},\n clientInfo: { name: \"gerbil\", version: \"0.1.0\" },\n });\n\n // Send initialized notification\n this.fallbackNotify(\"notifications/initialized\", {});\n }\n\n private processFallbackBuffer(): void {\n const lines = this.fallbackBuffer.split(\"\\n\");\n this.fallbackBuffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) {\n continue;\n }\n try {\n const response = JSON.parse(line);\n if (response.id !== undefined) {\n const pending = this.fallbackPending.get(response.id);\n if (pending) {\n this.fallbackPending.delete(response.id);\n if (response.error) {\n pending.reject(new Error(response.error.message));\n } else {\n pending.resolve(response.result);\n }\n }\n }\n } catch {}\n }\n }\n\n private fallbackRequest(method: string, params?: any): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!this.fallbackProcess?.stdin) {\n reject(new Error(\"Not connected\"));\n return;\n }\n\n const id = (this.fallbackRequestId += 1);\n const request = { jsonrpc: \"2.0\", id, method, params };\n\n const timeout = setTimeout(() => {\n this.fallbackPending.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, this.config.timeout);\n\n this.fallbackPending.set(id, {\n resolve: (v) => {\n clearTimeout(timeout);\n resolve(v);\n },\n reject: (e) => {\n clearTimeout(timeout);\n reject(e);\n },\n });\n\n this.fallbackProcess.stdin.write(`${JSON.stringify(request)}\\n`);\n });\n }\n\n private fallbackNotify(method: string, params?: any): void {\n if (!this.fallbackProcess?.stdin) {\n return;\n }\n this.fallbackProcess.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", method, params })}\\n`);\n }\n\n /**\n * Disconnect from the MCP server\n */\n async disconnect(): Promise<void> {\n if (!this.connected) {\n return;\n }\n\n if (this.useFallback && this.fallbackProcess) {\n this.fallbackProcess.kill(\"SIGTERM\");\n this.fallbackProcess = null;\n } else if (this.client) {\n await this.client.close();\n this.client = null;\n this.transport = null;\n }\n\n this.connected = false;\n this._tools = [];\n this._resources = [];\n }\n\n /**\n * Refresh tools and resources from the server\n */\n async refreshCapabilities(): Promise<void> {\n try {\n if (this.useFallback) {\n const result = await this.fallbackRequest(\"tools/list\", {});\n this._tools = result.tools || [];\n } else if (this.client) {\n const result = await this.client.listTools();\n this._tools = result.tools || [];\n }\n } catch {\n this._tools = [];\n }\n\n try {\n if (this.useFallback) {\n const result = await this.fallbackRequest(\"resources/list\", {});\n this._resources = result.resources || [];\n } else if (this.client) {\n const result = await this.client.listResources();\n this._resources = result.resources || [];\n }\n } catch {\n this._resources = [];\n }\n }\n\n /**\n * List available tools\n */\n listTools(): MCPTool[] {\n return this._tools;\n }\n\n /**\n * List available resources\n */\n listResources(): MCPResource[] {\n return this._resources;\n }\n\n /**\n * Call a tool\n */\n async callTool(name: string, args: Record<string, any> = {}): Promise<any> {\n let result: any;\n\n if (this.useFallback) {\n result = await this.fallbackRequest(\"tools/call\", {\n name,\n arguments: args,\n });\n } else if (this.client) {\n result = await this.client.callTool({ name, arguments: args });\n } else {\n throw new Error(\"Not connected\");\n }\n\n // MCP returns content array\n if (result.content && Array.isArray(result.content)) {\n return result.content.map((c: any) => c.text || JSON.stringify(c)).join(\"\\n\");\n }\n\n return result;\n }\n\n /**\n * Read a resource\n */\n async readResource(uri: string): Promise<string> {\n let result: any;\n\n if (this.useFallback) {\n result = await this.fallbackRequest(\"resources/read\", { uri });\n } else if (this.client) {\n result = await this.client.readResource({ uri });\n } else {\n throw new Error(\"Not connected\");\n }\n\n if (result.contents && Array.isArray(result.contents)) {\n return result.contents.map((c: any) => c.text || c.blob || \"\").join(\"\\n\");\n }\n\n return typeof result === \"string\" ? result : JSON.stringify(result);\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Get server name\n */\n getName(): string {\n return this.serverName;\n }\n}\n\n// ============================================\n// MCP Hub (manage multiple servers)\n// ============================================\n\n/**\n * Hub for managing multiple MCP server connections\n */\nexport class MCPHub {\n private readonly clients = new Map<string, MCPClient>();\n private readonly toolPrefix = \"mcp\";\n\n /**\n * Add and connect to an MCP server\n */\n async addServer(name: string, config: MCPServerConfig): Promise<MCPClient> {\n // Disconnect existing if same name\n if (this.clients.has(name)) {\n await this.removeServer(name);\n }\n\n const client = new MCPClient({ ...config, name });\n await client.connect();\n this.clients.set(name, client);\n\n // Register tools from this server\n this.registerServerTools(name, client);\n\n return client;\n }\n\n /**\n * Remove and disconnect an MCP server\n */\n async removeServer(name: string): Promise<void> {\n const client = this.clients.get(name);\n if (client) {\n await client.disconnect();\n this.clients.delete(name);\n }\n }\n\n /**\n * Get a specific client\n */\n getClient(name: string): MCPClient | undefined {\n return this.clients.get(name);\n }\n\n /**\n * List connected servers\n */\n listServers(): string[] {\n return Array.from(this.clients.keys());\n }\n\n /**\n * Get all tools from all servers\n */\n getAllTools(): Array<{ server: string; tool: MCPTool }> {\n const tools: Array<{ server: string; tool: MCPTool }> = [];\n\n for (const [serverName, client] of this.clients) {\n for (const tool of client.listTools()) {\n tools.push({ server: serverName, tool });\n }\n }\n\n return tools;\n }\n\n /**\n * Call a tool from any connected server\n * Tool name format: \"server_name:tool_name\" or just \"tool_name\" (searches all)\n */\n async callTool(toolName: string, args: Record<string, any> = {}): Promise<any> {\n // Check if prefixed with server name\n if (toolName.includes(\":\")) {\n const [serverName, actualToolName] = toolName.split(\":\", 2);\n const client = this.clients.get(serverName);\n if (!client) {\n throw new Error(`MCP server \"${serverName}\" not connected`);\n }\n return client.callTool(actualToolName, args);\n }\n\n // Search all servers for the tool\n for (const [_, client] of this.clients) {\n const tools = client.listTools();\n if (tools.some((t) => t.name === toolName)) {\n return client.callTool(toolName, args);\n }\n }\n\n throw new Error(`Tool \"${toolName}\" not found in any connected MCP server`);\n }\n\n /**\n * Disconnect all servers\n */\n async disconnectAll(): Promise<void> {\n for (const [name] of this.clients) {\n await this.removeServer(name);\n }\n }\n\n /**\n * Register tools from an MCP server into Gerbil's tool registry\n */\n private registerServerTools(serverName: string, client: MCPClient): void {\n const tools = client.listTools();\n\n for (const tool of tools) {\n // Create a Gerbil tool that wraps the MCP tool\n const gerbilToolName = `${this.toolPrefix}_${serverName}_${tool.name}`;\n\n // Build Zod schema from MCP input schema\n const zodSchema = this.mcpSchemaToZod(tool.inputSchema);\n\n defineTool({\n name: gerbilToolName,\n description: `[MCP:${serverName}] ${tool.description || tool.name}`,\n parameters: zodSchema,\n execute: async (params) => {\n const result = await client.callTool(tool.name, params);\n return typeof result === \"string\" ? result : JSON.stringify(result);\n },\n });\n }\n }\n\n /**\n * Convert MCP JSON Schema to Zod schema (simplified)\n */\n private mcpSchemaToZod(schema?: MCPTool[\"inputSchema\"]): z.ZodType<any> {\n if (!schema || schema.type !== \"object\") {\n return z.object({}).passthrough();\n }\n\n const shape: Record<string, z.ZodType<any>> = {};\n const properties = schema.properties || {};\n const required = new Set(schema.required || []);\n\n for (const [key, prop] of Object.entries(properties)) {\n let zodType: z.ZodType<any>;\n\n switch ((prop as any).type) {\n case \"string\":\n zodType = z.string();\n if ((prop as any).description) {\n zodType = zodType.describe((prop as any).description);\n }\n break;\n case \"number\":\n case \"integer\":\n zodType = z.number();\n break;\n case \"boolean\":\n zodType = z.boolean();\n break;\n case \"array\":\n zodType = z.array(z.any());\n break;\n default:\n zodType = z.any();\n }\n\n if (!required.has(key)) {\n zodType = zodType.optional();\n }\n\n shape[key] = zodType;\n }\n\n return z.object(shape).passthrough();\n }\n}\n\n// ============================================\n// Convenience functions\n// ============================================\n\nlet defaultHub: MCPHub | null = null;\n\n/**\n * Get the default MCP hub (singleton)\n */\nexport function getMCPHub(): MCPHub {\n if (!defaultHub) {\n defaultHub = new MCPHub();\n }\n return defaultHub;\n}\n\n/**\n * Connect to an MCP server\n */\nexport async function connectMCP(name: string, config: MCPServerConfig): Promise<MCPClient> {\n return getMCPHub().addServer(name, config);\n}\n\n/**\n * Disconnect from an MCP server\n */\nexport async function disconnectMCP(name: string): Promise<void> {\n return getMCPHub().removeServer(name);\n}\n\n/**\n * Call an MCP tool\n */\nexport async function callMCPTool(toolName: string, args?: Record<string, any>): Promise<any> {\n return getMCPHub().callTool(toolName, args);\n}\n\n// ============================================\n// Built-in MCP tools for chat\n// ============================================\n\n/**\n * Tool for the LLM to call MCP tools\n */\ndefineTool({\n name: \"mcp_call\",\n description:\n \"Call a tool from a connected MCP server. Use this when you need to interact with external tools like file systems, browsers, databases, etc.\",\n parameters: z.object({\n server: z.string().describe(\"The MCP server name (e.g., 'filesystem', 'browser')\"),\n tool: z.string().describe(\"The tool name to call\"),\n args: z.record(z.string(), z.any()).optional().describe(\"Arguments to pass to the tool\"),\n }),\n execute: async ({ server, tool, args }) => {\n const hub = getMCPHub();\n const client = hub.getClient(server);\n\n if (!client) {\n const servers = hub.listServers();\n if (servers.length === 0) {\n return \"No MCP servers are connected. Use the MCP settings to connect to servers first.\";\n }\n return `Server \"${server}\" not found. Available servers: ${servers.join(\", \")}`;\n }\n\n try {\n const result = await client.callTool(tool, args || {});\n return typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n } catch (e) {\n return `Error calling ${server}:${tool}: ${e}`;\n }\n },\n});\n\n/**\n * Tool to list available MCP tools\n */\ndefineTool({\n name: \"mcp_list\",\n description: \"List all tools available from connected MCP servers\",\n parameters: z.object({\n server: z.string().optional().describe(\"Filter by server name (optional)\"),\n }),\n execute: async ({ server }) => {\n const hub = getMCPHub();\n\n if (server) {\n const client = hub.getClient(server);\n if (!client) {\n return `Server \"${server}\" not connected`;\n }\n const tools = client.listTools();\n return tools.map((t) => `- ${t.name}: ${t.description || \"(no description)\"}`).join(\"\\n\");\n }\n\n const allTools = hub.getAllTools();\n if (allTools.length === 0) {\n return \"No MCP servers connected. Connect to MCP servers to use external tools.\";\n }\n\n const byServer: Record<string, string[]> = {};\n for (const { server: s, tool } of allTools) {\n if (!byServer[s]) {\n byServer[s] = [];\n }\n byServer[s].push(` - ${tool.name}: ${tool.description || \"(no description)\"}`);\n }\n\n return Object.entries(byServer)\n .map(([s, tools]) => `[${s}]\\n${tools.join(\"\\n\")}`)\n .join(\"\\n\\n\");\n },\n});\n\nexport default {\n MCPClient,\n MCPHub,\n getMCPHub,\n connectMCP,\n disconnectMCP,\n callMCPTool,\n};\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import { c as GerbilConfig } from "../types-CiTc7ez3.mjs";
2
- import { t as Gerbil } from "../gerbil-qOTe1nl2.mjs";
1
+ import { d as GerbilConfig } from "../types-LlyYILII.mjs";
2
+ import "../index-DukkJRMj.mjs";
3
+ import { t as Gerbil } from "../gerbil-BetB5xb0.mjs";
3
4
 
4
5
  //#region src/integrations/mcp.d.ts
5
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.mts","names":[],"sources":["../../src/integrations/mcp.ts"],"sourcesContent":[],"mappings":";;;;;UA2BiB,gBAAA,SAAyB;;;;;;;;;iBA2GpB,eAAA,WAAyB,mBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAwGxB;;;;;;iBAgBtB,cAAA,WAAwB,mBAAqB;cAyClE;0BAAA;yBAAA"}
1
+ {"version":3,"file":"mcp.d.mts","names":[],"sources":["../../src/integrations/mcp.ts"],"sourcesContent":[],"mappings":";;;;;;UA4BiB,gBAAA,SAAyB;;;;;;;;;iBA2GpB,eAAA,WAAyB,mBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAwGxB;;;;;;iBAgBtB,cAAA,WAAwB,mBAAqB;cAyClE;0BAAA;yBAAA"}
@@ -1,7 +1,7 @@
1
- import "../gerbil-Dw4Qj77e.mjs";
2
- import "../utils-CZBZ8dgR.mjs";
3
- import "../one-liner-s-lD8rCC.mjs";
4
- import "../skills-CD3Orlex.mjs";
5
- import { n as mcp_default, r as startMCPServer, t as createMCPServer } from "../mcp-BvbriaBy.mjs";
1
+ import "../gerbil-DNniplr4.mjs";
2
+ import "../utils-DKO55ZmZ.mjs";
3
+ import "../one-liner-JhdIPxzF.mjs";
4
+ import "../skills-CU694Dc8.mjs";
5
+ import { n as mcp_default, r as startMCPServer, t as createMCPServer } from "../mcp-D2vvH1Xc.mjs";
6
6
 
7
7
  export { createMCPServer, mcp_default as default, startMCPServer };
@@ -1,5 +1,5 @@
1
- import { t as Gerbil } from "./gerbil-Dw4Qj77e.mjs";
2
- import { a as summarize, d as explain, m as commit, s as review, t as translate } from "./skills-CD3Orlex.mjs";
1
+ import { r as DEFAULT_MODEL, t as Gerbil } from "./gerbil-DNniplr4.mjs";
2
+ import { a as summarize, f as explain, h as commit, s as review, t as translate } from "./skills-CU694Dc8.mjs";
3
3
 
4
4
  //#region src/integrations/mcp.ts
5
5
  /**
@@ -195,7 +195,7 @@ const TOOL_DEFINITIONS = {
195
195
  */
196
196
  async function createMCPServer(options = {}) {
197
197
  const g = new Gerbil(options);
198
- await g.loadModel(options.model || "qwen3-0.6b");
198
+ await g.loadModel(options.model || DEFAULT_MODEL);
199
199
  const enabledTools = options.tools || Object.keys(TOOL_DEFINITIONS);
200
200
  const handlers = {
201
201
  gerbil_generate: async (args) => {
@@ -318,4 +318,4 @@ var mcp_default = {
318
318
 
319
319
  //#endregion
320
320
  export { mcp_default as n, startMCPServer as r, createMCPServer as t };
321
- //# sourceMappingURL=mcp-BvbriaBy.mjs.map
321
+ //# sourceMappingURL=mcp-D2vvH1Xc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-D2vvH1Xc.mjs","names":["handlers: Record<string, (args: any) => Promise<any>>","skills.summarize","skills.explain","skills.review","skills.commit","skills.translate"],"sources":["../src/integrations/mcp.ts"],"sourcesContent":["/**\n * Gerbil MCP Server\n *\n * Model Context Protocol server for Claude Desktop, Cursor, etc.\n *\n * @example\n * ```bash\n * gerbil serve --mcp\n * ```\n *\n * @example Claude Desktop config\n * ```json\n * {\n * \"mcpServers\": {\n * \"gerbil\": {\n * \"command\": \"npx\",\n * \"args\": [\"-y\", \"gerbil\", \"serve\", \"--mcp\"]\n * }\n * }\n * }\n * ```\n */\n\nimport { Gerbil } from \"../core/gerbil.js\";\nimport { DEFAULT_MODEL } from \"../core/models.js\";\nimport type { GerbilConfig } from \"../core/types.js\";\nimport * as skills from \"../skills/index.js\";\n\nexport interface MCPServerOptions extends GerbilConfig {\n /** Port for HTTP transport (default: stdio) */\n port?: number;\n\n /** Tools to expose */\n tools?: string[];\n}\n\n// Tool definitions\nconst TOOL_DEFINITIONS = {\n generate: {\n name: \"gerbil_generate\",\n description: \"Generate text using a local LLM\",\n inputSchema: {\n type: \"object\",\n properties: {\n prompt: { type: \"string\", description: \"The prompt to generate from\" },\n maxTokens: { type: \"number\", description: \"Maximum tokens to generate\" },\n temperature: { type: \"number\", description: \"Sampling temperature (0-2)\" },\n system: { type: \"string\", description: \"System prompt\" },\n thinking: { type: \"boolean\", description: \"Enable thinking mode\" },\n },\n required: [\"prompt\"],\n },\n },\n summarize: {\n name: \"gerbil_summarize\",\n description: \"Summarize content\",\n inputSchema: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Content to summarize\" },\n length: { type: \"string\", enum: [\"short\", \"medium\", \"long\"] },\n format: { type: \"string\", enum: [\"paragraph\", \"bullets\"] },\n },\n required: [\"content\"],\n },\n },\n explain: {\n name: \"gerbil_explain\",\n description: \"Explain code or concepts\",\n inputSchema: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Code or concept to explain\" },\n level: { type: \"string\", enum: [\"beginner\", \"intermediate\", \"expert\"] },\n language: { type: \"string\", description: \"Programming language\" },\n },\n required: [\"content\"],\n },\n },\n review: {\n name: \"gerbil_review\",\n description: \"Review code for issues\",\n inputSchema: {\n type: \"object\",\n properties: {\n code: { type: \"string\", description: \"Code to review\" },\n focus: {\n type: \"array\",\n items: { type: \"string\", enum: [\"security\", \"performance\", \"style\", \"bugs\"] },\n },\n },\n required: [\"code\"],\n },\n },\n commit: {\n name: \"gerbil_commit\",\n description: \"Generate a commit message from a diff\",\n inputSchema: {\n type: \"object\",\n properties: {\n diff: { type: \"string\", description: \"Git diff\" },\n type: { type: \"string\", enum: [\"conventional\", \"simple\", \"detailed\"] },\n },\n required: [\"diff\"],\n },\n },\n translate: {\n name: \"gerbil_translate\",\n description: \"Translate text\",\n inputSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Text to translate\" },\n to: { type: \"string\", description: \"Target language\" },\n from: { type: \"string\", description: \"Source language (optional)\" },\n },\n required: [\"text\", \"to\"],\n },\n },\n embed: {\n name: \"gerbil_embed\",\n description: \"Generate embeddings for text\",\n inputSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Text to embed\" },\n },\n required: [\"text\"],\n },\n },\n};\n\n/**\n * Create MCP server\n */\nexport async function createMCPServer(options: MCPServerOptions = {}) {\n const g = new Gerbil(options);\n\n // Load model\n await g.loadModel(options.model || DEFAULT_MODEL);\n\n // Determine which tools to expose\n const enabledTools = options.tools || Object.keys(TOOL_DEFINITIONS);\n\n // Tool handlers\n const handlers: Record<string, (args: any) => Promise<any>> = {\n gerbil_generate: async (args) => {\n const result = await g.generate(args.prompt, {\n maxTokens: args.maxTokens,\n temperature: args.temperature,\n system: args.system,\n thinking: args.thinking,\n });\n return {\n content: [\n {\n type: \"text\",\n text: result.thinking\n ? `Thinking: ${result.thinking}\\n\\nAnswer: ${result.text}`\n : result.text,\n },\n ],\n };\n },\n\n gerbil_summarize: async (args) => {\n const summary = await skills.summarize({\n content: args.content,\n length: args.length,\n format: args.format,\n });\n return { content: [{ type: \"text\", text: summary }] };\n },\n\n gerbil_explain: async (args) => {\n const explanation = await skills.explain({\n content: args.content,\n level: args.level,\n language: args.language,\n } as Parameters<typeof skills.explain>[0]);\n return { content: [{ type: \"text\", text: explanation }] };\n },\n\n gerbil_review: async (args) => {\n const reviewResult = await skills.review({\n code: args.code,\n focus: args.focus,\n } as Parameters<typeof skills.review>[0]);\n return { content: [{ type: \"text\", text: reviewResult }] };\n },\n\n gerbil_commit: async (args) => {\n const message = await skills.commit({\n diff: args.diff,\n type: args.type,\n } as Parameters<typeof skills.commit>[0]);\n return { content: [{ type: \"text\", text: message }] };\n },\n\n gerbil_translate: async (args) => {\n const translated = await skills.translate({\n text: args.text,\n to: args.to,\n from: args.from,\n } as Parameters<typeof skills.translate>[0]);\n return { content: [{ type: \"text\", text: translated }] };\n },\n\n gerbil_embed: async (args) => {\n const result = await g.embed(args.text);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n vector: result.vector.slice(0, 10),\n dimensions: result.vector.length,\n }),\n },\n ],\n };\n },\n };\n\n return {\n // Server info\n info: {\n name: \"gerbil\",\n version: \"1.0.0\",\n description: \"Local LLM inference via Gerbil\",\n },\n\n // List available tools\n listTools: () =>\n enabledTools\n .filter((t) => TOOL_DEFINITIONS[t as keyof typeof TOOL_DEFINITIONS])\n .map((t) => TOOL_DEFINITIONS[t as keyof typeof TOOL_DEFINITIONS]),\n\n // Call a tool\n callTool: async (name: string, args: any) => {\n const handler = handlers[name];\n if (!handler) {\n throw new Error(`Unknown tool: ${name}`);\n }\n return handler(args);\n },\n\n // Get Gerbil instance\n gerbil: g,\n };\n}\n\n/**\n * Start MCP server with stdio transport\n */\nexport async function startMCPServer(options: MCPServerOptions = {}) {\n const server = await createMCPServer(options);\n\n // Simple stdio protocol handler\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n rl.on(\"line\", async (line) => {\n try {\n const request = JSON.parse(line);\n\n let _response: any;\n\n switch (request.method) {\n case \"initialize\":\n _response = {\n protocolVersion: \"2024-11-05\",\n serverInfo: server.info,\n capabilities: {\n tools: {},\n },\n };\n break;\n\n case \"tools/list\":\n _response = { tools: server.listTools() };\n break;\n\n case \"tools/call\":\n _response = await server.callTool(request.params.name, request.params.arguments);\n break;\n\n default:\n _response = { error: { code: -32_601, message: \"Method not found\" } };\n }\n } catch (_error) {}\n });\n}\n\nexport default { createMCPServer, startMCPServer };\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { a as MemoryMetadata, c as MemorySearchResult, d as RecallOptions, f as RecallResult, g as StoreSearchOptions, h as SerializedRecord, i as MemoryExport, l as MemoryStore, m as SearchOptions, n as ChunkOptions, o as MemoryOptions, p as Redactor, r as Embedder, s as MemoryRecord, t as AddOptions, u as MetadataFilter } from "../types-DQBe2lFo.mjs";
2
+ import { _ as createGerbilEmbedder, a as estimateTokens, c as IndexedDBStore, d as FileStore, f as createFileStore, g as BatchEmbedderLike, h as createMemory, i as topK, l as IndexedDBStoreOptions, m as Memory, n as dot, o as InMemoryStore, p as applyRedaction, r as normalize, s as createInMemoryStore, t as cosine, u as createIndexedDBStore, v as chunkText } from "../index-Dgmb2kE3.mjs";
3
+ export { AddOptions, BatchEmbedderLike, ChunkOptions, Embedder, FileStore, InMemoryStore, IndexedDBStore, IndexedDBStoreOptions, Memory, MemoryExport, MemoryMetadata, MemoryOptions, MemoryRecord, MemorySearchResult, MemoryStore, MetadataFilter, RecallOptions, RecallResult, Redactor, SearchOptions, SerializedRecord, StoreSearchOptions, applyRedaction, chunkText, cosine, createFileStore, createGerbilEmbedder, createInMemoryStore, createIndexedDBStore, createMemory, dot, estimateTokens, normalize, topK };
@@ -0,0 +1,6 @@
1
+ import { a as createInMemoryStore, i as InMemoryStore, n as createMemory, o as applyRedaction, r as estimateTokens, s as chunkText, t as Memory } from "../memory-Dj0J1v88.mjs";
2
+ import { n as createFileStore, r as createGerbilEmbedder, t as FileStore } from "../memory-DVN0MnIG.mjs";
3
+ import { i as topK, n as dot, r as normalize, t as cosine } from "../vector-B0panuy6.mjs";
4
+ import { n as createIndexedDBStore, t as IndexedDBStore } from "../indexeddb-store-BWIMtxxH.mjs";
5
+
6
+ export { FileStore, InMemoryStore, IndexedDBStore, Memory, applyRedaction, chunkText, cosine, createFileStore, createGerbilEmbedder, createInMemoryStore, createIndexedDBStore, createMemory, dot, estimateTokens, normalize, topK };