@juspay/neurolink 9.5.2 → 9.6.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 (356) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +29 -25
  3. package/dist/agent/directTools.d.ts +5 -5
  4. package/dist/cli/commands/config.d.ts +9 -9
  5. package/dist/cli/commands/serve.d.ts +37 -0
  6. package/dist/cli/commands/serve.js +302 -229
  7. package/dist/cli/commands/setup-anthropic.d.ts +2 -2
  8. package/dist/cli/commands/setup-azure.d.ts +2 -2
  9. package/dist/cli/commands/setup-bedrock.d.ts +2 -2
  10. package/dist/cli/commands/setup-gcp.d.ts +2 -2
  11. package/dist/cli/commands/setup-google-ai.d.ts +2 -2
  12. package/dist/cli/commands/setup-huggingface.d.ts +2 -2
  13. package/dist/cli/commands/setup-mistral.d.ts +2 -2
  14. package/dist/cli/commands/setup-openai.d.ts +2 -2
  15. package/dist/cli/commands/setup.d.ts +2 -2
  16. package/dist/cli/factories/commandFactory.js +16 -2
  17. package/dist/cli/loop/optionsSchema.d.ts +2 -2
  18. package/dist/cli/loop/session.d.ts +4 -0
  19. package/dist/cli/loop/session.js +49 -4
  20. package/dist/cli/utils/interactiveSetup.d.ts +4 -4
  21. package/dist/config/conversationMemory.d.ts +2 -0
  22. package/dist/config/conversationMemory.js +5 -5
  23. package/dist/constants/contextWindows.d.ts +46 -0
  24. package/dist/constants/contextWindows.js +156 -0
  25. package/dist/context/budgetChecker.d.ts +18 -0
  26. package/dist/context/budgetChecker.js +71 -0
  27. package/dist/context/contextCompactor.d.ts +22 -0
  28. package/dist/context/contextCompactor.js +106 -0
  29. package/dist/context/effectiveHistory.d.ts +52 -0
  30. package/dist/context/effectiveHistory.js +105 -0
  31. package/dist/context/errorDetection.d.ts +14 -0
  32. package/dist/context/errorDetection.js +124 -0
  33. package/dist/context/fileSummarizationService.d.ts +54 -0
  34. package/dist/context/fileSummarizationService.js +255 -0
  35. package/dist/context/fileSummarizer.d.ts +56 -0
  36. package/dist/context/fileSummarizer.js +145 -0
  37. package/dist/context/fileTokenBudget.d.ts +53 -0
  38. package/dist/context/fileTokenBudget.js +127 -0
  39. package/dist/context/prompts/summarizationPrompt.d.ts +17 -0
  40. package/dist/context/prompts/summarizationPrompt.js +110 -0
  41. package/dist/context/stages/fileReadDeduplicator.d.ts +10 -0
  42. package/dist/context/stages/fileReadDeduplicator.js +66 -0
  43. package/dist/context/stages/slidingWindowTruncator.d.ts +11 -0
  44. package/dist/context/stages/slidingWindowTruncator.js +42 -0
  45. package/dist/context/stages/structuredSummarizer.d.ts +10 -0
  46. package/dist/context/stages/structuredSummarizer.js +49 -0
  47. package/dist/context/stages/toolOutputPruner.d.ts +10 -0
  48. package/dist/context/stages/toolOutputPruner.js +52 -0
  49. package/dist/context/summarizationEngine.d.ts +45 -0
  50. package/dist/context/summarizationEngine.js +110 -0
  51. package/dist/context/toolOutputLimits.d.ts +17 -0
  52. package/dist/context/toolOutputLimits.js +84 -0
  53. package/dist/context/toolPairRepair.d.ts +16 -0
  54. package/dist/context/toolPairRepair.js +66 -0
  55. package/dist/core/conversationMemoryManager.d.ts +5 -15
  56. package/dist/core/conversationMemoryManager.js +15 -75
  57. package/dist/core/modules/MessageBuilder.d.ts +1 -1
  58. package/dist/core/modules/MessageBuilder.js +2 -0
  59. package/dist/core/modules/TelemetryHandler.d.ts +2 -3
  60. package/dist/core/modules/TelemetryHandler.js +3 -3
  61. package/dist/core/modules/ToolsManager.d.ts +2 -2
  62. package/dist/core/redisConversationMemoryManager.d.ts +8 -14
  63. package/dist/core/redisConversationMemoryManager.js +69 -78
  64. package/dist/factories/providerFactory.d.ts +2 -2
  65. package/dist/files/fileReferenceRegistry.d.ts +276 -0
  66. package/dist/files/fileReferenceRegistry.js +1543 -0
  67. package/dist/files/fileTools.d.ts +423 -0
  68. package/dist/files/fileTools.js +449 -0
  69. package/dist/files/index.d.ts +14 -0
  70. package/dist/files/index.js +13 -0
  71. package/dist/files/streamingReader.d.ts +93 -0
  72. package/dist/files/streamingReader.js +321 -0
  73. package/dist/files/types.d.ts +23 -0
  74. package/dist/files/types.js +23 -0
  75. package/dist/image-gen/imageGenTools.d.ts +2 -2
  76. package/dist/image-gen/types.d.ts +12 -12
  77. package/dist/lib/agent/directTools.d.ts +7 -7
  78. package/dist/lib/config/conversationMemory.d.ts +2 -0
  79. package/dist/lib/config/conversationMemory.js +5 -5
  80. package/dist/lib/constants/contextWindows.d.ts +46 -0
  81. package/dist/lib/constants/contextWindows.js +157 -0
  82. package/dist/lib/context/budgetChecker.d.ts +18 -0
  83. package/dist/lib/context/budgetChecker.js +72 -0
  84. package/dist/lib/context/contextCompactor.d.ts +22 -0
  85. package/dist/lib/context/contextCompactor.js +107 -0
  86. package/dist/lib/context/effectiveHistory.d.ts +52 -0
  87. package/dist/lib/context/effectiveHistory.js +106 -0
  88. package/dist/lib/context/errorDetection.d.ts +14 -0
  89. package/dist/lib/context/errorDetection.js +125 -0
  90. package/dist/lib/context/fileSummarizationService.d.ts +54 -0
  91. package/dist/lib/context/fileSummarizationService.js +256 -0
  92. package/dist/lib/context/fileSummarizer.d.ts +56 -0
  93. package/dist/lib/context/fileSummarizer.js +146 -0
  94. package/dist/lib/context/fileTokenBudget.d.ts +53 -0
  95. package/dist/lib/context/fileTokenBudget.js +128 -0
  96. package/dist/lib/context/prompts/summarizationPrompt.d.ts +17 -0
  97. package/dist/lib/context/prompts/summarizationPrompt.js +111 -0
  98. package/dist/lib/context/stages/fileReadDeduplicator.d.ts +10 -0
  99. package/dist/lib/context/stages/fileReadDeduplicator.js +67 -0
  100. package/dist/lib/context/stages/slidingWindowTruncator.d.ts +11 -0
  101. package/dist/lib/context/stages/slidingWindowTruncator.js +43 -0
  102. package/dist/lib/context/stages/structuredSummarizer.d.ts +10 -0
  103. package/dist/lib/context/stages/structuredSummarizer.js +50 -0
  104. package/dist/lib/context/stages/toolOutputPruner.d.ts +10 -0
  105. package/dist/lib/context/stages/toolOutputPruner.js +53 -0
  106. package/dist/lib/context/summarizationEngine.d.ts +45 -0
  107. package/dist/lib/context/summarizationEngine.js +111 -0
  108. package/dist/lib/context/toolOutputLimits.d.ts +17 -0
  109. package/dist/lib/context/toolOutputLimits.js +85 -0
  110. package/dist/lib/context/toolPairRepair.d.ts +16 -0
  111. package/dist/lib/context/toolPairRepair.js +67 -0
  112. package/dist/lib/core/conversationMemoryManager.d.ts +5 -15
  113. package/dist/lib/core/conversationMemoryManager.js +15 -75
  114. package/dist/lib/core/modules/MessageBuilder.d.ts +1 -1
  115. package/dist/lib/core/modules/MessageBuilder.js +2 -0
  116. package/dist/lib/core/modules/TelemetryHandler.d.ts +2 -3
  117. package/dist/lib/core/modules/TelemetryHandler.js +3 -3
  118. package/dist/lib/core/modules/ToolsManager.d.ts +2 -2
  119. package/dist/lib/core/redisConversationMemoryManager.d.ts +8 -14
  120. package/dist/lib/core/redisConversationMemoryManager.js +69 -78
  121. package/dist/lib/factories/providerFactory.d.ts +2 -2
  122. package/dist/lib/files/fileReferenceRegistry.d.ts +276 -0
  123. package/dist/lib/files/fileReferenceRegistry.js +1544 -0
  124. package/dist/lib/files/fileTools.d.ts +423 -0
  125. package/dist/lib/files/fileTools.js +450 -0
  126. package/dist/lib/files/index.d.ts +14 -0
  127. package/dist/lib/files/index.js +14 -0
  128. package/dist/lib/files/streamingReader.d.ts +93 -0
  129. package/dist/lib/files/streamingReader.js +322 -0
  130. package/dist/lib/files/types.d.ts +23 -0
  131. package/dist/lib/files/types.js +24 -0
  132. package/dist/lib/image-gen/imageGenTools.d.ts +2 -2
  133. package/dist/lib/image-gen/types.d.ts +12 -12
  134. package/dist/lib/memory/mem0Initializer.d.ts +2 -2
  135. package/dist/lib/neurolink.d.ts +61 -2
  136. package/dist/lib/neurolink.js +619 -307
  137. package/dist/lib/processors/archive/ArchiveProcessor.d.ts +327 -0
  138. package/dist/lib/processors/archive/ArchiveProcessor.js +1309 -0
  139. package/dist/lib/processors/archive/index.d.ts +33 -0
  140. package/dist/lib/processors/archive/index.js +43 -0
  141. package/dist/lib/processors/base/types.d.ts +70 -64
  142. package/dist/lib/processors/base/types.js +6 -0
  143. package/dist/lib/processors/cli/fileProcessorCli.d.ts +8 -8
  144. package/dist/lib/processors/cli/fileProcessorCli.js +5 -5
  145. package/dist/lib/processors/config/mimeTypes.js +25 -0
  146. package/dist/lib/processors/config/sizeLimits.d.ts +52 -40
  147. package/dist/lib/processors/config/sizeLimits.js +56 -44
  148. package/dist/lib/processors/document/ExcelProcessor.d.ts +14 -0
  149. package/dist/lib/processors/document/ExcelProcessor.js +72 -1
  150. package/dist/lib/processors/document/PptxProcessor.d.ts +63 -0
  151. package/dist/lib/processors/document/PptxProcessor.js +158 -0
  152. package/dist/lib/processors/document/index.d.ts +1 -0
  153. package/dist/lib/processors/document/index.js +6 -0
  154. package/dist/lib/processors/errors/FileErrorCode.d.ts +2 -2
  155. package/dist/lib/processors/errors/errorHelpers.d.ts +2 -2
  156. package/dist/lib/processors/errors/errorSerializer.d.ts +4 -4
  157. package/dist/lib/processors/index.d.ts +8 -2
  158. package/dist/lib/processors/index.js +5 -2
  159. package/dist/lib/processors/integration/FileProcessorIntegration.d.ts +8 -8
  160. package/dist/lib/processors/integration/FileProcessorIntegration.js +7 -7
  161. package/dist/lib/processors/media/AudioProcessor.d.ts +328 -0
  162. package/dist/lib/processors/media/AudioProcessor.js +708 -0
  163. package/dist/lib/processors/media/VideoProcessor.d.ts +350 -0
  164. package/dist/lib/processors/media/VideoProcessor.js +992 -0
  165. package/dist/lib/processors/media/index.d.ts +27 -0
  166. package/dist/lib/processors/media/index.js +37 -0
  167. package/dist/lib/processors/registry/ProcessorRegistry.d.ts +19 -5
  168. package/dist/lib/processors/registry/ProcessorRegistry.js +103 -8
  169. package/dist/lib/processors/registry/index.d.ts +1 -1
  170. package/dist/lib/processors/registry/index.js +1 -1
  171. package/dist/lib/processors/registry/types.d.ts +2 -2
  172. package/dist/lib/providers/googleAiStudio.d.ts +34 -0
  173. package/dist/lib/providers/googleAiStudio.js +267 -397
  174. package/dist/lib/providers/googleVertex.d.ts +55 -1
  175. package/dist/lib/providers/googleVertex.js +452 -719
  176. package/dist/lib/providers/sagemaker/detection.d.ts +6 -6
  177. package/dist/lib/providers/sagemaker/diagnostics.d.ts +4 -4
  178. package/dist/lib/providers/sagemaker/parsers.d.ts +4 -4
  179. package/dist/lib/rag/chunkers/RecursiveChunker.js +2 -2
  180. package/dist/lib/rag/document/loaders.d.ts +6 -71
  181. package/dist/lib/rag/document/loaders.js +5 -5
  182. package/dist/lib/rag/graphRag/graphRAG.js +26 -9
  183. package/dist/lib/rag/metadata/MetadataExtractorFactory.d.ts +5 -55
  184. package/dist/lib/rag/metadata/metadataExtractor.js +6 -3
  185. package/dist/lib/rag/pipeline/RAGPipeline.d.ts +8 -126
  186. package/dist/lib/rag/pipeline/RAGPipeline.js +11 -11
  187. package/dist/lib/rag/pipeline/contextAssembly.d.ts +3 -42
  188. package/dist/lib/rag/pipeline/contextAssembly.js +6 -3
  189. package/dist/lib/rag/reranker/RerankerFactory.d.ts +5 -60
  190. package/dist/lib/rag/resilience/CircuitBreaker.d.ts +3 -33
  191. package/dist/lib/rag/resilience/RetryHandler.d.ts +2 -21
  192. package/dist/lib/rag/retrieval/hybridSearch.d.ts +3 -41
  193. package/dist/lib/rag/retrieval/vectorQueryTool.d.ts +2 -13
  194. package/dist/lib/rag/retrieval/vectorQueryTool.js +4 -3
  195. package/dist/lib/rag/types.d.ts +3 -3
  196. package/dist/lib/sdk/toolRegistration.d.ts +2 -2
  197. package/dist/lib/server/middleware/cache.d.ts +2 -2
  198. package/dist/lib/server/middleware/rateLimit.d.ts +2 -2
  199. package/dist/lib/server/routes/mcpRoutes.js +277 -249
  200. package/dist/lib/server/routes/memoryRoutes.js +287 -281
  201. package/dist/lib/server/utils/validation.d.ts +10 -10
  202. package/dist/lib/session/globalSessionState.d.ts +2 -2
  203. package/dist/lib/telemetry/telemetryService.d.ts +2 -2
  204. package/dist/lib/types/common.d.ts +39 -0
  205. package/dist/lib/types/contextTypes.d.ts +255 -0
  206. package/dist/lib/types/contextTypes.js +0 -2
  207. package/dist/lib/types/conversation.d.ts +62 -0
  208. package/dist/lib/types/conversationMemoryInterface.d.ts +27 -0
  209. package/dist/lib/types/conversationMemoryInterface.js +7 -0
  210. package/dist/lib/types/fileReferenceTypes.d.ts +222 -0
  211. package/dist/lib/types/fileReferenceTypes.js +9 -0
  212. package/dist/lib/types/fileTypes.d.ts +26 -3
  213. package/dist/lib/types/generateTypes.d.ts +22 -1
  214. package/dist/lib/types/index.d.ts +4 -5
  215. package/dist/lib/types/index.js +8 -10
  216. package/dist/lib/types/modelTypes.d.ts +2 -2
  217. package/dist/lib/types/processorTypes.d.ts +597 -0
  218. package/dist/lib/types/processorTypes.js +91 -0
  219. package/dist/lib/types/ragTypes.d.ts +481 -0
  220. package/dist/lib/types/ragTypes.js +8 -0
  221. package/dist/lib/types/sdkTypes.d.ts +17 -18
  222. package/dist/lib/types/streamTypes.d.ts +11 -1
  223. package/dist/lib/utils/async/retry.d.ts +2 -2
  224. package/dist/lib/utils/async/withTimeout.js +3 -1
  225. package/dist/lib/utils/conversationMemory.d.ts +12 -6
  226. package/dist/lib/utils/conversationMemory.js +76 -36
  227. package/dist/lib/utils/fileDetector.d.ts +62 -0
  228. package/dist/lib/utils/fileDetector.js +1014 -14
  229. package/dist/lib/utils/json/safeParse.d.ts +2 -2
  230. package/dist/lib/utils/messageBuilder.js +806 -153
  231. package/dist/lib/utils/modelChoices.d.ts +2 -2
  232. package/dist/lib/utils/multimodalOptionsBuilder.d.ts +2 -1
  233. package/dist/lib/utils/multimodalOptionsBuilder.js +1 -0
  234. package/dist/lib/utils/rateLimiter.d.ts +2 -2
  235. package/dist/lib/utils/sanitizers/filename.d.ts +4 -4
  236. package/dist/lib/utils/sanitizers/svg.d.ts +2 -2
  237. package/dist/lib/utils/thinkingConfig.d.ts +6 -6
  238. package/dist/lib/utils/tokenEstimation.d.ts +68 -0
  239. package/dist/lib/utils/tokenEstimation.js +113 -0
  240. package/dist/lib/utils/tokenUtils.d.ts +4 -4
  241. package/dist/lib/utils/ttsProcessor.d.ts +2 -2
  242. package/dist/lib/workflow/config.d.ts +150 -150
  243. package/dist/memory/mem0Initializer.d.ts +2 -2
  244. package/dist/neurolink.d.ts +61 -2
  245. package/dist/neurolink.js +619 -307
  246. package/dist/processors/archive/ArchiveProcessor.d.ts +327 -0
  247. package/dist/processors/archive/ArchiveProcessor.js +1308 -0
  248. package/dist/processors/archive/index.d.ts +33 -0
  249. package/dist/processors/archive/index.js +42 -0
  250. package/dist/processors/base/types.d.ts +70 -64
  251. package/dist/processors/base/types.js +6 -0
  252. package/dist/processors/cli/fileProcessorCli.d.ts +8 -8
  253. package/dist/processors/cli/fileProcessorCli.js +5 -5
  254. package/dist/processors/config/mimeTypes.js +25 -0
  255. package/dist/processors/config/sizeLimits.d.ts +52 -40
  256. package/dist/processors/config/sizeLimits.js +56 -44
  257. package/dist/processors/document/ExcelProcessor.d.ts +14 -0
  258. package/dist/processors/document/ExcelProcessor.js +72 -1
  259. package/dist/processors/document/PptxProcessor.d.ts +63 -0
  260. package/dist/processors/document/PptxProcessor.js +157 -0
  261. package/dist/processors/document/index.d.ts +1 -0
  262. package/dist/processors/document/index.js +6 -0
  263. package/dist/processors/errors/FileErrorCode.d.ts +2 -2
  264. package/dist/processors/errors/errorHelpers.d.ts +2 -2
  265. package/dist/processors/errors/errorSerializer.d.ts +4 -4
  266. package/dist/processors/index.d.ts +8 -2
  267. package/dist/processors/index.js +5 -2
  268. package/dist/processors/integration/FileProcessorIntegration.d.ts +8 -8
  269. package/dist/processors/integration/FileProcessorIntegration.js +7 -7
  270. package/dist/processors/media/AudioProcessor.d.ts +328 -0
  271. package/dist/processors/media/AudioProcessor.js +707 -0
  272. package/dist/processors/media/VideoProcessor.d.ts +350 -0
  273. package/dist/processors/media/VideoProcessor.js +991 -0
  274. package/dist/processors/media/ffprobe-static.d.ts +4 -0
  275. package/dist/processors/media/index.d.ts +27 -0
  276. package/dist/processors/media/index.js +36 -0
  277. package/dist/processors/registry/ProcessorRegistry.d.ts +19 -5
  278. package/dist/processors/registry/ProcessorRegistry.js +103 -8
  279. package/dist/processors/registry/index.d.ts +1 -1
  280. package/dist/processors/registry/index.js +1 -1
  281. package/dist/processors/registry/types.d.ts +2 -2
  282. package/dist/providers/googleAiStudio.d.ts +34 -0
  283. package/dist/providers/googleAiStudio.js +267 -397
  284. package/dist/providers/googleVertex.d.ts +55 -1
  285. package/dist/providers/googleVertex.js +452 -719
  286. package/dist/providers/sagemaker/detection.d.ts +6 -6
  287. package/dist/providers/sagemaker/diagnostics.d.ts +4 -4
  288. package/dist/providers/sagemaker/parsers.d.ts +4 -4
  289. package/dist/rag/chunkers/RecursiveChunker.js +2 -2
  290. package/dist/rag/document/loaders.d.ts +6 -71
  291. package/dist/rag/document/loaders.js +5 -5
  292. package/dist/rag/graphRag/graphRAG.js +26 -9
  293. package/dist/rag/metadata/MetadataExtractorFactory.d.ts +5 -55
  294. package/dist/rag/metadata/metadataExtractor.js +6 -3
  295. package/dist/rag/pipeline/RAGPipeline.d.ts +8 -126
  296. package/dist/rag/pipeline/RAGPipeline.js +11 -11
  297. package/dist/rag/pipeline/contextAssembly.d.ts +3 -42
  298. package/dist/rag/pipeline/contextAssembly.js +6 -3
  299. package/dist/rag/reranker/RerankerFactory.d.ts +5 -60
  300. package/dist/rag/resilience/CircuitBreaker.d.ts +3 -33
  301. package/dist/rag/resilience/RetryHandler.d.ts +2 -21
  302. package/dist/rag/retrieval/hybridSearch.d.ts +3 -41
  303. package/dist/rag/retrieval/vectorQueryTool.d.ts +2 -13
  304. package/dist/rag/retrieval/vectorQueryTool.js +4 -3
  305. package/dist/rag/types.d.ts +3 -3
  306. package/dist/sdk/toolRegistration.d.ts +2 -2
  307. package/dist/server/middleware/cache.d.ts +2 -2
  308. package/dist/server/middleware/rateLimit.d.ts +2 -2
  309. package/dist/server/routes/mcpRoutes.js +277 -249
  310. package/dist/server/routes/memoryRoutes.js +287 -281
  311. package/dist/server/utils/validation.d.ts +4 -4
  312. package/dist/session/globalSessionState.d.ts +2 -2
  313. package/dist/telemetry/telemetryService.d.ts +2 -2
  314. package/dist/types/common.d.ts +39 -0
  315. package/dist/types/contextTypes.d.ts +255 -0
  316. package/dist/types/contextTypes.js +0 -2
  317. package/dist/types/conversation.d.ts +62 -0
  318. package/dist/types/conversationMemoryInterface.d.ts +27 -0
  319. package/dist/types/conversationMemoryInterface.js +6 -0
  320. package/dist/types/fileReferenceTypes.d.ts +222 -0
  321. package/dist/types/fileReferenceTypes.js +8 -0
  322. package/dist/types/fileTypes.d.ts +26 -3
  323. package/dist/types/generateTypes.d.ts +22 -1
  324. package/dist/types/index.d.ts +4 -5
  325. package/dist/types/index.js +8 -10
  326. package/dist/types/processorTypes.d.ts +597 -0
  327. package/dist/types/processorTypes.js +90 -0
  328. package/dist/types/ragTypes.d.ts +481 -0
  329. package/dist/types/ragTypes.js +7 -0
  330. package/dist/types/sdkTypes.d.ts +17 -18
  331. package/dist/types/streamTypes.d.ts +11 -1
  332. package/dist/utils/async/retry.d.ts +2 -2
  333. package/dist/utils/async/withTimeout.js +3 -1
  334. package/dist/utils/conversationMemory.d.ts +12 -6
  335. package/dist/utils/conversationMemory.js +76 -36
  336. package/dist/utils/fileDetector.d.ts +62 -0
  337. package/dist/utils/fileDetector.js +1014 -14
  338. package/dist/utils/json/safeParse.d.ts +2 -2
  339. package/dist/utils/messageBuilder.js +806 -153
  340. package/dist/utils/modelChoices.d.ts +2 -2
  341. package/dist/utils/multimodalOptionsBuilder.d.ts +2 -1
  342. package/dist/utils/multimodalOptionsBuilder.js +1 -0
  343. package/dist/utils/rateLimiter.d.ts +2 -2
  344. package/dist/utils/sanitizers/filename.d.ts +4 -4
  345. package/dist/utils/sanitizers/svg.d.ts +2 -2
  346. package/dist/utils/thinkingConfig.d.ts +6 -6
  347. package/dist/utils/tokenEstimation.d.ts +68 -0
  348. package/dist/utils/tokenEstimation.js +112 -0
  349. package/dist/utils/tokenUtils.d.ts +4 -4
  350. package/dist/utils/ttsProcessor.d.ts +2 -2
  351. package/dist/workflow/config.d.ts +104 -104
  352. package/package.json +18 -6
  353. package/dist/lib/utils/conversationMemoryUtils.d.ts +0 -25
  354. package/dist/lib/utils/conversationMemoryUtils.js +0 -138
  355. package/dist/utils/conversationMemoryUtils.d.ts +0 -25
  356. package/dist/utils/conversationMemoryUtils.js +0 -137
@@ -510,82 +510,29 @@ export class GoogleAIStudioProvider extends BaseProvider {
510
510
  hasTools: !!options.tools && Object.keys(options.tools).length > 0,
511
511
  });
512
512
  // 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();
513
+ const currentContents = [{ role: "user", parts: [{ text: options.input.text }] }];
514
+ // Convert tools
515
+ let toolsConfig;
516
+ let executeMap = new Map();
520
517
  if (options.tools &&
521
518
  Object.keys(options.tools).length > 0 &&
522
519
  !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 }];
520
+ const result = this.buildNativeToolDeclarations(options.tools);
521
+ toolsConfig = result.toolsConfig;
522
+ executeMap = result.executeMap;
554
523
  logger.debug("[GoogleAIStudio] Converted tools for native SDK", {
555
- toolCount: functionDeclarations.length,
556
- toolNames: functionDeclarations.map((t) => t.name),
524
+ toolCount: toolsConfig[0].functionDeclarations.length,
525
+ toolNames: toolsConfig[0].functionDeclarations.map((t) => t.name),
557
526
  });
558
527
  }
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];
528
+ const config = this.buildNativeConfig(options, toolsConfig);
529
+ const maxSteps = this.computeMaxSteps(options.maxSteps);
581
530
  let finalText = "";
582
- let lastStepText = ""; // Track text from last step for maxSteps termination
531
+ let lastStepText = "";
583
532
  let totalInputTokens = 0;
584
533
  let totalOutputTokens = 0;
585
534
  const allToolCalls = [];
586
535
  let step = 0;
587
- // Track failed tools to prevent infinite retry loops
588
- // Key: tool name, Value: { count: retry attempts, lastError: error message }
589
536
  const failedTools = new Map();
590
537
  // Agentic loop for tool calling
591
538
  while (step < maxSteps) {
@@ -597,133 +544,27 @@ export class GoogleAIStudioProvider extends BaseProvider {
597
544
  contents: currentContents,
598
545
  config,
599
546
  });
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("");
547
+ const chunkResult = await this.collectStreamChunks(stream);
548
+ totalInputTokens = Math.max(totalInputTokens, chunkResult.inputTokens);
549
+ totalOutputTokens = Math.max(totalOutputTokens, chunkResult.outputTokens);
550
+ const stepText = this.extractTextFromParts(chunkResult.rawResponseParts);
630
551
  // If no function calls, we're done
631
- if (stepFunctionCalls.length === 0) {
552
+ if (chunkResult.stepFunctionCalls.length === 0) {
632
553
  finalText = stepText;
633
554
  break;
634
555
  }
635
- // Track the last step text for maxSteps termination
636
556
  lastStepText = stepText;
637
- // Execute function calls
638
- logger.debug(`[GoogleAIStudio] Executing ${stepFunctionCalls.length} function calls`);
557
+ logger.debug(`[GoogleAIStudio] Executing ${chunkResult.stepFunctionCalls.length} function calls`);
639
558
  // Add model response with ALL parts (including thoughtSignature) to history
640
559
  currentContents.push({
641
560
  role: "model",
642
- parts: rawResponseParts.length > 0
643
- ? rawResponseParts
644
- : stepFunctionCalls.map((fc) => ({
561
+ parts: chunkResult.rawResponseParts.length > 0
562
+ ? chunkResult.rawResponseParts
563
+ : chunkResult.stepFunctionCalls.map((fc) => ({
645
564
  functionCall: fc,
646
565
  })),
647
566
  });
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
- });
725
- }
726
- }
567
+ const functionResponses = await this.executeNativeToolCalls(chunkResult.stepFunctionCalls, executeMap, failedTools, allToolCalls);
727
568
  // Add function responses to history
728
569
  currentContents.push({
729
570
  role: "function",
@@ -736,14 +577,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
736
577
  }
737
578
  }
738
579
  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.]`;
746
- }
580
+ finalText = this.handleMaxStepsTermination(step, maxSteps, finalText, lastStepText);
747
581
  const responseTime = Date.now() - startTime;
748
582
  // Create async iterable for streaming result
749
583
  async function* createTextStream() {
@@ -789,86 +623,35 @@ export class GoogleAIStudioProvider extends BaseProvider {
789
623
  hasTools: !!options.tools && Object.keys(options.tools).length > 0,
790
624
  });
791
625
  // Build contents from input
792
- const contents = [];
793
626
  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
627
+ const currentContents = [{ role: "user", parts: [{ text: promptText }] }];
628
+ // Convert tools (merge SDK tools with options.tools)
629
+ let toolsConfig;
630
+ let executeMap = new Map();
802
631
  const shouldUseTools = !options.disableTools;
803
632
  if (shouldUseTools) {
804
633
  const sdkTools = await this.getAllTools();
805
634
  const mergedTools = { ...sdkTools, ...(options.tools || {}) };
806
635
  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 }];
636
+ const result = this.buildNativeToolDeclarations(mergedTools);
637
+ toolsConfig = result.toolsConfig;
638
+ executeMap = result.executeMap;
839
639
  logger.debug("[GoogleAIStudio] Converted tools for native SDK generate", {
840
- toolCount: functionDeclarations.length,
841
- toolNames: functionDeclarations.map((t) => t.name),
640
+ toolCount: toolsConfig[0].functionDeclarations.length,
641
+ toolNames: toolsConfig[0].functionDeclarations.map((t) => t.name),
842
642
  });
843
643
  }
844
644
  }
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
- }
645
+ const config = this.buildNativeConfig(options, toolsConfig);
856
646
  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];
647
+ const maxSteps = this.computeMaxSteps(options.maxSteps);
863
648
  let finalText = "";
864
- let lastStepText = ""; // Track text from last step for maxSteps termination
649
+ let lastStepText = "";
865
650
  let totalInputTokens = 0;
866
651
  let totalOutputTokens = 0;
867
652
  const allToolCalls = [];
868
653
  const toolExecutions = [];
869
654
  let step = 0;
870
- // Track failed tools to prevent infinite retry loops
871
- // Key: tool name, Value: { count: retry attempts, lastError: error message }
872
655
  const failedTools = new Map();
873
656
  // Agentic loop for tool calling
874
657
  while (step < maxSteps) {
@@ -880,155 +663,28 @@ export class GoogleAIStudioProvider extends BaseProvider {
880
663
  contents: currentContents,
881
664
  config,
882
665
  });
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("");
666
+ const chunkResult = await this.collectStreamChunks(stream);
667
+ totalInputTokens = Math.max(totalInputTokens, chunkResult.inputTokens);
668
+ totalOutputTokens = Math.max(totalOutputTokens, chunkResult.outputTokens);
669
+ const stepText = this.extractTextFromParts(chunkResult.rawResponseParts);
913
670
  // If no function calls, we're done
914
- if (stepFunctionCalls.length === 0) {
671
+ if (chunkResult.stepFunctionCalls.length === 0) {
915
672
  finalText = stepText;
916
673
  break;
917
674
  }
918
- // Track the last step text for maxSteps termination
919
675
  lastStepText = stepText;
920
- // Execute function calls
921
- logger.debug(`[GoogleAIStudio] Executing ${stepFunctionCalls.length} function calls in generate`);
676
+ logger.debug(`[GoogleAIStudio] Executing ${chunkResult.stepFunctionCalls.length} function calls in generate`);
922
677
  // Add model response with ALL parts (including thoughtSignature) to history
923
678
  // This is critical for Gemini 3 - it requires thought signatures in subsequent turns
924
679
  currentContents.push({
925
680
  role: "model",
926
- parts: rawResponseParts.length > 0
927
- ? rawResponseParts
928
- : stepFunctionCalls.map((fc) => ({
681
+ parts: chunkResult.rawResponseParts.length > 0
682
+ ? chunkResult.rawResponseParts
683
+ : chunkResult.stepFunctionCalls.map((fc) => ({
929
684
  functionCall: fc,
930
685
  })),
931
686
  });
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
- });
1030
- }
1031
- }
687
+ const functionResponses = await this.executeNativeToolCalls(chunkResult.stepFunctionCalls, executeMap, failedTools, allToolCalls, toolExecutions);
1032
688
  // Add function responses to history
1033
689
  currentContents.push({
1034
690
  role: "function",
@@ -1040,14 +696,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
1040
696
  throw this.handleProviderError(error);
1041
697
  }
1042
698
  }
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.]`;
1050
- }
699
+ finalText = this.handleMaxStepsTermination(step, maxSteps, finalText, lastStepText);
1051
700
  const responseTime = Date.now() - startTime;
1052
701
  // Build EnhancedGenerateResult
1053
702
  return {
@@ -1099,6 +748,227 @@ export class GoogleAIStudioProvider extends BaseProvider {
1099
748
  return super.generate(optionsOrPrompt);
1100
749
  }
1101
750
  // ===================
751
+ // NATIVE GEMINI 3 HELPER METHODS
752
+ // ===================
753
+ /**
754
+ * Convert Vercel AI SDK tools to @google/genai FunctionDeclarations and an execute map.
755
+ * Shared by executeNativeGemini3Stream and executeNativeGemini3Generate.
756
+ */
757
+ buildNativeToolDeclarations(tools) {
758
+ const functionDeclarations = [];
759
+ const executeMap = new Map();
760
+ for (const [name, tool] of Object.entries(tools)) {
761
+ const decl = {
762
+ name,
763
+ description: tool.description || `Tool: ${name}`,
764
+ };
765
+ if (tool.parameters) {
766
+ let rawSchema;
767
+ if (isZodSchema(tool.parameters)) {
768
+ rawSchema = convertZodToJsonSchema(tool.parameters);
769
+ }
770
+ else if (typeof tool.parameters === "object") {
771
+ rawSchema = tool.parameters;
772
+ }
773
+ else {
774
+ rawSchema = { type: "object", properties: {} };
775
+ }
776
+ decl.parametersJsonSchema = inlineJsonSchema(rawSchema);
777
+ if (decl.parametersJsonSchema.$schema) {
778
+ delete decl.parametersJsonSchema.$schema;
779
+ }
780
+ }
781
+ functionDeclarations.push(decl);
782
+ if (tool.execute) {
783
+ executeMap.set(name, tool.execute);
784
+ }
785
+ }
786
+ return { toolsConfig: [{ functionDeclarations }], executeMap };
787
+ }
788
+ /**
789
+ * Build the native @google/genai config object shared by stream and generate.
790
+ */
791
+ buildNativeConfig(options, toolsConfig) {
792
+ const config = {
793
+ temperature: options.temperature ?? 1.0, // Gemini 3 requires 1.0 for tool calling
794
+ maxOutputTokens: options.maxTokens,
795
+ };
796
+ if (toolsConfig) {
797
+ config.tools = toolsConfig;
798
+ }
799
+ if (options.systemPrompt) {
800
+ config.systemInstruction = options.systemPrompt;
801
+ }
802
+ // Add thinking config for Gemini 3
803
+ const nativeThinkingConfig = createNativeThinkingConfig(options.thinkingConfig);
804
+ if (nativeThinkingConfig) {
805
+ config.thinkingConfig = nativeThinkingConfig;
806
+ }
807
+ return config;
808
+ }
809
+ /**
810
+ * Compute a safe, clamped maxSteps value.
811
+ */
812
+ computeMaxSteps(rawMaxSteps) {
813
+ const value = rawMaxSteps || DEFAULT_MAX_STEPS;
814
+ return Number.isFinite(value) && value > 0
815
+ ? Math.min(Math.floor(value), 100)
816
+ : Math.min(DEFAULT_MAX_STEPS, 100);
817
+ }
818
+ /**
819
+ * Process stream chunks to extract raw response parts, function calls, and usage metadata.
820
+ * Shared by executeNativeGemini3Stream and executeNativeGemini3Generate.
821
+ */
822
+ async collectStreamChunks(stream) {
823
+ const rawResponseParts = [];
824
+ const stepFunctionCalls = [];
825
+ let inputTokens = 0;
826
+ let outputTokens = 0;
827
+ for await (const chunk of stream) {
828
+ // Extract raw parts from candidates FIRST
829
+ // This avoids using chunk.text which triggers SDK warning when
830
+ // non-text parts (thoughtSignature, functionCall) are present
831
+ const chunkRecord = chunk;
832
+ const candidates = chunkRecord.candidates;
833
+ const firstCandidate = candidates?.[0];
834
+ const chunkContent = firstCandidate?.content;
835
+ if (chunkContent && Array.isArray(chunkContent.parts)) {
836
+ rawResponseParts.push(...chunkContent.parts);
837
+ }
838
+ if (chunk.functionCalls) {
839
+ stepFunctionCalls.push(...chunk.functionCalls);
840
+ }
841
+ // Accumulate usage metadata from chunks
842
+ const usage = chunkRecord.usageMetadata;
843
+ if (usage) {
844
+ inputTokens = Math.max(inputTokens, usage.promptTokenCount || 0);
845
+ outputTokens = Math.max(outputTokens, usage.candidatesTokenCount || 0);
846
+ }
847
+ }
848
+ return { rawResponseParts, stepFunctionCalls, inputTokens, outputTokens };
849
+ }
850
+ /**
851
+ * Extract text from raw response parts. Used after collectStreamChunks.
852
+ */
853
+ extractTextFromParts(rawResponseParts) {
854
+ return rawResponseParts
855
+ .filter((part) => typeof part.text === "string")
856
+ .map((part) => part.text)
857
+ .join("");
858
+ }
859
+ /**
860
+ * Execute a batch of function calls with retry tracking and permanent failure detection.
861
+ * Shared by executeNativeGemini3Stream and executeNativeGemini3Generate.
862
+ *
863
+ * Returns function responses for history and optional tool execution records for generate.
864
+ */
865
+ async executeNativeToolCalls(stepFunctionCalls, executeMap, failedTools, allToolCalls, toolExecutions) {
866
+ const functionResponses = [];
867
+ for (const call of stepFunctionCalls) {
868
+ allToolCalls.push({ toolName: call.name, args: call.args });
869
+ // Check if this tool has already exceeded retry limit
870
+ const failedInfo = failedTools.get(call.name);
871
+ if (failedInfo && failedInfo.count >= DEFAULT_TOOL_MAX_RETRIES) {
872
+ logger.warn(`[GoogleAIStudio] Tool "${call.name}" has exceeded retry limit (${DEFAULT_TOOL_MAX_RETRIES}), skipping execution`);
873
+ const errorOutput = {
874
+ 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.`,
875
+ status: "permanently_failed",
876
+ do_not_retry: true,
877
+ };
878
+ functionResponses.push({
879
+ functionResponse: { name: call.name, response: errorOutput },
880
+ });
881
+ toolExecutions?.push({
882
+ name: call.name,
883
+ input: call.args,
884
+ output: errorOutput,
885
+ });
886
+ continue;
887
+ }
888
+ const execute = executeMap.get(call.name);
889
+ if (execute) {
890
+ try {
891
+ // AI SDK Tool execute requires (args, options) - provide minimal options
892
+ const toolOptions = {
893
+ toolCallId: `${call.name}-${Date.now()}`,
894
+ messages: [],
895
+ abortSignal: undefined,
896
+ };
897
+ const result = await execute(call.args, toolOptions);
898
+ functionResponses.push({
899
+ functionResponse: { name: call.name, response: { result } },
900
+ });
901
+ toolExecutions?.push({
902
+ name: call.name,
903
+ input: call.args,
904
+ output: result,
905
+ });
906
+ }
907
+ catch (error) {
908
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
909
+ // Track this failure
910
+ const currentFailInfo = failedTools.get(call.name) || {
911
+ count: 0,
912
+ lastError: "",
913
+ };
914
+ currentFailInfo.count++;
915
+ currentFailInfo.lastError = errorMessage;
916
+ failedTools.set(call.name, currentFailInfo);
917
+ logger.warn(`[GoogleAIStudio] Tool "${call.name}" failed (attempt ${currentFailInfo.count}/${DEFAULT_TOOL_MAX_RETRIES}): ${errorMessage}`);
918
+ // Determine if this is a permanent failure
919
+ const isPermanentFailure = currentFailInfo.count >= DEFAULT_TOOL_MAX_RETRIES;
920
+ const errorOutput = {
921
+ error: isPermanentFailure
922
+ ? `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.`
923
+ : `TOOL_EXECUTION_ERROR: ${errorMessage}. Retry attempt ${currentFailInfo.count}/${DEFAULT_TOOL_MAX_RETRIES}.`,
924
+ status: isPermanentFailure ? "permanently_failed" : "failed",
925
+ do_not_retry: isPermanentFailure,
926
+ retry_count: currentFailInfo.count,
927
+ max_retries: DEFAULT_TOOL_MAX_RETRIES,
928
+ };
929
+ functionResponses.push({
930
+ functionResponse: { name: call.name, response: errorOutput },
931
+ });
932
+ toolExecutions?.push({
933
+ name: call.name,
934
+ input: call.args,
935
+ output: errorOutput,
936
+ });
937
+ }
938
+ }
939
+ else {
940
+ // Tool not found is a permanent error
941
+ const errorOutput = {
942
+ error: `TOOL_NOT_FOUND: The tool "${call.name}" does not exist. Do not attempt to call this tool again.`,
943
+ status: "permanently_failed",
944
+ do_not_retry: true,
945
+ };
946
+ functionResponses.push({
947
+ functionResponse: { name: call.name, response: errorOutput },
948
+ });
949
+ toolExecutions?.push({
950
+ name: call.name,
951
+ input: call.args,
952
+ output: errorOutput,
953
+ });
954
+ }
955
+ }
956
+ return functionResponses;
957
+ }
958
+ /**
959
+ * Handle maxSteps termination by producing a final text when the model
960
+ * was still calling tools when the step limit was reached.
961
+ */
962
+ handleMaxStepsTermination(step, maxSteps, finalText, lastStepText) {
963
+ if (step >= maxSteps && !finalText) {
964
+ logger.warn(`[GoogleAIStudio] Tool call loop terminated after reaching maxSteps (${maxSteps}). ` +
965
+ `Model was still calling tools. Using accumulated text from last step.`);
966
+ return (lastStepText ||
967
+ `[Tool execution limit reached after ${maxSteps} steps. The model continued requesting tool calls beyond the limit.]`);
968
+ }
969
+ return finalText;
970
+ }
971
+ // ===================
1102
972
  // HELPER METHODS
1103
973
  // ===================
1104
974
  async executeAudioStreamViaGeminiLive(options) {