@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
@@ -0,0 +1,170 @@
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
+ }
170
+ //# sourceMappingURL=logSanitize.js.map
@@ -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,60 @@
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
+ }
60
+ //# sourceMappingURL=loggingFetch.js.map
@@ -17,6 +17,16 @@ export declare function convertToModelMessages(messages: MultimodalChatMessage[]
17
17
  * Enhanced with CSV file processing support
18
18
  */
19
19
  export declare function buildMessagesArray(options: TextGenerationOptions | StreamOptions): Promise<ModelMessage[]>;
20
+ /**
21
+ * Process the unified files array with auto-detection.
22
+ * Handles lazy file registration, full processing, and preview injection.
23
+ *
24
+ * Exported so providers that bypass BaseProvider.generate() (e.g.
25
+ * GoogleVertex's native @google/genai path) can still preprocess
26
+ * `input.files` — without this, mimetype-hint and text-file inputs
27
+ * would silently never reach the model on those paths.
28
+ */
29
+ export declare function processUnifiedFilesArray(options: GenerateOptions, maxSize: number, provider: string): Promise<void>;
20
30
  /**
21
31
  * Build multimodal message array with image support
22
32
  * Detects when images are present and routes through provider adapter
@@ -534,8 +534,13 @@ export async function buildMessagesArray(options) {
534
534
  csvSection += metadataText + `\n\n`;
535
535
  }
536
536
  }
537
- csvSection += buildCSVToolInstructions(filePath);
537
+ // Put the actual CSV content BEFORE the tool instructions —
538
+ // buildCSVToolInstructions references "the CSV data shown above"
539
+ // and the trailing position keeps that reference accurate.
540
+ // Vertex Gemini misreads CSV-only prompts as "no files attached"
541
+ // when the NOTE-then-data order makes the reference dangle.
538
542
  csvSection += result.content;
543
+ csvSection += buildCSVToolInstructions(filePath);
539
544
  csvContent += csvSection;
540
545
  logger.info(`[CSV] ✅ Processed: ${filename}`, result.metadata);
541
546
  }
@@ -597,6 +602,7 @@ export async function buildMessagesArray(options) {
597
602
  * Mutates options.input.files and options.input.text as needed.
598
603
  */
599
604
  function enforceFileBudget(options, provider, model) {
605
+ options.input ??= {};
600
606
  if (!options.input.files || options.input.files.length === 0) {
601
607
  return;
602
608
  }
@@ -654,6 +660,7 @@ function enforceFileBudget(options, provider, model) {
654
660
  * Handles CSV, SVG, image, PDF, video, audio, archive, xlsx, docx, pptx, text, and unknown types.
655
661
  */
656
662
  function appendDetectedFileResult(result, file, options) {
663
+ options.input ??= {};
657
664
  const filename = extractFilename(file);
658
665
  if (result.type === "csv") {
659
666
  const filePath = typeof file === "string" ? file : filename;
@@ -664,8 +671,11 @@ function appendDetectedFileResult(result, file, options) {
664
671
  csvSection += metadataText + `\n\n`;
665
672
  }
666
673
  }
667
- csvSection += buildCSVToolInstructions(filePath);
674
+ // Put the actual CSV content BEFORE the tool instructions —
675
+ // buildCSVToolInstructions references "the CSV data shown above" and
676
+ // the trailing position keeps that reference accurate.
668
677
  csvSection += result.content;
678
+ csvSection += buildCSVToolInstructions(filePath);
669
679
  options.input.text += csvSection;
670
680
  logger.info(`[FileDetector] ✅ CSV: ${filename}`);
671
681
  }
@@ -771,8 +781,14 @@ function appendDetectedFileResult(result, file, options) {
771
781
  /**
772
782
  * Process the unified files array with auto-detection.
773
783
  * Handles lazy file registration, full processing, and preview injection.
784
+ *
785
+ * Exported so providers that bypass BaseProvider.generate() (e.g.
786
+ * GoogleVertex's native @google/genai path) can still preprocess
787
+ * `input.files` — without this, mimetype-hint and text-file inputs
788
+ * would silently never reach the model on those paths.
774
789
  */
775
- async function processUnifiedFilesArray(options, maxSize, provider) {
790
+ export async function processUnifiedFilesArray(options, maxSize, provider) {
791
+ options.input ??= {};
776
792
  if (!options.input.files || options.input.files.length === 0) {
777
793
  return;
778
794
  }
@@ -787,7 +803,12 @@ async function processUnifiedFilesArray(options, maxSize, provider) {
787
803
  },
788
804
  }, async (span) => {
789
805
  logger.info(`[NEUROLINK] Processing ${totalFiles} file(s) with auto-detection`);
790
- 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 || "";
791
812
  let includedCount = 0;
792
813
  const fileRegistry = options.fileRegistry;
793
814
  for (let fileIdx = 0; fileIdx < files.length; fileIdx++) {
@@ -849,27 +870,43 @@ async function processUnifiedFilesArray(options, maxSize, provider) {
849
870
  if (fileRegistry && fileRegistry.size > 0) {
850
871
  const previewText = await fileRegistry.generatePromptPreview();
851
872
  if (previewText) {
852
- options.input.text = (options.input.text || "") + previewText;
873
+ inp2.text = (inp2.text || "") + previewText;
853
874
  logger.info(`[FileDetector] Injected previews for ${fileRegistry.size} lazily-registered file(s)`);
854
875
  }
855
876
  const registeredFiles = fileRegistry.list();
856
877
  for (const ref of registeredFiles) {
857
878
  if (ref.extractedImages && ref.extractedImages.length > 0) {
858
- options.input.images = [
859
- ...(options.input.images || []),
860
- ...ref.extractedImages,
861
- ];
879
+ inp2.images = [...(inp2.images || []), ...ref.extractedImages];
862
880
  logger.info(`[FileDetector] Injected ${ref.extractedImages.length} extracted images from "${ref.filename}"`);
863
881
  }
864
882
  }
865
883
  }
866
884
  logger.info(`[NEUROLINK] File processing complete: ${includedCount}/${totalFiles} files included in message`);
885
+ // Augment options.systemPrompt with file-handling guidance so providers
886
+ // that bypass the message-builder's system message and read
887
+ // `options.systemPrompt` directly (e.g. GoogleVertex's native @google/genai
888
+ // path uses `config.systemInstruction = options.systemPrompt`) still see
889
+ // the "treat inlined CSV/PDF as the actual file" guidance. Without this,
890
+ // Vertex Gemini 2.5 reliably responds with "no files attached" even
891
+ // though the CSV content is fully embedded in the user prompt.
892
+ if (includedCount > 0) {
893
+ const filePromptAugmentation = `\n\nIMPORTANT FILE HANDLING INSTRUCTIONS:
894
+ - The full content of the user's local file(s) is INLINED in this message under "## CSV Data from ..." / "## PDF Data from ..." / "## File: ..." headings — it is the actual file the user is asking about.
895
+ - TREAT THE INLINED CONTENT AS IF IT WERE AN ATTACHMENT. Do NOT respond with "no files attached" or ask the user to re-upload — the data is already here.
896
+ - DO NOT use GitHub tools (get_file_contents, search_code, etc.) for local files - they only work for remote repository files.
897
+ - Analyze the inlined file content directly without attempting to fetch or read files using tools.`;
898
+ const existingSystem = (options.systemPrompt || "").trim();
899
+ options.systemPrompt = existingSystem
900
+ ? `${existingSystem}${filePromptAugmentation}`
901
+ : filePromptAugmentation.trim();
902
+ }
867
903
  });
868
904
  }
869
905
  /**
870
906
  * Process explicit CSV files array and append to options.input.text.
871
907
  */
872
908
  async function processExplicitCsvFiles(options) {
909
+ options.input ??= {};
873
910
  if (!options.input.csvFiles || options.input.csvFiles.length === 0) {
874
911
  return;
875
912
  }
@@ -891,8 +928,11 @@ async function processExplicitCsvFiles(options) {
891
928
  csvSection += metadataText + `\n\n`;
892
929
  }
893
930
  }
894
- csvSection += buildCSVToolInstructions(filePath);
931
+ // Put the actual CSV content BEFORE the tool instructions —
932
+ // buildCSVToolInstructions references "the CSV data shown above"
933
+ // and the trailing position keeps that reference accurate.
895
934
  csvSection += result.content;
935
+ csvSection += buildCSVToolInstructions(filePath);
896
936
  options.input.text += csvSection;
897
937
  logger.info(`[CSV] ✅ Processed: ${filename}`);
898
938
  }
@@ -908,6 +948,7 @@ async function processExplicitCsvFiles(options) {
908
948
  * Enforce post-processing budget on accumulated text content and log token usage.
909
949
  */
910
950
  function enforcePostProcessingBudget(options, provider, model) {
951
+ options.input ??= {};
911
952
  if (!options.input.text) {
912
953
  return;
913
954
  }
@@ -946,6 +987,7 @@ function enforcePostProcessingBudget(options, provider, model) {
946
987
  * Process explicit PDF files and return structured PDF entries for multimodal processing.
947
988
  */
948
989
  async function processExplicitPdfFiles(options, maxSize, provider) {
990
+ options.input ??= {};
949
991
  const pdfFiles = [];
950
992
  if (!options.input.pdfFiles || options.input.pdfFiles.length === 0) {
951
993
  return pdfFiles;
@@ -981,6 +1023,7 @@ async function processExplicitPdfFiles(options, maxSize, provider) {
981
1023
  * conversation instructions, structured output instructions, and file handling guidance.
982
1024
  */
983
1025
  function buildMultimodalSystemPrompt(options, hasPDFFiles) {
1026
+ options.input ??= {};
984
1027
  let systemPrompt = options.systemPrompt?.trim() || "";
985
1028
  const hasConversationHistory = options.conversationHistory && options.conversationHistory.length > 0;
986
1029
  if (hasConversationHistory) {
@@ -989,9 +1032,10 @@ function buildMultimodalSystemPrompt(options, hasPDFFiles) {
989
1032
  if (shouldUseStructuredOutput(options)) {
990
1033
  systemPrompt = `${systemPrompt.trim()}${STRUCTURED_OUTPUT_INSTRUCTIONS}`;
991
1034
  }
992
- const hasCSVFiles = (options.input.csvFiles && options.input.csvFiles.length > 0) ||
993
- (options.input.files &&
994
- 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));
995
1039
  if (hasCSVFiles || hasPDFFiles) {
996
1040
  const fileTypes = [];
997
1041
  if (hasPDFFiles) {
@@ -1001,7 +1045,8 @@ function buildMultimodalSystemPrompt(options, hasPDFFiles) {
1001
1045
  fileTypes.push("CSVs");
1002
1046
  }
1003
1047
  systemPrompt += `\n\nIMPORTANT FILE HANDLING INSTRUCTIONS:
1004
- - File content (${fileTypes.join(", ")}, images) is already processed and included in this message
1048
+ - The full content of the user's local ${fileTypes.join(", ")} (and any images) is INLINED in this message under the "## CSV Data from ..." / "## PDF Data from ..." headings — it is the actual file the user is asking about.
1049
+ - TREAT THE INLINED CONTENT AS IF IT WERE AN ATTACHMENT. Do NOT respond with "no files attached" or ask the user to re-upload — the data is already here.
1005
1050
  - DO NOT use GitHub tools (get_file_contents, search_code, etc.) for local files - they only work for remote repository files
1006
1051
  - Analyze the provided file content directly without attempting to fetch or read files using tools
1007
1052
  - GitHub MCP tools are ONLY for remote repository operations, not local filesystem access
@@ -1014,6 +1059,16 @@ function buildMultimodalSystemPrompt(options, hasPDFFiles) {
1014
1059
  * Detects when images are present and routes through provider adapter
1015
1060
  */
1016
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;
1017
1072
  // Compute provider-specific max PDF size once for consistent validation
1018
1073
  const pdfConfig = PDFProcessor.getProviderConfig(provider);
1019
1074
  const maxSize = pdfConfig
@@ -1030,20 +1085,19 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1030
1085
  // Process explicit PDF files
1031
1086
  const pdfFiles = await processExplicitPdfFiles(options, maxSize, provider);
1032
1087
  // Check if this is a multimodal request
1033
- const hasImages = (options.input.images && options.input.images.length > 0) ||
1034
- (options.input.content &&
1035
- 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"));
1036
1090
  const hasPDFs = pdfFiles.length > 0;
1037
1091
  // If no images or PDFs, use standard message building and convert to MultimodalChatMessage[]
1038
1092
  if (!hasImages && !hasPDFs) {
1039
- if (options.input.csvFiles) {
1040
- options.input.csvFiles = [];
1093
+ if (inp.csvFiles) {
1094
+ inp.csvFiles = [];
1041
1095
  }
1042
- if (options.input.pdfFiles) {
1043
- options.input.pdfFiles = [];
1096
+ if (inp.pdfFiles) {
1097
+ inp.pdfFiles = [];
1044
1098
  }
1045
- if (options.input.files) {
1046
- options.input.files = [];
1099
+ if (inp.files) {
1100
+ inp.files = [];
1047
1101
  }
1048
1102
  const standardMessages = await buildMessagesArray(options);
1049
1103
  return standardMessages.map((msg) => {
@@ -1128,15 +1182,14 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1128
1182
  // Handle multimodal content
1129
1183
  try {
1130
1184
  let userContent;
1131
- if (options.input.content && options.input.content.length > 0) {
1132
- userContent = await convertContentToProviderFormat(options.input.content, provider, model);
1185
+ if (inp.content && inp.content.length > 0) {
1186
+ userContent = await convertContentToProviderFormat(inp.content, provider, model);
1133
1187
  }
1134
- else if ((options.input.images && options.input.images.length > 0) ||
1135
- pdfFiles.length > 0) {
1136
- 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);
1137
1190
  }
1138
1191
  else {
1139
- userContent = options.input.text;
1192
+ userContent = inp.text;
1140
1193
  }
1141
1194
  if (typeof userContent === "string") {
1142
1195
  messages.push({
@@ -1160,7 +1213,7 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1160
1213
  provider,
1161
1214
  model,
1162
1215
  hasImages,
1163
- imageCount: options.input.images?.length || 0,
1216
+ imageCount: inp.images?.length || 0,
1164
1217
  });
1165
1218
  throw error;
1166
1219
  }