@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.
- package/CHANGELOG.md +16 -0
- package/README.md +29 -25
- 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/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/conversationMemoryManager.d.ts +5 -15
- package/dist/core/conversationMemoryManager.js +15 -75
- 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 +8 -14
- package/dist/core/redisConversationMemoryManager.js +69 -78
- 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/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/conversationMemoryManager.d.ts +5 -15
- package/dist/lib/core/conversationMemoryManager.js +15 -75
- 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 +8 -14
- package/dist/lib/core/redisConversationMemoryManager.js +69 -78
- 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/memory/mem0Initializer.d.ts +2 -2
- package/dist/lib/neurolink.d.ts +61 -2
- package/dist/lib/neurolink.js +619 -307
- 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/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/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/googleAiStudio.d.ts +34 -0
- package/dist/lib/providers/googleAiStudio.js +267 -397
- package/dist/lib/providers/googleVertex.d.ts +55 -1
- package/dist/lib/providers/googleVertex.js +452 -719
- 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/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/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 +22 -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 +481 -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 +11 -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 +76 -36
- 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/rateLimiter.d.ts +2 -2
- 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/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/memory/mem0Initializer.d.ts +2 -2
- package/dist/neurolink.d.ts +61 -2
- package/dist/neurolink.js +619 -307
- 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/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/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/googleAiStudio.d.ts +34 -0
- package/dist/providers/googleAiStudio.js +267 -397
- package/dist/providers/googleVertex.d.ts +55 -1
- package/dist/providers/googleVertex.js +452 -719
- 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/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/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 +22 -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 +481 -0
- package/dist/types/ragTypes.js +7 -0
- package/dist/types/sdkTypes.d.ts +17 -18
- package/dist/types/streamTypes.d.ts +11 -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 +76 -36
- 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/rateLimiter.d.ts +2 -2
- 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/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
|
@@ -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
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
|
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 }];
|
|
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
|
-
|
|
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];
|
|
528
|
+
const config = this.buildNativeConfig(options, toolsConfig);
|
|
529
|
+
const maxSteps = this.computeMaxSteps(options.maxSteps);
|
|
581
530
|
let finalText = "";
|
|
582
|
-
let lastStepText = "";
|
|
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
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
|
|
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
|
|
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 }];
|
|
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
|
-
|
|
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
|
-
|
|
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 = "";
|
|
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
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|