@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.
- package/CHANGELOG.md +16 -0
- package/README.md +29 -25
- package/dist/adapters/video/vertexVideoHandler.js +3 -3
- package/dist/agent/directTools.d.ts +5 -5
- package/dist/cli/commands/config.d.ts +9 -9
- package/dist/cli/commands/serve.d.ts +37 -0
- package/dist/cli/commands/serve.js +302 -229
- package/dist/cli/commands/setup-anthropic.d.ts +2 -2
- package/dist/cli/commands/setup-azure.d.ts +2 -2
- package/dist/cli/commands/setup-bedrock.d.ts +2 -2
- package/dist/cli/commands/setup-gcp.d.ts +2 -2
- package/dist/cli/commands/setup-google-ai.d.ts +2 -2
- package/dist/cli/commands/setup-huggingface.d.ts +2 -2
- package/dist/cli/commands/setup-mistral.d.ts +2 -2
- package/dist/cli/commands/setup-openai.d.ts +2 -2
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/factories/commandFactory.js +16 -2
- package/dist/cli/loop/optionsSchema.d.ts +2 -2
- package/dist/cli/loop/optionsSchema.js +4 -0
- package/dist/cli/loop/session.d.ts +4 -0
- package/dist/cli/loop/session.js +49 -4
- package/dist/cli/utils/interactiveSetup.d.ts +4 -4
- package/dist/config/conversationMemory.d.ts +2 -0
- package/dist/config/conversationMemory.js +5 -5
- package/dist/constants/contextWindows.d.ts +46 -0
- package/dist/constants/contextWindows.js +156 -0
- package/dist/context/budgetChecker.d.ts +18 -0
- package/dist/context/budgetChecker.js +71 -0
- package/dist/context/contextCompactor.d.ts +22 -0
- package/dist/context/contextCompactor.js +106 -0
- package/dist/context/effectiveHistory.d.ts +52 -0
- package/dist/context/effectiveHistory.js +105 -0
- package/dist/context/errorDetection.d.ts +14 -0
- package/dist/context/errorDetection.js +124 -0
- package/dist/context/fileSummarizationService.d.ts +54 -0
- package/dist/context/fileSummarizationService.js +255 -0
- package/dist/context/fileSummarizer.d.ts +56 -0
- package/dist/context/fileSummarizer.js +145 -0
- package/dist/context/fileTokenBudget.d.ts +53 -0
- package/dist/context/fileTokenBudget.js +127 -0
- package/dist/context/prompts/summarizationPrompt.d.ts +17 -0
- package/dist/context/prompts/summarizationPrompt.js +110 -0
- package/dist/context/stages/fileReadDeduplicator.d.ts +10 -0
- package/dist/context/stages/fileReadDeduplicator.js +66 -0
- package/dist/context/stages/slidingWindowTruncator.d.ts +11 -0
- package/dist/context/stages/slidingWindowTruncator.js +42 -0
- package/dist/context/stages/structuredSummarizer.d.ts +10 -0
- package/dist/context/stages/structuredSummarizer.js +49 -0
- package/dist/context/stages/toolOutputPruner.d.ts +10 -0
- package/dist/context/stages/toolOutputPruner.js +52 -0
- package/dist/context/summarizationEngine.d.ts +45 -0
- package/dist/context/summarizationEngine.js +110 -0
- package/dist/context/toolOutputLimits.d.ts +17 -0
- package/dist/context/toolOutputLimits.js +84 -0
- package/dist/context/toolPairRepair.d.ts +16 -0
- package/dist/context/toolPairRepair.js +66 -0
- package/dist/core/analytics.js +11 -4
- package/dist/core/baseProvider.d.ts +6 -0
- package/dist/core/baseProvider.js +83 -14
- package/dist/core/conversationMemoryManager.d.ts +14 -11
- package/dist/core/conversationMemoryManager.js +36 -68
- package/dist/core/dynamicModels.js +3 -2
- package/dist/core/modules/GenerationHandler.js +2 -0
- package/dist/core/modules/MessageBuilder.d.ts +1 -1
- package/dist/core/modules/MessageBuilder.js +2 -0
- package/dist/core/modules/TelemetryHandler.d.ts +2 -3
- package/dist/core/modules/TelemetryHandler.js +3 -3
- package/dist/core/modules/ToolsManager.d.ts +2 -2
- package/dist/core/redisConversationMemoryManager.d.ts +19 -14
- package/dist/core/redisConversationMemoryManager.js +94 -86
- package/dist/factories/providerFactory.d.ts +2 -2
- package/dist/files/fileReferenceRegistry.d.ts +276 -0
- package/dist/files/fileReferenceRegistry.js +1543 -0
- package/dist/files/fileTools.d.ts +423 -0
- package/dist/files/fileTools.js +449 -0
- package/dist/files/index.d.ts +14 -0
- package/dist/files/index.js +13 -0
- package/dist/files/streamingReader.d.ts +93 -0
- package/dist/files/streamingReader.js +321 -0
- package/dist/files/types.d.ts +23 -0
- package/dist/files/types.js +23 -0
- package/dist/image-gen/imageGenTools.d.ts +2 -2
- package/dist/image-gen/types.d.ts +12 -12
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/lib/adapters/video/vertexVideoHandler.js +3 -3
- package/dist/lib/agent/directTools.d.ts +7 -7
- package/dist/lib/config/conversationMemory.d.ts +2 -0
- package/dist/lib/config/conversationMemory.js +5 -5
- package/dist/lib/constants/contextWindows.d.ts +46 -0
- package/dist/lib/constants/contextWindows.js +157 -0
- package/dist/lib/context/budgetChecker.d.ts +18 -0
- package/dist/lib/context/budgetChecker.js +72 -0
- package/dist/lib/context/contextCompactor.d.ts +22 -0
- package/dist/lib/context/contextCompactor.js +107 -0
- package/dist/lib/context/effectiveHistory.d.ts +52 -0
- package/dist/lib/context/effectiveHistory.js +106 -0
- package/dist/lib/context/errorDetection.d.ts +14 -0
- package/dist/lib/context/errorDetection.js +125 -0
- package/dist/lib/context/fileSummarizationService.d.ts +54 -0
- package/dist/lib/context/fileSummarizationService.js +256 -0
- package/dist/lib/context/fileSummarizer.d.ts +56 -0
- package/dist/lib/context/fileSummarizer.js +146 -0
- package/dist/lib/context/fileTokenBudget.d.ts +53 -0
- package/dist/lib/context/fileTokenBudget.js +128 -0
- package/dist/lib/context/prompts/summarizationPrompt.d.ts +17 -0
- package/dist/lib/context/prompts/summarizationPrompt.js +111 -0
- package/dist/lib/context/stages/fileReadDeduplicator.d.ts +10 -0
- package/dist/lib/context/stages/fileReadDeduplicator.js +67 -0
- package/dist/lib/context/stages/slidingWindowTruncator.d.ts +11 -0
- package/dist/lib/context/stages/slidingWindowTruncator.js +43 -0
- package/dist/lib/context/stages/structuredSummarizer.d.ts +10 -0
- package/dist/lib/context/stages/structuredSummarizer.js +50 -0
- package/dist/lib/context/stages/toolOutputPruner.d.ts +10 -0
- package/dist/lib/context/stages/toolOutputPruner.js +53 -0
- package/dist/lib/context/summarizationEngine.d.ts +45 -0
- package/dist/lib/context/summarizationEngine.js +111 -0
- package/dist/lib/context/toolOutputLimits.d.ts +17 -0
- package/dist/lib/context/toolOutputLimits.js +85 -0
- package/dist/lib/context/toolPairRepair.d.ts +16 -0
- package/dist/lib/context/toolPairRepair.js +67 -0
- package/dist/lib/core/analytics.js +11 -4
- package/dist/lib/core/baseProvider.d.ts +6 -0
- package/dist/lib/core/baseProvider.js +83 -14
- package/dist/lib/core/conversationMemoryManager.d.ts +14 -11
- package/dist/lib/core/conversationMemoryManager.js +36 -68
- package/dist/lib/core/dynamicModels.js +3 -2
- package/dist/lib/core/modules/GenerationHandler.js +2 -0
- package/dist/lib/core/modules/MessageBuilder.d.ts +1 -1
- package/dist/lib/core/modules/MessageBuilder.js +2 -0
- package/dist/lib/core/modules/TelemetryHandler.d.ts +2 -3
- package/dist/lib/core/modules/TelemetryHandler.js +3 -3
- package/dist/lib/core/modules/ToolsManager.d.ts +2 -2
- package/dist/lib/core/redisConversationMemoryManager.d.ts +19 -14
- package/dist/lib/core/redisConversationMemoryManager.js +94 -86
- package/dist/lib/factories/providerFactory.d.ts +2 -2
- package/dist/lib/files/fileReferenceRegistry.d.ts +276 -0
- package/dist/lib/files/fileReferenceRegistry.js +1544 -0
- package/dist/lib/files/fileTools.d.ts +423 -0
- package/dist/lib/files/fileTools.js +450 -0
- package/dist/lib/files/index.d.ts +14 -0
- package/dist/lib/files/index.js +14 -0
- package/dist/lib/files/streamingReader.d.ts +93 -0
- package/dist/lib/files/streamingReader.js +322 -0
- package/dist/lib/files/types.d.ts +23 -0
- package/dist/lib/files/types.js +24 -0
- package/dist/lib/image-gen/imageGenTools.d.ts +2 -2
- package/dist/lib/image-gen/types.d.ts +12 -12
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/mcp/httpRetryHandler.js +6 -2
- package/dist/lib/memory/mem0Initializer.d.ts +2 -2
- package/dist/lib/neurolink.d.ts +66 -2
- package/dist/lib/neurolink.js +777 -315
- package/dist/lib/processors/archive/ArchiveProcessor.d.ts +327 -0
- package/dist/lib/processors/archive/ArchiveProcessor.js +1309 -0
- package/dist/lib/processors/archive/index.d.ts +33 -0
- package/dist/lib/processors/archive/index.js +43 -0
- package/dist/lib/processors/base/BaseFileProcessor.js +2 -1
- package/dist/lib/processors/base/types.d.ts +70 -64
- package/dist/lib/processors/base/types.js +6 -0
- package/dist/lib/processors/cli/fileProcessorCli.d.ts +8 -8
- package/dist/lib/processors/cli/fileProcessorCli.js +5 -5
- package/dist/lib/processors/config/mimeTypes.js +25 -0
- package/dist/lib/processors/config/sizeLimits.d.ts +52 -40
- package/dist/lib/processors/config/sizeLimits.js +56 -44
- package/dist/lib/processors/document/ExcelProcessor.d.ts +14 -0
- package/dist/lib/processors/document/ExcelProcessor.js +72 -1
- package/dist/lib/processors/document/PptxProcessor.d.ts +63 -0
- package/dist/lib/processors/document/PptxProcessor.js +158 -0
- package/dist/lib/processors/document/index.d.ts +1 -0
- package/dist/lib/processors/document/index.js +6 -0
- package/dist/lib/processors/errors/FileErrorCode.d.ts +2 -2
- package/dist/lib/processors/errors/errorHelpers.d.ts +2 -2
- package/dist/lib/processors/errors/errorHelpers.js +12 -4
- package/dist/lib/processors/errors/errorSerializer.d.ts +4 -4
- package/dist/lib/processors/index.d.ts +8 -2
- package/dist/lib/processors/index.js +5 -2
- package/dist/lib/processors/integration/FileProcessorIntegration.d.ts +8 -8
- package/dist/lib/processors/integration/FileProcessorIntegration.js +7 -7
- package/dist/lib/processors/media/AudioProcessor.d.ts +328 -0
- package/dist/lib/processors/media/AudioProcessor.js +708 -0
- package/dist/lib/processors/media/VideoProcessor.d.ts +350 -0
- package/dist/lib/processors/media/VideoProcessor.js +992 -0
- package/dist/lib/processors/media/index.d.ts +27 -0
- package/dist/lib/processors/media/index.js +37 -0
- package/dist/lib/processors/registry/ProcessorRegistry.d.ts +19 -5
- package/dist/lib/processors/registry/ProcessorRegistry.js +103 -8
- package/dist/lib/processors/registry/index.d.ts +1 -1
- package/dist/lib/processors/registry/index.js +1 -1
- package/dist/lib/processors/registry/types.d.ts +2 -2
- package/dist/lib/providers/amazonBedrock.js +2 -1
- package/dist/lib/providers/anthropic.js +2 -2
- package/dist/lib/providers/anthropicBaseProvider.js +10 -4
- package/dist/lib/providers/azureOpenai.js +14 -25
- package/dist/lib/providers/googleAiStudio.js +136 -457
- package/dist/lib/providers/googleNativeGemini3.d.ts +119 -0
- package/dist/lib/providers/googleNativeGemini3.js +264 -0
- package/dist/lib/providers/googleVertex.d.ts +15 -1
- package/dist/lib/providers/googleVertex.js +341 -775
- package/dist/lib/providers/huggingFace.js +20 -5
- package/dist/lib/providers/litellm.js +6 -4
- package/dist/lib/providers/mistral.js +3 -2
- package/dist/lib/providers/openAI.js +2 -2
- package/dist/lib/providers/openRouter.js +8 -7
- package/dist/lib/providers/openaiCompatible.js +10 -4
- package/dist/lib/providers/sagemaker/detection.d.ts +6 -6
- package/dist/lib/providers/sagemaker/diagnostics.d.ts +4 -4
- package/dist/lib/providers/sagemaker/parsers.d.ts +4 -4
- package/dist/lib/rag/chunkers/RecursiveChunker.js +2 -2
- package/dist/lib/rag/document/loaders.d.ts +6 -71
- package/dist/lib/rag/document/loaders.js +5 -5
- package/dist/lib/rag/graphRag/graphRAG.js +26 -9
- package/dist/lib/rag/metadata/MetadataExtractorFactory.d.ts +5 -55
- package/dist/lib/rag/metadata/metadataExtractor.js +6 -3
- package/dist/lib/rag/pipeline/RAGPipeline.d.ts +8 -126
- package/dist/lib/rag/pipeline/RAGPipeline.js +11 -11
- package/dist/lib/rag/pipeline/contextAssembly.d.ts +3 -42
- package/dist/lib/rag/pipeline/contextAssembly.js +6 -3
- package/dist/lib/rag/reranker/RerankerFactory.d.ts +5 -60
- package/dist/lib/rag/resilience/CircuitBreaker.d.ts +3 -33
- package/dist/lib/rag/resilience/RetryHandler.d.ts +2 -21
- package/dist/lib/rag/resilience/RetryHandler.js +6 -2
- package/dist/lib/rag/retrieval/hybridSearch.d.ts +3 -41
- package/dist/lib/rag/retrieval/vectorQueryTool.d.ts +2 -13
- package/dist/lib/rag/retrieval/vectorQueryTool.js +4 -3
- package/dist/lib/rag/types.d.ts +3 -3
- package/dist/lib/sdk/toolRegistration.d.ts +2 -2
- package/dist/lib/server/middleware/cache.d.ts +2 -2
- package/dist/lib/server/middleware/rateLimit.d.ts +2 -2
- package/dist/lib/server/routes/mcpRoutes.js +277 -249
- package/dist/lib/server/routes/memoryRoutes.js +287 -281
- package/dist/lib/server/utils/validation.d.ts +10 -10
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +24 -2
- package/dist/lib/services/server/ai/observability/instrumentation.js +12 -1
- package/dist/lib/session/globalSessionState.d.ts +2 -2
- package/dist/lib/telemetry/telemetryService.d.ts +2 -2
- package/dist/lib/types/common.d.ts +39 -0
- package/dist/lib/types/contextTypes.d.ts +255 -0
- package/dist/lib/types/contextTypes.js +0 -2
- package/dist/lib/types/conversation.d.ts +62 -0
- package/dist/lib/types/conversationMemoryInterface.d.ts +27 -0
- package/dist/lib/types/conversationMemoryInterface.js +7 -0
- package/dist/lib/types/fileReferenceTypes.d.ts +222 -0
- package/dist/lib/types/fileReferenceTypes.js +9 -0
- package/dist/lib/types/fileTypes.d.ts +26 -3
- package/dist/lib/types/generateTypes.d.ts +50 -1
- package/dist/lib/types/index.d.ts +4 -5
- package/dist/lib/types/index.js +8 -10
- package/dist/lib/types/modelTypes.d.ts +2 -2
- package/dist/lib/types/processorTypes.d.ts +597 -0
- package/dist/lib/types/processorTypes.js +91 -0
- package/dist/lib/types/ragTypes.d.ts +489 -0
- package/dist/lib/types/ragTypes.js +8 -0
- package/dist/lib/types/sdkTypes.d.ts +17 -18
- package/dist/lib/types/streamTypes.d.ts +24 -1
- package/dist/lib/utils/async/retry.d.ts +2 -2
- package/dist/lib/utils/async/withTimeout.js +3 -1
- package/dist/lib/utils/conversationMemory.d.ts +12 -6
- package/dist/lib/utils/conversationMemory.js +91 -36
- package/dist/lib/utils/errorHandling.d.ts +5 -0
- package/dist/lib/utils/errorHandling.js +19 -0
- package/dist/lib/utils/fileDetector.d.ts +62 -0
- package/dist/lib/utils/fileDetector.js +1014 -14
- package/dist/lib/utils/json/safeParse.d.ts +2 -2
- package/dist/lib/utils/messageBuilder.js +806 -153
- package/dist/lib/utils/modelChoices.d.ts +2 -2
- package/dist/lib/utils/multimodalOptionsBuilder.d.ts +2 -1
- package/dist/lib/utils/multimodalOptionsBuilder.js +1 -0
- package/dist/lib/utils/pricing.d.ts +12 -0
- package/dist/lib/utils/pricing.js +134 -0
- package/dist/lib/utils/rateLimiter.d.ts +2 -2
- package/dist/lib/utils/redis.d.ts +17 -0
- package/dist/lib/utils/redis.js +105 -0
- package/dist/lib/utils/sanitizers/filename.d.ts +4 -4
- package/dist/lib/utils/sanitizers/svg.d.ts +2 -2
- package/dist/lib/utils/thinkingConfig.d.ts +6 -6
- package/dist/lib/utils/timeout.d.ts +10 -0
- package/dist/lib/utils/timeout.js +15 -0
- package/dist/lib/utils/tokenEstimation.d.ts +68 -0
- package/dist/lib/utils/tokenEstimation.js +113 -0
- package/dist/lib/utils/tokenUtils.d.ts +4 -4
- package/dist/lib/utils/ttsProcessor.d.ts +2 -2
- package/dist/lib/workflow/config.d.ts +150 -150
- package/dist/mcp/httpRetryHandler.js +6 -2
- package/dist/memory/mem0Initializer.d.ts +2 -2
- package/dist/neurolink.d.ts +66 -2
- package/dist/neurolink.js +777 -315
- package/dist/processors/archive/ArchiveProcessor.d.ts +327 -0
- package/dist/processors/archive/ArchiveProcessor.js +1308 -0
- package/dist/processors/archive/index.d.ts +33 -0
- package/dist/processors/archive/index.js +42 -0
- package/dist/processors/base/BaseFileProcessor.js +2 -1
- package/dist/processors/base/types.d.ts +70 -64
- package/dist/processors/base/types.js +6 -0
- package/dist/processors/cli/fileProcessorCli.d.ts +8 -8
- package/dist/processors/cli/fileProcessorCli.js +5 -5
- package/dist/processors/config/mimeTypes.js +25 -0
- package/dist/processors/config/sizeLimits.d.ts +52 -40
- package/dist/processors/config/sizeLimits.js +56 -44
- package/dist/processors/document/ExcelProcessor.d.ts +14 -0
- package/dist/processors/document/ExcelProcessor.js +72 -1
- package/dist/processors/document/PptxProcessor.d.ts +63 -0
- package/dist/processors/document/PptxProcessor.js +157 -0
- package/dist/processors/document/index.d.ts +1 -0
- package/dist/processors/document/index.js +6 -0
- package/dist/processors/errors/FileErrorCode.d.ts +2 -2
- package/dist/processors/errors/errorHelpers.d.ts +2 -2
- package/dist/processors/errors/errorHelpers.js +12 -4
- package/dist/processors/errors/errorSerializer.d.ts +4 -4
- package/dist/processors/index.d.ts +8 -2
- package/dist/processors/index.js +5 -2
- package/dist/processors/integration/FileProcessorIntegration.d.ts +8 -8
- package/dist/processors/integration/FileProcessorIntegration.js +7 -7
- package/dist/processors/media/AudioProcessor.d.ts +328 -0
- package/dist/processors/media/AudioProcessor.js +707 -0
- package/dist/processors/media/VideoProcessor.d.ts +350 -0
- package/dist/processors/media/VideoProcessor.js +991 -0
- package/dist/processors/media/ffprobe-static.d.ts +4 -0
- package/dist/processors/media/index.d.ts +27 -0
- package/dist/processors/media/index.js +36 -0
- package/dist/processors/registry/ProcessorRegistry.d.ts +19 -5
- package/dist/processors/registry/ProcessorRegistry.js +103 -8
- package/dist/processors/registry/index.d.ts +1 -1
- package/dist/processors/registry/index.js +1 -1
- package/dist/processors/registry/types.d.ts +2 -2
- package/dist/providers/amazonBedrock.js +2 -1
- package/dist/providers/anthropic.js +2 -2
- package/dist/providers/anthropicBaseProvider.js +10 -4
- package/dist/providers/azureOpenai.js +14 -25
- package/dist/providers/googleAiStudio.js +136 -457
- package/dist/providers/googleNativeGemini3.d.ts +119 -0
- package/dist/providers/googleNativeGemini3.js +263 -0
- package/dist/providers/googleVertex.d.ts +15 -1
- package/dist/providers/googleVertex.js +341 -775
- package/dist/providers/huggingFace.js +20 -5
- package/dist/providers/litellm.js +6 -4
- package/dist/providers/mistral.js +3 -2
- package/dist/providers/openAI.js +2 -2
- package/dist/providers/openRouter.js +8 -7
- package/dist/providers/openaiCompatible.js +10 -4
- package/dist/providers/sagemaker/detection.d.ts +6 -6
- package/dist/providers/sagemaker/diagnostics.d.ts +4 -4
- package/dist/providers/sagemaker/parsers.d.ts +4 -4
- package/dist/rag/chunkers/RecursiveChunker.js +2 -2
- package/dist/rag/document/loaders.d.ts +6 -71
- package/dist/rag/document/loaders.js +5 -5
- package/dist/rag/graphRag/graphRAG.js +26 -9
- package/dist/rag/metadata/MetadataExtractorFactory.d.ts +5 -55
- package/dist/rag/metadata/metadataExtractor.js +6 -3
- package/dist/rag/pipeline/RAGPipeline.d.ts +8 -126
- package/dist/rag/pipeline/RAGPipeline.js +11 -11
- package/dist/rag/pipeline/contextAssembly.d.ts +3 -42
- package/dist/rag/pipeline/contextAssembly.js +6 -3
- package/dist/rag/reranker/RerankerFactory.d.ts +5 -60
- package/dist/rag/resilience/CircuitBreaker.d.ts +3 -33
- package/dist/rag/resilience/RetryHandler.d.ts +2 -21
- package/dist/rag/resilience/RetryHandler.js +6 -2
- package/dist/rag/retrieval/hybridSearch.d.ts +3 -41
- package/dist/rag/retrieval/vectorQueryTool.d.ts +2 -13
- package/dist/rag/retrieval/vectorQueryTool.js +4 -3
- package/dist/rag/types.d.ts +3 -3
- package/dist/sdk/toolRegistration.d.ts +2 -2
- package/dist/server/middleware/cache.d.ts +2 -2
- package/dist/server/middleware/rateLimit.d.ts +2 -2
- package/dist/server/routes/mcpRoutes.js +277 -249
- package/dist/server/routes/memoryRoutes.js +287 -281
- package/dist/server/utils/validation.d.ts +4 -4
- package/dist/services/server/ai/observability/instrumentation.d.ts +24 -2
- package/dist/services/server/ai/observability/instrumentation.js +12 -1
- package/dist/session/globalSessionState.d.ts +2 -2
- package/dist/telemetry/telemetryService.d.ts +2 -2
- package/dist/types/common.d.ts +39 -0
- package/dist/types/contextTypes.d.ts +255 -0
- package/dist/types/contextTypes.js +0 -2
- package/dist/types/conversation.d.ts +62 -0
- package/dist/types/conversationMemoryInterface.d.ts +27 -0
- package/dist/types/conversationMemoryInterface.js +6 -0
- package/dist/types/fileReferenceTypes.d.ts +222 -0
- package/dist/types/fileReferenceTypes.js +8 -0
- package/dist/types/fileTypes.d.ts +26 -3
- package/dist/types/generateTypes.d.ts +50 -1
- package/dist/types/index.d.ts +4 -5
- package/dist/types/index.js +8 -10
- package/dist/types/processorTypes.d.ts +597 -0
- package/dist/types/processorTypes.js +90 -0
- package/dist/types/ragTypes.d.ts +489 -0
- package/dist/types/ragTypes.js +7 -0
- package/dist/types/sdkTypes.d.ts +17 -18
- package/dist/types/streamTypes.d.ts +24 -1
- package/dist/utils/async/retry.d.ts +2 -2
- package/dist/utils/async/withTimeout.js +3 -1
- package/dist/utils/conversationMemory.d.ts +12 -6
- package/dist/utils/conversationMemory.js +91 -36
- package/dist/utils/errorHandling.d.ts +5 -0
- package/dist/utils/errorHandling.js +19 -0
- package/dist/utils/fileDetector.d.ts +62 -0
- package/dist/utils/fileDetector.js +1014 -14
- package/dist/utils/json/safeParse.d.ts +2 -2
- package/dist/utils/messageBuilder.js +806 -153
- package/dist/utils/modelChoices.d.ts +2 -2
- package/dist/utils/multimodalOptionsBuilder.d.ts +2 -1
- package/dist/utils/multimodalOptionsBuilder.js +1 -0
- package/dist/utils/pricing.d.ts +12 -0
- package/dist/utils/pricing.js +133 -0
- package/dist/utils/rateLimiter.d.ts +2 -2
- package/dist/utils/redis.d.ts +17 -0
- package/dist/utils/redis.js +105 -0
- package/dist/utils/sanitizers/filename.d.ts +4 -4
- package/dist/utils/sanitizers/svg.d.ts +2 -2
- package/dist/utils/thinkingConfig.d.ts +6 -6
- package/dist/utils/timeout.d.ts +10 -0
- package/dist/utils/timeout.js +15 -0
- package/dist/utils/tokenEstimation.d.ts +68 -0
- package/dist/utils/tokenEstimation.js +112 -0
- package/dist/utils/tokenUtils.d.ts +4 -4
- package/dist/utils/ttsProcessor.d.ts +2 -2
- package/dist/workflow/config.d.ts +104 -104
- package/package.json +18 -6
- package/dist/lib/utils/conversationMemoryUtils.d.ts +0 -25
- package/dist/lib/utils/conversationMemoryUtils.js +0 -138
- package/dist/utils/conversationMemoryUtils.d.ts +0 -25
- 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
|
|
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 {
|
|
12
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
|
|
560
|
-
const
|
|
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 = "";
|
|
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
|
-
//
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
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
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
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
|
-
|
|
739
|
-
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
|
|
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
|
|
808
|
-
|
|
809
|
-
|
|
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
|
-
|
|
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
|
-
|
|
858
|
-
const
|
|
859
|
-
const
|
|
860
|
-
|
|
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 = "";
|
|
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
|
-
|
|
874
|
-
|
|
875
|
-
step
|
|
876
|
-
|
|
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
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
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
|
-
|
|
1044
|
-
|
|
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
|
-
|
|
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,
|