@juspay/neurolink 9.64.0 → 9.65.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) 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 +33 -9
  16. package/dist/agent/directTools.js +11 -3
  17. package/dist/autoresearch/runner.js +8 -2
  18. package/dist/avatar/index.d.ts +13 -0
  19. package/dist/avatar/index.js +13 -0
  20. package/dist/avatar/providers/DIDAvatar.d.ts +49 -0
  21. package/dist/avatar/providers/DIDAvatar.js +501 -0
  22. package/dist/avatar/providers/HeyGenAvatar.d.ts +30 -0
  23. package/dist/avatar/providers/HeyGenAvatar.js +337 -0
  24. package/dist/avatar/providers/ReplicateAvatar.d.ts +36 -0
  25. package/dist/avatar/providers/ReplicateAvatar.js +267 -0
  26. package/dist/browser/neurolink.min.js +624 -601
  27. package/dist/cli/commands/mcp.js +29 -0
  28. package/dist/cli/commands/proxy.js +24 -5
  29. package/dist/cli/factories/commandFactory.d.ts +11 -1
  30. package/dist/cli/factories/commandFactory.js +291 -38
  31. package/dist/constants/contextWindows.js +101 -0
  32. package/dist/constants/enums.d.ts +273 -2
  33. package/dist/constants/enums.js +290 -1
  34. package/dist/constants/videoErrors.d.ts +4 -0
  35. package/dist/constants/videoErrors.js +4 -0
  36. package/dist/core/baseProvider.d.ts +22 -2
  37. package/dist/core/baseProvider.js +217 -11
  38. package/dist/core/constants.d.ts +12 -0
  39. package/dist/core/constants.js +72 -1
  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/agent/directTools.js +11 -3
  61. package/dist/lib/autoresearch/runner.js +8 -2
  62. package/dist/lib/avatar/index.d.ts +13 -0
  63. package/dist/lib/avatar/index.js +14 -0
  64. package/dist/lib/avatar/providers/DIDAvatar.d.ts +49 -0
  65. package/dist/lib/avatar/providers/DIDAvatar.js +502 -0
  66. package/dist/lib/avatar/providers/HeyGenAvatar.d.ts +30 -0
  67. package/dist/lib/avatar/providers/HeyGenAvatar.js +338 -0
  68. package/dist/lib/avatar/providers/ReplicateAvatar.d.ts +36 -0
  69. package/dist/lib/avatar/providers/ReplicateAvatar.js +268 -0
  70. package/dist/lib/constants/contextWindows.js +101 -0
  71. package/dist/lib/constants/enums.d.ts +273 -2
  72. package/dist/lib/constants/enums.js +290 -1
  73. package/dist/lib/constants/videoErrors.d.ts +4 -0
  74. package/dist/lib/constants/videoErrors.js +4 -0
  75. package/dist/lib/core/baseProvider.d.ts +22 -2
  76. package/dist/lib/core/baseProvider.js +217 -11
  77. package/dist/lib/core/constants.d.ts +12 -0
  78. package/dist/lib/core/constants.js +72 -1
  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 +126 -10
  112. package/dist/lib/providers/googleNativeGemini3.d.ts +26 -6
  113. package/dist/lib/providers/googleNativeGemini3.js +276 -29
  114. package/dist/lib/providers/googleVertex.js +639 -181
  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/conversation.d.ts +16 -0
  157. package/dist/lib/types/generate.d.ts +62 -5
  158. package/dist/lib/types/index.d.ts +5 -0
  159. package/dist/lib/types/index.js +7 -0
  160. package/dist/lib/types/middleware.d.ts +27 -0
  161. package/dist/lib/types/multimodal.d.ts +35 -2
  162. package/dist/lib/types/music.d.ts +165 -0
  163. package/dist/lib/types/music.js +21 -0
  164. package/dist/lib/types/providers.d.ts +144 -1
  165. package/dist/lib/types/replicate.d.ts +67 -0
  166. package/dist/lib/types/replicate.js +10 -0
  167. package/dist/lib/types/safeFetch.d.ts +15 -0
  168. package/dist/lib/types/safeFetch.js +7 -0
  169. package/dist/lib/types/stream.d.ts +2 -1
  170. package/dist/lib/types/tools.d.ts +13 -0
  171. package/dist/lib/types/video.d.ts +89 -0
  172. package/dist/lib/types/video.js +15 -0
  173. package/dist/lib/utils/avatarProcessor.d.ts +68 -0
  174. package/dist/lib/utils/avatarProcessor.js +172 -0
  175. package/dist/lib/utils/cloneOptions.d.ts +36 -0
  176. package/dist/lib/utils/cloneOptions.js +62 -0
  177. package/dist/lib/utils/lifecycleCallbacks.d.ts +51 -8
  178. package/dist/lib/utils/lifecycleCallbacks.js +82 -26
  179. package/dist/lib/utils/lifecycleTimeout.d.ts +25 -0
  180. package/dist/lib/utils/lifecycleTimeout.js +39 -0
  181. package/dist/lib/utils/logSanitize.d.ts +49 -0
  182. package/dist/lib/utils/logSanitize.js +170 -0
  183. package/dist/lib/utils/loggingFetch.d.ts +29 -0
  184. package/dist/lib/utils/loggingFetch.js +60 -0
  185. package/dist/lib/utils/messageBuilder.js +43 -25
  186. package/dist/lib/utils/modelChoices.js +236 -3
  187. package/dist/lib/utils/musicProcessor.d.ts +67 -0
  188. package/dist/lib/utils/musicProcessor.js +189 -0
  189. package/dist/lib/utils/optionsConversion.js +3 -2
  190. package/dist/lib/utils/parameterValidation.js +14 -4
  191. package/dist/lib/utils/pricing.js +193 -0
  192. package/dist/lib/utils/providerConfig.d.ts +55 -0
  193. package/dist/lib/utils/providerConfig.js +224 -0
  194. package/dist/lib/utils/safeFetch.d.ts +26 -0
  195. package/dist/lib/utils/safeFetch.js +83 -0
  196. package/dist/lib/utils/sizeGuard.d.ts +34 -0
  197. package/dist/lib/utils/sizeGuard.js +45 -0
  198. package/dist/lib/utils/ssrfGuard.d.ts +52 -0
  199. package/dist/lib/utils/ssrfGuard.js +411 -0
  200. package/dist/lib/utils/videoProcessor.d.ts +60 -0
  201. package/dist/lib/utils/videoProcessor.js +201 -0
  202. package/dist/lib/voice/providers/FishAudioTTS.d.ts +27 -0
  203. package/dist/lib/voice/providers/FishAudioTTS.js +183 -0
  204. package/dist/lib/workflow/core/ensembleExecutor.js +26 -9
  205. package/dist/middleware/builtin/lifecycle.js +39 -9
  206. package/dist/music/index.d.ts +13 -0
  207. package/dist/music/index.js +13 -0
  208. package/dist/music/providers/BeatovenMusic.d.ts +31 -0
  209. package/dist/music/providers/BeatovenMusic.js +333 -0
  210. package/dist/music/providers/ElevenLabsMusic.d.ts +30 -0
  211. package/dist/music/providers/ElevenLabsMusic.js +168 -0
  212. package/dist/music/providers/LyriaMusic.d.ts +29 -0
  213. package/dist/music/providers/LyriaMusic.js +172 -0
  214. package/dist/music/providers/ReplicateMusic.d.ts +31 -0
  215. package/dist/music/providers/ReplicateMusic.js +261 -0
  216. package/dist/neurolink.d.ts +30 -0
  217. package/dist/neurolink.js +323 -77
  218. package/dist/providers/amazonBedrock.d.ts +10 -0
  219. package/dist/providers/amazonBedrock.js +94 -39
  220. package/dist/providers/anthropic.js +55 -7
  221. package/dist/providers/anthropicBaseProvider.js +1 -1
  222. package/dist/providers/azureOpenai.js +66 -17
  223. package/dist/providers/cloudflare.d.ts +35 -0
  224. package/dist/providers/cloudflare.js +173 -0
  225. package/dist/providers/cohere.d.ts +52 -0
  226. package/dist/providers/cohere.js +252 -0
  227. package/dist/providers/deepseek.js +72 -17
  228. package/dist/providers/fireworks.d.ts +33 -0
  229. package/dist/providers/fireworks.js +163 -0
  230. package/dist/providers/googleAiStudio.js +126 -10
  231. package/dist/providers/googleNativeGemini3.d.ts +26 -6
  232. package/dist/providers/googleNativeGemini3.js +276 -29
  233. package/dist/providers/googleVertex.js +639 -181
  234. package/dist/providers/groq.d.ts +33 -0
  235. package/dist/providers/groq.js +180 -0
  236. package/dist/providers/huggingFace.js +9 -8
  237. package/dist/providers/ideogram.d.ts +34 -0
  238. package/dist/providers/ideogram.js +183 -0
  239. package/dist/providers/index.d.ts +13 -0
  240. package/dist/providers/index.js +13 -0
  241. package/dist/providers/jina.d.ts +59 -0
  242. package/dist/providers/jina.js +217 -0
  243. package/dist/providers/llamaCpp.js +14 -46
  244. package/dist/providers/lmStudio.js +14 -47
  245. package/dist/providers/mistral.js +7 -7
  246. package/dist/providers/nvidiaNim.js +160 -19
  247. package/dist/providers/ollama.js +7 -7
  248. package/dist/providers/openAI.d.ts +22 -1
  249. package/dist/providers/openAI.js +181 -0
  250. package/dist/providers/openRouter.js +35 -23
  251. package/dist/providers/openaiCompatible.js +9 -8
  252. package/dist/providers/perplexity.d.ts +33 -0
  253. package/dist/providers/perplexity.js +178 -0
  254. package/dist/providers/recraft.d.ts +34 -0
  255. package/dist/providers/recraft.js +196 -0
  256. package/dist/providers/replicate.d.ts +75 -0
  257. package/dist/providers/replicate.js +402 -0
  258. package/dist/providers/stability.d.ts +37 -0
  259. package/dist/providers/stability.js +190 -0
  260. package/dist/providers/togetherAi.d.ts +33 -0
  261. package/dist/providers/togetherAi.js +175 -0
  262. package/dist/providers/voyage.d.ts +47 -0
  263. package/dist/providers/voyage.js +176 -0
  264. package/dist/providers/xai.d.ts +33 -0
  265. package/dist/providers/xai.js +171 -0
  266. package/dist/telemetry/index.d.ts +1 -1
  267. package/dist/telemetry/index.js +1 -1
  268. package/dist/telemetry/tracers.d.ts +19 -0
  269. package/dist/telemetry/tracers.js +19 -0
  270. package/dist/telemetry/withSpan.d.ts +35 -0
  271. package/dist/telemetry/withSpan.js +103 -0
  272. package/dist/types/avatar.d.ts +143 -0
  273. package/dist/types/avatar.js +19 -0
  274. package/dist/types/cli.d.ts +6 -0
  275. package/dist/types/conversation.d.ts +16 -0
  276. package/dist/types/generate.d.ts +62 -5
  277. package/dist/types/index.d.ts +5 -0
  278. package/dist/types/index.js +7 -0
  279. package/dist/types/middleware.d.ts +27 -0
  280. package/dist/types/multimodal.d.ts +35 -2
  281. package/dist/types/music.d.ts +165 -0
  282. package/dist/types/music.js +20 -0
  283. package/dist/types/providers.d.ts +144 -1
  284. package/dist/types/replicate.d.ts +67 -0
  285. package/dist/types/replicate.js +9 -0
  286. package/dist/types/safeFetch.d.ts +15 -0
  287. package/dist/types/safeFetch.js +6 -0
  288. package/dist/types/stream.d.ts +2 -1
  289. package/dist/types/tools.d.ts +13 -0
  290. package/dist/types/video.d.ts +89 -0
  291. package/dist/types/video.js +14 -0
  292. package/dist/utils/avatarProcessor.d.ts +68 -0
  293. package/dist/utils/avatarProcessor.js +171 -0
  294. package/dist/utils/cloneOptions.d.ts +36 -0
  295. package/dist/utils/cloneOptions.js +61 -0
  296. package/dist/utils/lifecycleCallbacks.d.ts +51 -8
  297. package/dist/utils/lifecycleCallbacks.js +82 -26
  298. package/dist/utils/lifecycleTimeout.d.ts +25 -0
  299. package/dist/utils/lifecycleTimeout.js +38 -0
  300. package/dist/utils/logSanitize.d.ts +49 -0
  301. package/dist/utils/logSanitize.js +169 -0
  302. package/dist/utils/loggingFetch.d.ts +29 -0
  303. package/dist/utils/loggingFetch.js +59 -0
  304. package/dist/utils/messageBuilder.js +43 -25
  305. package/dist/utils/modelChoices.js +236 -3
  306. package/dist/utils/musicProcessor.d.ts +67 -0
  307. package/dist/utils/musicProcessor.js +188 -0
  308. package/dist/utils/optionsConversion.js +3 -2
  309. package/dist/utils/parameterValidation.js +14 -4
  310. package/dist/utils/pricing.js +193 -0
  311. package/dist/utils/providerConfig.d.ts +55 -0
  312. package/dist/utils/providerConfig.js +224 -0
  313. package/dist/utils/safeFetch.d.ts +26 -0
  314. package/dist/utils/safeFetch.js +82 -0
  315. package/dist/utils/sizeGuard.d.ts +34 -0
  316. package/dist/utils/sizeGuard.js +44 -0
  317. package/dist/utils/ssrfGuard.d.ts +52 -0
  318. package/dist/utils/ssrfGuard.js +410 -0
  319. package/dist/utils/videoProcessor.d.ts +60 -0
  320. package/dist/utils/videoProcessor.js +200 -0
  321. package/dist/voice/providers/FishAudioTTS.d.ts +27 -0
  322. package/dist/voice/providers/FishAudioTTS.js +182 -0
  323. package/dist/workflow/core/ensembleExecutor.js +26 -9
  324. package/package.json +32 -5
@@ -0,0 +1,25 @@
1
+ import type { LifecycleMiddlewareConfig } from "../types/index.js";
2
+ /**
3
+ * Default deadline applied to consumer-supplied lifecycle callbacks
4
+ * (`onChunk`, `onFinish`, `onError`) when neither
5
+ * `LifecycleMiddlewareConfig.timeoutMs` nor the
6
+ * `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var is set.
7
+ *
8
+ * 5s is generous — far longer than legitimate sync logging, far
9
+ * shorter than a stuck network call. Callers with slow telemetry
10
+ * sinks should set `timeoutMs` explicitly.
11
+ */
12
+ export declare const DEFAULT_LIFECYCLE_TIMEOUT_MS = 5000;
13
+ /**
14
+ * Resolve the deadline for a single lifecycle callback invocation.
15
+ *
16
+ * Order of precedence:
17
+ * 1. `lifecycle.timeoutMs` from the per-call SDK config
18
+ * 2. `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var (also honored by the CLI)
19
+ * 3. `DEFAULT_LIFECYCLE_TIMEOUT_MS` (5_000)
20
+ *
21
+ * Negative / non-finite values fall through to the next source. `0`
22
+ * is accepted and means "no wait" (the consumer's async work is
23
+ * effectively fire-and-forget).
24
+ */
25
+ export declare function resolveLifecycleTimeoutMs(lifecycle?: Pick<LifecycleMiddlewareConfig, "timeoutMs"> | null): number;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Default deadline applied to consumer-supplied lifecycle callbacks
3
+ * (`onChunk`, `onFinish`, `onError`) when neither
4
+ * `LifecycleMiddlewareConfig.timeoutMs` nor the
5
+ * `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var is set.
6
+ *
7
+ * 5s is generous — far longer than legitimate sync logging, far
8
+ * shorter than a stuck network call. Callers with slow telemetry
9
+ * sinks should set `timeoutMs` explicitly.
10
+ */
11
+ export const DEFAULT_LIFECYCLE_TIMEOUT_MS = 5_000;
12
+ /**
13
+ * Resolve the deadline for a single lifecycle callback invocation.
14
+ *
15
+ * Order of precedence:
16
+ * 1. `lifecycle.timeoutMs` from the per-call SDK config
17
+ * 2. `NEUROLINK_LIFECYCLE_TIMEOUT_MS` env var (also honored by the CLI)
18
+ * 3. `DEFAULT_LIFECYCLE_TIMEOUT_MS` (5_000)
19
+ *
20
+ * Negative / non-finite values fall through to the next source. `0`
21
+ * is accepted and means "no wait" (the consumer's async work is
22
+ * effectively fire-and-forget).
23
+ */
24
+ export function resolveLifecycleTimeoutMs(lifecycle) {
25
+ if (lifecycle && typeof lifecycle.timeoutMs === "number") {
26
+ if (Number.isFinite(lifecycle.timeoutMs) && lifecycle.timeoutMs >= 0) {
27
+ return lifecycle.timeoutMs;
28
+ }
29
+ }
30
+ const raw = process.env.NEUROLINK_LIFECYCLE_TIMEOUT_MS;
31
+ if (raw) {
32
+ const parsed = Number(raw);
33
+ if (Number.isFinite(parsed) && parsed >= 0) {
34
+ return parsed;
35
+ }
36
+ }
37
+ return DEFAULT_LIFECYCLE_TIMEOUT_MS;
38
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Shared log-sanitization helpers.
3
+ *
4
+ * Centralises truncate + secret-redaction patterns so every provider stays
5
+ * consistent and any regex improvements only need one change.
6
+ *
7
+ * Coverage:
8
+ * - `Authorization: Bearer <token>` (with required whitespace)
9
+ * - `Authorization: Token <token>` (Replicate uses this, not Bearer)
10
+ * - `Authorization: Basic <base64>` (D-ID and similar)
11
+ * - Bare tokens by known provider prefix:
12
+ * sk-/pk- (OpenAI, Anthropic, Stability),
13
+ * r8_ (Replicate), gsk_ (Groq), xai- (xAI), tgp_ (Together),
14
+ * fw_ (Fireworks), pplx- (Perplexity), pa- (Voyage),
15
+ * jina_ (Jina), fish- (Fish Audio)
16
+ * - Generic key=value pairs: api_key=…, access_token: …, secret_key=…
17
+ */
18
+ /**
19
+ * Truncate `text` to `maxLen` chars then replace embedded secrets with `***`.
20
+ *
21
+ * Use this for free-form text logged from response/request bodies. For
22
+ * structured data (records, headers) prefer {@link sanitizeRecord} and
23
+ * {@link sanitizeHeaders} which know to redact by key name as well.
24
+ *
25
+ * @param text - Raw text to sanitize (typically an HTTP response body).
26
+ * @param maxLen - Maximum number of characters to keep (default 500).
27
+ */
28
+ export declare function sanitizeForLog(text: string, maxLen?: number): string;
29
+ /**
30
+ * Recursively sanitize a record/array, returning a structurally identical
31
+ * value with sensitive keys redacted and string values run through
32
+ * {@link sanitizeForLog}.
33
+ *
34
+ * Safe to call on any JSON-shaped data. Cycles are detected and replaced
35
+ * with the string `"[Circular]"` to avoid infinite recursion when logging
36
+ * mid-stream objects that reference themselves.
37
+ *
38
+ * @param value - The value to sanitize.
39
+ * @param maxStringLen - Per-string truncation cap (default 1000).
40
+ */
41
+ export declare function sanitizeRecord<T>(value: T, maxStringLen?: number): T;
42
+ /**
43
+ * Sanitize an HTTP headers object — redacts sensitive header names entirely
44
+ * (`***`) and applies {@link sanitizeForLog} to remaining values.
45
+ *
46
+ * Accepts both `Headers` instances and plain-object header maps so providers
47
+ * can log either shape uniformly.
48
+ */
49
+ export declare function sanitizeHeaders(headers: Headers | Record<string, string | undefined> | undefined): Record<string, string>;
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Shared log-sanitization helpers.
3
+ *
4
+ * Centralises truncate + secret-redaction patterns so every provider stays
5
+ * consistent and any regex improvements only need one change.
6
+ *
7
+ * Coverage:
8
+ * - `Authorization: Bearer <token>` (with required whitespace)
9
+ * - `Authorization: Token <token>` (Replicate uses this, not Bearer)
10
+ * - `Authorization: Basic <base64>` (D-ID and similar)
11
+ * - Bare tokens by known provider prefix:
12
+ * sk-/pk- (OpenAI, Anthropic, Stability),
13
+ * r8_ (Replicate), gsk_ (Groq), xai- (xAI), tgp_ (Together),
14
+ * fw_ (Fireworks), pplx- (Perplexity), pa- (Voyage),
15
+ * jina_ (Jina), fish- (Fish Audio)
16
+ * - Generic key=value pairs: api_key=…, access_token: …, secret_key=…
17
+ */
18
+ const TOKEN_PREFIXES = [
19
+ "sk",
20
+ "pk",
21
+ "r8",
22
+ "gsk",
23
+ "xai",
24
+ "tgp",
25
+ "fw",
26
+ "pplx",
27
+ "pa",
28
+ "jina",
29
+ "fish",
30
+ ];
31
+ const PREFIX_PATTERN = TOKEN_PREFIXES.join("|");
32
+ /**
33
+ * Pattern matching common bearer/API-key tokens in plain text.
34
+ *
35
+ * Case-insensitive (`i` flag) since header names ("Authorization") and scheme
36
+ * names ("Bearer", "Token", "Basic") are sometimes lower-cased in error
37
+ * bodies. `g` flag for replace-all.
38
+ */
39
+ const SECRET_PATTERN = new RegExp(
40
+ // Authorization schemes — required whitespace between scheme and value
41
+ "\\bBearer\\s+[A-Za-z0-9_\\-\\.]{8,}\\b" +
42
+ "|\\bToken\\s+[A-Za-z0-9_\\-\\.]{8,}\\b" +
43
+ "|\\bBasic\\s+[A-Za-z0-9+/=]{12,}\\b" +
44
+ // Bare tokens by known prefix (e.g. `sk-abc…`, `r8_xyz…`)
45
+ `|\\b(?:${PREFIX_PATTERN})[_\\-][A-Za-z0-9_\\-\\.]{8,}\\b` +
46
+ // Generic key=value pairs (URL params, JSON bodies, header dumps)
47
+ "|\\b(?:api[_-]?key|access[_-]?token|secret[_-]?key|refresh[_-]?token)\\s*[:=]\\s*['\"]?[^\\s,;'\"&]+", "gi");
48
+ /** Header names that should always be redacted regardless of value shape. */
49
+ const SENSITIVE_HEADER_NAMES = [
50
+ "authorization",
51
+ "cookie",
52
+ "set-cookie",
53
+ "x-api-key",
54
+ "api-key",
55
+ "apikey",
56
+ "x-auth-token",
57
+ "x-csrf-token",
58
+ ];
59
+ /** Object keys that should always be redacted regardless of value shape. */
60
+ const SENSITIVE_OBJECT_KEYS = [
61
+ "apikey",
62
+ "api_key",
63
+ "apiKey",
64
+ "access_token",
65
+ "accessToken",
66
+ "refresh_token",
67
+ "refreshToken",
68
+ "secret",
69
+ "secretkey",
70
+ "secret_key",
71
+ "secretKey",
72
+ "password",
73
+ "authorization",
74
+ "oauth",
75
+ "oauthToken",
76
+ "credentials",
77
+ ];
78
+ /**
79
+ * Truncate `text` to `maxLen` chars then replace embedded secrets with `***`.
80
+ *
81
+ * Use this for free-form text logged from response/request bodies. For
82
+ * structured data (records, headers) prefer {@link sanitizeRecord} and
83
+ * {@link sanitizeHeaders} which know to redact by key name as well.
84
+ *
85
+ * @param text - Raw text to sanitize (typically an HTTP response body).
86
+ * @param maxLen - Maximum number of characters to keep (default 500).
87
+ */
88
+ export function sanitizeForLog(text, maxLen = 500) {
89
+ if (!text) {
90
+ return text;
91
+ }
92
+ return text.slice(0, maxLen).replace(SECRET_PATTERN, "***");
93
+ }
94
+ /**
95
+ * Recursively sanitize a record/array, returning a structurally identical
96
+ * value with sensitive keys redacted and string values run through
97
+ * {@link sanitizeForLog}.
98
+ *
99
+ * Safe to call on any JSON-shaped data. Cycles are detected and replaced
100
+ * with the string `"[Circular]"` to avoid infinite recursion when logging
101
+ * mid-stream objects that reference themselves.
102
+ *
103
+ * @param value - The value to sanitize.
104
+ * @param maxStringLen - Per-string truncation cap (default 1000).
105
+ */
106
+ export function sanitizeRecord(value, maxStringLen = 1000) {
107
+ const seen = new WeakSet();
108
+ const walk = (v) => {
109
+ if (v === null || v === undefined) {
110
+ return v;
111
+ }
112
+ if (typeof v === "string") {
113
+ return sanitizeForLog(v, maxStringLen);
114
+ }
115
+ if (typeof v !== "object") {
116
+ return v;
117
+ }
118
+ if (seen.has(v)) {
119
+ return "[Circular]";
120
+ }
121
+ seen.add(v);
122
+ if (Array.isArray(v)) {
123
+ return v.map(walk);
124
+ }
125
+ const out = {};
126
+ for (const [k, val] of Object.entries(v)) {
127
+ if (SENSITIVE_OBJECT_KEYS.some((name) => name.toLowerCase() === k.toLowerCase())) {
128
+ out[k] = "***";
129
+ }
130
+ else {
131
+ out[k] = walk(val);
132
+ }
133
+ }
134
+ return out;
135
+ };
136
+ return walk(value);
137
+ }
138
+ /**
139
+ * Sanitize an HTTP headers object — redacts sensitive header names entirely
140
+ * (`***`) and applies {@link sanitizeForLog} to remaining values.
141
+ *
142
+ * Accepts both `Headers` instances and plain-object header maps so providers
143
+ * can log either shape uniformly.
144
+ */
145
+ export function sanitizeHeaders(headers) {
146
+ if (!headers) {
147
+ return {};
148
+ }
149
+ const out = {};
150
+ const set = (name, value) => {
151
+ if (value === undefined || value === null) {
152
+ return;
153
+ }
154
+ const lower = name.toLowerCase();
155
+ if (SENSITIVE_HEADER_NAMES.includes(lower)) {
156
+ out[name] = "***";
157
+ return;
158
+ }
159
+ out[name] = sanitizeForLog(value, 500);
160
+ };
161
+ if (headers instanceof Headers) {
162
+ headers.forEach((value, key) => set(key, value));
163
+ return out;
164
+ }
165
+ for (const [key, value] of Object.entries(headers)) {
166
+ set(key, value);
167
+ }
168
+ return out;
169
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared logging-fetch wrapper.
3
+ *
4
+ * Wraps `createProxyFetch()` and logs every non-2xx upstream response with:
5
+ * - provider label
6
+ * - HTTP status code
7
+ * - URL with embedded credentials / signed query params masked
8
+ * (via `maskProxyUrl`)
9
+ * - request body size (string-body only — multipart/streamed bodies
10
+ * report 0)
11
+ *
12
+ * Response bodies are NOT logged by default (they can echo prompt fragments,
13
+ * tool payloads, or echoed auth tokens). Set `NEUROLINK_DEBUG_HTTP=1` to opt
14
+ * into body logging — and even then bodies are run through `sanitizeForLog`
15
+ * to redact `Bearer …`, `sk-…`, `Token …`, and the other 11 token formats
16
+ * covered by `logSanitize.SECRET_PATTERN`.
17
+ *
18
+ * Previously this same function was hand-rolled in 11 provider files
19
+ * (cohere, xai, groq, togetherAi, fireworks, perplexity, cloudflare,
20
+ * llamaCpp, lmStudio, nvidiaNim, deepseek) with subtly different bodies.
21
+ * Extracting it kills the drift risk and gives a single place to harden.
22
+ *
23
+ * @module utils/loggingFetch
24
+ */
25
+ /**
26
+ * Construct a fetch-compatible function that logs upstream non-OK responses
27
+ * under the given provider label.
28
+ */
29
+ export declare function createLoggingFetch(provider: string): typeof fetch;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared logging-fetch wrapper.
3
+ *
4
+ * Wraps `createProxyFetch()` and logs every non-2xx upstream response with:
5
+ * - provider label
6
+ * - HTTP status code
7
+ * - URL with embedded credentials / signed query params masked
8
+ * (via `maskProxyUrl`)
9
+ * - request body size (string-body only — multipart/streamed bodies
10
+ * report 0)
11
+ *
12
+ * Response bodies are NOT logged by default (they can echo prompt fragments,
13
+ * tool payloads, or echoed auth tokens). Set `NEUROLINK_DEBUG_HTTP=1` to opt
14
+ * into body logging — and even then bodies are run through `sanitizeForLog`
15
+ * to redact `Bearer …`, `sk-…`, `Token …`, and the other 11 token formats
16
+ * covered by `logSanitize.SECRET_PATTERN`.
17
+ *
18
+ * Previously this same function was hand-rolled in 11 provider files
19
+ * (cohere, xai, groq, togetherAi, fireworks, perplexity, cloudflare,
20
+ * llamaCpp, lmStudio, nvidiaNim, deepseek) with subtly different bodies.
21
+ * Extracting it kills the drift risk and gives a single place to harden.
22
+ *
23
+ * @module utils/loggingFetch
24
+ */
25
+ import { createProxyFetch, maskProxyUrl } from "../proxy/proxyFetch.js";
26
+ import { logger } from "./logger.js";
27
+ import { sanitizeForLog } from "./logSanitize.js";
28
+ /**
29
+ * Construct a fetch-compatible function that logs upstream non-OK responses
30
+ * under the given provider label.
31
+ */
32
+ export function createLoggingFetch(provider) {
33
+ const base = createProxyFetch();
34
+ return (async (input, init) => {
35
+ const url = typeof input === "string"
36
+ ? input
37
+ : input instanceof URL
38
+ ? input.toString()
39
+ : input.url;
40
+ const reqSize = init?.body && typeof init.body === "string" ? init.body.length : 0;
41
+ const response = await base(input, init);
42
+ if (!response.ok) {
43
+ const safeUrl = maskProxyUrl(url) ?? "<redacted>";
44
+ if (process.env.NEUROLINK_DEBUG_HTTP === "1") {
45
+ const clone = response.clone();
46
+ const raw = await clone.text().catch(() => "<unreadable>");
47
+ logger.warn(`[${provider}] upstream ${response.status}`, {
48
+ url: safeUrl,
49
+ body: sanitizeForLog(raw),
50
+ reqSize,
51
+ });
52
+ }
53
+ else {
54
+ logger.warn(`[${provider}] upstream ${response.status} url=${safeUrl} reqSize=${reqSize}`);
55
+ }
56
+ }
57
+ return response;
58
+ });
59
+ }
@@ -602,6 +602,7 @@ export async function buildMessagesArray(options) {
602
602
  * Mutates options.input.files and options.input.text as needed.
603
603
  */
604
604
  function enforceFileBudget(options, provider, model) {
605
+ options.input ??= {};
605
606
  if (!options.input.files || options.input.files.length === 0) {
606
607
  return;
607
608
  }
@@ -659,6 +660,7 @@ function enforceFileBudget(options, provider, model) {
659
660
  * Handles CSV, SVG, image, PDF, video, audio, archive, xlsx, docx, pptx, text, and unknown types.
660
661
  */
661
662
  function appendDetectedFileResult(result, file, options) {
663
+ options.input ??= {};
662
664
  const filename = extractFilename(file);
663
665
  if (result.type === "csv") {
664
666
  const filePath = typeof file === "string" ? file : filename;
@@ -786,6 +788,7 @@ function appendDetectedFileResult(result, file, options) {
786
788
  * would silently never reach the model on those paths.
787
789
  */
788
790
  export async function processUnifiedFilesArray(options, maxSize, provider) {
791
+ options.input ??= {};
789
792
  if (!options.input.files || options.input.files.length === 0) {
790
793
  return;
791
794
  }
@@ -800,7 +803,12 @@ export async function processUnifiedFilesArray(options, maxSize, provider) {
800
803
  },
801
804
  }, async (span) => {
802
805
  logger.info(`[NEUROLINK] Processing ${totalFiles} file(s) with auto-detection`);
803
- options.input.text = options.input.text || "";
806
+ // `options.input` was guaranteed non-null by the `??= {}` guard at the
807
+ // top of processUnifiedFilesArray; re-assert here so TypeScript is happy
808
+ // inside this withSpan closure (it doesn't track mutations across closures).
809
+ options.input ??= {};
810
+ const inp2 = options.input;
811
+ inp2.text = inp2.text || "";
804
812
  let includedCount = 0;
805
813
  const fileRegistry = options.fileRegistry;
806
814
  for (let fileIdx = 0; fileIdx < files.length; fileIdx++) {
@@ -862,16 +870,13 @@ export async function processUnifiedFilesArray(options, maxSize, provider) {
862
870
  if (fileRegistry && fileRegistry.size > 0) {
863
871
  const previewText = await fileRegistry.generatePromptPreview();
864
872
  if (previewText) {
865
- options.input.text = (options.input.text || "") + previewText;
873
+ inp2.text = (inp2.text || "") + previewText;
866
874
  logger.info(`[FileDetector] Injected previews for ${fileRegistry.size} lazily-registered file(s)`);
867
875
  }
868
876
  const registeredFiles = fileRegistry.list();
869
877
  for (const ref of registeredFiles) {
870
878
  if (ref.extractedImages && ref.extractedImages.length > 0) {
871
- options.input.images = [
872
- ...(options.input.images || []),
873
- ...ref.extractedImages,
874
- ];
879
+ inp2.images = [...(inp2.images || []), ...ref.extractedImages];
875
880
  logger.info(`[FileDetector] Injected ${ref.extractedImages.length} extracted images from "${ref.filename}"`);
876
881
  }
877
882
  }
@@ -901,6 +906,7 @@ export async function processUnifiedFilesArray(options, maxSize, provider) {
901
906
  * Process explicit CSV files array and append to options.input.text.
902
907
  */
903
908
  async function processExplicitCsvFiles(options) {
909
+ options.input ??= {};
904
910
  if (!options.input.csvFiles || options.input.csvFiles.length === 0) {
905
911
  return;
906
912
  }
@@ -942,6 +948,7 @@ async function processExplicitCsvFiles(options) {
942
948
  * Enforce post-processing budget on accumulated text content and log token usage.
943
949
  */
944
950
  function enforcePostProcessingBudget(options, provider, model) {
951
+ options.input ??= {};
945
952
  if (!options.input.text) {
946
953
  return;
947
954
  }
@@ -980,6 +987,7 @@ function enforcePostProcessingBudget(options, provider, model) {
980
987
  * Process explicit PDF files and return structured PDF entries for multimodal processing.
981
988
  */
982
989
  async function processExplicitPdfFiles(options, maxSize, provider) {
990
+ options.input ??= {};
983
991
  const pdfFiles = [];
984
992
  if (!options.input.pdfFiles || options.input.pdfFiles.length === 0) {
985
993
  return pdfFiles;
@@ -1015,6 +1023,7 @@ async function processExplicitPdfFiles(options, maxSize, provider) {
1015
1023
  * conversation instructions, structured output instructions, and file handling guidance.
1016
1024
  */
1017
1025
  function buildMultimodalSystemPrompt(options, hasPDFFiles) {
1026
+ options.input ??= {};
1018
1027
  let systemPrompt = options.systemPrompt?.trim() || "";
1019
1028
  const hasConversationHistory = options.conversationHistory && options.conversationHistory.length > 0;
1020
1029
  if (hasConversationHistory) {
@@ -1023,9 +1032,10 @@ function buildMultimodalSystemPrompt(options, hasPDFFiles) {
1023
1032
  if (shouldUseStructuredOutput(options)) {
1024
1033
  systemPrompt = `${systemPrompt.trim()}${STRUCTURED_OUTPUT_INSTRUCTIONS}`;
1025
1034
  }
1026
- const hasCSVFiles = (options.input.csvFiles && options.input.csvFiles.length > 0) ||
1027
- (options.input.files &&
1028
- options.input.files.some((f) => typeof f === "string" ? f.toLowerCase().endsWith(".csv") : false));
1035
+ const inp = options.input;
1036
+ const hasCSVFiles = (inp.csvFiles && inp.csvFiles.length > 0) ||
1037
+ (inp.files &&
1038
+ inp.files.some((f) => typeof f === "string" ? f.toLowerCase().endsWith(".csv") : false));
1029
1039
  if (hasCSVFiles || hasPDFFiles) {
1030
1040
  const fileTypes = [];
1031
1041
  if (hasPDFFiles) {
@@ -1049,6 +1059,16 @@ function buildMultimodalSystemPrompt(options, hasPDFFiles) {
1049
1059
  * Detects when images are present and routes through provider adapter
1050
1060
  */
1051
1061
  export async function buildMultimodalMessagesArray(options, provider, model) {
1062
+ // Media-only callers (avatar / music / video) may omit `input` entirely.
1063
+ // Normalise to an empty object so all sub-functions can access input.*
1064
+ // without defensive null checks on every field access.
1065
+ if (!options.input) {
1066
+ options.input = {};
1067
+ }
1068
+ // After normalisation `input` is guaranteed non-undefined. Capture it in a
1069
+ // local const so TypeScript sees the definite (non-optional) type in the
1070
+ // rest of this function, avoiding 60+ "possibly undefined" errors.
1071
+ const inp = options.input;
1052
1072
  // Compute provider-specific max PDF size once for consistent validation
1053
1073
  const pdfConfig = PDFProcessor.getProviderConfig(provider);
1054
1074
  const maxSize = pdfConfig
@@ -1065,20 +1085,19 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1065
1085
  // Process explicit PDF files
1066
1086
  const pdfFiles = await processExplicitPdfFiles(options, maxSize, provider);
1067
1087
  // Check if this is a multimodal request
1068
- const hasImages = (options.input.images && options.input.images.length > 0) ||
1069
- (options.input.content &&
1070
- options.input.content.some((c) => c.type === "image"));
1088
+ const hasImages = (inp.images && inp.images.length > 0) ||
1089
+ (inp.content && inp.content.some((c) => c.type === "image"));
1071
1090
  const hasPDFs = pdfFiles.length > 0;
1072
1091
  // If no images or PDFs, use standard message building and convert to MultimodalChatMessage[]
1073
1092
  if (!hasImages && !hasPDFs) {
1074
- if (options.input.csvFiles) {
1075
- options.input.csvFiles = [];
1093
+ if (inp.csvFiles) {
1094
+ inp.csvFiles = [];
1076
1095
  }
1077
- if (options.input.pdfFiles) {
1078
- options.input.pdfFiles = [];
1096
+ if (inp.pdfFiles) {
1097
+ inp.pdfFiles = [];
1079
1098
  }
1080
- if (options.input.files) {
1081
- options.input.files = [];
1099
+ if (inp.files) {
1100
+ inp.files = [];
1082
1101
  }
1083
1102
  const standardMessages = await buildMessagesArray(options);
1084
1103
  return standardMessages.map((msg) => {
@@ -1163,15 +1182,14 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1163
1182
  // Handle multimodal content
1164
1183
  try {
1165
1184
  let userContent;
1166
- if (options.input.content && options.input.content.length > 0) {
1167
- userContent = await convertContentToProviderFormat(options.input.content, provider, model);
1185
+ if (inp.content && inp.content.length > 0) {
1186
+ userContent = await convertContentToProviderFormat(inp.content, provider, model);
1168
1187
  }
1169
- else if ((options.input.images && options.input.images.length > 0) ||
1170
- pdfFiles.length > 0) {
1171
- userContent = await convertMultimodalToProviderFormat(options.input.text, options.input.images || [], pdfFiles, provider, model);
1188
+ else if ((inp.images && inp.images.length > 0) || pdfFiles.length > 0) {
1189
+ userContent = await convertMultimodalToProviderFormat(inp.text ?? "", inp.images || [], pdfFiles, provider, model);
1172
1190
  }
1173
1191
  else {
1174
- userContent = options.input.text;
1192
+ userContent = inp.text;
1175
1193
  }
1176
1194
  if (typeof userContent === "string") {
1177
1195
  messages.push({
@@ -1195,7 +1213,7 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1195
1213
  provider,
1196
1214
  model,
1197
1215
  hasImages,
1198
- imageCount: options.input.images?.length || 0,
1216
+ imageCount: inp.images?.length || 0,
1199
1217
  });
1200
1218
  throw error;
1201
1219
  }