@juspay/neurolink 9.64.0 → 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 (322) hide show
  1. package/CHANGELOG.md +6 -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 +33 -9
  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 +633 -610
  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 +11 -1
  29. package/dist/cli/factories/commandFactory.js +291 -38
  30. package/dist/constants/contextWindows.js +101 -0
  31. package/dist/constants/enums.d.ts +273 -2
  32. package/dist/constants/enums.js +290 -1
  33. package/dist/constants/videoErrors.d.ts +4 -0
  34. package/dist/constants/videoErrors.js +4 -0
  35. package/dist/core/baseProvider.d.ts +22 -2
  36. package/dist/core/baseProvider.js +217 -11
  37. package/dist/core/constants.d.ts +11 -0
  38. package/dist/core/constants.js +69 -1
  39. package/dist/core/redisConversationMemoryManager.js +6 -0
  40. package/dist/evaluation/index.d.ts +2 -0
  41. package/dist/evaluation/index.js +4 -0
  42. package/dist/factories/providerFactory.js +7 -1
  43. package/dist/factories/providerRegistry.js +202 -5
  44. package/dist/features/ppt/contentPlanner.js +42 -14
  45. package/dist/index.d.ts +9 -1
  46. package/dist/index.js +16 -1
  47. package/dist/lib/adapters/providerImageAdapter.js +29 -1
  48. package/dist/lib/adapters/replicate/auth.d.ts +19 -0
  49. package/dist/lib/adapters/replicate/auth.js +33 -0
  50. package/dist/lib/adapters/replicate/predictionLifecycle.d.ts +46 -0
  51. package/dist/lib/adapters/replicate/predictionLifecycle.js +284 -0
  52. package/dist/lib/adapters/video/klingVideoHandler.d.ts +37 -0
  53. package/dist/lib/adapters/video/klingVideoHandler.js +306 -0
  54. package/dist/lib/adapters/video/replicateVideoHandler.d.ts +29 -0
  55. package/dist/lib/adapters/video/replicateVideoHandler.js +158 -0
  56. package/dist/lib/adapters/video/runwayVideoHandler.d.ts +32 -0
  57. package/dist/lib/adapters/video/runwayVideoHandler.js +317 -0
  58. package/dist/lib/adapters/video/vertexVideoHandler.d.ts +19 -1
  59. package/dist/lib/adapters/video/vertexVideoHandler.js +33 -9
  60. package/dist/lib/autoresearch/runner.js +8 -2
  61. package/dist/lib/avatar/index.d.ts +13 -0
  62. package/dist/lib/avatar/index.js +14 -0
  63. package/dist/lib/avatar/providers/DIDAvatar.d.ts +49 -0
  64. package/dist/lib/avatar/providers/DIDAvatar.js +502 -0
  65. package/dist/lib/avatar/providers/HeyGenAvatar.d.ts +30 -0
  66. package/dist/lib/avatar/providers/HeyGenAvatar.js +338 -0
  67. package/dist/lib/avatar/providers/ReplicateAvatar.d.ts +36 -0
  68. package/dist/lib/avatar/providers/ReplicateAvatar.js +268 -0
  69. package/dist/lib/constants/contextWindows.js +101 -0
  70. package/dist/lib/constants/enums.d.ts +273 -2
  71. package/dist/lib/constants/enums.js +290 -1
  72. package/dist/lib/constants/videoErrors.d.ts +4 -0
  73. package/dist/lib/constants/videoErrors.js +4 -0
  74. package/dist/lib/core/baseProvider.d.ts +22 -2
  75. package/dist/lib/core/baseProvider.js +217 -11
  76. package/dist/lib/core/constants.d.ts +11 -0
  77. package/dist/lib/core/constants.js +69 -1
  78. package/dist/lib/core/redisConversationMemoryManager.js +6 -0
  79. package/dist/lib/evaluation/index.d.ts +2 -0
  80. package/dist/lib/evaluation/index.js +4 -0
  81. package/dist/lib/factories/providerFactory.js +7 -1
  82. package/dist/lib/factories/providerRegistry.js +202 -5
  83. package/dist/lib/features/ppt/contentPlanner.js +42 -14
  84. package/dist/lib/index.d.ts +9 -1
  85. package/dist/lib/index.js +16 -1
  86. package/dist/lib/middleware/builtin/lifecycle.js +39 -9
  87. package/dist/lib/music/index.d.ts +13 -0
  88. package/dist/lib/music/index.js +14 -0
  89. package/dist/lib/music/providers/BeatovenMusic.d.ts +31 -0
  90. package/dist/lib/music/providers/BeatovenMusic.js +334 -0
  91. package/dist/lib/music/providers/ElevenLabsMusic.d.ts +30 -0
  92. package/dist/lib/music/providers/ElevenLabsMusic.js +169 -0
  93. package/dist/lib/music/providers/LyriaMusic.d.ts +29 -0
  94. package/dist/lib/music/providers/LyriaMusic.js +173 -0
  95. package/dist/lib/music/providers/ReplicateMusic.d.ts +31 -0
  96. package/dist/lib/music/providers/ReplicateMusic.js +262 -0
  97. package/dist/lib/neurolink.d.ts +30 -0
  98. package/dist/lib/neurolink.js +323 -77
  99. package/dist/lib/providers/amazonBedrock.d.ts +10 -0
  100. package/dist/lib/providers/amazonBedrock.js +94 -39
  101. package/dist/lib/providers/anthropic.js +55 -7
  102. package/dist/lib/providers/anthropicBaseProvider.js +1 -1
  103. package/dist/lib/providers/azureOpenai.js +66 -17
  104. package/dist/lib/providers/cloudflare.d.ts +35 -0
  105. package/dist/lib/providers/cloudflare.js +174 -0
  106. package/dist/lib/providers/cohere.d.ts +52 -0
  107. package/dist/lib/providers/cohere.js +253 -0
  108. package/dist/lib/providers/deepseek.js +72 -17
  109. package/dist/lib/providers/fireworks.d.ts +33 -0
  110. package/dist/lib/providers/fireworks.js +164 -0
  111. package/dist/lib/providers/googleAiStudio.js +45 -6
  112. package/dist/lib/providers/googleNativeGemini3.d.ts +24 -1
  113. package/dist/lib/providers/googleNativeGemini3.js +173 -21
  114. package/dist/lib/providers/googleVertex.js +173 -17
  115. package/dist/lib/providers/groq.d.ts +33 -0
  116. package/dist/lib/providers/groq.js +181 -0
  117. package/dist/lib/providers/huggingFace.js +9 -8
  118. package/dist/lib/providers/ideogram.d.ts +34 -0
  119. package/dist/lib/providers/ideogram.js +184 -0
  120. package/dist/lib/providers/index.d.ts +13 -0
  121. package/dist/lib/providers/index.js +13 -0
  122. package/dist/lib/providers/jina.d.ts +59 -0
  123. package/dist/lib/providers/jina.js +218 -0
  124. package/dist/lib/providers/llamaCpp.js +14 -46
  125. package/dist/lib/providers/lmStudio.js +14 -47
  126. package/dist/lib/providers/mistral.js +7 -7
  127. package/dist/lib/providers/nvidiaNim.js +160 -19
  128. package/dist/lib/providers/ollama.js +7 -7
  129. package/dist/lib/providers/openAI.d.ts +22 -1
  130. package/dist/lib/providers/openAI.js +181 -0
  131. package/dist/lib/providers/openRouter.js +35 -23
  132. package/dist/lib/providers/openaiCompatible.js +9 -8
  133. package/dist/lib/providers/perplexity.d.ts +33 -0
  134. package/dist/lib/providers/perplexity.js +179 -0
  135. package/dist/lib/providers/recraft.d.ts +34 -0
  136. package/dist/lib/providers/recraft.js +197 -0
  137. package/dist/lib/providers/replicate.d.ts +75 -0
  138. package/dist/lib/providers/replicate.js +403 -0
  139. package/dist/lib/providers/stability.d.ts +37 -0
  140. package/dist/lib/providers/stability.js +191 -0
  141. package/dist/lib/providers/togetherAi.d.ts +33 -0
  142. package/dist/lib/providers/togetherAi.js +176 -0
  143. package/dist/lib/providers/voyage.d.ts +47 -0
  144. package/dist/lib/providers/voyage.js +177 -0
  145. package/dist/lib/providers/xai.d.ts +33 -0
  146. package/dist/lib/providers/xai.js +172 -0
  147. package/dist/lib/telemetry/index.d.ts +1 -1
  148. package/dist/lib/telemetry/index.js +1 -1
  149. package/dist/lib/telemetry/tracers.d.ts +19 -0
  150. package/dist/lib/telemetry/tracers.js +19 -0
  151. package/dist/lib/telemetry/withSpan.d.ts +35 -0
  152. package/dist/lib/telemetry/withSpan.js +103 -0
  153. package/dist/lib/types/avatar.d.ts +143 -0
  154. package/dist/lib/types/avatar.js +20 -0
  155. package/dist/lib/types/cli.d.ts +6 -0
  156. package/dist/lib/types/generate.d.ts +62 -5
  157. package/dist/lib/types/index.d.ts +5 -0
  158. package/dist/lib/types/index.js +7 -0
  159. package/dist/lib/types/middleware.d.ts +27 -0
  160. package/dist/lib/types/multimodal.d.ts +35 -2
  161. package/dist/lib/types/music.d.ts +165 -0
  162. package/dist/lib/types/music.js +21 -0
  163. package/dist/lib/types/providers.d.ts +144 -1
  164. package/dist/lib/types/replicate.d.ts +67 -0
  165. package/dist/lib/types/replicate.js +10 -0
  166. package/dist/lib/types/safeFetch.d.ts +15 -0
  167. package/dist/lib/types/safeFetch.js +7 -0
  168. package/dist/lib/types/stream.d.ts +2 -1
  169. package/dist/lib/types/tools.d.ts +13 -0
  170. package/dist/lib/types/video.d.ts +89 -0
  171. package/dist/lib/types/video.js +15 -0
  172. package/dist/lib/utils/avatarProcessor.d.ts +68 -0
  173. package/dist/lib/utils/avatarProcessor.js +172 -0
  174. package/dist/lib/utils/cloneOptions.d.ts +36 -0
  175. package/dist/lib/utils/cloneOptions.js +62 -0
  176. package/dist/lib/utils/lifecycleCallbacks.d.ts +51 -8
  177. package/dist/lib/utils/lifecycleCallbacks.js +82 -26
  178. package/dist/lib/utils/lifecycleTimeout.d.ts +25 -0
  179. package/dist/lib/utils/lifecycleTimeout.js +39 -0
  180. package/dist/lib/utils/logSanitize.d.ts +49 -0
  181. package/dist/lib/utils/logSanitize.js +170 -0
  182. package/dist/lib/utils/loggingFetch.d.ts +29 -0
  183. package/dist/lib/utils/loggingFetch.js +60 -0
  184. package/dist/lib/utils/messageBuilder.js +43 -25
  185. package/dist/lib/utils/modelChoices.js +236 -3
  186. package/dist/lib/utils/musicProcessor.d.ts +67 -0
  187. package/dist/lib/utils/musicProcessor.js +189 -0
  188. package/dist/lib/utils/optionsConversion.js +3 -2
  189. package/dist/lib/utils/parameterValidation.js +14 -4
  190. package/dist/lib/utils/pricing.js +193 -0
  191. package/dist/lib/utils/providerConfig.d.ts +55 -0
  192. package/dist/lib/utils/providerConfig.js +224 -0
  193. package/dist/lib/utils/safeFetch.d.ts +26 -0
  194. package/dist/lib/utils/safeFetch.js +83 -0
  195. package/dist/lib/utils/sizeGuard.d.ts +34 -0
  196. package/dist/lib/utils/sizeGuard.js +45 -0
  197. package/dist/lib/utils/ssrfGuard.d.ts +52 -0
  198. package/dist/lib/utils/ssrfGuard.js +411 -0
  199. package/dist/lib/utils/videoProcessor.d.ts +60 -0
  200. package/dist/lib/utils/videoProcessor.js +201 -0
  201. package/dist/lib/voice/providers/FishAudioTTS.d.ts +27 -0
  202. package/dist/lib/voice/providers/FishAudioTTS.js +183 -0
  203. package/dist/lib/workflow/core/ensembleExecutor.js +26 -9
  204. package/dist/middleware/builtin/lifecycle.js +39 -9
  205. package/dist/music/index.d.ts +13 -0
  206. package/dist/music/index.js +13 -0
  207. package/dist/music/providers/BeatovenMusic.d.ts +31 -0
  208. package/dist/music/providers/BeatovenMusic.js +333 -0
  209. package/dist/music/providers/ElevenLabsMusic.d.ts +30 -0
  210. package/dist/music/providers/ElevenLabsMusic.js +168 -0
  211. package/dist/music/providers/LyriaMusic.d.ts +29 -0
  212. package/dist/music/providers/LyriaMusic.js +172 -0
  213. package/dist/music/providers/ReplicateMusic.d.ts +31 -0
  214. package/dist/music/providers/ReplicateMusic.js +261 -0
  215. package/dist/neurolink.d.ts +30 -0
  216. package/dist/neurolink.js +323 -77
  217. package/dist/providers/amazonBedrock.d.ts +10 -0
  218. package/dist/providers/amazonBedrock.js +94 -39
  219. package/dist/providers/anthropic.js +55 -7
  220. package/dist/providers/anthropicBaseProvider.js +1 -1
  221. package/dist/providers/azureOpenai.js +66 -17
  222. package/dist/providers/cloudflare.d.ts +35 -0
  223. package/dist/providers/cloudflare.js +173 -0
  224. package/dist/providers/cohere.d.ts +52 -0
  225. package/dist/providers/cohere.js +252 -0
  226. package/dist/providers/deepseek.js +72 -17
  227. package/dist/providers/fireworks.d.ts +33 -0
  228. package/dist/providers/fireworks.js +163 -0
  229. package/dist/providers/googleAiStudio.js +45 -6
  230. package/dist/providers/googleNativeGemini3.d.ts +24 -1
  231. package/dist/providers/googleNativeGemini3.js +173 -21
  232. package/dist/providers/googleVertex.js +173 -17
  233. package/dist/providers/groq.d.ts +33 -0
  234. package/dist/providers/groq.js +180 -0
  235. package/dist/providers/huggingFace.js +9 -8
  236. package/dist/providers/ideogram.d.ts +34 -0
  237. package/dist/providers/ideogram.js +183 -0
  238. package/dist/providers/index.d.ts +13 -0
  239. package/dist/providers/index.js +13 -0
  240. package/dist/providers/jina.d.ts +59 -0
  241. package/dist/providers/jina.js +217 -0
  242. package/dist/providers/llamaCpp.js +14 -46
  243. package/dist/providers/lmStudio.js +14 -47
  244. package/dist/providers/mistral.js +7 -7
  245. package/dist/providers/nvidiaNim.js +160 -19
  246. package/dist/providers/ollama.js +7 -7
  247. package/dist/providers/openAI.d.ts +22 -1
  248. package/dist/providers/openAI.js +181 -0
  249. package/dist/providers/openRouter.js +35 -23
  250. package/dist/providers/openaiCompatible.js +9 -8
  251. package/dist/providers/perplexity.d.ts +33 -0
  252. package/dist/providers/perplexity.js +178 -0
  253. package/dist/providers/recraft.d.ts +34 -0
  254. package/dist/providers/recraft.js +196 -0
  255. package/dist/providers/replicate.d.ts +75 -0
  256. package/dist/providers/replicate.js +402 -0
  257. package/dist/providers/stability.d.ts +37 -0
  258. package/dist/providers/stability.js +190 -0
  259. package/dist/providers/togetherAi.d.ts +33 -0
  260. package/dist/providers/togetherAi.js +175 -0
  261. package/dist/providers/voyage.d.ts +47 -0
  262. package/dist/providers/voyage.js +176 -0
  263. package/dist/providers/xai.d.ts +33 -0
  264. package/dist/providers/xai.js +171 -0
  265. package/dist/telemetry/index.d.ts +1 -1
  266. package/dist/telemetry/index.js +1 -1
  267. package/dist/telemetry/tracers.d.ts +19 -0
  268. package/dist/telemetry/tracers.js +19 -0
  269. package/dist/telemetry/withSpan.d.ts +35 -0
  270. package/dist/telemetry/withSpan.js +103 -0
  271. package/dist/types/avatar.d.ts +143 -0
  272. package/dist/types/avatar.js +19 -0
  273. package/dist/types/cli.d.ts +6 -0
  274. package/dist/types/generate.d.ts +62 -5
  275. package/dist/types/index.d.ts +5 -0
  276. package/dist/types/index.js +7 -0
  277. package/dist/types/middleware.d.ts +27 -0
  278. package/dist/types/multimodal.d.ts +35 -2
  279. package/dist/types/music.d.ts +165 -0
  280. package/dist/types/music.js +20 -0
  281. package/dist/types/providers.d.ts +144 -1
  282. package/dist/types/replicate.d.ts +67 -0
  283. package/dist/types/replicate.js +9 -0
  284. package/dist/types/safeFetch.d.ts +15 -0
  285. package/dist/types/safeFetch.js +6 -0
  286. package/dist/types/stream.d.ts +2 -1
  287. package/dist/types/tools.d.ts +13 -0
  288. package/dist/types/video.d.ts +89 -0
  289. package/dist/types/video.js +14 -0
  290. package/dist/utils/avatarProcessor.d.ts +68 -0
  291. package/dist/utils/avatarProcessor.js +171 -0
  292. package/dist/utils/cloneOptions.d.ts +36 -0
  293. package/dist/utils/cloneOptions.js +61 -0
  294. package/dist/utils/lifecycleCallbacks.d.ts +51 -8
  295. package/dist/utils/lifecycleCallbacks.js +82 -26
  296. package/dist/utils/lifecycleTimeout.d.ts +25 -0
  297. package/dist/utils/lifecycleTimeout.js +38 -0
  298. package/dist/utils/logSanitize.d.ts +49 -0
  299. package/dist/utils/logSanitize.js +169 -0
  300. package/dist/utils/loggingFetch.d.ts +29 -0
  301. package/dist/utils/loggingFetch.js +59 -0
  302. package/dist/utils/messageBuilder.js +43 -25
  303. package/dist/utils/modelChoices.js +236 -3
  304. package/dist/utils/musicProcessor.d.ts +67 -0
  305. package/dist/utils/musicProcessor.js +188 -0
  306. package/dist/utils/optionsConversion.js +3 -2
  307. package/dist/utils/parameterValidation.js +14 -4
  308. package/dist/utils/pricing.js +193 -0
  309. package/dist/utils/providerConfig.d.ts +55 -0
  310. package/dist/utils/providerConfig.js +224 -0
  311. package/dist/utils/safeFetch.d.ts +26 -0
  312. package/dist/utils/safeFetch.js +82 -0
  313. package/dist/utils/sizeGuard.d.ts +34 -0
  314. package/dist/utils/sizeGuard.js +44 -0
  315. package/dist/utils/ssrfGuard.d.ts +52 -0
  316. package/dist/utils/ssrfGuard.js +410 -0
  317. package/dist/utils/videoProcessor.d.ts +60 -0
  318. package/dist/utils/videoProcessor.js +200 -0
  319. package/dist/voice/providers/FishAudioTTS.d.ts +27 -0
  320. package/dist/voice/providers/FishAudioTTS.js +182 -0
  321. package/dist/workflow/core/ensembleExecutor.js +26 -9
  322. package/package.json +32 -5
@@ -0,0 +1,171 @@
1
+ import { createOpenAI } from "@ai-sdk/openai";
2
+ import { stepCountIs, streamText } from "ai";
3
+ import { XaiModels } from "../constants/enums.js";
4
+ import { BaseProvider } from "../core/baseProvider.js";
5
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
6
+ import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
7
+ import { isNeuroLink } from "../neurolink.js";
8
+ import { createLoggingFetch } from "../utils/loggingFetch.js";
9
+ import { tracers, ATTR, withClientStreamSpan } from "../telemetry/index.js";
10
+ import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
11
+ import { logger } from "../utils/logger.js";
12
+ import { createXaiConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
13
+ import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
14
+ import { emitToolEndFromStepFinish } from "../utils/toolEndEmitter.js";
15
+ import { resolveToolChoice } from "../utils/toolChoice.js";
16
+ import { toAnalyticsStreamResult } from "./providerTypeUtils.js";
17
+ /**
18
+ * Logging fetch wrapper — masks the proxy URL on non-2xx responses so
19
+ * stack traces and log lines don't leak the upstream's internal token /
20
+ * tenant id (mirrors the deepseek/groq/etc. providers).
21
+ */
22
+ const XAI_DEFAULT_BASE_URL = "https://api.x.ai/v1";
23
+ const getXaiApiKey = () => validateApiKey(createXaiConfig());
24
+ const getDefaultXaiModel = () => getProviderModel("XAI_MODEL", XaiModels.GROK_3);
25
+ /**
26
+ * xAI Grok Provider
27
+ *
28
+ * OpenAI-compatible chat completions at api.x.ai/v1. Supports the Grok
29
+ * family: grok-2, grok-3, grok-3-mini, grok-2-vision-latest (multimodal),
30
+ * and grok-beta. Streaming and tool calling supported.
31
+ *
32
+ * @see https://docs.x.ai/api
33
+ */
34
+ export class XaiProvider extends BaseProvider {
35
+ model;
36
+ apiKey;
37
+ baseURL;
38
+ constructor(modelName, sdk, _region, credentials) {
39
+ const validatedNeurolink = isNeuroLink(sdk) ? sdk : undefined;
40
+ super(modelName, "xai", validatedNeurolink);
41
+ const overrideApiKey = credentials?.apiKey?.trim();
42
+ this.apiKey =
43
+ overrideApiKey && overrideApiKey.length > 0
44
+ ? overrideApiKey
45
+ : getXaiApiKey();
46
+ this.baseURL =
47
+ credentials?.baseURL ?? process.env.XAI_BASE_URL ?? XAI_DEFAULT_BASE_URL;
48
+ const xai = createOpenAI({
49
+ apiKey: this.apiKey,
50
+ baseURL: this.baseURL,
51
+ fetch: createLoggingFetch("xai"),
52
+ });
53
+ this.model = xai.chat(this.modelName);
54
+ logger.debug("xAI Provider initialized", {
55
+ modelName: this.modelName,
56
+ providerName: this.providerName,
57
+ baseURL: this.baseURL,
58
+ });
59
+ }
60
+ async executeStream(options, _analysisSchema) {
61
+ return withClientStreamSpan({
62
+ name: "neurolink.provider.stream",
63
+ tracer: tracers.provider,
64
+ attributes: {
65
+ [ATTR.GEN_AI_SYSTEM]: "xai",
66
+ [ATTR.GEN_AI_MODEL]: this.modelName,
67
+ [ATTR.GEN_AI_OPERATION]: "stream",
68
+ [ATTR.NL_STREAM_MODE]: true,
69
+ },
70
+ }, async () => this.executeStreamInner(options), (r) => r.stream, (r, wrapped) => ({ ...r, stream: wrapped }));
71
+ }
72
+ async executeStreamInner(options) {
73
+ this.validateStreamOptions(options);
74
+ const startTime = Date.now();
75
+ const timeout = this.getTimeout(options);
76
+ const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
77
+ try {
78
+ const shouldUseTools = !options.disableTools && this.supportsTools();
79
+ const tools = shouldUseTools
80
+ ? options.tools || (await this.getAllTools())
81
+ : {};
82
+ const messages = await this.buildMessagesForStream(options);
83
+ const model = await this.getAISDKModelWithMiddleware(options);
84
+ const result = await streamText({
85
+ model,
86
+ messages,
87
+ temperature: options.temperature,
88
+ maxOutputTokens: options.maxTokens,
89
+ tools,
90
+ stopWhen: stepCountIs(options.maxSteps || DEFAULT_MAX_STEPS),
91
+ toolChoice: resolveToolChoice(options, tools, shouldUseTools),
92
+ abortSignal: composeAbortSignals(options.abortSignal, timeoutController?.controller.signal),
93
+ experimental_telemetry: this.telemetryHandler.getTelemetryConfig(options),
94
+ experimental_repairToolCall: this.getToolCallRepairFn(options),
95
+ onStepFinish: ({ toolCalls, toolResults }) => {
96
+ emitToolEndFromStepFinish(this.neurolink?.getEventEmitter(), toolResults);
97
+ this.handleToolExecutionStorage(toolCalls, toolResults, options, new Date()).catch((error) => {
98
+ logger.warn("[XaiProvider] Failed to store tool executions", {
99
+ provider: this.providerName,
100
+ error: error instanceof Error ? error.message : String(error),
101
+ });
102
+ });
103
+ },
104
+ });
105
+ timeoutController?.cleanup();
106
+ const transformedStream = this.createTextStream(result);
107
+ const analyticsPromise = streamAnalyticsCollector.createAnalytics(this.providerName, this.modelName, toAnalyticsStreamResult(result), Date.now() - startTime, {
108
+ requestId: `xai-stream-${Date.now()}`,
109
+ streamingMode: true,
110
+ });
111
+ return {
112
+ stream: transformedStream,
113
+ provider: this.providerName,
114
+ model: this.modelName,
115
+ analytics: analyticsPromise,
116
+ metadata: { startTime, streamId: `xai-${Date.now()}` },
117
+ };
118
+ }
119
+ catch (error) {
120
+ timeoutController?.cleanup();
121
+ throw this.handleProviderError(error);
122
+ }
123
+ }
124
+ getProviderName() {
125
+ return this.providerName;
126
+ }
127
+ getDefaultModel() {
128
+ return getDefaultXaiModel();
129
+ }
130
+ getAISDKModel() {
131
+ return this.model;
132
+ }
133
+ formatProviderError(error) {
134
+ if (error instanceof TimeoutError) {
135
+ return new NetworkError(`Request timed out: ${error.message}`, "xai");
136
+ }
137
+ const errorRecord = error;
138
+ const message = typeof errorRecord?.message === "string"
139
+ ? errorRecord.message
140
+ : "Unknown error";
141
+ if (message.includes("Invalid API key") ||
142
+ message.includes("Authentication") ||
143
+ message.includes("401") ||
144
+ message.includes("invalid_api_key")) {
145
+ return new AuthenticationError("Invalid xAI API key. Please check your XAI_API_KEY environment variable. Get one at https://console.x.ai/", "xai");
146
+ }
147
+ if (message.includes("rate limit") || message.includes("429")) {
148
+ return new RateLimitError("xAI rate limit exceeded. Back off and retry.", "xai");
149
+ }
150
+ if (message.includes("model_not_found") || message.includes("404")) {
151
+ return new InvalidModelError(`xAI model '${this.modelName}' not found. Use grok-2-latest, grok-3, grok-3-mini, grok-2-vision-latest, or grok-beta.`, "xai");
152
+ }
153
+ if (message.includes("insufficient_quota") ||
154
+ message.includes("quota exceeded")) {
155
+ return new ProviderError("xAI account has insufficient quota. Top up at https://console.x.ai/", "xai");
156
+ }
157
+ return new ProviderError(`xAI error: ${message}`, "xai");
158
+ }
159
+ async validateConfiguration() {
160
+ return typeof this.apiKey === "string" && this.apiKey.trim().length > 0;
161
+ }
162
+ getConfiguration() {
163
+ return {
164
+ provider: this.providerName,
165
+ model: this.modelName,
166
+ defaultModel: getDefaultXaiModel(),
167
+ baseURL: this.baseURL,
168
+ };
169
+ }
170
+ }
171
+ export default XaiProvider;
@@ -1,6 +1,6 @@
1
1
  export { TelemetryService } from "./telemetryService.js";
2
2
  export { tracers } from "./tracers.js";
3
- export { withSpan, withClientSpan } from "./withSpan.js";
3
+ export { withSpan, withClientSpan, withStreamSpan, withClientStreamSpan, } from "./withSpan.js";
4
4
  export { ATTR } from "./attributes.js";
5
5
  /**
6
6
  * Initialize telemetry for NeuroLink
@@ -1,7 +1,7 @@
1
1
  // Optional Telemetry Infrastructure (Phase 2)
2
2
  export { TelemetryService } from "./telemetryService.js";
3
3
  export { tracers } from "./tracers.js";
4
- export { withSpan, withClientSpan } from "./withSpan.js";
4
+ export { withSpan, withClientSpan, withStreamSpan, withClientStreamSpan, } from "./withSpan.js";
5
5
  export { ATTR } from "./attributes.js";
6
6
  import { logger } from "../utils/logger.js";
7
7
  /**
@@ -1,3 +1,22 @@
1
+ /**
2
+ * Pre-resolved tracers cached at module load.
3
+ *
4
+ * Module-load timing is intentional and safe: `trace.getTracer(name)` from
5
+ * `@opentelemetry/api` always returns a proxy that defers to whatever
6
+ * `TracerProvider` is registered globally at the moment a span is created.
7
+ * If the OTel SDK initializes *after* this module is imported (the common
8
+ * case — telemetry setup typically runs once at app boot, after lazy
9
+ * imports have already pulled this file), the tracer reference is still
10
+ * valid; spans created via it correctly route to the SDK once registered.
11
+ *
12
+ * Pre-SDK calls produce a noop span — `span.end()` etc. are valid; nothing
13
+ * is exported. This is OTel's documented contract:
14
+ * https://opentelemetry.io/docs/specs/otel/trace/api/#tracerprovider
15
+ *
16
+ * If a future refactor moves to a non-proxy TracerProvider API (e.g. a
17
+ * custom provider where `getTracer` returns the live instance), revisit
18
+ * this file and switch to lazy accessors.
19
+ */
1
20
  export declare const tracers: {
2
21
  readonly sdk: import("@opentelemetry/api").Tracer;
3
22
  readonly provider: import("@opentelemetry/api").Tracer;
@@ -1,4 +1,23 @@
1
1
  import { trace } from "@opentelemetry/api";
2
+ /**
3
+ * Pre-resolved tracers cached at module load.
4
+ *
5
+ * Module-load timing is intentional and safe: `trace.getTracer(name)` from
6
+ * `@opentelemetry/api` always returns a proxy that defers to whatever
7
+ * `TracerProvider` is registered globally at the moment a span is created.
8
+ * If the OTel SDK initializes *after* this module is imported (the common
9
+ * case — telemetry setup typically runs once at app boot, after lazy
10
+ * imports have already pulled this file), the tracer reference is still
11
+ * valid; spans created via it correctly route to the SDK once registered.
12
+ *
13
+ * Pre-SDK calls produce a noop span — `span.end()` etc. are valid; nothing
14
+ * is exported. This is OTel's documented contract:
15
+ * https://opentelemetry.io/docs/specs/otel/trace/api/#tracerprovider
16
+ *
17
+ * If a future refactor moves to a non-proxy TracerProvider API (e.g. a
18
+ * custom provider where `getTracer` returns the live instance), revisit
19
+ * this file and switch to lazy accessors.
20
+ */
2
21
  export const tracers = {
3
22
  sdk: trace.getTracer("neurolink"),
4
23
  provider: trace.getTracer("neurolink.provider"),
@@ -2,3 +2,38 @@ import { type Span } from "@opentelemetry/api";
2
2
  import type { SpanOptions } from "../types/index.js";
3
3
  export declare function withSpan<T>(options: SpanOptions, fn: (span: Span) => Promise<T>): Promise<T>;
4
4
  export declare function withClientSpan<T>(options: Omit<SpanOptions, "kind">, fn: (span: Span) => Promise<T>): Promise<T>;
5
+ /**
6
+ * Span wrapper for streaming operations.
7
+ *
8
+ * Unlike {@link withSpan}, which ends the span when `fn` resolves, this
9
+ * helper extends the span's lifetime until the **consumer** of the returned
10
+ * iterable reaches end-of-stream (success), throws (error), or aborts.
11
+ *
12
+ * Required for any operation whose result is a producer (`StreamResult`,
13
+ * `AsyncIterable`-returning function, etc.) — ending the span on `fn`
14
+ * resolution would capture only the setup phase and report zero tokens /
15
+ * meaningless duration.
16
+ *
17
+ * @param options Span options (name, tracer, attributes, kind).
18
+ * @param fn Callback that produces the result. Must NOT depend on
19
+ * the iterable being consumed before returning.
20
+ * @param getIterable Selector that picks the `AsyncIterable` out of the
21
+ * result for wrapping.
22
+ * @param setIterable Setter that returns a new result with the iterable
23
+ * replaced by the wrapped (span-lifetime-extending)
24
+ * iterable. Should be a pure function — clone the
25
+ * result rather than mutating in place.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * return withStreamSpan(
30
+ * { name: "neurolink.provider.stream", tracer, attributes: {...} },
31
+ * async () => this.executeStreamInner(options),
32
+ * (r) => r.stream,
33
+ * (r, wrapped) => ({ ...r, stream: wrapped }),
34
+ * );
35
+ * ```
36
+ */
37
+ export declare function withStreamSpan<TResult, TChunk>(options: SpanOptions, fn: (span: Span) => Promise<TResult>, getIterable: (result: TResult) => AsyncIterable<TChunk>, setIterable: (result: TResult, wrapped: AsyncGenerator<TChunk>) => TResult): Promise<TResult>;
38
+ /** Convenience CLIENT-kind alias matching `withClientSpan`. */
39
+ export declare function withClientStreamSpan<TResult, TChunk>(options: Omit<SpanOptions, "kind">, fn: (span: Span) => Promise<TResult>, getIterable: (result: TResult) => AsyncIterable<TChunk>, setIterable: (result: TResult, wrapped: AsyncGenerator<TChunk>) => TResult): Promise<TResult>;
@@ -32,3 +32,106 @@ export async function withSpan(options, fn) {
32
32
  export async function withClientSpan(options, fn) {
33
33
  return withSpan({ ...options, kind: SpanKind.CLIENT }, fn);
34
34
  }
35
+ /**
36
+ * Span wrapper for streaming operations.
37
+ *
38
+ * Unlike {@link withSpan}, which ends the span when `fn` resolves, this
39
+ * helper extends the span's lifetime until the **consumer** of the returned
40
+ * iterable reaches end-of-stream (success), throws (error), or aborts.
41
+ *
42
+ * Required for any operation whose result is a producer (`StreamResult`,
43
+ * `AsyncIterable`-returning function, etc.) — ending the span on `fn`
44
+ * resolution would capture only the setup phase and report zero tokens /
45
+ * meaningless duration.
46
+ *
47
+ * @param options Span options (name, tracer, attributes, kind).
48
+ * @param fn Callback that produces the result. Must NOT depend on
49
+ * the iterable being consumed before returning.
50
+ * @param getIterable Selector that picks the `AsyncIterable` out of the
51
+ * result for wrapping.
52
+ * @param setIterable Setter that returns a new result with the iterable
53
+ * replaced by the wrapped (span-lifetime-extending)
54
+ * iterable. Should be a pure function — clone the
55
+ * result rather than mutating in place.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * return withStreamSpan(
60
+ * { name: "neurolink.provider.stream", tracer, attributes: {...} },
61
+ * async () => this.executeStreamInner(options),
62
+ * (r) => r.stream,
63
+ * (r, wrapped) => ({ ...r, stream: wrapped }),
64
+ * );
65
+ * ```
66
+ */
67
+ export async function withStreamSpan(options, fn, getIterable, setIterable) {
68
+ const { name, tracer, kind = SpanKind.CLIENT, attributes } = options;
69
+ const span = tracer.startSpan(name, { kind });
70
+ if (attributes) {
71
+ for (const [key, value] of Object.entries(attributes)) {
72
+ if (value !== undefined) {
73
+ span.setAttribute(key, value);
74
+ }
75
+ }
76
+ }
77
+ let result;
78
+ try {
79
+ result = await fn(span);
80
+ }
81
+ catch (error) {
82
+ span.setStatus({
83
+ code: SpanStatusCode.ERROR,
84
+ message: error instanceof Error ? error.message : String(error),
85
+ });
86
+ if (error instanceof Error) {
87
+ span.recordException(error);
88
+ }
89
+ span.end();
90
+ throw error;
91
+ }
92
+ // Setup succeeded. Now wrap the iterable so the span ends with the stream.
93
+ const original = getIterable(result);
94
+ let ended = false;
95
+ const endOnce = (status) => {
96
+ if (ended) {
97
+ return;
98
+ }
99
+ ended = true;
100
+ if (status) {
101
+ span.setStatus(status);
102
+ }
103
+ else {
104
+ span.setStatus({ code: SpanStatusCode.OK });
105
+ }
106
+ span.end();
107
+ };
108
+ // Build an AsyncGenerator (not just an AsyncIterable) so the wrapped
109
+ // value is structurally assignable wherever the original stream type
110
+ // already expected `AsyncGenerator<X>` (e.g. Ollama's executeStream
111
+ // returns `AsyncGenerator<{ content: string }>`).
112
+ const wrapped = (async function* () {
113
+ try {
114
+ for await (const chunk of original) {
115
+ yield chunk;
116
+ }
117
+ endOnce();
118
+ }
119
+ catch (err) {
120
+ // recordException must come BEFORE span.end() — OTel ignores events
121
+ // on ended spans, so flipping the order silently drops the exception.
122
+ if (err instanceof Error) {
123
+ span.recordException(err);
124
+ }
125
+ endOnce({
126
+ code: SpanStatusCode.ERROR,
127
+ message: err instanceof Error ? err.message : String(err),
128
+ });
129
+ throw err;
130
+ }
131
+ })();
132
+ return setIterable(result, wrapped);
133
+ }
134
+ /** Convenience CLIENT-kind alias matching `withClientSpan`. */
135
+ export async function withClientStreamSpan(options, fn, getIterable, setIterable) {
136
+ return withStreamSpan({ ...options, kind: SpanKind.CLIENT }, fn, getIterable, setIterable);
137
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Avatar / Lip-sync Type Definitions
3
+ *
4
+ * Types for generating talking-head videos by combining a portrait image
5
+ * with narration audio (or text routed through a TTS provider first).
6
+ *
7
+ * Avatar is a separate modality from Video — Video is image-to-video
8
+ * (motion synthesis); Avatar is image + audio → lip-synced video.
9
+ *
10
+ * @module types/avatar
11
+ */
12
+ /**
13
+ * Output formats for avatar videos.
14
+ */
15
+ export type AvatarVideoFormat = "mp4" | "webm" | "mov";
16
+ /**
17
+ * Quality presets for avatar generation. Provider-specific mappings:
18
+ * - D-ID: "standard" → 720p, "hd" → 1080p
19
+ * - HeyGen: "standard" → 720p, "hd" → 1080p with enhancement
20
+ * - MuseTalk (Replicate): single quality only; "hd" is no-op
21
+ */
22
+ export type AvatarQuality = "standard" | "hd";
23
+ /**
24
+ * Options for avatar video generation.
25
+ */
26
+ export type AvatarOptions = {
27
+ /** Source portrait image (Buffer, file path, or HTTPS URL). */
28
+ image: Buffer | string;
29
+ /**
30
+ * Audio source — direct lip-sync.
31
+ * Either provide `audio` OR `text` (with optional `ttsProvider` / `voice`).
32
+ */
33
+ audio?: Buffer | string;
34
+ /**
35
+ * Text for the avatar to speak. When provided without `audio`, the
36
+ * NeuroLink dispatcher first runs TTS (`ttsProvider`) to produce audio,
37
+ * then passes the audio to the avatar handler.
38
+ */
39
+ text?: string;
40
+ /** TTS provider for text → audio when `text` is used. Default: "openai-tts". */
41
+ ttsProvider?: string;
42
+ /** Voice id passed through to the TTS provider when `text` is used. */
43
+ voice?: string;
44
+ /** Avatar provider override (e.g. "d-id", "heygen", "replicate"). */
45
+ provider?: string;
46
+ /** Output quality preset. */
47
+ quality?: AvatarQuality;
48
+ /** Output format (default: "mp4"). */
49
+ format?: AvatarVideoFormat;
50
+ /** Output file path (optional — buffer is always returned in the result). */
51
+ output?: string;
52
+ /** Per-call timeout in ms (default: 5 minutes). */
53
+ timeout?: number;
54
+ /** Provider-specific additional options. */
55
+ [key: string]: unknown;
56
+ };
57
+ /**
58
+ * Result of an avatar generation request.
59
+ */
60
+ export type AvatarResult = {
61
+ /** Generated video buffer. */
62
+ buffer: Buffer;
63
+ /** Output format. */
64
+ format: AvatarVideoFormat;
65
+ /** File size in bytes. */
66
+ size: number;
67
+ /** Duration in seconds (when reported by the provider). */
68
+ duration?: number;
69
+ /** Provider used. */
70
+ provider?: string;
71
+ /** Performance / request metadata. */
72
+ metadata?: {
73
+ /** Request latency in milliseconds. */
74
+ latency: number;
75
+ /** Provider name. */
76
+ provider?: string;
77
+ /** Model variant used (when applicable). */
78
+ model?: string;
79
+ /** Job / talk identifier from the upstream. */
80
+ jobId?: string;
81
+ /** Any additional provider-specific metadata. */
82
+ [key: string]: unknown;
83
+ };
84
+ };
85
+ /**
86
+ * Handler contract for avatar / lip-sync providers.
87
+ *
88
+ * Implementations enforce their own timeouts. Recommended:
89
+ * - Per-request fetch timeout: 30 seconds
90
+ * - Total job-completion timeout: 5 minutes
91
+ */
92
+ export type AvatarHandler = {
93
+ /**
94
+ * Generate a talking-head video from an image + audio (or pre-rendered text).
95
+ */
96
+ generate(options: AvatarOptions): Promise<AvatarResult>;
97
+ /** Validate the provider is configured (auth, base URL, etc.). */
98
+ isConfigured(): boolean;
99
+ /** Maximum supported audio length in seconds (provider-specific). */
100
+ readonly maxAudioDurationSeconds?: number;
101
+ /** Output formats supported by this handler. */
102
+ readonly supportedFormats?: readonly AvatarVideoFormat[];
103
+ };
104
+ /**
105
+ * Valid avatar video formats — runtime validation array.
106
+ */
107
+ export declare const VALID_AVATAR_FORMATS: readonly AvatarVideoFormat[];
108
+ /**
109
+ * D-ID `/talks` API response shape.
110
+ *
111
+ * Used by `DIDAvatar` handler to type-check upstream responses. Lives here
112
+ * (in `src/lib/types/`) per CLAUDE.md rule 2; the handler imports it via
113
+ * the types barrel.
114
+ */
115
+ export type DIDTalkResponse = {
116
+ id: string;
117
+ status?: string;
118
+ result_url?: string;
119
+ error?: {
120
+ kind?: string;
121
+ description?: string;
122
+ };
123
+ duration?: number;
124
+ };
125
+ /**
126
+ * HeyGen `/v1/video_status.get` response shape.
127
+ */
128
+ export type HeyGenVideoStatusResponse = {
129
+ code?: number;
130
+ data?: {
131
+ id?: string;
132
+ status?: "pending" | "processing" | "completed" | "failed";
133
+ video_url?: string;
134
+ thumbnail_url?: string;
135
+ duration?: number;
136
+ error?: {
137
+ code?: string;
138
+ message?: string;
139
+ detail?: string;
140
+ };
141
+ };
142
+ message?: string;
143
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Avatar / Lip-sync Type Definitions
3
+ *
4
+ * Types for generating talking-head videos by combining a portrait image
5
+ * with narration audio (or text routed through a TTS provider first).
6
+ *
7
+ * Avatar is a separate modality from Video — Video is image-to-video
8
+ * (motion synthesis); Avatar is image + audio → lip-synced video.
9
+ *
10
+ * @module types/avatar
11
+ */
12
+ /**
13
+ * Valid avatar video formats — runtime validation array.
14
+ */
15
+ export const VALID_AVATAR_FORMATS = [
16
+ "mp4",
17
+ "webm",
18
+ "mov",
19
+ ];
@@ -8,6 +8,8 @@ import type { ToolCall, ToolResult } from "./tools.js";
8
8
  import type { TTSResult } from "./tts.js";
9
9
  import type { VideoGenerationResult } from "./multimodal.js";
10
10
  import type { PPTGenerationResult } from "./ppt.js";
11
+ import type { AvatarResult } from "./avatar.js";
12
+ import type { MusicResult } from "./music.js";
11
13
  import type { OAuthTokens } from "./auth.js";
12
14
  import type { ClaudeSubscriptionTier } from "./subscription.js";
13
15
  import type { ServerFramework } from "./server.js";
@@ -393,6 +395,10 @@ export type CliGenerateResult = CommandResult & {
393
395
  audio?: TTSResult;
394
396
  /** Video generation result when video mode is enabled */
395
397
  video?: VideoGenerationResult;
398
+ /** Avatar (talking-head) generation result when avatar mode is enabled */
399
+ avatar?: AvatarResult;
400
+ /** Music generation result when music mode is enabled */
401
+ music?: MusicResult;
396
402
  /** PPT generation result when ppt mode is enabled */
397
403
  ppt?: PPTGenerationResult;
398
404
  imageOutput?: {