@juspay/neurolink 9.5.3 → 9.7.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 (423) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +29 -25
  3. package/dist/adapters/video/vertexVideoHandler.js +3 -3
  4. package/dist/agent/directTools.d.ts +5 -5
  5. package/dist/cli/commands/config.d.ts +9 -9
  6. package/dist/cli/commands/serve.d.ts +37 -0
  7. package/dist/cli/commands/serve.js +302 -229
  8. package/dist/cli/commands/setup-anthropic.d.ts +2 -2
  9. package/dist/cli/commands/setup-azure.d.ts +2 -2
  10. package/dist/cli/commands/setup-bedrock.d.ts +2 -2
  11. package/dist/cli/commands/setup-gcp.d.ts +2 -2
  12. package/dist/cli/commands/setup-google-ai.d.ts +2 -2
  13. package/dist/cli/commands/setup-huggingface.d.ts +2 -2
  14. package/dist/cli/commands/setup-mistral.d.ts +2 -2
  15. package/dist/cli/commands/setup-openai.d.ts +2 -2
  16. package/dist/cli/commands/setup.d.ts +2 -2
  17. package/dist/cli/factories/commandFactory.js +16 -2
  18. package/dist/cli/loop/optionsSchema.d.ts +2 -2
  19. package/dist/cli/loop/optionsSchema.js +4 -0
  20. package/dist/cli/loop/session.d.ts +4 -0
  21. package/dist/cli/loop/session.js +49 -4
  22. package/dist/cli/utils/interactiveSetup.d.ts +4 -4
  23. package/dist/config/conversationMemory.d.ts +2 -0
  24. package/dist/config/conversationMemory.js +5 -5
  25. package/dist/constants/contextWindows.d.ts +46 -0
  26. package/dist/constants/contextWindows.js +156 -0
  27. package/dist/context/budgetChecker.d.ts +18 -0
  28. package/dist/context/budgetChecker.js +71 -0
  29. package/dist/context/contextCompactor.d.ts +22 -0
  30. package/dist/context/contextCompactor.js +106 -0
  31. package/dist/context/effectiveHistory.d.ts +52 -0
  32. package/dist/context/effectiveHistory.js +105 -0
  33. package/dist/context/errorDetection.d.ts +14 -0
  34. package/dist/context/errorDetection.js +124 -0
  35. package/dist/context/fileSummarizationService.d.ts +54 -0
  36. package/dist/context/fileSummarizationService.js +255 -0
  37. package/dist/context/fileSummarizer.d.ts +56 -0
  38. package/dist/context/fileSummarizer.js +145 -0
  39. package/dist/context/fileTokenBudget.d.ts +53 -0
  40. package/dist/context/fileTokenBudget.js +127 -0
  41. package/dist/context/prompts/summarizationPrompt.d.ts +17 -0
  42. package/dist/context/prompts/summarizationPrompt.js +110 -0
  43. package/dist/context/stages/fileReadDeduplicator.d.ts +10 -0
  44. package/dist/context/stages/fileReadDeduplicator.js +66 -0
  45. package/dist/context/stages/slidingWindowTruncator.d.ts +11 -0
  46. package/dist/context/stages/slidingWindowTruncator.js +42 -0
  47. package/dist/context/stages/structuredSummarizer.d.ts +10 -0
  48. package/dist/context/stages/structuredSummarizer.js +49 -0
  49. package/dist/context/stages/toolOutputPruner.d.ts +10 -0
  50. package/dist/context/stages/toolOutputPruner.js +52 -0
  51. package/dist/context/summarizationEngine.d.ts +45 -0
  52. package/dist/context/summarizationEngine.js +110 -0
  53. package/dist/context/toolOutputLimits.d.ts +17 -0
  54. package/dist/context/toolOutputLimits.js +84 -0
  55. package/dist/context/toolPairRepair.d.ts +16 -0
  56. package/dist/context/toolPairRepair.js +66 -0
  57. package/dist/core/analytics.js +11 -4
  58. package/dist/core/baseProvider.d.ts +6 -0
  59. package/dist/core/baseProvider.js +83 -14
  60. package/dist/core/conversationMemoryManager.d.ts +14 -11
  61. package/dist/core/conversationMemoryManager.js +36 -68
  62. package/dist/core/dynamicModels.js +3 -2
  63. package/dist/core/modules/GenerationHandler.js +2 -0
  64. package/dist/core/modules/MessageBuilder.d.ts +1 -1
  65. package/dist/core/modules/MessageBuilder.js +2 -0
  66. package/dist/core/modules/TelemetryHandler.d.ts +2 -3
  67. package/dist/core/modules/TelemetryHandler.js +3 -3
  68. package/dist/core/modules/ToolsManager.d.ts +2 -2
  69. package/dist/core/redisConversationMemoryManager.d.ts +19 -14
  70. package/dist/core/redisConversationMemoryManager.js +94 -86
  71. package/dist/factories/providerFactory.d.ts +2 -2
  72. package/dist/files/fileReferenceRegistry.d.ts +276 -0
  73. package/dist/files/fileReferenceRegistry.js +1543 -0
  74. package/dist/files/fileTools.d.ts +423 -0
  75. package/dist/files/fileTools.js +449 -0
  76. package/dist/files/index.d.ts +14 -0
  77. package/dist/files/index.js +13 -0
  78. package/dist/files/streamingReader.d.ts +93 -0
  79. package/dist/files/streamingReader.js +321 -0
  80. package/dist/files/types.d.ts +23 -0
  81. package/dist/files/types.js +23 -0
  82. package/dist/image-gen/imageGenTools.d.ts +2 -2
  83. package/dist/image-gen/types.d.ts +12 -12
  84. package/dist/index.d.ts +4 -0
  85. package/dist/index.js +5 -0
  86. package/dist/lib/adapters/video/vertexVideoHandler.js +3 -3
  87. package/dist/lib/agent/directTools.d.ts +7 -7
  88. package/dist/lib/config/conversationMemory.d.ts +2 -0
  89. package/dist/lib/config/conversationMemory.js +5 -5
  90. package/dist/lib/constants/contextWindows.d.ts +46 -0
  91. package/dist/lib/constants/contextWindows.js +157 -0
  92. package/dist/lib/context/budgetChecker.d.ts +18 -0
  93. package/dist/lib/context/budgetChecker.js +72 -0
  94. package/dist/lib/context/contextCompactor.d.ts +22 -0
  95. package/dist/lib/context/contextCompactor.js +107 -0
  96. package/dist/lib/context/effectiveHistory.d.ts +52 -0
  97. package/dist/lib/context/effectiveHistory.js +106 -0
  98. package/dist/lib/context/errorDetection.d.ts +14 -0
  99. package/dist/lib/context/errorDetection.js +125 -0
  100. package/dist/lib/context/fileSummarizationService.d.ts +54 -0
  101. package/dist/lib/context/fileSummarizationService.js +256 -0
  102. package/dist/lib/context/fileSummarizer.d.ts +56 -0
  103. package/dist/lib/context/fileSummarizer.js +146 -0
  104. package/dist/lib/context/fileTokenBudget.d.ts +53 -0
  105. package/dist/lib/context/fileTokenBudget.js +128 -0
  106. package/dist/lib/context/prompts/summarizationPrompt.d.ts +17 -0
  107. package/dist/lib/context/prompts/summarizationPrompt.js +111 -0
  108. package/dist/lib/context/stages/fileReadDeduplicator.d.ts +10 -0
  109. package/dist/lib/context/stages/fileReadDeduplicator.js +67 -0
  110. package/dist/lib/context/stages/slidingWindowTruncator.d.ts +11 -0
  111. package/dist/lib/context/stages/slidingWindowTruncator.js +43 -0
  112. package/dist/lib/context/stages/structuredSummarizer.d.ts +10 -0
  113. package/dist/lib/context/stages/structuredSummarizer.js +50 -0
  114. package/dist/lib/context/stages/toolOutputPruner.d.ts +10 -0
  115. package/dist/lib/context/stages/toolOutputPruner.js +53 -0
  116. package/dist/lib/context/summarizationEngine.d.ts +45 -0
  117. package/dist/lib/context/summarizationEngine.js +111 -0
  118. package/dist/lib/context/toolOutputLimits.d.ts +17 -0
  119. package/dist/lib/context/toolOutputLimits.js +85 -0
  120. package/dist/lib/context/toolPairRepair.d.ts +16 -0
  121. package/dist/lib/context/toolPairRepair.js +67 -0
  122. package/dist/lib/core/analytics.js +11 -4
  123. package/dist/lib/core/baseProvider.d.ts +6 -0
  124. package/dist/lib/core/baseProvider.js +83 -14
  125. package/dist/lib/core/conversationMemoryManager.d.ts +14 -11
  126. package/dist/lib/core/conversationMemoryManager.js +36 -68
  127. package/dist/lib/core/dynamicModels.js +3 -2
  128. package/dist/lib/core/modules/GenerationHandler.js +2 -0
  129. package/dist/lib/core/modules/MessageBuilder.d.ts +1 -1
  130. package/dist/lib/core/modules/MessageBuilder.js +2 -0
  131. package/dist/lib/core/modules/TelemetryHandler.d.ts +2 -3
  132. package/dist/lib/core/modules/TelemetryHandler.js +3 -3
  133. package/dist/lib/core/modules/ToolsManager.d.ts +2 -2
  134. package/dist/lib/core/redisConversationMemoryManager.d.ts +19 -14
  135. package/dist/lib/core/redisConversationMemoryManager.js +94 -86
  136. package/dist/lib/factories/providerFactory.d.ts +2 -2
  137. package/dist/lib/files/fileReferenceRegistry.d.ts +276 -0
  138. package/dist/lib/files/fileReferenceRegistry.js +1544 -0
  139. package/dist/lib/files/fileTools.d.ts +423 -0
  140. package/dist/lib/files/fileTools.js +450 -0
  141. package/dist/lib/files/index.d.ts +14 -0
  142. package/dist/lib/files/index.js +14 -0
  143. package/dist/lib/files/streamingReader.d.ts +93 -0
  144. package/dist/lib/files/streamingReader.js +322 -0
  145. package/dist/lib/files/types.d.ts +23 -0
  146. package/dist/lib/files/types.js +24 -0
  147. package/dist/lib/image-gen/imageGenTools.d.ts +2 -2
  148. package/dist/lib/image-gen/types.d.ts +12 -12
  149. package/dist/lib/index.d.ts +4 -0
  150. package/dist/lib/index.js +5 -0
  151. package/dist/lib/mcp/httpRetryHandler.js +6 -2
  152. package/dist/lib/memory/mem0Initializer.d.ts +2 -2
  153. package/dist/lib/neurolink.d.ts +66 -2
  154. package/dist/lib/neurolink.js +777 -315
  155. package/dist/lib/processors/archive/ArchiveProcessor.d.ts +327 -0
  156. package/dist/lib/processors/archive/ArchiveProcessor.js +1309 -0
  157. package/dist/lib/processors/archive/index.d.ts +33 -0
  158. package/dist/lib/processors/archive/index.js +43 -0
  159. package/dist/lib/processors/base/BaseFileProcessor.js +2 -1
  160. package/dist/lib/processors/base/types.d.ts +70 -64
  161. package/dist/lib/processors/base/types.js +6 -0
  162. package/dist/lib/processors/cli/fileProcessorCli.d.ts +8 -8
  163. package/dist/lib/processors/cli/fileProcessorCli.js +5 -5
  164. package/dist/lib/processors/config/mimeTypes.js +25 -0
  165. package/dist/lib/processors/config/sizeLimits.d.ts +52 -40
  166. package/dist/lib/processors/config/sizeLimits.js +56 -44
  167. package/dist/lib/processors/document/ExcelProcessor.d.ts +14 -0
  168. package/dist/lib/processors/document/ExcelProcessor.js +72 -1
  169. package/dist/lib/processors/document/PptxProcessor.d.ts +63 -0
  170. package/dist/lib/processors/document/PptxProcessor.js +158 -0
  171. package/dist/lib/processors/document/index.d.ts +1 -0
  172. package/dist/lib/processors/document/index.js +6 -0
  173. package/dist/lib/processors/errors/FileErrorCode.d.ts +2 -2
  174. package/dist/lib/processors/errors/errorHelpers.d.ts +2 -2
  175. package/dist/lib/processors/errors/errorHelpers.js +12 -4
  176. package/dist/lib/processors/errors/errorSerializer.d.ts +4 -4
  177. package/dist/lib/processors/index.d.ts +8 -2
  178. package/dist/lib/processors/index.js +5 -2
  179. package/dist/lib/processors/integration/FileProcessorIntegration.d.ts +8 -8
  180. package/dist/lib/processors/integration/FileProcessorIntegration.js +7 -7
  181. package/dist/lib/processors/media/AudioProcessor.d.ts +328 -0
  182. package/dist/lib/processors/media/AudioProcessor.js +708 -0
  183. package/dist/lib/processors/media/VideoProcessor.d.ts +350 -0
  184. package/dist/lib/processors/media/VideoProcessor.js +992 -0
  185. package/dist/lib/processors/media/index.d.ts +27 -0
  186. package/dist/lib/processors/media/index.js +37 -0
  187. package/dist/lib/processors/registry/ProcessorRegistry.d.ts +19 -5
  188. package/dist/lib/processors/registry/ProcessorRegistry.js +103 -8
  189. package/dist/lib/processors/registry/index.d.ts +1 -1
  190. package/dist/lib/processors/registry/index.js +1 -1
  191. package/dist/lib/processors/registry/types.d.ts +2 -2
  192. package/dist/lib/providers/amazonBedrock.js +2 -1
  193. package/dist/lib/providers/anthropic.js +2 -2
  194. package/dist/lib/providers/anthropicBaseProvider.js +10 -4
  195. package/dist/lib/providers/azureOpenai.js +14 -25
  196. package/dist/lib/providers/googleAiStudio.js +136 -457
  197. package/dist/lib/providers/googleNativeGemini3.d.ts +119 -0
  198. package/dist/lib/providers/googleNativeGemini3.js +264 -0
  199. package/dist/lib/providers/googleVertex.d.ts +15 -1
  200. package/dist/lib/providers/googleVertex.js +341 -775
  201. package/dist/lib/providers/huggingFace.js +20 -5
  202. package/dist/lib/providers/litellm.js +6 -4
  203. package/dist/lib/providers/mistral.js +3 -2
  204. package/dist/lib/providers/openAI.js +2 -2
  205. package/dist/lib/providers/openRouter.js +8 -7
  206. package/dist/lib/providers/openaiCompatible.js +10 -4
  207. package/dist/lib/providers/sagemaker/detection.d.ts +6 -6
  208. package/dist/lib/providers/sagemaker/diagnostics.d.ts +4 -4
  209. package/dist/lib/providers/sagemaker/parsers.d.ts +4 -4
  210. package/dist/lib/rag/chunkers/RecursiveChunker.js +2 -2
  211. package/dist/lib/rag/document/loaders.d.ts +6 -71
  212. package/dist/lib/rag/document/loaders.js +5 -5
  213. package/dist/lib/rag/graphRag/graphRAG.js +26 -9
  214. package/dist/lib/rag/metadata/MetadataExtractorFactory.d.ts +5 -55
  215. package/dist/lib/rag/metadata/metadataExtractor.js +6 -3
  216. package/dist/lib/rag/pipeline/RAGPipeline.d.ts +8 -126
  217. package/dist/lib/rag/pipeline/RAGPipeline.js +11 -11
  218. package/dist/lib/rag/pipeline/contextAssembly.d.ts +3 -42
  219. package/dist/lib/rag/pipeline/contextAssembly.js +6 -3
  220. package/dist/lib/rag/reranker/RerankerFactory.d.ts +5 -60
  221. package/dist/lib/rag/resilience/CircuitBreaker.d.ts +3 -33
  222. package/dist/lib/rag/resilience/RetryHandler.d.ts +2 -21
  223. package/dist/lib/rag/resilience/RetryHandler.js +6 -2
  224. package/dist/lib/rag/retrieval/hybridSearch.d.ts +3 -41
  225. package/dist/lib/rag/retrieval/vectorQueryTool.d.ts +2 -13
  226. package/dist/lib/rag/retrieval/vectorQueryTool.js +4 -3
  227. package/dist/lib/rag/types.d.ts +3 -3
  228. package/dist/lib/sdk/toolRegistration.d.ts +2 -2
  229. package/dist/lib/server/middleware/cache.d.ts +2 -2
  230. package/dist/lib/server/middleware/rateLimit.d.ts +2 -2
  231. package/dist/lib/server/routes/mcpRoutes.js +277 -249
  232. package/dist/lib/server/routes/memoryRoutes.js +287 -281
  233. package/dist/lib/server/utils/validation.d.ts +10 -10
  234. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +24 -2
  235. package/dist/lib/services/server/ai/observability/instrumentation.js +12 -1
  236. package/dist/lib/session/globalSessionState.d.ts +2 -2
  237. package/dist/lib/telemetry/telemetryService.d.ts +2 -2
  238. package/dist/lib/types/common.d.ts +39 -0
  239. package/dist/lib/types/contextTypes.d.ts +255 -0
  240. package/dist/lib/types/contextTypes.js +0 -2
  241. package/dist/lib/types/conversation.d.ts +62 -0
  242. package/dist/lib/types/conversationMemoryInterface.d.ts +27 -0
  243. package/dist/lib/types/conversationMemoryInterface.js +7 -0
  244. package/dist/lib/types/fileReferenceTypes.d.ts +222 -0
  245. package/dist/lib/types/fileReferenceTypes.js +9 -0
  246. package/dist/lib/types/fileTypes.d.ts +26 -3
  247. package/dist/lib/types/generateTypes.d.ts +50 -1
  248. package/dist/lib/types/index.d.ts +4 -5
  249. package/dist/lib/types/index.js +8 -10
  250. package/dist/lib/types/modelTypes.d.ts +2 -2
  251. package/dist/lib/types/processorTypes.d.ts +597 -0
  252. package/dist/lib/types/processorTypes.js +91 -0
  253. package/dist/lib/types/ragTypes.d.ts +489 -0
  254. package/dist/lib/types/ragTypes.js +8 -0
  255. package/dist/lib/types/sdkTypes.d.ts +17 -18
  256. package/dist/lib/types/streamTypes.d.ts +24 -1
  257. package/dist/lib/utils/async/retry.d.ts +2 -2
  258. package/dist/lib/utils/async/withTimeout.js +3 -1
  259. package/dist/lib/utils/conversationMemory.d.ts +12 -6
  260. package/dist/lib/utils/conversationMemory.js +91 -36
  261. package/dist/lib/utils/errorHandling.d.ts +5 -0
  262. package/dist/lib/utils/errorHandling.js +19 -0
  263. package/dist/lib/utils/fileDetector.d.ts +62 -0
  264. package/dist/lib/utils/fileDetector.js +1014 -14
  265. package/dist/lib/utils/json/safeParse.d.ts +2 -2
  266. package/dist/lib/utils/messageBuilder.js +806 -153
  267. package/dist/lib/utils/modelChoices.d.ts +2 -2
  268. package/dist/lib/utils/multimodalOptionsBuilder.d.ts +2 -1
  269. package/dist/lib/utils/multimodalOptionsBuilder.js +1 -0
  270. package/dist/lib/utils/pricing.d.ts +12 -0
  271. package/dist/lib/utils/pricing.js +134 -0
  272. package/dist/lib/utils/rateLimiter.d.ts +2 -2
  273. package/dist/lib/utils/redis.d.ts +17 -0
  274. package/dist/lib/utils/redis.js +105 -0
  275. package/dist/lib/utils/sanitizers/filename.d.ts +4 -4
  276. package/dist/lib/utils/sanitizers/svg.d.ts +2 -2
  277. package/dist/lib/utils/thinkingConfig.d.ts +6 -6
  278. package/dist/lib/utils/timeout.d.ts +10 -0
  279. package/dist/lib/utils/timeout.js +15 -0
  280. package/dist/lib/utils/tokenEstimation.d.ts +68 -0
  281. package/dist/lib/utils/tokenEstimation.js +113 -0
  282. package/dist/lib/utils/tokenUtils.d.ts +4 -4
  283. package/dist/lib/utils/ttsProcessor.d.ts +2 -2
  284. package/dist/lib/workflow/config.d.ts +150 -150
  285. package/dist/mcp/httpRetryHandler.js +6 -2
  286. package/dist/memory/mem0Initializer.d.ts +2 -2
  287. package/dist/neurolink.d.ts +66 -2
  288. package/dist/neurolink.js +777 -315
  289. package/dist/processors/archive/ArchiveProcessor.d.ts +327 -0
  290. package/dist/processors/archive/ArchiveProcessor.js +1308 -0
  291. package/dist/processors/archive/index.d.ts +33 -0
  292. package/dist/processors/archive/index.js +42 -0
  293. package/dist/processors/base/BaseFileProcessor.js +2 -1
  294. package/dist/processors/base/types.d.ts +70 -64
  295. package/dist/processors/base/types.js +6 -0
  296. package/dist/processors/cli/fileProcessorCli.d.ts +8 -8
  297. package/dist/processors/cli/fileProcessorCli.js +5 -5
  298. package/dist/processors/config/mimeTypes.js +25 -0
  299. package/dist/processors/config/sizeLimits.d.ts +52 -40
  300. package/dist/processors/config/sizeLimits.js +56 -44
  301. package/dist/processors/document/ExcelProcessor.d.ts +14 -0
  302. package/dist/processors/document/ExcelProcessor.js +72 -1
  303. package/dist/processors/document/PptxProcessor.d.ts +63 -0
  304. package/dist/processors/document/PptxProcessor.js +157 -0
  305. package/dist/processors/document/index.d.ts +1 -0
  306. package/dist/processors/document/index.js +6 -0
  307. package/dist/processors/errors/FileErrorCode.d.ts +2 -2
  308. package/dist/processors/errors/errorHelpers.d.ts +2 -2
  309. package/dist/processors/errors/errorHelpers.js +12 -4
  310. package/dist/processors/errors/errorSerializer.d.ts +4 -4
  311. package/dist/processors/index.d.ts +8 -2
  312. package/dist/processors/index.js +5 -2
  313. package/dist/processors/integration/FileProcessorIntegration.d.ts +8 -8
  314. package/dist/processors/integration/FileProcessorIntegration.js +7 -7
  315. package/dist/processors/media/AudioProcessor.d.ts +328 -0
  316. package/dist/processors/media/AudioProcessor.js +707 -0
  317. package/dist/processors/media/VideoProcessor.d.ts +350 -0
  318. package/dist/processors/media/VideoProcessor.js +991 -0
  319. package/dist/processors/media/ffprobe-static.d.ts +4 -0
  320. package/dist/processors/media/index.d.ts +27 -0
  321. package/dist/processors/media/index.js +36 -0
  322. package/dist/processors/registry/ProcessorRegistry.d.ts +19 -5
  323. package/dist/processors/registry/ProcessorRegistry.js +103 -8
  324. package/dist/processors/registry/index.d.ts +1 -1
  325. package/dist/processors/registry/index.js +1 -1
  326. package/dist/processors/registry/types.d.ts +2 -2
  327. package/dist/providers/amazonBedrock.js +2 -1
  328. package/dist/providers/anthropic.js +2 -2
  329. package/dist/providers/anthropicBaseProvider.js +10 -4
  330. package/dist/providers/azureOpenai.js +14 -25
  331. package/dist/providers/googleAiStudio.js +136 -457
  332. package/dist/providers/googleNativeGemini3.d.ts +119 -0
  333. package/dist/providers/googleNativeGemini3.js +263 -0
  334. package/dist/providers/googleVertex.d.ts +15 -1
  335. package/dist/providers/googleVertex.js +341 -775
  336. package/dist/providers/huggingFace.js +20 -5
  337. package/dist/providers/litellm.js +6 -4
  338. package/dist/providers/mistral.js +3 -2
  339. package/dist/providers/openAI.js +2 -2
  340. package/dist/providers/openRouter.js +8 -7
  341. package/dist/providers/openaiCompatible.js +10 -4
  342. package/dist/providers/sagemaker/detection.d.ts +6 -6
  343. package/dist/providers/sagemaker/diagnostics.d.ts +4 -4
  344. package/dist/providers/sagemaker/parsers.d.ts +4 -4
  345. package/dist/rag/chunkers/RecursiveChunker.js +2 -2
  346. package/dist/rag/document/loaders.d.ts +6 -71
  347. package/dist/rag/document/loaders.js +5 -5
  348. package/dist/rag/graphRag/graphRAG.js +26 -9
  349. package/dist/rag/metadata/MetadataExtractorFactory.d.ts +5 -55
  350. package/dist/rag/metadata/metadataExtractor.js +6 -3
  351. package/dist/rag/pipeline/RAGPipeline.d.ts +8 -126
  352. package/dist/rag/pipeline/RAGPipeline.js +11 -11
  353. package/dist/rag/pipeline/contextAssembly.d.ts +3 -42
  354. package/dist/rag/pipeline/contextAssembly.js +6 -3
  355. package/dist/rag/reranker/RerankerFactory.d.ts +5 -60
  356. package/dist/rag/resilience/CircuitBreaker.d.ts +3 -33
  357. package/dist/rag/resilience/RetryHandler.d.ts +2 -21
  358. package/dist/rag/resilience/RetryHandler.js +6 -2
  359. package/dist/rag/retrieval/hybridSearch.d.ts +3 -41
  360. package/dist/rag/retrieval/vectorQueryTool.d.ts +2 -13
  361. package/dist/rag/retrieval/vectorQueryTool.js +4 -3
  362. package/dist/rag/types.d.ts +3 -3
  363. package/dist/sdk/toolRegistration.d.ts +2 -2
  364. package/dist/server/middleware/cache.d.ts +2 -2
  365. package/dist/server/middleware/rateLimit.d.ts +2 -2
  366. package/dist/server/routes/mcpRoutes.js +277 -249
  367. package/dist/server/routes/memoryRoutes.js +287 -281
  368. package/dist/server/utils/validation.d.ts +4 -4
  369. package/dist/services/server/ai/observability/instrumentation.d.ts +24 -2
  370. package/dist/services/server/ai/observability/instrumentation.js +12 -1
  371. package/dist/session/globalSessionState.d.ts +2 -2
  372. package/dist/telemetry/telemetryService.d.ts +2 -2
  373. package/dist/types/common.d.ts +39 -0
  374. package/dist/types/contextTypes.d.ts +255 -0
  375. package/dist/types/contextTypes.js +0 -2
  376. package/dist/types/conversation.d.ts +62 -0
  377. package/dist/types/conversationMemoryInterface.d.ts +27 -0
  378. package/dist/types/conversationMemoryInterface.js +6 -0
  379. package/dist/types/fileReferenceTypes.d.ts +222 -0
  380. package/dist/types/fileReferenceTypes.js +8 -0
  381. package/dist/types/fileTypes.d.ts +26 -3
  382. package/dist/types/generateTypes.d.ts +50 -1
  383. package/dist/types/index.d.ts +4 -5
  384. package/dist/types/index.js +8 -10
  385. package/dist/types/processorTypes.d.ts +597 -0
  386. package/dist/types/processorTypes.js +90 -0
  387. package/dist/types/ragTypes.d.ts +489 -0
  388. package/dist/types/ragTypes.js +7 -0
  389. package/dist/types/sdkTypes.d.ts +17 -18
  390. package/dist/types/streamTypes.d.ts +24 -1
  391. package/dist/utils/async/retry.d.ts +2 -2
  392. package/dist/utils/async/withTimeout.js +3 -1
  393. package/dist/utils/conversationMemory.d.ts +12 -6
  394. package/dist/utils/conversationMemory.js +91 -36
  395. package/dist/utils/errorHandling.d.ts +5 -0
  396. package/dist/utils/errorHandling.js +19 -0
  397. package/dist/utils/fileDetector.d.ts +62 -0
  398. package/dist/utils/fileDetector.js +1014 -14
  399. package/dist/utils/json/safeParse.d.ts +2 -2
  400. package/dist/utils/messageBuilder.js +806 -153
  401. package/dist/utils/modelChoices.d.ts +2 -2
  402. package/dist/utils/multimodalOptionsBuilder.d.ts +2 -1
  403. package/dist/utils/multimodalOptionsBuilder.js +1 -0
  404. package/dist/utils/pricing.d.ts +12 -0
  405. package/dist/utils/pricing.js +133 -0
  406. package/dist/utils/rateLimiter.d.ts +2 -2
  407. package/dist/utils/redis.d.ts +17 -0
  408. package/dist/utils/redis.js +105 -0
  409. package/dist/utils/sanitizers/filename.d.ts +4 -4
  410. package/dist/utils/sanitizers/svg.d.ts +2 -2
  411. package/dist/utils/thinkingConfig.d.ts +6 -6
  412. package/dist/utils/timeout.d.ts +10 -0
  413. package/dist/utils/timeout.js +15 -0
  414. package/dist/utils/tokenEstimation.d.ts +68 -0
  415. package/dist/utils/tokenEstimation.js +112 -0
  416. package/dist/utils/tokenUtils.d.ts +4 -4
  417. package/dist/utils/ttsProcessor.d.ts +2 -2
  418. package/dist/workflow/config.d.ts +104 -104
  419. package/package.json +18 -6
  420. package/dist/lib/utils/conversationMemoryUtils.d.ts +0 -25
  421. package/dist/lib/utils/conversationMemoryUtils.js +0 -138
  422. package/dist/utils/conversationMemoryUtils.d.ts +0 -25
  423. package/dist/utils/conversationMemoryUtils.js +0 -137
@@ -2,15 +2,14 @@ import { createGoogleGenerativeAI } from "@ai-sdk/google";
2
2
  import { streamText } from "ai";
3
3
  import { ErrorCategory, ErrorSeverity, GoogleAIModels, } from "../constants/enums.js";
4
4
  import { BaseProvider } from "../core/baseProvider.js";
5
- import { DEFAULT_MAX_STEPS, DEFAULT_TOOL_MAX_RETRIES, } from "../core/constants.js";
5
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
6
6
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
7
7
  import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
8
8
  import { ERROR_CODES, NeuroLinkError } from "../utils/errorHandling.js";
9
9
  import { logger } from "../utils/logger.js";
10
10
  import { isGemini3Model } from "../utils/modelDetection.js";
11
- import { convertZodToJsonSchema, inlineJsonSchema, isZodSchema, } from "../utils/schemaConversion.js";
12
- import { createNativeThinkingConfig } from "../utils/thinkingConfig.js";
13
- import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
11
+ import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
12
+ import { buildNativeToolDeclarations, buildNativeConfig, computeMaxSteps, collectStreamChunks, extractTextFromParts, executeNativeToolCalls, handleMaxStepsTermination, pushModelResponseToHistory, } from "./googleNativeGemini3.js";
14
13
  // Google AI Live API types now imported from ../types/providerSpecific.js
15
14
  // Import proper types for multimodal message handling
16
15
  // Create Google GenAI client
@@ -397,10 +396,19 @@ export class GoogleAIStudioProvider extends BaseProvider {
397
396
  const hasTools = gemini3CheckShouldUseTools && combinedToolCount > 0;
398
397
  if (isGemini3Model(gemini3CheckModelName) && hasTools) {
399
398
  // Merge SDK tools into options for native SDK path
400
- const mergedOptions = {
399
+ let mergedOptions = {
401
400
  ...options,
402
401
  tools: { ...sdkTools, ...optionTools },
403
402
  };
403
+ // Check for tools + JSON schema conflict (Gemini limitation)
404
+ const wantsJsonOutput = options.output?.format === "json" || options.schema;
405
+ if (wantsJsonOutput &&
406
+ mergedOptions.tools &&
407
+ Object.keys(mergedOptions.tools).length > 0 &&
408
+ !mergedOptions.disableTools) {
409
+ logger.warn("[GoogleAIStudio] Gemini does not support tools and JSON schema output simultaneously. Disabling tools for this request.");
410
+ mergedOptions = { ...mergedOptions, disableTools: true, tools: {} };
411
+ }
404
412
  logger.info("[GoogleAIStudio] Routing Gemini 3 to native SDK for tool calling", {
405
413
  model: gemini3CheckModelName,
406
414
  optionToolCount: Object.keys(optionTools).length,
@@ -441,7 +449,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
441
449
  tools,
442
450
  maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
443
451
  toolChoice: shouldUseTools ? "auto" : "none",
444
- abortSignal: timeoutController?.controller.signal,
452
+ abortSignal: composeAbortSignals(options.abortSignal, timeoutController?.controller.signal),
445
453
  experimental_telemetry: this.telemetryHandler.getTelemetryConfig(options),
446
454
  // Gemini 3: use thinkingLevel via providerOptions
447
455
  // Gemini 2.5: use thinkingBudget via providerOptions
@@ -470,7 +478,8 @@ export class GoogleAIStudioProvider extends BaseProvider {
470
478
  });
471
479
  },
472
480
  });
473
- timeoutController?.cleanup();
481
+ // Defer timeout cleanup until the stream completes or errors
482
+ result.text.finally(() => timeoutController?.cleanup());
474
483
  // Transform string stream to content object stream using BaseProvider method
475
484
  const transformedStream = this.createTextStream(result);
476
485
  // Create analytics promise that resolves after stream completion
@@ -510,240 +519,79 @@ export class GoogleAIStudioProvider extends BaseProvider {
510
519
  hasTools: !!options.tools && Object.keys(options.tools).length > 0,
511
520
  });
512
521
  // Build contents from input
513
- const contents = [];
514
- contents.push({
515
- role: "user",
516
- parts: [{ text: options.input.text }],
517
- });
518
- let tools;
519
- const executeMap = new Map();
522
+ const currentContents = [{ role: "user", parts: [{ text: options.input.text }] }];
523
+ // Convert tools
524
+ let toolsConfig;
525
+ let executeMap = new Map();
520
526
  if (options.tools &&
521
527
  Object.keys(options.tools).length > 0 &&
522
528
  !options.disableTools) {
523
- const functionDeclarations = [];
524
- for (const [name, tool] of Object.entries(options.tools)) {
525
- const decl = {
526
- name,
527
- description: tool.description || `Tool: ${name}`,
528
- };
529
- if (tool.parameters) {
530
- let rawSchema;
531
- if (isZodSchema(tool.parameters)) {
532
- // It's a Zod schema - convert it
533
- rawSchema = convertZodToJsonSchema(tool.parameters);
534
- }
535
- else if (typeof tool.parameters === "object") {
536
- // Already JSON schema (jsonSchema() wrapper) - use directly
537
- rawSchema = tool.parameters;
538
- }
539
- else {
540
- rawSchema = { type: "object", properties: {} };
541
- }
542
- decl.parametersJsonSchema = inlineJsonSchema(rawSchema);
543
- // Remove $schema if present - @google/genai doesn't need it
544
- if (decl.parametersJsonSchema.$schema) {
545
- delete decl.parametersJsonSchema.$schema;
546
- }
547
- }
548
- functionDeclarations.push(decl);
549
- if (tool.execute) {
550
- executeMap.set(name, tool.execute);
551
- }
552
- }
553
- tools = [{ functionDeclarations }];
529
+ const result = buildNativeToolDeclarations(options.tools);
530
+ toolsConfig = result.toolsConfig;
531
+ executeMap = result.executeMap;
554
532
  logger.debug("[GoogleAIStudio] Converted tools for native SDK", {
555
- toolCount: functionDeclarations.length,
556
- toolNames: functionDeclarations.map((t) => t.name),
533
+ toolCount: toolsConfig[0].functionDeclarations.length,
534
+ toolNames: toolsConfig[0].functionDeclarations.map((t) => t.name),
557
535
  });
558
536
  }
559
- // Build config
560
- const config = {
561
- temperature: options.temperature ?? 1.0, // Gemini 3 requires 1.0 for tool calling
562
- maxOutputTokens: options.maxTokens,
563
- };
564
- if (tools) {
565
- config.tools = tools;
566
- }
567
- if (options.systemPrompt) {
568
- config.systemInstruction = options.systemPrompt;
569
- }
570
- // Add thinking config for Gemini 3
571
- const nativeThinkingConfig = createNativeThinkingConfig(options.thinkingConfig);
572
- if (nativeThinkingConfig) {
573
- config.thinkingConfig = nativeThinkingConfig;
574
- }
575
- // Ensure maxSteps is a valid positive integer to prevent infinite loops
576
- const rawMaxSteps = options.maxSteps || DEFAULT_MAX_STEPS;
577
- const maxSteps = Number.isFinite(rawMaxSteps) && rawMaxSteps > 0
578
- ? Math.min(Math.floor(rawMaxSteps), 100) // Cap at 100 for safety
579
- : Math.min(DEFAULT_MAX_STEPS, 100);
580
- const currentContents = [...contents];
537
+ const config = buildNativeConfig(options, toolsConfig);
538
+ const maxSteps = computeMaxSteps(options.maxSteps);
581
539
  let finalText = "";
582
- let lastStepText = ""; // Track text from last step for maxSteps termination
540
+ let lastStepText = "";
583
541
  let totalInputTokens = 0;
584
542
  let totalOutputTokens = 0;
585
543
  const allToolCalls = [];
586
544
  let step = 0;
587
- // Track failed tools to prevent infinite retry loops
588
- // Key: tool name, Value: { count: retry attempts, lastError: error message }
589
545
  const failedTools = new Map();
590
- // Agentic loop for tool calling
591
- while (step < maxSteps) {
592
- step++;
593
- logger.debug(`[GoogleAIStudio] Native SDK step ${step}/${maxSteps}`);
594
- try {
595
- const stream = await client.models.generateContentStream({
596
- model: modelName,
597
- contents: currentContents,
598
- config,
599
- });
600
- const stepFunctionCalls = [];
601
- // Capture all raw parts including thoughtSignature for history
602
- const rawResponseParts = [];
603
- for await (const chunk of stream) {
604
- // Extract raw parts from candidates FIRST
605
- // This avoids using chunk.text which triggers SDK warning when
606
- // non-text parts (thoughtSignature, functionCall) are present
607
- const chunkRecord = chunk;
608
- const candidates = chunkRecord.candidates;
609
- const firstCandidate = candidates?.[0];
610
- const chunkContent = firstCandidate?.content;
611
- if (chunkContent && Array.isArray(chunkContent.parts)) {
612
- rawResponseParts.push(...chunkContent.parts);
613
- }
614
- if (chunk.functionCalls) {
615
- stepFunctionCalls.push(...chunk.functionCalls);
616
- }
617
- // Accumulate usage metadata from chunks
618
- const usage = chunkRecord.usageMetadata;
619
- if (usage) {
620
- totalInputTokens = Math.max(totalInputTokens, usage.promptTokenCount || 0);
621
- totalOutputTokens = Math.max(totalOutputTokens, usage.candidatesTokenCount || 0);
622
- }
623
- }
624
- // Extract text from raw parts after stream completes
625
- // This avoids SDK warning about non-text parts (thoughtSignature, functionCall)
626
- const stepText = rawResponseParts
627
- .filter((part) => typeof part.text === "string")
628
- .map((part) => part.text)
629
- .join("");
630
- // If no function calls, we're done
631
- if (stepFunctionCalls.length === 0) {
632
- finalText = stepText;
546
+ // Compose abort signal from user signal + timeout
547
+ const composedSignal = composeAbortSignals(options.abortSignal, timeoutController?.controller.signal);
548
+ try {
549
+ // Agentic loop for tool calling
550
+ while (step < maxSteps) {
551
+ if (composedSignal?.aborted) {
633
552
  break;
634
553
  }
635
- // Track the last step text for maxSteps termination
636
- lastStepText = stepText;
637
- // Execute function calls
638
- logger.debug(`[GoogleAIStudio] Executing ${stepFunctionCalls.length} function calls`);
639
- // Add model response with ALL parts (including thoughtSignature) to history
640
- currentContents.push({
641
- role: "model",
642
- parts: rawResponseParts.length > 0
643
- ? rawResponseParts
644
- : stepFunctionCalls.map((fc) => ({
645
- functionCall: fc,
646
- })),
647
- });
648
- // Execute each function and collect responses
649
- const functionResponses = [];
650
- for (const call of stepFunctionCalls) {
651
- allToolCalls.push({ toolName: call.name, args: call.args });
652
- // Check if this tool has already exceeded retry limit
653
- const failedInfo = failedTools.get(call.name);
654
- if (failedInfo && failedInfo.count >= DEFAULT_TOOL_MAX_RETRIES) {
655
- logger.warn(`[GoogleAIStudio] Tool "${call.name}" has exceeded retry limit (${DEFAULT_TOOL_MAX_RETRIES}), skipping execution`);
656
- functionResponses.push({
657
- functionResponse: {
658
- name: call.name,
659
- response: {
660
- error: `TOOL_PERMANENTLY_FAILED: The tool "${call.name}" has failed ${failedInfo.count} times and will not be retried. Last error: ${failedInfo.lastError}. Please proceed without using this tool or inform the user that this functionality is unavailable.`,
661
- status: "permanently_failed",
662
- do_not_retry: true,
663
- },
664
- },
665
- });
666
- continue;
667
- }
668
- const execute = executeMap.get(call.name);
669
- if (execute) {
670
- try {
671
- // AI SDK Tool execute requires (args, options) - provide minimal options
672
- const toolOptions = {
673
- toolCallId: `${call.name}-${Date.now()}`,
674
- messages: [],
675
- abortSignal: undefined,
676
- };
677
- const result = await execute(call.args, toolOptions);
678
- functionResponses.push({
679
- functionResponse: { name: call.name, response: { result } },
680
- });
681
- }
682
- catch (error) {
683
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
684
- // Track this failure
685
- const currentFailInfo = failedTools.get(call.name) || {
686
- count: 0,
687
- lastError: "",
688
- };
689
- currentFailInfo.count++;
690
- currentFailInfo.lastError = errorMessage;
691
- failedTools.set(call.name, currentFailInfo);
692
- logger.warn(`[GoogleAIStudio] Tool "${call.name}" failed (attempt ${currentFailInfo.count}/${DEFAULT_TOOL_MAX_RETRIES}): ${errorMessage}`);
693
- // Determine if this is a permanent failure
694
- const isPermanentFailure = currentFailInfo.count >= DEFAULT_TOOL_MAX_RETRIES;
695
- functionResponses.push({
696
- functionResponse: {
697
- name: call.name,
698
- response: {
699
- error: isPermanentFailure
700
- ? `TOOL_PERMANENTLY_FAILED: The tool "${call.name}" has failed ${currentFailInfo.count} times with error: ${errorMessage}. This tool will not be retried. Please proceed without using this tool or inform the user that this functionality is unavailable.`
701
- : `TOOL_EXECUTION_ERROR: ${errorMessage}. Retry attempt ${currentFailInfo.count}/${DEFAULT_TOOL_MAX_RETRIES}.`,
702
- status: isPermanentFailure
703
- ? "permanently_failed"
704
- : "failed",
705
- do_not_retry: isPermanentFailure,
706
- retry_count: currentFailInfo.count,
707
- max_retries: DEFAULT_TOOL_MAX_RETRIES,
708
- },
709
- },
710
- });
711
- }
712
- }
713
- else {
714
- // Tool not found is a permanent error
715
- functionResponses.push({
716
- functionResponse: {
717
- name: call.name,
718
- response: {
719
- error: `TOOL_NOT_FOUND: The tool "${call.name}" does not exist. Do not attempt to call this tool again.`,
720
- status: "permanently_failed",
721
- do_not_retry: true,
722
- },
723
- },
724
- });
554
+ step++;
555
+ logger.debug(`[GoogleAIStudio] Native SDK step ${step}/${maxSteps}`);
556
+ try {
557
+ const stream = await client.models.generateContentStream({
558
+ model: modelName,
559
+ contents: currentContents,
560
+ config,
561
+ ...(composedSignal
562
+ ? { httpOptions: { signal: composedSignal } }
563
+ : {}),
564
+ });
565
+ const chunkResult = await collectStreamChunks(stream);
566
+ totalInputTokens += chunkResult.inputTokens;
567
+ totalOutputTokens += chunkResult.outputTokens;
568
+ const stepText = extractTextFromParts(chunkResult.rawResponseParts);
569
+ // If no function calls, we're done
570
+ if (chunkResult.stepFunctionCalls.length === 0) {
571
+ finalText = stepText;
572
+ break;
725
573
  }
574
+ lastStepText = stepText;
575
+ logger.debug(`[GoogleAIStudio] Executing ${chunkResult.stepFunctionCalls.length} function calls`);
576
+ // Add model response with ALL parts (including thoughtSignature) to history
577
+ pushModelResponseToHistory(currentContents, chunkResult.rawResponseParts, chunkResult.stepFunctionCalls);
578
+ const functionResponses = await executeNativeToolCalls("[GoogleAIStudio]", chunkResult.stepFunctionCalls, executeMap, failedTools, allToolCalls, { abortSignal: composedSignal });
579
+ // Add function responses to history
580
+ currentContents.push({
581
+ role: "function",
582
+ parts: functionResponses,
583
+ });
584
+ }
585
+ catch (error) {
586
+ logger.error("[GoogleAIStudio] Native SDK error", error);
587
+ throw this.handleProviderError(error);
726
588
  }
727
- // Add function responses to history
728
- currentContents.push({
729
- role: "function",
730
- parts: functionResponses,
731
- });
732
- }
733
- catch (error) {
734
- logger.error("[GoogleAIStudio] Native SDK error", error);
735
- throw this.handleProviderError(error);
736
589
  }
737
590
  }
738
- timeoutController?.cleanup();
739
- // Handle maxSteps termination - if we exited the loop due to maxSteps being reached
740
- if (step >= maxSteps && !finalText) {
741
- logger.warn(`[GoogleAIStudio] Tool call loop terminated after reaching maxSteps (${maxSteps}). ` +
742
- `Model was still calling tools. Using accumulated text from last step.`);
743
- finalText =
744
- lastStepText ||
745
- `[Tool execution limit reached after ${maxSteps} steps. The model continued requesting tool calls beyond the limit.]`;
591
+ finally {
592
+ timeoutController?.cleanup();
746
593
  }
594
+ finalText = handleMaxStepsTermination("[GoogleAIStudio]", step, maxSteps, finalText, lastStepText);
747
595
  const responseTime = Date.now() - startTime;
748
596
  // Create async iterable for streaming result
749
597
  async function* createTextStream() {
@@ -789,265 +637,87 @@ export class GoogleAIStudioProvider extends BaseProvider {
789
637
  hasTools: !!options.tools && Object.keys(options.tools).length > 0,
790
638
  });
791
639
  // Build contents from input
792
- const contents = [];
793
640
  const promptText = options.prompt || options.input?.text || "";
794
- contents.push({
795
- role: "user",
796
- parts: [{ text: promptText }],
797
- });
798
- let tools;
799
- const executeMap = new Map();
800
- const allToolsForResult = {};
801
- // Merge SDK tools with options.tools
641
+ const currentContents = [{ role: "user", parts: [{ text: promptText }] }];
642
+ // Convert tools (merge SDK tools with options.tools)
643
+ let toolsConfig;
644
+ let executeMap = new Map();
802
645
  const shouldUseTools = !options.disableTools;
803
646
  if (shouldUseTools) {
804
647
  const sdkTools = await this.getAllTools();
805
648
  const mergedTools = { ...sdkTools, ...(options.tools || {}) };
806
649
  if (Object.keys(mergedTools).length > 0) {
807
- const functionDeclarations = [];
808
- for (const [name, tool] of Object.entries(mergedTools)) {
809
- allToolsForResult[name] = tool;
810
- const decl = {
811
- name,
812
- description: tool.description || `Tool: ${name}`,
813
- };
814
- if (tool.parameters) {
815
- let rawSchema;
816
- if (isZodSchema(tool.parameters)) {
817
- // It's a Zod schema - convert it
818
- rawSchema = convertZodToJsonSchema(tool.parameters);
819
- }
820
- else if (typeof tool.parameters === "object") {
821
- // Already JSON schema (jsonSchema() wrapper) - use directly
822
- rawSchema = tool.parameters;
823
- }
824
- else {
825
- rawSchema = { type: "object", properties: {} };
826
- }
827
- decl.parametersJsonSchema = inlineJsonSchema(rawSchema);
828
- // Remove $schema if present - @google/genai doesn't need it
829
- if (decl.parametersJsonSchema.$schema) {
830
- delete decl.parametersJsonSchema.$schema;
831
- }
832
- }
833
- functionDeclarations.push(decl);
834
- if (tool.execute) {
835
- executeMap.set(name, tool.execute);
836
- }
837
- }
838
- tools = [{ functionDeclarations }];
650
+ const result = buildNativeToolDeclarations(mergedTools);
651
+ toolsConfig = result.toolsConfig;
652
+ executeMap = result.executeMap;
839
653
  logger.debug("[GoogleAIStudio] Converted tools for native SDK generate", {
840
- toolCount: functionDeclarations.length,
841
- toolNames: functionDeclarations.map((t) => t.name),
654
+ toolCount: toolsConfig[0].functionDeclarations.length,
655
+ toolNames: toolsConfig[0].functionDeclarations.map((t) => t.name),
842
656
  });
843
657
  }
844
658
  }
845
- // Build config
846
- const config = {
847
- temperature: options.temperature ?? 1.0, // Gemini 3 requires 1.0 for tool calling
848
- maxOutputTokens: options.maxTokens,
849
- };
850
- if (tools) {
851
- config.tools = tools;
852
- }
853
- if (options.systemPrompt) {
854
- config.systemInstruction = options.systemPrompt;
855
- }
659
+ const config = buildNativeConfig(options, toolsConfig);
856
660
  const startTime = Date.now();
857
- // Ensure maxSteps is a valid positive integer to prevent infinite loops
858
- const rawMaxSteps = options.maxSteps || DEFAULT_MAX_STEPS;
859
- const maxSteps = Number.isFinite(rawMaxSteps) && rawMaxSteps > 0
860
- ? Math.min(Math.floor(rawMaxSteps), 100) // Cap at 100 for safety
861
- : Math.min(DEFAULT_MAX_STEPS, 100);
862
- const currentContents = [...contents];
661
+ const timeout = this.getTimeout(options);
662
+ const timeoutController = createTimeoutController(timeout, this.providerName, "generate");
663
+ const composedSignal = composeAbortSignals(options.abortSignal, timeoutController?.controller.signal);
664
+ const maxSteps = computeMaxSteps(options.maxSteps);
863
665
  let finalText = "";
864
- let lastStepText = ""; // Track text from last step for maxSteps termination
666
+ let lastStepText = "";
865
667
  let totalInputTokens = 0;
866
668
  let totalOutputTokens = 0;
867
669
  const allToolCalls = [];
868
670
  const toolExecutions = [];
869
671
  let step = 0;
870
- // Track failed tools to prevent infinite retry loops
871
- // Key: tool name, Value: { count: retry attempts, lastError: error message }
872
672
  const failedTools = new Map();
873
- // Agentic loop for tool calling
874
- while (step < maxSteps) {
875
- step++;
876
- logger.debug(`[GoogleAIStudio] Native SDK generate step ${step}/${maxSteps}`);
877
- try {
878
- const stream = await client.models.generateContentStream({
879
- model: modelName,
880
- contents: currentContents,
881
- config,
882
- });
883
- const stepFunctionCalls = [];
884
- // Capture all raw parts including thoughtSignature for history
885
- const rawResponseParts = [];
886
- for await (const chunk of stream) {
887
- // Extract raw parts from candidates FIRST
888
- // This avoids using chunk.text which triggers SDK warning when
889
- // non-text parts (thoughtSignature, functionCall) are present
890
- const chunkRecord = chunk;
891
- const candidates = chunkRecord.candidates;
892
- const firstCandidate = candidates?.[0];
893
- const chunkContent = firstCandidate?.content;
894
- if (chunkContent && Array.isArray(chunkContent.parts)) {
895
- rawResponseParts.push(...chunkContent.parts);
896
- }
897
- if (chunk.functionCalls) {
898
- stepFunctionCalls.push(...chunk.functionCalls);
899
- }
900
- // Accumulate usage metadata from chunks
901
- const usage = chunkRecord.usageMetadata;
902
- if (usage) {
903
- totalInputTokens = Math.max(totalInputTokens, usage.promptTokenCount || 0);
904
- totalOutputTokens = Math.max(totalOutputTokens, usage.candidatesTokenCount || 0);
905
- }
906
- }
907
- // Extract text from raw parts after stream completes
908
- // This avoids SDK warning about non-text parts (thoughtSignature, functionCall)
909
- const stepText = rawResponseParts
910
- .filter((part) => typeof part.text === "string")
911
- .map((part) => part.text)
912
- .join("");
913
- // If no function calls, we're done
914
- if (stepFunctionCalls.length === 0) {
915
- finalText = stepText;
673
+ try {
674
+ // Agentic loop for tool calling
675
+ while (step < maxSteps) {
676
+ if (composedSignal?.aborted) {
916
677
  break;
917
678
  }
918
- // Track the last step text for maxSteps termination
919
- lastStepText = stepText;
920
- // Execute function calls
921
- logger.debug(`[GoogleAIStudio] Executing ${stepFunctionCalls.length} function calls in generate`);
922
- // Add model response with ALL parts (including thoughtSignature) to history
923
- // This is critical for Gemini 3 - it requires thought signatures in subsequent turns
924
- currentContents.push({
925
- role: "model",
926
- parts: rawResponseParts.length > 0
927
- ? rawResponseParts
928
- : stepFunctionCalls.map((fc) => ({
929
- functionCall: fc,
930
- })),
931
- });
932
- // Execute each function and collect responses
933
- const functionResponses = [];
934
- for (const call of stepFunctionCalls) {
935
- allToolCalls.push({ toolName: call.name, args: call.args });
936
- // Check if this tool has already exceeded retry limit
937
- const failedInfo = failedTools.get(call.name);
938
- if (failedInfo && failedInfo.count >= DEFAULT_TOOL_MAX_RETRIES) {
939
- logger.warn(`[GoogleAIStudio] Tool "${call.name}" has exceeded retry limit (${DEFAULT_TOOL_MAX_RETRIES}), skipping execution`);
940
- const errorOutput = {
941
- error: `TOOL_PERMANENTLY_FAILED: The tool "${call.name}" has failed ${failedInfo.count} times and will not be retried. Last error: ${failedInfo.lastError}. Please proceed without using this tool or inform the user that this functionality is unavailable.`,
942
- status: "permanently_failed",
943
- do_not_retry: true,
944
- };
945
- functionResponses.push({
946
- functionResponse: {
947
- name: call.name,
948
- response: errorOutput,
949
- },
950
- });
951
- toolExecutions.push({
952
- name: call.name,
953
- input: call.args,
954
- output: errorOutput,
955
- });
956
- continue;
957
- }
958
- const execute = executeMap.get(call.name);
959
- if (execute) {
960
- try {
961
- // AI SDK Tool execute requires (args, options) - provide minimal options
962
- const toolOptions = {
963
- toolCallId: `${call.name}-${Date.now()}`,
964
- messages: [],
965
- abortSignal: undefined,
966
- };
967
- const result = await execute(call.args, toolOptions);
968
- functionResponses.push({
969
- functionResponse: { name: call.name, response: { result } },
970
- });
971
- toolExecutions.push({
972
- name: call.name,
973
- input: call.args,
974
- output: result,
975
- });
976
- }
977
- catch (error) {
978
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
979
- // Track this failure
980
- const currentFailInfo = failedTools.get(call.name) || {
981
- count: 0,
982
- lastError: "",
983
- };
984
- currentFailInfo.count++;
985
- currentFailInfo.lastError = errorMessage;
986
- failedTools.set(call.name, currentFailInfo);
987
- logger.warn(`[GoogleAIStudio] Tool "${call.name}" failed (attempt ${currentFailInfo.count}/${DEFAULT_TOOL_MAX_RETRIES}): ${errorMessage}`);
988
- // Determine if this is a permanent failure
989
- const isPermanentFailure = currentFailInfo.count >= DEFAULT_TOOL_MAX_RETRIES;
990
- const errorOutput = {
991
- error: isPermanentFailure
992
- ? `TOOL_PERMANENTLY_FAILED: The tool "${call.name}" has failed ${currentFailInfo.count} times with error: ${errorMessage}. This tool will not be retried. Please proceed without using this tool or inform the user that this functionality is unavailable.`
993
- : `TOOL_EXECUTION_ERROR: ${errorMessage}. Retry attempt ${currentFailInfo.count}/${DEFAULT_TOOL_MAX_RETRIES}.`,
994
- status: isPermanentFailure ? "permanently_failed" : "failed",
995
- do_not_retry: isPermanentFailure,
996
- retry_count: currentFailInfo.count,
997
- max_retries: DEFAULT_TOOL_MAX_RETRIES,
998
- };
999
- functionResponses.push({
1000
- functionResponse: {
1001
- name: call.name,
1002
- response: errorOutput,
1003
- },
1004
- });
1005
- toolExecutions.push({
1006
- name: call.name,
1007
- input: call.args,
1008
- output: errorOutput,
1009
- });
1010
- }
1011
- }
1012
- else {
1013
- // Tool not found is a permanent error
1014
- const errorOutput = {
1015
- error: `TOOL_NOT_FOUND: The tool "${call.name}" does not exist. Do not attempt to call this tool again.`,
1016
- status: "permanently_failed",
1017
- do_not_retry: true,
1018
- };
1019
- functionResponses.push({
1020
- functionResponse: {
1021
- name: call.name,
1022
- response: errorOutput,
1023
- },
1024
- });
1025
- toolExecutions.push({
1026
- name: call.name,
1027
- input: call.args,
1028
- output: errorOutput,
1029
- });
679
+ step++;
680
+ logger.debug(`[GoogleAIStudio] Native SDK generate step ${step}/${maxSteps}`);
681
+ try {
682
+ const stream = await client.models.generateContentStream({
683
+ model: modelName,
684
+ contents: currentContents,
685
+ config,
686
+ ...(composedSignal
687
+ ? { httpOptions: { signal: composedSignal } }
688
+ : {}),
689
+ });
690
+ const chunkResult = await collectStreamChunks(stream);
691
+ totalInputTokens += chunkResult.inputTokens;
692
+ totalOutputTokens += chunkResult.outputTokens;
693
+ const stepText = extractTextFromParts(chunkResult.rawResponseParts);
694
+ // If no function calls, we're done
695
+ if (chunkResult.stepFunctionCalls.length === 0) {
696
+ finalText = stepText;
697
+ break;
1030
698
  }
699
+ lastStepText = stepText;
700
+ logger.debug(`[GoogleAIStudio] Executing ${chunkResult.stepFunctionCalls.length} function calls in generate`);
701
+ // Add model response with ALL parts (including thoughtSignature) to history
702
+ // This is critical for Gemini 3 - it requires thought signatures in subsequent turns
703
+ pushModelResponseToHistory(currentContents, chunkResult.rawResponseParts, chunkResult.stepFunctionCalls);
704
+ const functionResponses = await executeNativeToolCalls("[GoogleAIStudio]", chunkResult.stepFunctionCalls, executeMap, failedTools, allToolCalls, { toolExecutions, abortSignal: composedSignal });
705
+ // Add function responses to history
706
+ currentContents.push({
707
+ role: "function",
708
+ parts: functionResponses,
709
+ });
710
+ }
711
+ catch (error) {
712
+ logger.error("[GoogleAIStudio] Native SDK generate error", error);
713
+ throw this.handleProviderError(error);
1031
714
  }
1032
- // Add function responses to history
1033
- currentContents.push({
1034
- role: "function",
1035
- parts: functionResponses,
1036
- });
1037
- }
1038
- catch (error) {
1039
- logger.error("[GoogleAIStudio] Native SDK generate error", error);
1040
- throw this.handleProviderError(error);
1041
715
  }
1042
716
  }
1043
- // Handle maxSteps termination - if we exited the loop due to maxSteps being reached
1044
- if (step >= maxSteps && !finalText) {
1045
- logger.warn(`[GoogleAIStudio] Generate tool call loop terminated after reaching maxSteps (${maxSteps}). ` +
1046
- `Model was still calling tools. Using accumulated text from last step.`);
1047
- finalText =
1048
- lastStepText ||
1049
- `[Tool execution limit reached after ${maxSteps} steps. The model continued requesting tool calls beyond the limit.]`;
717
+ finally {
718
+ timeoutController?.cleanup();
1050
719
  }
720
+ finalText = handleMaxStepsTermination("[GoogleAIStudio]", step, maxSteps, finalText, lastStepText);
1051
721
  const responseTime = Date.now() - startTime;
1052
722
  // Build EnhancedGenerateResult
1053
723
  return {
@@ -1082,10 +752,19 @@ export class GoogleAIStudioProvider extends BaseProvider {
1082
752
  (options.tools && Object.keys(options.tools).length > 0));
1083
753
  if (isGemini3Model(modelName) && hasTools) {
1084
754
  // Merge SDK tools into options for native SDK path
1085
- const mergedOptions = {
755
+ let mergedOptions = {
1086
756
  ...options,
1087
757
  tools: { ...sdkTools, ...(options.tools || {}) },
1088
758
  };
759
+ // Check for tools + JSON schema conflict (Gemini limitation)
760
+ const wantsJsonOutput = options.output?.format === "json" || options.schema;
761
+ if (wantsJsonOutput &&
762
+ mergedOptions.tools &&
763
+ Object.keys(mergedOptions.tools).length > 0 &&
764
+ !mergedOptions.disableTools) {
765
+ logger.warn("[GoogleAIStudio] Gemini does not support tools and JSON schema output simultaneously. Disabling tools for this request.");
766
+ mergedOptions = { ...mergedOptions, disableTools: true, tools: {} };
767
+ }
1089
768
  logger.info("[GoogleAIStudio] Routing Gemini 3 generate to native SDK for tool calling", {
1090
769
  model: modelName,
1091
770
  sdkToolCount: Object.keys(sdkTools).length,