@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
@@ -9,6 +9,32 @@
9
9
  */
10
10
  import { logger } from "../../utils/logger.js";
11
11
  import { isRecoverableError } from "../../utils/errorHandling.js";
12
+ import { fireOnErrorOnce } from "../../utils/lifecycleCallbacks.js";
13
+ /**
14
+ * Normalize a thrown value to an `Error` while preserving structured
15
+ * fields (`code`, `status`, `statusCode`, `retryAfter`, `details`,
16
+ * `cause`, etc.) that downstream retry logic and SDK callers depend on.
17
+ *
18
+ * Previously the lifecycle middleware did
19
+ * `error instanceof Error ? error : new Error(String(error))`, which
20
+ * silently dropped every custom property on non-Error throws — so a
21
+ * provider's `{ code: "RATE_LIMITED", retryAfter: 30 }` rejection
22
+ * surfaced to consumers as a bare `Error("[object Object]")`.
23
+ */
24
+ function normalizeToError(error) {
25
+ if (error instanceof Error) {
26
+ return error;
27
+ }
28
+ if (typeof error === "object" && error !== null) {
29
+ const obj = error;
30
+ const msg = typeof obj.message === "string" ? obj.message : String(error);
31
+ // Object.assign keeps Error's prototype chain (including the
32
+ // captured stack from this synthetic Error's construction) while
33
+ // copying enumerable fields from the original throw.
34
+ return Object.assign(new Error(msg), obj);
35
+ }
36
+ return new Error(String(error));
37
+ }
12
38
  export function createLifecycleMiddleware(config = {}) {
13
39
  const metadata = {
14
40
  id: "lifecycle",
@@ -50,23 +76,18 @@ export function createLifecycleMiddleware(config = {}) {
50
76
  return result;
51
77
  }
52
78
  catch (error) {
53
- if (config.onError) {
54
- const err = error instanceof Error ? error : new Error(String(error));
55
- try {
56
- const callbackResult = config.onError({
57
- error: err,
58
- duration: Date.now() - startTime,
59
- recoverable: isRecoverableError(err),
60
- });
61
- Promise.resolve(callbackResult).catch((e) => {
62
- logger.warn("[LifecycleMiddleware] onError callback error:", e);
63
- });
64
- }
65
- catch (e) {
66
- logger.warn("[LifecycleMiddleware] onError callback error:", e);
67
- }
68
- }
69
- throw error;
79
+ const err = normalizeToError(error);
80
+ // fireOnErrorOnce stamps a Symbol on `err` so the SDK-level catch
81
+ // in neurolink.ts (and baseProvider.handleProviderError) skips
82
+ // its own onError fire for the same logical failure.
83
+ fireOnErrorOnce(config.onError, err, {
84
+ error: err,
85
+ duration: Date.now() - startTime,
86
+ recoverable: isRecoverableError(err),
87
+ });
88
+ // Rethrow the normalized err (not the raw `error`) so the
89
+ // fired-mark and any preserved structured fields propagate.
90
+ throw err;
70
91
  }
71
92
  },
72
93
  wrapStream: async ({ doStream, }) => {
@@ -102,23 +123,13 @@ export function createLifecycleMiddleware(config = {}) {
102
123
  controller.enqueue(chunk);
103
124
  }
104
125
  catch (error) {
105
- if (config.onError) {
106
- const err = error instanceof Error ? error : new Error(String(error));
107
- try {
108
- const callbackResult = config.onError({
109
- error: err,
110
- duration: Date.now() - startTime,
111
- recoverable: isRecoverableError(err),
112
- });
113
- Promise.resolve(callbackResult).catch((e) => {
114
- logger.warn("[LifecycleMiddleware] onError callback error:", e);
115
- });
116
- }
117
- catch (e) {
118
- logger.warn("[LifecycleMiddleware] onError callback error:", e);
119
- }
120
- }
121
- throw error;
126
+ const err = normalizeToError(error);
127
+ fireOnErrorOnce(config.onError, err, {
128
+ error: err,
129
+ duration: Date.now() - startTime,
130
+ recoverable: isRecoverableError(err),
131
+ });
132
+ throw err;
122
133
  }
123
134
  },
124
135
  flush() {
@@ -144,23 +155,13 @@ export function createLifecycleMiddleware(config = {}) {
144
155
  };
145
156
  }
146
157
  catch (error) {
147
- if (config.onError) {
148
- const err = error instanceof Error ? error : new Error(String(error));
149
- try {
150
- const callbackResult = config.onError({
151
- error: err,
152
- duration: Date.now() - startTime,
153
- recoverable: isRecoverableError(err),
154
- });
155
- Promise.resolve(callbackResult).catch((e) => {
156
- logger.warn("[LifecycleMiddleware] onError callback error:", e);
157
- });
158
- }
159
- catch (e) {
160
- logger.warn("[LifecycleMiddleware] onError callback error:", e);
161
- }
162
- }
163
- throw error;
158
+ const err = normalizeToError(error);
159
+ fireOnErrorOnce(config.onError, err, {
160
+ error: err,
161
+ duration: Date.now() - startTime,
162
+ recoverable: isRecoverableError(err),
163
+ });
164
+ throw err;
164
165
  }
165
166
  },
166
167
  };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Music Module — Music Generation Integration for NeuroLink
3
+ *
4
+ * Provides music-generation capability across providers (Beatoven,
5
+ * ElevenLabs Music, Lyria, Replicate-hosted MusicGen / Riffusion).
6
+ *
7
+ * Use `MusicProcessor.generate(provider, options)` to dispatch to the
8
+ * registered handler for `provider`.
9
+ *
10
+ * @module music
11
+ */
12
+ export { MUSIC_ERROR_CODES, MusicError, MusicProcessor, } from "../utils/musicProcessor.js";
13
+ export { BeatovenMusic, BeatovenMusic as BeatovenMusicHandler, } from "./providers/BeatovenMusic.js";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Music Module — Music Generation Integration for NeuroLink
3
+ *
4
+ * Provides music-generation capability across providers (Beatoven,
5
+ * ElevenLabs Music, Lyria, Replicate-hosted MusicGen / Riffusion).
6
+ *
7
+ * Use `MusicProcessor.generate(provider, options)` to dispatch to the
8
+ * registered handler for `provider`.
9
+ *
10
+ * @module music
11
+ */
12
+ export { MUSIC_ERROR_CODES, MusicError, MusicProcessor, } from "../utils/musicProcessor.js";
13
+ export { BeatovenMusic, BeatovenMusic as BeatovenMusicHandler, } from "./providers/BeatovenMusic.js";
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Beatoven.ai Music Generation Handler
3
+ *
4
+ * Async track-composition API. Submits a compose-track request, polls the
5
+ * task status, and downloads the resulting audio.
6
+ *
7
+ * @module music/providers/BeatovenMusic
8
+ * @see https://www.beatoven.ai/api-docs
9
+ */
10
+ import type { MusicAudioFormat, MusicHandler, MusicOptions, MusicResult } from "../../types/index.js";
11
+ /**
12
+ * Beatoven.ai Music Generation Handler.
13
+ *
14
+ * Beatoven is a royalty-free music generation API tuned for
15
+ * background / cinematic / brand music. Tracks are composed
16
+ * asynchronously: submit a prompt, poll the task, then download.
17
+ */
18
+ export declare class BeatovenMusic implements MusicHandler {
19
+ readonly maxDurationSeconds = 300;
20
+ readonly supportedFormats: readonly MusicAudioFormat[];
21
+ readonly supportedGenres: readonly string[];
22
+ private readonly apiKey;
23
+ private readonly baseUrl;
24
+ constructor(apiKey?: string);
25
+ isConfigured(): boolean;
26
+ generate(options: MusicOptions): Promise<MusicResult>;
27
+ private submitCompose;
28
+ private pollUntilComposed;
29
+ private fetchTaskStatus;
30
+ private downloadTrack;
31
+ }
@@ -0,0 +1,333 @@
1
+ /**
2
+ * Beatoven.ai Music Generation Handler
3
+ *
4
+ * Async track-composition API. Submits a compose-track request, polls the
5
+ * task status, and downloads the resulting audio.
6
+ *
7
+ * @module music/providers/BeatovenMusic
8
+ * @see https://www.beatoven.ai/api-docs
9
+ */
10
+ import { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
11
+ import { logger } from "../../utils/logger.js";
12
+ import { MUSIC_ERROR_CODES, MusicError } from "../../utils/musicProcessor.js";
13
+ import { MAX_AUDIO_BYTES, readBoundedBuffer } from "../../utils/sizeGuard.js";
14
+ import { assertSafeUrl } from "../../utils/ssrfGuard.js";
15
+ const DEFAULT_BASE_URL = "https://public-api.beatoven.ai";
16
+ const REQUEST_TIMEOUT_MS = 30_000;
17
+ const POLL_INTERVAL_MS = 3_000;
18
+ const TOTAL_TIMEOUT_MS = 5 * 60_000;
19
+ /**
20
+ * Beatoven.ai Music Generation Handler.
21
+ *
22
+ * Beatoven is a royalty-free music generation API tuned for
23
+ * background / cinematic / brand music. Tracks are composed
24
+ * asynchronously: submit a prompt, poll the task, then download.
25
+ */
26
+ export class BeatovenMusic {
27
+ maxDurationSeconds = 300; // 5 minutes per track
28
+ supportedFormats = [
29
+ "mp3",
30
+ "wav",
31
+ ];
32
+ supportedGenres = [
33
+ "ambient",
34
+ "cinematic",
35
+ "corporate",
36
+ "lo-fi",
37
+ "rock",
38
+ "pop",
39
+ "electronic",
40
+ "orchestral",
41
+ "folk",
42
+ ];
43
+ apiKey;
44
+ baseUrl;
45
+ constructor(apiKey) {
46
+ const resolved = (apiKey ?? process.env.BEATOVEN_API_KEY ?? "").trim();
47
+ this.apiKey = resolved.length > 0 ? resolved : null;
48
+ this.baseUrl = (process.env.BEATOVEN_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
49
+ }
50
+ isConfigured() {
51
+ return this.apiKey !== null;
52
+ }
53
+ async generate(options) {
54
+ if (!this.apiKey) {
55
+ throw new MusicError({
56
+ code: MUSIC_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
57
+ message: "BEATOVEN_API_KEY not configured",
58
+ category: ErrorCategory.CONFIGURATION,
59
+ severity: ErrorSeverity.HIGH,
60
+ retriable: false,
61
+ });
62
+ }
63
+ const startTime = Date.now();
64
+ const requestedFormat = options.format ?? "mp3";
65
+ if (!this.supportedFormats.includes(requestedFormat)) {
66
+ logger.warn(`[BeatovenMusic] Format "${requestedFormat}" not supported — falling back to "mp3"`);
67
+ }
68
+ const upstreamFormat = this.supportedFormats.includes(requestedFormat)
69
+ ? requestedFormat
70
+ : "mp3";
71
+ // 1. Submit compose-track request.
72
+ const compose = await this.submitCompose(options, upstreamFormat);
73
+ const taskId = compose.task_id;
74
+ // 2. Poll until composed or failed.
75
+ const taskResult = await this.pollUntilComposed(taskId, options.timeout ?? TOTAL_TIMEOUT_MS);
76
+ const trackUrl = taskResult.meta?.track_url;
77
+ if (!trackUrl) {
78
+ throw new MusicError({
79
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
80
+ message: `Beatoven task ${taskId} completed but no track_url returned`,
81
+ category: ErrorCategory.EXECUTION,
82
+ severity: ErrorSeverity.HIGH,
83
+ retriable: false,
84
+ context: { taskId, taskResult },
85
+ });
86
+ }
87
+ // 3. Download.
88
+ const buffer = await this.downloadTrack(trackUrl);
89
+ const latency = Date.now() - startTime;
90
+ logger.info(`[BeatovenMusic] Generated ${buffer.length} bytes (${upstreamFormat}) in ${latency}ms — task ${taskId}`);
91
+ return {
92
+ buffer,
93
+ format: upstreamFormat,
94
+ size: buffer.length,
95
+ duration: taskResult.meta?.duration,
96
+ provider: "beatoven",
97
+ metadata: {
98
+ latency,
99
+ provider: "beatoven",
100
+ model: "beatoven-default",
101
+ jobId: taskId,
102
+ trackId: taskResult.meta?.track_id,
103
+ projectId: taskResult.meta?.project_id,
104
+ requestedFormat: options.format,
105
+ },
106
+ };
107
+ }
108
+ async submitCompose(options, format) {
109
+ const durationMs = (options.duration ?? 60) * 1000;
110
+ const promptParts = [options.prompt];
111
+ if (options.genre) {
112
+ promptParts.push(`Genre: ${options.genre}`);
113
+ }
114
+ if (options.mood) {
115
+ promptParts.push(`Mood: ${options.mood}`);
116
+ }
117
+ if (options.tempo !== undefined) {
118
+ promptParts.push(`Tempo: ${options.tempo} BPM`);
119
+ }
120
+ const body = {
121
+ prompt: { text: promptParts.join(". ") },
122
+ duration: durationMs,
123
+ format,
124
+ };
125
+ const controller = new AbortController();
126
+ const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
127
+ let response;
128
+ try {
129
+ response = await fetch(`${this.baseUrl}/api/v1/tracks/compose`, {
130
+ method: "POST",
131
+ headers: {
132
+ Authorization: `Bearer ${this.apiKey}`,
133
+ "Content-Type": "application/json",
134
+ },
135
+ body: JSON.stringify(body),
136
+ signal: controller.signal,
137
+ });
138
+ }
139
+ catch (err) {
140
+ if (err instanceof Error && err.name === "AbortError") {
141
+ throw new MusicError({
142
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
143
+ message: `Beatoven compose request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`,
144
+ category: ErrorCategory.NETWORK,
145
+ severity: ErrorSeverity.HIGH,
146
+ retriable: true,
147
+ originalError: err,
148
+ });
149
+ }
150
+ throw new MusicError({
151
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
152
+ message: `Beatoven compose network error: ${err instanceof Error ? err.message : String(err)}`,
153
+ category: ErrorCategory.NETWORK,
154
+ severity: ErrorSeverity.HIGH,
155
+ retriable: true,
156
+ originalError: err instanceof Error ? err : undefined,
157
+ });
158
+ }
159
+ finally {
160
+ clearTimeout(timeoutId);
161
+ }
162
+ if (!response.ok) {
163
+ const text = await response.text();
164
+ const retriable = response.status === 408 ||
165
+ response.status === 429 ||
166
+ response.status >= 500;
167
+ throw new MusicError({
168
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
169
+ message: `Beatoven compose failed: ${response.status} — ${text}`,
170
+ category: retriable ? ErrorCategory.NETWORK : ErrorCategory.EXECUTION,
171
+ severity: ErrorSeverity.HIGH,
172
+ retriable,
173
+ context: { status: response.status, body: text },
174
+ });
175
+ }
176
+ const json = (await response.json());
177
+ if (!json.task_id) {
178
+ throw new MusicError({
179
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
180
+ message: "Beatoven compose response missing task_id",
181
+ category: ErrorCategory.EXECUTION,
182
+ severity: ErrorSeverity.HIGH,
183
+ retriable: false,
184
+ context: { response: json },
185
+ });
186
+ }
187
+ return json;
188
+ }
189
+ async pollUntilComposed(taskId, totalTimeoutMs) {
190
+ const startTime = Date.now();
191
+ while (Date.now() - startTime < totalTimeoutMs) {
192
+ const status = await this.fetchTaskStatus(taskId);
193
+ if (status.status === "composed") {
194
+ return status;
195
+ }
196
+ if (status.status === "failed") {
197
+ throw new MusicError({
198
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
199
+ message: `Beatoven task ${taskId} failed: ${status.message ?? "unknown"}`,
200
+ category: ErrorCategory.EXECUTION,
201
+ severity: ErrorSeverity.HIGH,
202
+ retriable: false,
203
+ context: { taskId, status },
204
+ });
205
+ }
206
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
207
+ }
208
+ throw new MusicError({
209
+ code: MUSIC_ERROR_CODES.POLL_TIMEOUT,
210
+ message: `Beatoven task ${taskId} did not complete within ${Math.round(totalTimeoutMs / 1000)}s`,
211
+ category: ErrorCategory.TIMEOUT,
212
+ severity: ErrorSeverity.MEDIUM,
213
+ retriable: true,
214
+ context: { taskId, totalTimeoutMs },
215
+ });
216
+ }
217
+ async fetchTaskStatus(taskId) {
218
+ const controller = new AbortController();
219
+ const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
220
+ let response;
221
+ try {
222
+ response = await fetch(`${this.baseUrl}/api/v1/tasks/${taskId}`, {
223
+ method: "GET",
224
+ headers: { Authorization: `Bearer ${this.apiKey}` },
225
+ signal: controller.signal,
226
+ });
227
+ }
228
+ catch (err) {
229
+ if (err instanceof Error && err.name === "AbortError") {
230
+ throw new MusicError({
231
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
232
+ message: `Beatoven status poll timed out after ${REQUEST_TIMEOUT_MS / 1000}s`,
233
+ category: ErrorCategory.NETWORK,
234
+ severity: ErrorSeverity.MEDIUM,
235
+ retriable: true,
236
+ originalError: err,
237
+ });
238
+ }
239
+ throw new MusicError({
240
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
241
+ message: `Beatoven status poll network error: ${err instanceof Error ? err.message : String(err)}`,
242
+ category: ErrorCategory.NETWORK,
243
+ severity: ErrorSeverity.MEDIUM,
244
+ retriable: true,
245
+ originalError: err instanceof Error ? err : undefined,
246
+ context: { taskId },
247
+ });
248
+ }
249
+ finally {
250
+ clearTimeout(timeoutId);
251
+ }
252
+ if (!response.ok) {
253
+ const text = await response.text();
254
+ throw new MusicError({
255
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
256
+ message: `Beatoven status request failed: ${response.status} — ${text}`,
257
+ category: ErrorCategory.EXECUTION,
258
+ severity: ErrorSeverity.MEDIUM,
259
+ retriable: response.status >= 500,
260
+ context: { status: response.status, taskId },
261
+ });
262
+ }
263
+ return (await response.json());
264
+ }
265
+ async downloadTrack(url) {
266
+ try {
267
+ await assertSafeUrl(url);
268
+ }
269
+ catch (err) {
270
+ throw new MusicError({
271
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
272
+ message: `Beatoven track URL rejected: ${err instanceof Error ? err.message : String(err)}`,
273
+ category: ErrorCategory.VALIDATION,
274
+ severity: ErrorSeverity.HIGH,
275
+ retriable: false,
276
+ context: { url },
277
+ });
278
+ }
279
+ const controller = new AbortController();
280
+ const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
281
+ let response;
282
+ try {
283
+ response = await fetch(url, { signal: controller.signal });
284
+ }
285
+ catch (err) {
286
+ if (err instanceof Error && err.name === "AbortError") {
287
+ throw new MusicError({
288
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
289
+ message: `Beatoven track download timed out after ${REQUEST_TIMEOUT_MS / 1000}s`,
290
+ category: ErrorCategory.NETWORK,
291
+ severity: ErrorSeverity.MEDIUM,
292
+ retriable: true,
293
+ originalError: err,
294
+ });
295
+ }
296
+ throw new MusicError({
297
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
298
+ message: `Beatoven track download network error: ${err instanceof Error ? err.message : String(err)}`,
299
+ category: ErrorCategory.NETWORK,
300
+ severity: ErrorSeverity.MEDIUM,
301
+ retriable: true,
302
+ originalError: err instanceof Error ? err : undefined,
303
+ context: { url },
304
+ });
305
+ }
306
+ finally {
307
+ clearTimeout(timeoutId);
308
+ }
309
+ if (!response.ok) {
310
+ throw new MusicError({
311
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
312
+ message: `Beatoven track download failed: ${response.status}`,
313
+ category: ErrorCategory.NETWORK,
314
+ severity: ErrorSeverity.MEDIUM,
315
+ retriable: response.status >= 500,
316
+ context: { status: response.status, url },
317
+ });
318
+ }
319
+ try {
320
+ return await readBoundedBuffer(response, MAX_AUDIO_BYTES, "Beatoven track");
321
+ }
322
+ catch (err) {
323
+ throw new MusicError({
324
+ code: MUSIC_ERROR_CODES.GENERATION_FAILED,
325
+ message: `Beatoven track download exceeded size limit: ${err instanceof Error ? err.message : String(err)}`,
326
+ category: ErrorCategory.EXECUTION,
327
+ severity: ErrorSeverity.HIGH,
328
+ retriable: false,
329
+ context: { url },
330
+ });
331
+ }
332
+ }
333
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ElevenLabs Music / Sound Generation Handler
3
+ *
4
+ * Distinct from ElevenLabs TTS — uses the `/v1/sound-generation` endpoint
5
+ * (synchronous; returns binary audio directly, no polling).
6
+ *
7
+ * @module music/providers/ElevenLabsMusic
8
+ * @see https://elevenlabs.io/docs/api-reference/sound-generation
9
+ */
10
+ import type { MusicAudioFormat, MusicHandler, MusicOptions, MusicResult } from "../../types/index.js";
11
+ /**
12
+ * ElevenLabs Music / Sound Generation Handler.
13
+ *
14
+ * Auth: `xi-api-key: ${ELEVENLABS_API_KEY}` (shares the same env var as
15
+ * ElevenLabs TTS — same account; different endpoint).
16
+ *
17
+ * Best for: short sound effects (ambient drones, hits, foley) and short
18
+ * music loops up to 22 seconds.
19
+ */
20
+ export declare class ElevenLabsMusic implements MusicHandler {
21
+ readonly maxDurationSeconds = 22;
22
+ readonly supportedFormats: readonly MusicAudioFormat[];
23
+ readonly supportedGenres: readonly string[];
24
+ private readonly apiKey;
25
+ private readonly baseUrl;
26
+ constructor(apiKey?: string);
27
+ isConfigured(): boolean;
28
+ generate(options: MusicOptions): Promise<MusicResult>;
29
+ private buildPrompt;
30
+ }