@juspay/neurolink 9.63.1 → 9.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +18 -17
  3. package/dist/adapters/providerImageAdapter.js +29 -1
  4. package/dist/adapters/replicate/auth.d.ts +19 -0
  5. package/dist/adapters/replicate/auth.js +32 -0
  6. package/dist/adapters/replicate/predictionLifecycle.d.ts +46 -0
  7. package/dist/adapters/replicate/predictionLifecycle.js +283 -0
  8. package/dist/adapters/video/klingVideoHandler.d.ts +37 -0
  9. package/dist/adapters/video/klingVideoHandler.js +305 -0
  10. package/dist/adapters/video/replicateVideoHandler.d.ts +29 -0
  11. package/dist/adapters/video/replicateVideoHandler.js +157 -0
  12. package/dist/adapters/video/runwayVideoHandler.d.ts +32 -0
  13. package/dist/adapters/video/runwayVideoHandler.js +316 -0
  14. package/dist/adapters/video/vertexVideoHandler.d.ts +19 -1
  15. package/dist/adapters/video/vertexVideoHandler.js +42 -11
  16. package/dist/autoresearch/runner.js +8 -2
  17. package/dist/avatar/index.d.ts +13 -0
  18. package/dist/avatar/index.js +13 -0
  19. package/dist/avatar/providers/DIDAvatar.d.ts +49 -0
  20. package/dist/avatar/providers/DIDAvatar.js +501 -0
  21. package/dist/avatar/providers/HeyGenAvatar.d.ts +30 -0
  22. package/dist/avatar/providers/HeyGenAvatar.js +337 -0
  23. package/dist/avatar/providers/ReplicateAvatar.d.ts +36 -0
  24. package/dist/avatar/providers/ReplicateAvatar.js +267 -0
  25. package/dist/browser/neurolink.min.js +573 -554
  26. package/dist/cli/commands/mcp.js +29 -0
  27. package/dist/cli/commands/proxy.js +24 -5
  28. package/dist/cli/factories/commandFactory.d.ts +25 -1
  29. package/dist/cli/factories/commandFactory.js +341 -63
  30. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  31. package/dist/cli/loop/optionsSchema.js +12 -0
  32. package/dist/constants/contextWindows.js +101 -0
  33. package/dist/constants/enums.d.ts +273 -2
  34. package/dist/constants/enums.js +290 -1
  35. package/dist/constants/videoErrors.d.ts +4 -0
  36. package/dist/constants/videoErrors.js +4 -0
  37. package/dist/core/baseProvider.d.ts +23 -3
  38. package/dist/core/baseProvider.js +217 -11
  39. package/dist/core/constants.d.ts +11 -0
  40. package/dist/core/constants.js +69 -1
  41. package/dist/core/modules/MessageBuilder.js +20 -0
  42. package/dist/core/redisConversationMemoryManager.js +6 -0
  43. package/dist/evaluation/index.d.ts +2 -0
  44. package/dist/evaluation/index.js +4 -0
  45. package/dist/factories/providerFactory.js +7 -1
  46. package/dist/factories/providerRegistry.js +203 -2
  47. package/dist/features/ppt/contentPlanner.js +42 -14
  48. package/dist/index.d.ts +9 -1
  49. package/dist/index.js +16 -1
  50. package/dist/lib/adapters/providerImageAdapter.js +29 -1
  51. package/dist/lib/adapters/replicate/auth.d.ts +19 -0
  52. package/dist/lib/adapters/replicate/auth.js +33 -0
  53. package/dist/lib/adapters/replicate/predictionLifecycle.d.ts +46 -0
  54. package/dist/lib/adapters/replicate/predictionLifecycle.js +284 -0
  55. package/dist/lib/adapters/video/klingVideoHandler.d.ts +37 -0
  56. package/dist/lib/adapters/video/klingVideoHandler.js +306 -0
  57. package/dist/lib/adapters/video/replicateVideoHandler.d.ts +29 -0
  58. package/dist/lib/adapters/video/replicateVideoHandler.js +158 -0
  59. package/dist/lib/adapters/video/runwayVideoHandler.d.ts +32 -0
  60. package/dist/lib/adapters/video/runwayVideoHandler.js +317 -0
  61. package/dist/lib/adapters/video/vertexVideoHandler.d.ts +19 -1
  62. package/dist/lib/adapters/video/vertexVideoHandler.js +42 -11
  63. package/dist/lib/autoresearch/runner.js +8 -2
  64. package/dist/lib/avatar/index.d.ts +13 -0
  65. package/dist/lib/avatar/index.js +14 -0
  66. package/dist/lib/avatar/providers/DIDAvatar.d.ts +49 -0
  67. package/dist/lib/avatar/providers/DIDAvatar.js +502 -0
  68. package/dist/lib/avatar/providers/HeyGenAvatar.d.ts +30 -0
  69. package/dist/lib/avatar/providers/HeyGenAvatar.js +338 -0
  70. package/dist/lib/avatar/providers/ReplicateAvatar.d.ts +36 -0
  71. package/dist/lib/avatar/providers/ReplicateAvatar.js +268 -0
  72. package/dist/lib/constants/contextWindows.js +101 -0
  73. package/dist/lib/constants/enums.d.ts +273 -2
  74. package/dist/lib/constants/enums.js +290 -1
  75. package/dist/lib/constants/videoErrors.d.ts +4 -0
  76. package/dist/lib/constants/videoErrors.js +4 -0
  77. package/dist/lib/core/baseProvider.d.ts +23 -3
  78. package/dist/lib/core/baseProvider.js +217 -11
  79. package/dist/lib/core/constants.d.ts +11 -0
  80. package/dist/lib/core/constants.js +69 -1
  81. package/dist/lib/core/modules/MessageBuilder.js +20 -0
  82. package/dist/lib/core/redisConversationMemoryManager.js +6 -0
  83. package/dist/lib/evaluation/index.d.ts +2 -0
  84. package/dist/lib/evaluation/index.js +4 -0
  85. package/dist/lib/factories/providerFactory.js +7 -1
  86. package/dist/lib/factories/providerRegistry.js +203 -2
  87. package/dist/lib/features/ppt/contentPlanner.js +42 -14
  88. package/dist/lib/index.d.ts +9 -1
  89. package/dist/lib/index.js +16 -1
  90. package/dist/lib/memory/hippocampusInitializer.d.ts +2 -2
  91. package/dist/lib/memory/hippocampusInitializer.js +32 -2
  92. package/dist/lib/middleware/builtin/lifecycle.js +52 -51
  93. package/dist/lib/music/index.d.ts +13 -0
  94. package/dist/lib/music/index.js +14 -0
  95. package/dist/lib/music/providers/BeatovenMusic.d.ts +31 -0
  96. package/dist/lib/music/providers/BeatovenMusic.js +334 -0
  97. package/dist/lib/music/providers/ElevenLabsMusic.d.ts +30 -0
  98. package/dist/lib/music/providers/ElevenLabsMusic.js +169 -0
  99. package/dist/lib/music/providers/LyriaMusic.d.ts +29 -0
  100. package/dist/lib/music/providers/LyriaMusic.js +173 -0
  101. package/dist/lib/music/providers/ReplicateMusic.d.ts +31 -0
  102. package/dist/lib/music/providers/ReplicateMusic.js +262 -0
  103. package/dist/lib/neurolink.d.ts +30 -0
  104. package/dist/lib/neurolink.js +342 -49
  105. package/dist/lib/providers/amazonBedrock.d.ts +10 -0
  106. package/dist/lib/providers/amazonBedrock.js +94 -39
  107. package/dist/lib/providers/anthropic.js +55 -7
  108. package/dist/lib/providers/anthropicBaseProvider.js +1 -1
  109. package/dist/lib/providers/azureOpenai.js +66 -17
  110. package/dist/lib/providers/cloudflare.d.ts +35 -0
  111. package/dist/lib/providers/cloudflare.js +174 -0
  112. package/dist/lib/providers/cohere.d.ts +52 -0
  113. package/dist/lib/providers/cohere.js +253 -0
  114. package/dist/lib/providers/deepseek.js +72 -17
  115. package/dist/lib/providers/fireworks.d.ts +33 -0
  116. package/dist/lib/providers/fireworks.js +164 -0
  117. package/dist/lib/providers/googleAiStudio.d.ts +11 -3
  118. package/dist/lib/providers/googleAiStudio.js +336 -344
  119. package/dist/lib/providers/googleNativeGemini3.d.ts +107 -2
  120. package/dist/lib/providers/googleNativeGemini3.js +381 -25
  121. package/dist/lib/providers/googleVertex.d.ts +116 -129
  122. package/dist/lib/providers/googleVertex.js +3002 -1988
  123. package/dist/lib/providers/groq.d.ts +33 -0
  124. package/dist/lib/providers/groq.js +181 -0
  125. package/dist/lib/providers/huggingFace.js +9 -8
  126. package/dist/lib/providers/ideogram.d.ts +34 -0
  127. package/dist/lib/providers/ideogram.js +184 -0
  128. package/dist/lib/providers/index.d.ts +13 -0
  129. package/dist/lib/providers/index.js +13 -0
  130. package/dist/lib/providers/jina.d.ts +59 -0
  131. package/dist/lib/providers/jina.js +218 -0
  132. package/dist/lib/providers/llamaCpp.js +14 -46
  133. package/dist/lib/providers/lmStudio.js +14 -47
  134. package/dist/lib/providers/mistral.js +7 -7
  135. package/dist/lib/providers/nvidiaNim.js +160 -19
  136. package/dist/lib/providers/ollama.js +7 -7
  137. package/dist/lib/providers/openAI.d.ts +22 -1
  138. package/dist/lib/providers/openAI.js +181 -0
  139. package/dist/lib/providers/openRouter.js +38 -22
  140. package/dist/lib/providers/openaiCompatible.js +9 -8
  141. package/dist/lib/providers/perplexity.d.ts +33 -0
  142. package/dist/lib/providers/perplexity.js +179 -0
  143. package/dist/lib/providers/recraft.d.ts +34 -0
  144. package/dist/lib/providers/recraft.js +197 -0
  145. package/dist/lib/providers/replicate.d.ts +75 -0
  146. package/dist/lib/providers/replicate.js +403 -0
  147. package/dist/lib/providers/stability.d.ts +37 -0
  148. package/dist/lib/providers/stability.js +191 -0
  149. package/dist/lib/providers/togetherAi.d.ts +33 -0
  150. package/dist/lib/providers/togetherAi.js +176 -0
  151. package/dist/lib/providers/voyage.d.ts +47 -0
  152. package/dist/lib/providers/voyage.js +177 -0
  153. package/dist/lib/providers/xai.d.ts +33 -0
  154. package/dist/lib/providers/xai.js +172 -0
  155. package/dist/lib/telemetry/index.d.ts +1 -1
  156. package/dist/lib/telemetry/index.js +1 -1
  157. package/dist/lib/telemetry/tracers.d.ts +19 -0
  158. package/dist/lib/telemetry/tracers.js +19 -0
  159. package/dist/lib/telemetry/withSpan.d.ts +35 -0
  160. package/dist/lib/telemetry/withSpan.js +103 -0
  161. package/dist/lib/types/aliases.d.ts +14 -0
  162. package/dist/lib/types/avatar.d.ts +143 -0
  163. package/dist/lib/types/avatar.js +20 -0
  164. package/dist/lib/types/cli.d.ts +6 -0
  165. package/dist/lib/types/common.d.ts +0 -3
  166. package/dist/lib/types/conversation.d.ts +10 -3
  167. package/dist/lib/types/generate.d.ts +76 -5
  168. package/dist/lib/types/index.d.ts +6 -0
  169. package/dist/lib/types/index.js +8 -0
  170. package/dist/lib/types/memory.d.ts +96 -0
  171. package/dist/lib/types/memory.js +23 -0
  172. package/dist/lib/types/middleware.d.ts +27 -0
  173. package/dist/lib/types/multimodal.d.ts +35 -2
  174. package/dist/lib/types/music.d.ts +165 -0
  175. package/dist/lib/types/music.js +21 -0
  176. package/dist/lib/types/providers.d.ts +284 -3
  177. package/dist/lib/types/replicate.d.ts +67 -0
  178. package/dist/lib/types/replicate.js +10 -0
  179. package/dist/lib/types/safeFetch.d.ts +15 -0
  180. package/dist/lib/types/safeFetch.js +7 -0
  181. package/dist/lib/types/stream.d.ts +8 -1
  182. package/dist/lib/types/tools.d.ts +13 -0
  183. package/dist/lib/types/video.d.ts +89 -0
  184. package/dist/lib/types/video.js +15 -0
  185. package/dist/lib/utils/avatarProcessor.d.ts +68 -0
  186. package/dist/lib/utils/avatarProcessor.js +172 -0
  187. package/dist/lib/utils/cloneOptions.d.ts +36 -0
  188. package/dist/lib/utils/cloneOptions.js +62 -0
  189. package/dist/lib/utils/lifecycleCallbacks.d.ts +56 -0
  190. package/dist/lib/utils/lifecycleCallbacks.js +100 -0
  191. package/dist/lib/utils/lifecycleTimeout.d.ts +25 -0
  192. package/dist/lib/utils/lifecycleTimeout.js +39 -0
  193. package/dist/lib/utils/logSanitize.d.ts +49 -0
  194. package/dist/lib/utils/logSanitize.js +170 -0
  195. package/dist/lib/utils/loggingFetch.d.ts +29 -0
  196. package/dist/lib/utils/loggingFetch.js +60 -0
  197. package/dist/lib/utils/messageBuilder.d.ts +10 -0
  198. package/dist/lib/utils/messageBuilder.js +83 -30
  199. package/dist/lib/utils/modelChoices.js +236 -3
  200. package/dist/lib/utils/modelDetection.d.ts +11 -0
  201. package/dist/lib/utils/modelDetection.js +27 -0
  202. package/dist/lib/utils/musicProcessor.d.ts +67 -0
  203. package/dist/lib/utils/musicProcessor.js +189 -0
  204. package/dist/lib/utils/optionsConversion.js +3 -2
  205. package/dist/lib/utils/parameterValidation.js +14 -4
  206. package/dist/lib/utils/pricing.js +193 -0
  207. package/dist/lib/utils/providerConfig.d.ts +55 -0
  208. package/dist/lib/utils/providerConfig.js +224 -0
  209. package/dist/lib/utils/providerHealth.js +7 -7
  210. package/dist/lib/utils/safeFetch.d.ts +26 -0
  211. package/dist/lib/utils/safeFetch.js +83 -0
  212. package/dist/lib/utils/schemaConversion.d.ts +1 -1
  213. package/dist/lib/utils/schemaConversion.js +59 -4
  214. package/dist/lib/utils/sizeGuard.d.ts +34 -0
  215. package/dist/lib/utils/sizeGuard.js +45 -0
  216. package/dist/lib/utils/ssrfGuard.d.ts +52 -0
  217. package/dist/lib/utils/ssrfGuard.js +411 -0
  218. package/dist/lib/utils/tokenLimits.js +23 -32
  219. package/dist/lib/utils/videoProcessor.d.ts +60 -0
  220. package/dist/lib/utils/videoProcessor.js +201 -0
  221. package/dist/lib/voice/providers/FishAudioTTS.d.ts +27 -0
  222. package/dist/lib/voice/providers/FishAudioTTS.js +183 -0
  223. package/dist/lib/workflow/core/ensembleExecutor.js +26 -9
  224. package/dist/memory/hippocampusInitializer.d.ts +2 -2
  225. package/dist/memory/hippocampusInitializer.js +32 -2
  226. package/dist/middleware/builtin/lifecycle.js +52 -51
  227. package/dist/music/index.d.ts +13 -0
  228. package/dist/music/index.js +13 -0
  229. package/dist/music/providers/BeatovenMusic.d.ts +31 -0
  230. package/dist/music/providers/BeatovenMusic.js +333 -0
  231. package/dist/music/providers/ElevenLabsMusic.d.ts +30 -0
  232. package/dist/music/providers/ElevenLabsMusic.js +168 -0
  233. package/dist/music/providers/LyriaMusic.d.ts +29 -0
  234. package/dist/music/providers/LyriaMusic.js +172 -0
  235. package/dist/music/providers/ReplicateMusic.d.ts +31 -0
  236. package/dist/music/providers/ReplicateMusic.js +261 -0
  237. package/dist/neurolink.d.ts +30 -0
  238. package/dist/neurolink.js +342 -49
  239. package/dist/providers/amazonBedrock.d.ts +10 -0
  240. package/dist/providers/amazonBedrock.js +94 -39
  241. package/dist/providers/anthropic.js +55 -7
  242. package/dist/providers/anthropicBaseProvider.js +1 -1
  243. package/dist/providers/azureOpenai.js +66 -17
  244. package/dist/providers/cloudflare.d.ts +35 -0
  245. package/dist/providers/cloudflare.js +173 -0
  246. package/dist/providers/cohere.d.ts +52 -0
  247. package/dist/providers/cohere.js +252 -0
  248. package/dist/providers/deepseek.js +72 -17
  249. package/dist/providers/fireworks.d.ts +33 -0
  250. package/dist/providers/fireworks.js +163 -0
  251. package/dist/providers/googleAiStudio.d.ts +11 -3
  252. package/dist/providers/googleAiStudio.js +335 -344
  253. package/dist/providers/googleNativeGemini3.d.ts +107 -2
  254. package/dist/providers/googleNativeGemini3.js +381 -25
  255. package/dist/providers/googleVertex.d.ts +116 -129
  256. package/dist/providers/googleVertex.js +3000 -1987
  257. package/dist/providers/groq.d.ts +33 -0
  258. package/dist/providers/groq.js +180 -0
  259. package/dist/providers/huggingFace.js +9 -8
  260. package/dist/providers/ideogram.d.ts +34 -0
  261. package/dist/providers/ideogram.js +183 -0
  262. package/dist/providers/index.d.ts +13 -0
  263. package/dist/providers/index.js +13 -0
  264. package/dist/providers/jina.d.ts +59 -0
  265. package/dist/providers/jina.js +217 -0
  266. package/dist/providers/llamaCpp.js +14 -46
  267. package/dist/providers/lmStudio.js +14 -47
  268. package/dist/providers/mistral.js +7 -7
  269. package/dist/providers/nvidiaNim.js +160 -19
  270. package/dist/providers/ollama.js +7 -7
  271. package/dist/providers/openAI.d.ts +22 -1
  272. package/dist/providers/openAI.js +181 -0
  273. package/dist/providers/openRouter.js +38 -22
  274. package/dist/providers/openaiCompatible.js +9 -8
  275. package/dist/providers/perplexity.d.ts +33 -0
  276. package/dist/providers/perplexity.js +178 -0
  277. package/dist/providers/recraft.d.ts +34 -0
  278. package/dist/providers/recraft.js +196 -0
  279. package/dist/providers/replicate.d.ts +75 -0
  280. package/dist/providers/replicate.js +402 -0
  281. package/dist/providers/stability.d.ts +37 -0
  282. package/dist/providers/stability.js +190 -0
  283. package/dist/providers/togetherAi.d.ts +33 -0
  284. package/dist/providers/togetherAi.js +175 -0
  285. package/dist/providers/voyage.d.ts +47 -0
  286. package/dist/providers/voyage.js +176 -0
  287. package/dist/providers/xai.d.ts +33 -0
  288. package/dist/providers/xai.js +171 -0
  289. package/dist/telemetry/index.d.ts +1 -1
  290. package/dist/telemetry/index.js +1 -1
  291. package/dist/telemetry/tracers.d.ts +19 -0
  292. package/dist/telemetry/tracers.js +19 -0
  293. package/dist/telemetry/withSpan.d.ts +35 -0
  294. package/dist/telemetry/withSpan.js +103 -0
  295. package/dist/types/aliases.d.ts +14 -0
  296. package/dist/types/avatar.d.ts +143 -0
  297. package/dist/types/avatar.js +19 -0
  298. package/dist/types/cli.d.ts +6 -0
  299. package/dist/types/common.d.ts +0 -3
  300. package/dist/types/conversation.d.ts +10 -3
  301. package/dist/types/generate.d.ts +76 -5
  302. package/dist/types/index.d.ts +6 -0
  303. package/dist/types/index.js +8 -0
  304. package/dist/types/memory.d.ts +96 -0
  305. package/dist/types/memory.js +22 -0
  306. package/dist/types/middleware.d.ts +27 -0
  307. package/dist/types/multimodal.d.ts +35 -2
  308. package/dist/types/music.d.ts +165 -0
  309. package/dist/types/music.js +20 -0
  310. package/dist/types/providers.d.ts +284 -3
  311. package/dist/types/replicate.d.ts +67 -0
  312. package/dist/types/replicate.js +9 -0
  313. package/dist/types/safeFetch.d.ts +15 -0
  314. package/dist/types/safeFetch.js +6 -0
  315. package/dist/types/stream.d.ts +8 -1
  316. package/dist/types/tools.d.ts +13 -0
  317. package/dist/types/video.d.ts +89 -0
  318. package/dist/types/video.js +14 -0
  319. package/dist/utils/avatarProcessor.d.ts +68 -0
  320. package/dist/utils/avatarProcessor.js +171 -0
  321. package/dist/utils/cloneOptions.d.ts +36 -0
  322. package/dist/utils/cloneOptions.js +61 -0
  323. package/dist/utils/lifecycleCallbacks.d.ts +56 -0
  324. package/dist/utils/lifecycleCallbacks.js +99 -0
  325. package/dist/utils/lifecycleTimeout.d.ts +25 -0
  326. package/dist/utils/lifecycleTimeout.js +38 -0
  327. package/dist/utils/logSanitize.d.ts +49 -0
  328. package/dist/utils/logSanitize.js +169 -0
  329. package/dist/utils/loggingFetch.d.ts +29 -0
  330. package/dist/utils/loggingFetch.js +59 -0
  331. package/dist/utils/messageBuilder.d.ts +10 -0
  332. package/dist/utils/messageBuilder.js +83 -30
  333. package/dist/utils/modelChoices.js +236 -3
  334. package/dist/utils/modelDetection.d.ts +11 -0
  335. package/dist/utils/modelDetection.js +27 -0
  336. package/dist/utils/musicProcessor.d.ts +67 -0
  337. package/dist/utils/musicProcessor.js +188 -0
  338. package/dist/utils/optionsConversion.js +3 -2
  339. package/dist/utils/parameterValidation.js +14 -4
  340. package/dist/utils/pricing.js +193 -0
  341. package/dist/utils/providerConfig.d.ts +55 -0
  342. package/dist/utils/providerConfig.js +224 -0
  343. package/dist/utils/providerHealth.js +7 -7
  344. package/dist/utils/safeFetch.d.ts +26 -0
  345. package/dist/utils/safeFetch.js +82 -0
  346. package/dist/utils/schemaConversion.d.ts +1 -1
  347. package/dist/utils/schemaConversion.js +59 -4
  348. package/dist/utils/sizeGuard.d.ts +34 -0
  349. package/dist/utils/sizeGuard.js +44 -0
  350. package/dist/utils/ssrfGuard.d.ts +52 -0
  351. package/dist/utils/ssrfGuard.js +410 -0
  352. package/dist/utils/tokenLimits.js +23 -32
  353. package/dist/utils/videoProcessor.d.ts +60 -0
  354. package/dist/utils/videoProcessor.js +200 -0
  355. package/dist/voice/providers/FishAudioTTS.d.ts +27 -0
  356. package/dist/voice/providers/FishAudioTTS.js +182 -0
  357. package/dist/workflow/core/ensembleExecutor.js +26 -9
  358. package/package.json +42 -8
@@ -2,30 +2,14 @@
2
2
  * Provider-specific token limit utilities
3
3
  * Provides safe maxTokens values based on provider and model capabilities
4
4
  */
5
- import { PROVIDER_MAX_TOKENS, IMAGE_GENERATION_MODELS, } from "../core/constants.js";
5
+ import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
6
6
  import { logger } from "./logger.js";
7
- // Gemini 3 models and Gemini 2.5 image models have a hard limit of 32768 output tokens
8
- const GEMINI_RESTRICTED_MAX_OUTPUT_TOKENS = 32768;
9
- /**
10
- * Check if a model has the restricted 32768 output token limit
11
- * This applies to:
12
- * - All Gemini 3 models (gemini-3-flash, gemini-3-pro, etc.)
13
- * - All Gemini 2.5 image generation models (gemini-2.5-flash-image)
14
- */
15
- function hasRestrictedOutputLimit(model) {
16
- if (!model) {
17
- return false;
18
- }
19
- // Check for Gemini 3 models
20
- if (model.includes("gemini-3")) {
21
- return true;
22
- }
23
- // Check for image generation models (includes gemini-2.5-flash-image)
24
- if (IMAGE_GENERATION_MODELS.some((m) => model.includes(m))) {
25
- return true;
26
- }
27
- return false;
28
- }
7
+ import { hasRestrictedOutputLimit, RESTRICTED_OUTPUT_TOKEN_LIMIT, } from "./modelDetection.js";
8
+ // Restricted-model detection (Gemini 3.x + image-gen models capped at 32768
9
+ // output tokens) lives in modelDetection.ts. Importing the canonical helper
10
+ // keeps both call sites on one definition; the previous local copy used
11
+ // case-sensitive substring matches and could miss identifiers like
12
+ // "Gemini-3-Pro" which the canonical anchored, case-insensitive regex matches.
29
13
  /**
30
14
  * Get the safe maximum tokens for a provider and model
31
15
  */
@@ -33,19 +17,19 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
33
17
  // CRITICAL: Gemini 3 models AND image generation models have a hard limit of 32768 output tokens
34
18
  // This check must happen FIRST, before any other logic, because these models
35
19
  // will reject requests with maxOutputTokens > 32768
36
- const isRestrictedModel = hasRestrictedOutputLimit(model);
20
+ const isRestrictedModel = model ? hasRestrictedOutputLimit(model) : false;
37
21
  if (isRestrictedModel) {
38
22
  // Explicit undefined/null check so a caller-supplied 0 is preserved
39
- // (truthy checks would treat 0 as "unset" and silently fall back to the cap).
23
+ // (truthy guards would treat 0 as "unset" and silently fall back to the cap).
40
24
  if (requestedMaxTokens !== undefined &&
41
25
  requestedMaxTokens !== null &&
42
- requestedMaxTokens > GEMINI_RESTRICTED_MAX_OUTPUT_TOKENS) {
43
- logger.warn(`Requested maxTokens ${requestedMaxTokens} exceeds ${model} limit of ${GEMINI_RESTRICTED_MAX_OUTPUT_TOKENS}. Using ${GEMINI_RESTRICTED_MAX_OUTPUT_TOKENS} instead.`);
44
- return GEMINI_RESTRICTED_MAX_OUTPUT_TOKENS;
26
+ requestedMaxTokens > RESTRICTED_OUTPUT_TOKEN_LIMIT) {
27
+ logger.warn(`Requested maxTokens ${requestedMaxTokens} exceeds ${model} limit of ${RESTRICTED_OUTPUT_TOKEN_LIMIT}. Using ${RESTRICTED_OUTPUT_TOKEN_LIMIT} instead.`);
28
+ return RESTRICTED_OUTPUT_TOKEN_LIMIT;
45
29
  }
46
30
  // If no maxTokens specified, use the restricted limit as default
47
31
  if (requestedMaxTokens === undefined || requestedMaxTokens === null) {
48
- return GEMINI_RESTRICTED_MAX_OUTPUT_TOKENS;
32
+ return RESTRICTED_OUTPUT_TOKEN_LIMIT;
49
33
  }
50
34
  // Otherwise, use the requested value (it's within limits, including 0)
51
35
  return requestedMaxTokens;
@@ -54,7 +38,12 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
54
38
  const providerLimits = PROVIDER_MAX_TOKENS[provider];
55
39
  if (!providerLimits) {
56
40
  logger.warn(`Unknown provider ${provider}, no token limits enforced`);
57
- return requestedMaxTokens || undefined; // No default limit for unknown providers
41
+ // Explicit undefined/null check so a caller-supplied 0 is preserved
42
+ // (truthy guard would silently drop 0 here as it does in the restricted branch).
43
+ if (requestedMaxTokens === undefined || requestedMaxTokens === null) {
44
+ return undefined;
45
+ }
46
+ return requestedMaxTokens;
58
47
  }
59
48
  // Get model-specific limit or provider default
60
49
  let maxLimit;
@@ -73,8 +62,10 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
73
62
  else {
74
63
  maxLimit = PROVIDER_MAX_TOKENS.default;
75
64
  }
76
- // If no specific maxTokens requested, return the provider limit
77
- if (!requestedMaxTokens) {
65
+ // If no specific maxTokens requested, return the provider limit.
66
+ // Use explicit undefined/null so a caller-supplied 0 is preserved
67
+ // (matches the restricted-model branch above).
68
+ if (requestedMaxTokens === undefined || requestedMaxTokens === null) {
78
69
  return maxLimit;
79
70
  }
80
71
  // If requested maxTokens exceeds the limit, use the limit and warn
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Video Generation Processing Utility
3
+ *
4
+ * Central registry + dispatch for video-generation handlers across
5
+ * providers (Vertex Veo, Kling, Runway, Replicate-hosted models, etc.).
6
+ *
7
+ * Mirrors the static-handler-registry pattern established by
8
+ * `TTSProcessor` (`utils/ttsProcessor.ts`) and `STTProcessor`
9
+ * (`utils/sttProcessor.ts`).
10
+ *
11
+ * @module utils/videoProcessor
12
+ */
13
+ import { VIDEO_ERROR_CODES } from "../constants/videoErrors.js";
14
+ import type { VideoGenerationResult, VideoHandler, VideoOutputOptions, VideoTransitionOptions } from "../types/index.js";
15
+ import { VideoError } from "../adapters/video/vertexVideoHandler.js";
16
+ export { VideoError, VIDEO_ERROR_CODES };
17
+ /**
18
+ * Static processor managing the video handler registry.
19
+ *
20
+ * Handlers register themselves during `ProviderRegistry._doRegister()`
21
+ * via `VideoProcessor.registerHandler(name, instance)`. Lookups are
22
+ * O(1) on a normalised lower-case provider key.
23
+ */
24
+ export declare class VideoProcessor {
25
+ private static readonly handlers;
26
+ /**
27
+ * Register a video handler for a specific provider.
28
+ */
29
+ static registerHandler(providerName: string, handler: VideoHandler): void;
30
+ /**
31
+ * Check if a provider has a registered video handler.
32
+ */
33
+ static supports(providerName: string): boolean;
34
+ /**
35
+ * List the names of all registered providers.
36
+ */
37
+ static listProviders(): string[];
38
+ private static getHandler;
39
+ private static buildSpanAttributes;
40
+ /**
41
+ * Generate a single video clip via the registered handler.
42
+ *
43
+ * @param provider - Registered provider name (e.g. "vertex", "kling")
44
+ * @param image - Source image buffer
45
+ * @param prompt - Text prompt describing the desired motion / content
46
+ * @param options - Resolution / length / aspect-ratio / audio options
47
+ * @param region - Optional region override (Vertex location, etc.)
48
+ * @throws VideoError on registry miss, handler-not-configured, or
49
+ * generation failure
50
+ */
51
+ static generate(provider: string, image: Buffer, prompt: string, options: VideoOutputOptions, region?: string): Promise<VideoGenerationResult>;
52
+ /**
53
+ * Generate a transition clip via the registered handler (Director Mode).
54
+ *
55
+ * Providers without first-and-last-frame interpolation surface a typed
56
+ * `TRANSITION_NOT_SUPPORTED` error here; callers should fall back to
57
+ * generating a regular clip with a transition prompt.
58
+ */
59
+ static generateTransition(provider: string, firstFrame: Buffer, lastFrame: Buffer, prompt: string, options?: VideoTransitionOptions, region?: string): Promise<Buffer>;
60
+ }
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Video Generation Processing Utility
3
+ *
4
+ * Central registry + dispatch for video-generation handlers across
5
+ * providers (Vertex Veo, Kling, Runway, Replicate-hosted models, etc.).
6
+ *
7
+ * Mirrors the static-handler-registry pattern established by
8
+ * `TTSProcessor` (`utils/ttsProcessor.ts`) and `STTProcessor`
9
+ * (`utils/sttProcessor.ts`).
10
+ *
11
+ * @module utils/videoProcessor
12
+ */
13
+ import { ErrorCategory, ErrorSeverity } from "../constants/enums.js";
14
+ import { VIDEO_ERROR_CODES } from "../constants/videoErrors.js";
15
+ import { SpanSerializer, SpanStatus, SpanType, getMetricsAggregator, } from "../observability/index.js";
16
+ import { logger } from "./logger.js";
17
+ // VideoError is canonical in vertexVideoHandler.ts (existing). Re-export
18
+ // here so consumers of `VideoProcessor` can import the typed error from
19
+ // the same module. Both throws and instanceof checks resolve to the same
20
+ // class.
21
+ import { VideoError } from "../adapters/video/vertexVideoHandler.js";
22
+ export { VideoError, VIDEO_ERROR_CODES };
23
+ /**
24
+ * Static processor managing the video handler registry.
25
+ *
26
+ * Handlers register themselves during `ProviderRegistry._doRegister()`
27
+ * via `VideoProcessor.registerHandler(name, instance)`. Lookups are
28
+ * O(1) on a normalised lower-case provider key.
29
+ */
30
+ export class VideoProcessor {
31
+ static handlers = new Map();
32
+ /**
33
+ * Register a video handler for a specific provider.
34
+ */
35
+ static registerHandler(providerName, handler) {
36
+ if (!providerName) {
37
+ throw new Error("Provider name is required");
38
+ }
39
+ if (!handler) {
40
+ throw new Error("Handler is required");
41
+ }
42
+ const key = providerName.toLowerCase();
43
+ if (this.handlers.has(key)) {
44
+ logger.warn(`[VideoProcessor] Overwriting existing handler for provider: ${key}`);
45
+ }
46
+ this.handlers.set(key, handler);
47
+ logger.debug(`[VideoProcessor] Registered video handler: ${key}`);
48
+ }
49
+ /**
50
+ * Check if a provider has a registered video handler.
51
+ */
52
+ static supports(providerName) {
53
+ if (!providerName) {
54
+ return false;
55
+ }
56
+ return this.handlers.has(providerName.toLowerCase());
57
+ }
58
+ /**
59
+ * List the names of all registered providers.
60
+ */
61
+ static listProviders() {
62
+ return Array.from(this.handlers.keys());
63
+ }
64
+ static getHandler(providerName) {
65
+ return this.handlers.get(providerName.toLowerCase());
66
+ }
67
+ static buildSpanAttributes(provider, options) {
68
+ return {
69
+ "video.operation": "generate",
70
+ "video.provider": provider,
71
+ "video.resolution": options.resolution,
72
+ "video.duration": options.length,
73
+ "video.aspect_ratio": options.aspectRatio,
74
+ "video.audio": options.audio,
75
+ };
76
+ }
77
+ /**
78
+ * Generate a single video clip via the registered handler.
79
+ *
80
+ * @param provider - Registered provider name (e.g. "vertex", "kling")
81
+ * @param image - Source image buffer
82
+ * @param prompt - Text prompt describing the desired motion / content
83
+ * @param options - Resolution / length / aspect-ratio / audio options
84
+ * @param region - Optional region override (Vertex location, etc.)
85
+ * @throws VideoError on registry miss, handler-not-configured, or
86
+ * generation failure
87
+ */
88
+ static async generate(provider, image, prompt, options, region) {
89
+ const span = SpanSerializer.createSpan(SpanType.MEDIA_GENERATION, "video.generate", this.buildSpanAttributes(provider, options));
90
+ try {
91
+ const handler = this.getHandler(provider);
92
+ if (!handler) {
93
+ throw new VideoError({
94
+ code: VIDEO_ERROR_CODES.PROVIDER_NOT_SUPPORTED,
95
+ message: `Video provider "${provider}" is not registered. Available: ${this.listProviders().join(", ")}`,
96
+ category: ErrorCategory.CONFIGURATION,
97
+ severity: ErrorSeverity.HIGH,
98
+ retriable: false,
99
+ context: { provider, available: this.listProviders() },
100
+ });
101
+ }
102
+ if (!handler.isConfigured()) {
103
+ throw new VideoError({
104
+ code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
105
+ message: `Video provider "${provider}" is not configured. Set the required credentials.`,
106
+ category: ErrorCategory.CONFIGURATION,
107
+ severity: ErrorSeverity.HIGH,
108
+ retriable: false,
109
+ context: { provider },
110
+ });
111
+ }
112
+ logger.debug(`[VideoProcessor] Starting video generation with provider: ${provider}`);
113
+ const result = await handler.generate(image, prompt, options, region);
114
+ const ended = SpanSerializer.endSpan(span, SpanStatus.OK);
115
+ getMetricsAggregator().recordSpan(ended);
116
+ logger.info(`[VideoProcessor] Generated ${result.data.length} bytes (${provider})`);
117
+ return result;
118
+ }
119
+ catch (err) {
120
+ const ended = SpanSerializer.endSpan(span, SpanStatus.ERROR, err instanceof Error ? err.message : String(err));
121
+ getMetricsAggregator().recordSpan(ended);
122
+ if (err instanceof VideoError) {
123
+ throw err;
124
+ }
125
+ const message = err instanceof Error ? err.message : String(err);
126
+ throw new VideoError({
127
+ code: VIDEO_ERROR_CODES.GENERATION_FAILED,
128
+ message: `Video generation failed for provider "${provider}": ${message}`,
129
+ category: ErrorCategory.EXECUTION,
130
+ severity: ErrorSeverity.HIGH,
131
+ retriable: true,
132
+ context: { provider, options, region },
133
+ originalError: err instanceof Error ? err : undefined,
134
+ });
135
+ }
136
+ }
137
+ /**
138
+ * Generate a transition clip via the registered handler (Director Mode).
139
+ *
140
+ * Providers without first-and-last-frame interpolation surface a typed
141
+ * `TRANSITION_NOT_SUPPORTED` error here; callers should fall back to
142
+ * generating a regular clip with a transition prompt.
143
+ */
144
+ static async generateTransition(provider, firstFrame, lastFrame, prompt, options, region) {
145
+ const handler = this.getHandler(provider);
146
+ if (!handler) {
147
+ throw new VideoError({
148
+ code: VIDEO_ERROR_CODES.PROVIDER_NOT_SUPPORTED,
149
+ message: `Video provider "${provider}" is not registered for transitions`,
150
+ category: ErrorCategory.CONFIGURATION,
151
+ severity: ErrorSeverity.HIGH,
152
+ retriable: false,
153
+ context: { provider, available: this.listProviders() },
154
+ });
155
+ }
156
+ if (!handler.generateTransition) {
157
+ throw new VideoError({
158
+ code: VIDEO_ERROR_CODES.TRANSITION_NOT_SUPPORTED,
159
+ message: `Video provider "${provider}" does not support transition clips`,
160
+ category: ErrorCategory.VALIDATION,
161
+ severity: ErrorSeverity.MEDIUM,
162
+ retriable: false,
163
+ context: { provider },
164
+ });
165
+ }
166
+ if (!handler.isConfigured()) {
167
+ throw new VideoError({
168
+ code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
169
+ message: `Video provider "${provider}" is not configured`,
170
+ category: ErrorCategory.CONFIGURATION,
171
+ severity: ErrorSeverity.HIGH,
172
+ retriable: false,
173
+ context: { provider },
174
+ });
175
+ }
176
+ try {
177
+ return await handler.generateTransition(firstFrame, lastFrame, prompt, options, region);
178
+ }
179
+ catch (err) {
180
+ if (err instanceof VideoError) {
181
+ throw err;
182
+ }
183
+ const message = err instanceof Error ? err.message : String(err);
184
+ throw new VideoError({
185
+ code: VIDEO_ERROR_CODES.DIRECTOR_TRANSITION_FAILED,
186
+ message: `Video transition generation failed for provider "${provider}": ${message}`,
187
+ category: ErrorCategory.EXECUTION,
188
+ severity: ErrorSeverity.MEDIUM,
189
+ retriable: true,
190
+ context: {
191
+ provider,
192
+ firstFrameSize: firstFrame.length,
193
+ lastFrameSize: lastFrame.length,
194
+ durationSeconds: options?.durationSeconds,
195
+ },
196
+ originalError: err instanceof Error ? err : undefined,
197
+ });
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=videoProcessor.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Fish Audio TTS Handler
3
+ *
4
+ * Implementation of TTS using Fish Audio API. Lower-cost alternative to
5
+ * ElevenLabs with strong multilingual support and 15s voice cloning.
6
+ *
7
+ * @module voice/providers/FishAudioTTS
8
+ * @see https://docs.fish.audio/text-to-speech/text-to-speech
9
+ */
10
+ import type { TTSHandler, TTSOptions, TTSResult } from "../../types/index.js";
11
+ /**
12
+ * Fish Audio Text-to-Speech Handler.
13
+ *
14
+ * Auth: `Authorization: Bearer ${FISH_AUDIO_API_KEY}`.
15
+ * Models: speech-1.5 (standard), speech-1.6, s1 (default; latest).
16
+ */
17
+ export declare class FishAudioTTS implements TTSHandler {
18
+ readonly maxTextLength = 5000;
19
+ private readonly apiKey;
20
+ private readonly baseUrl;
21
+ constructor(apiKey?: string);
22
+ isConfigured(): boolean;
23
+ synthesize(text: string, options?: TTSOptions): Promise<TTSResult>;
24
+ private mapFormat;
25
+ private effectiveFormat;
26
+ private getSampleRate;
27
+ }
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Fish Audio TTS Handler
3
+ *
4
+ * Implementation of TTS using Fish Audio API. Lower-cost alternative to
5
+ * ElevenLabs with strong multilingual support and 15s voice cloning.
6
+ *
7
+ * @module voice/providers/FishAudioTTS
8
+ * @see https://docs.fish.audio/text-to-speech/text-to-speech
9
+ */
10
+ import { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
11
+ import { logger } from "../../utils/logger.js";
12
+ import { TTS_ERROR_CODES, TTSError } from "../../utils/ttsProcessor.js";
13
+ const DEFAULT_BASE_URL = "https://api.fish.audio";
14
+ const REQUEST_TIMEOUT_MS = 30_000;
15
+ /**
16
+ * Default reference voice — "Energetic Male" by official author `lengyue`,
17
+ * a long-standing public English voice on Fish Audio.
18
+ *
19
+ * @see https://fish.audio (model id 802e3bc2b27e49c2995d23ef70e6ac89)
20
+ *
21
+ * Note: the previous default `fb6c0e1ea91e427fb9a93b9bbf0a1e4d` was
22
+ * removed upstream and started returning 400 "Reference not found".
23
+ */
24
+ const DEFAULT_REFERENCE_ID = "802e3bc2b27e49c2995d23ef70e6ac89";
25
+ /**
26
+ * Fish Audio Text-to-Speech Handler.
27
+ *
28
+ * Auth: `Authorization: Bearer ${FISH_AUDIO_API_KEY}`.
29
+ * Models: speech-1.5 (standard), speech-1.6, s1 (default; latest).
30
+ */
31
+ export class FishAudioTTS {
32
+ maxTextLength = 5000;
33
+ apiKey;
34
+ baseUrl;
35
+ constructor(apiKey) {
36
+ const resolved = (apiKey ?? process.env.FISH_AUDIO_API_KEY ?? "").trim();
37
+ this.apiKey = resolved.length > 0 ? resolved : null;
38
+ this.baseUrl = (process.env.FISH_AUDIO_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
39
+ }
40
+ isConfigured() {
41
+ return this.apiKey !== null;
42
+ }
43
+ async synthesize(text, options = {}) {
44
+ if (!this.apiKey) {
45
+ throw new TTSError({
46
+ code: TTS_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
47
+ message: "FISH_AUDIO_API_KEY not configured",
48
+ category: ErrorCategory.CONFIGURATION,
49
+ severity: ErrorSeverity.HIGH,
50
+ retriable: false,
51
+ });
52
+ }
53
+ const startTime = Date.now();
54
+ const referenceId = options.voice ?? DEFAULT_REFERENCE_ID;
55
+ const requestedFormat = options.format ?? "mp3";
56
+ const upstreamFormat = this.mapFormat(requestedFormat);
57
+ const body = {
58
+ text,
59
+ reference_id: referenceId,
60
+ format: upstreamFormat,
61
+ mp3_bitrate: 128,
62
+ chunk_length: 200,
63
+ normalize: true,
64
+ latency: "normal",
65
+ };
66
+ const fishOpts = options;
67
+ if (fishOpts.model) {
68
+ body.model = fishOpts.model;
69
+ }
70
+ if (fishOpts.latency) {
71
+ body.latency = fishOpts.latency;
72
+ }
73
+ if (fishOpts.mp3Bitrate !== undefined) {
74
+ body.mp3_bitrate = fishOpts.mp3Bitrate;
75
+ }
76
+ const controller = new AbortController();
77
+ const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
78
+ let response;
79
+ try {
80
+ response = await fetch(`${this.baseUrl}/v1/tts`, {
81
+ method: "POST",
82
+ headers: {
83
+ Authorization: `Bearer ${this.apiKey}`,
84
+ "Content-Type": "application/json",
85
+ },
86
+ body: JSON.stringify(body),
87
+ signal: controller.signal,
88
+ });
89
+ }
90
+ catch (err) {
91
+ if (err instanceof Error && err.name === "AbortError") {
92
+ throw new TTSError({
93
+ code: TTS_ERROR_CODES.SYNTHESIS_FAILED,
94
+ message: `Fish Audio request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`,
95
+ category: ErrorCategory.NETWORK,
96
+ severity: ErrorSeverity.HIGH,
97
+ retriable: true,
98
+ originalError: err,
99
+ });
100
+ }
101
+ throw new TTSError({
102
+ code: TTS_ERROR_CODES.SYNTHESIS_FAILED,
103
+ message: `Fish Audio network error: ${err instanceof Error ? err.message : String(err)}`,
104
+ category: ErrorCategory.NETWORK,
105
+ severity: ErrorSeverity.HIGH,
106
+ retriable: true,
107
+ originalError: err instanceof Error ? err : undefined,
108
+ });
109
+ }
110
+ finally {
111
+ clearTimeout(timeoutId);
112
+ }
113
+ if (!response.ok) {
114
+ const text = await response.text();
115
+ const retriable = response.status === 408 ||
116
+ response.status === 429 ||
117
+ response.status >= 500;
118
+ throw new TTSError({
119
+ code: TTS_ERROR_CODES.SYNTHESIS_FAILED,
120
+ message: `Fish Audio synthesis failed: ${response.status} — ${text}`,
121
+ category: retriable ? ErrorCategory.NETWORK : ErrorCategory.EXECUTION,
122
+ severity: ErrorSeverity.HIGH,
123
+ retriable,
124
+ context: { status: response.status, referenceId, upstreamFormat },
125
+ });
126
+ }
127
+ const arrayBuffer = await response.arrayBuffer();
128
+ const audioBuffer = Buffer.from(arrayBuffer);
129
+ const latency = Date.now() - startTime;
130
+ const effectiveFormat = this.effectiveFormat(upstreamFormat);
131
+ const result = {
132
+ buffer: audioBuffer,
133
+ format: effectiveFormat,
134
+ size: audioBuffer.length,
135
+ voice: referenceId,
136
+ sampleRate: this.getSampleRate(effectiveFormat),
137
+ metadata: {
138
+ latency,
139
+ provider: "fish-audio",
140
+ model: fishOpts.model ?? "s1",
141
+ requestedFormat: options.format,
142
+ upstreamFormat,
143
+ },
144
+ };
145
+ logger.info(`[FishAudioTTS] Synthesized ${audioBuffer.length} bytes in ${latency}ms`);
146
+ return result;
147
+ }
148
+ mapFormat(format) {
149
+ const supported = {
150
+ mp3: "mp3",
151
+ wav: "wav",
152
+ pcm16: "pcm",
153
+ };
154
+ const mapped = supported[format];
155
+ if (!mapped) {
156
+ logger.warn(`[FishAudioTTS] Unsupported format "${format}" — falling back to "mp3"`);
157
+ return "mp3";
158
+ }
159
+ return mapped;
160
+ }
161
+ effectiveFormat(upstreamFormat) {
162
+ if (upstreamFormat === "mp3") {
163
+ return "mp3";
164
+ }
165
+ if (upstreamFormat === "wav") {
166
+ return "wav";
167
+ }
168
+ if (upstreamFormat === "pcm") {
169
+ return "pcm16";
170
+ }
171
+ return "mp3";
172
+ }
173
+ getSampleRate(format) {
174
+ if (format === "wav") {
175
+ return 44_100;
176
+ }
177
+ if (format === "pcm16") {
178
+ return 44_100;
179
+ }
180
+ return 44_100;
181
+ }
182
+ }
183
+ //# sourceMappingURL=FishAudioTTS.js.map
@@ -120,15 +120,32 @@ async function executeModel(options, workflowDefaultSystemPrompt) {
120
120
  // 3. Workflow-level default
121
121
  // 4. undefined (provider default)
122
122
  const resolvedSystemPrompt = systemPrompt || model.systemPrompt || workflowDefaultSystemPrompt;
123
- // Execute with timeout
124
- const result = await executeWithTimeout(async () => {
125
- return await provider.generate({
126
- prompt,
127
- systemPrompt: resolvedSystemPrompt,
128
- temperature: model.temperature,
129
- maxTokens: model.maxTokens,
130
- });
131
- }, timeout, `Model ${model.provider}/${model.model} timed out after ${timeout}ms`);
123
+ // Execute with timeout. Some upstream LLM endpoints (notably Vertex
124
+ // under high parallel load) occasionally respond with an empty
125
+ // assistant message instead of content; retry once before giving up so
126
+ // a transient empty response doesn't cascade into an empty ensemble
127
+ // result that downstream tests + judges have no way to evaluate.
128
+ let result;
129
+ let attempts = 0;
130
+ const MAX_ATTEMPTS = 2;
131
+ /* eslint-disable no-constant-condition */
132
+ while (true) {
133
+ attempts++;
134
+ result = await executeWithTimeout(async () => {
135
+ return await provider.generate({
136
+ prompt,
137
+ systemPrompt: resolvedSystemPrompt,
138
+ temperature: model.temperature,
139
+ maxTokens: model.maxTokens,
140
+ });
141
+ }, timeout, `Model ${model.provider}/${model.model} timed out after ${timeout}ms`);
142
+ const contentLen = result?.content?.length ?? 0;
143
+ if (contentLen > 0 || attempts >= MAX_ATTEMPTS) {
144
+ break;
145
+ }
146
+ logger.warn(`[${functionTag}] Model returned empty content — retrying once`, { provider: model.provider, model: model.model, attempt: attempts });
147
+ }
148
+ /* eslint-enable no-constant-condition */
132
149
  const responseTime = Date.now() - startTime;
133
150
  logger.debug(`[${functionTag}] Model execution successful`, {
134
151
  provider: model.provider,
@@ -1,2 +1,2 @@
1
- import { Hippocampus, type HippocampusConfig } from "@juspay/hippocampus";
2
- export declare function initializeHippocampus(config: HippocampusConfig): Hippocampus | null;
1
+ import type { HippocampusConfig, HippocampusLike } from "../types/index.js";
2
+ export declare function initializeHippocampus(config: HippocampusConfig): HippocampusLike | null;
@@ -1,8 +1,38 @@
1
- import { Hippocampus } from "@juspay/hippocampus";
1
+ import { createRequire } from "node:module";
2
2
  import { logger } from "../utils/logger.js";
3
+ // Lazy require so importing NeuroLink core does not fail when the optional
4
+ // peer @juspay/hippocampus is not installed. The package was previously a
5
+ // hard runtime dependency, but Hippocampus declares a peer on
6
+ // @juspay/neurolink which made pnpm pull a registry NeuroLink that
7
+ // transitively required @ai-sdk/google + @ai-sdk/google-vertex into the
8
+ // production graph. Making memory optional breaks that cycle while keeping
9
+ // the same runtime behavior whenever the package is installed.
10
+ const lazyRequire = createRequire(import.meta.url);
11
+ let cachedModule;
12
+ function loadHippocampusModule() {
13
+ if (cachedModule !== undefined) {
14
+ return cachedModule;
15
+ }
16
+ try {
17
+ cachedModule = lazyRequire("@juspay/hippocampus");
18
+ return cachedModule;
19
+ }
20
+ catch (error) {
21
+ cachedModule = null;
22
+ logger.debug("[memoryInitializer] @juspay/hippocampus is not installed; memory features disabled.", {
23
+ error: error instanceof Error ? error.message : String(error),
24
+ });
25
+ return null;
26
+ }
27
+ }
3
28
  export function initializeHippocampus(config) {
29
+ const mod = loadHippocampusModule();
30
+ if (!mod) {
31
+ logger.warn("[memoryInitializer] Memory configuration provided but @juspay/hippocampus is not installed. Run `pnpm add @juspay/hippocampus` (or your package manager equivalent) to enable memory.");
32
+ return null;
33
+ }
4
34
  try {
5
- const instance = new Hippocampus(config);
35
+ const instance = new mod.Hippocampus(config);
6
36
  logger.info("[memoryInitializer] Memory initialized successfully", {
7
37
  storageType: config.storage?.type || "sqlite",
8
38
  maxWords: config.maxWords || 50,