@blackbox_ai/blackbox-cli-core 0.0.4
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/LICENSE +203 -0
- package/README.md +420 -0
- package/dist/.last_build +0 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/src/__mocks__/fs/promises.d.ts +11 -0
- package/dist/src/__mocks__/fs/promises.js +17 -0
- package/dist/src/__mocks__/fs/promises.js.map +1 -0
- package/dist/src/blackbox/blackboxContentGenerator.d.ts +70 -0
- package/dist/src/blackbox/blackboxContentGenerator.js +180 -0
- package/dist/src/blackbox/blackboxContentGenerator.js.map +1 -0
- package/dist/src/blackbox/blackboxContentGenerator.test.d.ts +6 -0
- package/dist/src/blackbox/blackboxContentGenerator.test.js +1178 -0
- package/dist/src/blackbox/blackboxContentGenerator.test.js.map +1 -0
- package/dist/src/blackbox/blackboxOAuth2.d.ts +191 -0
- package/dist/src/blackbox/blackboxOAuth2.js +566 -0
- package/dist/src/blackbox/blackboxOAuth2.js.map +1 -0
- package/dist/src/blackbox/blackboxOAuth2.test.d.ts +6 -0
- package/dist/src/blackbox/blackboxOAuth2.test.js +1718 -0
- package/dist/src/blackbox/blackboxOAuth2.test.js.map +1 -0
- package/dist/src/blackbox/sharedTokenManager.d.ts +196 -0
- package/dist/src/blackbox/sharedTokenManager.js +647 -0
- package/dist/src/blackbox/sharedTokenManager.js.map +1 -0
- package/dist/src/blackbox/sharedTokenManager.test.d.ts +7 -0
- package/dist/src/blackbox/sharedTokenManager.test.js +662 -0
- package/dist/src/blackbox/sharedTokenManager.test.js.map +1 -0
- package/dist/src/code_assist/codeAssist.d.ts +10 -0
- package/dist/src/code_assist/codeAssist.js +19 -0
- package/dist/src/code_assist/codeAssist.js.map +1 -0
- package/dist/src/code_assist/converter.d.ts +72 -0
- package/dist/src/code_assist/converter.js +159 -0
- package/dist/src/code_assist/converter.js.map +1 -0
- package/dist/src/code_assist/converter.test.d.ts +6 -0
- package/dist/src/code_assist/converter.test.js +362 -0
- package/dist/src/code_assist/converter.test.js.map +1 -0
- package/dist/src/code_assist/oauth2.d.ts +22 -0
- package/dist/src/code_assist/oauth2.js +368 -0
- package/dist/src/code_assist/oauth2.js.map +1 -0
- package/dist/src/code_assist/oauth2.test.d.ts +6 -0
- package/dist/src/code_assist/oauth2.test.js +436 -0
- package/dist/src/code_assist/oauth2.test.js.map +1 -0
- package/dist/src/code_assist/server.d.ts +37 -0
- package/dist/src/code_assist/server.js +125 -0
- package/dist/src/code_assist/server.js.map +1 -0
- package/dist/src/code_assist/server.test.d.ts +6 -0
- package/dist/src/code_assist/server.test.js +134 -0
- package/dist/src/code_assist/server.test.js.map +1 -0
- package/dist/src/code_assist/setup.d.ts +20 -0
- package/dist/src/code_assist/setup.js +101 -0
- package/dist/src/code_assist/setup.js.map +1 -0
- package/dist/src/code_assist/setup.test.d.ts +6 -0
- package/dist/src/code_assist/setup.test.js +171 -0
- package/dist/src/code_assist/setup.test.js.map +1 -0
- package/dist/src/code_assist/types.d.ts +148 -0
- package/dist/src/code_assist/types.js +46 -0
- package/dist/src/code_assist/types.js.map +1 -0
- package/dist/src/config/blackboxModels.d.ts +28 -0
- package/dist/src/config/blackboxModels.js +148 -0
- package/dist/src/config/blackboxModels.js.map +1 -0
- package/dist/src/config/config.d.ts +381 -0
- package/dist/src/config/config.js +753 -0
- package/dist/src/config/config.js.map +1 -0
- package/dist/src/config/config.test.d.ts +6 -0
- package/dist/src/config/config.test.js +674 -0
- package/dist/src/config/config.test.js.map +1 -0
- package/dist/src/config/flashFallback.test.d.ts +6 -0
- package/dist/src/config/flashFallback.test.js +87 -0
- package/dist/src/config/flashFallback.test.js.map +1 -0
- package/dist/src/config/models.d.ts +12 -0
- package/dist/src/config/models.js +13 -0
- package/dist/src/config/models.js.map +1 -0
- package/dist/src/config/storage.d.ts +32 -0
- package/dist/src/config/storage.js +90 -0
- package/dist/src/config/storage.js.map +1 -0
- package/dist/src/config/storage.test.d.ts +6 -0
- package/dist/src/config/storage.test.js +43 -0
- package/dist/src/config/storage.test.js.map +1 -0
- package/dist/src/core/__tests__/openaiTimeoutHandling.test.d.ts +6 -0
- package/dist/src/core/__tests__/openaiTimeoutHandling.test.js +292 -0
- package/dist/src/core/__tests__/openaiTimeoutHandling.test.js.map +1 -0
- package/dist/src/core/__tests__/orphanedToolCallsTest.d.ts +64 -0
- package/dist/src/core/__tests__/orphanedToolCallsTest.js +122 -0
- package/dist/src/core/__tests__/orphanedToolCallsTest.js.map +1 -0
- package/dist/src/core/client.d.ts +75 -0
- package/dist/src/core/client.js +826 -0
- package/dist/src/core/client.js.map +1 -0
- package/dist/src/core/client.test.d.ts +6 -0
- package/dist/src/core/client.test.js +2059 -0
- package/dist/src/core/client.test.js.map +1 -0
- package/dist/src/core/contentGenerator.d.ts +51 -0
- package/dist/src/core/contentGenerator.js +149 -0
- package/dist/src/core/contentGenerator.js.map +1 -0
- package/dist/src/core/contentGenerator.test.d.ts +6 -0
- package/dist/src/core/contentGenerator.test.js +133 -0
- package/dist/src/core/contentGenerator.test.js.map +1 -0
- package/dist/src/core/coreToolScheduler.d.ts +126 -0
- package/dist/src/core/coreToolScheduler.js +630 -0
- package/dist/src/core/coreToolScheduler.js.map +1 -0
- package/dist/src/core/coreToolScheduler.test.d.ts +6 -0
- package/dist/src/core/coreToolScheduler.test.js +1228 -0
- package/dist/src/core/coreToolScheduler.test.js.map +1 -0
- package/dist/src/core/geminiChat.d.ts +139 -0
- package/dist/src/core/geminiChat.js +636 -0
- package/dist/src/core/geminiChat.js.map +1 -0
- package/dist/src/core/geminiChat.test.d.ts +6 -0
- package/dist/src/core/geminiChat.test.js +1178 -0
- package/dist/src/core/geminiChat.test.js.map +1 -0
- package/dist/src/core/geminiRequest.d.ts +13 -0
- package/dist/src/core/geminiRequest.js +11 -0
- package/dist/src/core/geminiRequest.js.map +1 -0
- package/dist/src/core/geminiRequest.test.d.ts +6 -0
- package/dist/src/core/geminiRequest.test.js +73 -0
- package/dist/src/core/geminiRequest.test.js.map +1 -0
- package/dist/src/core/logger.d.ts +68 -0
- package/dist/src/core/logger.js +370 -0
- package/dist/src/core/logger.js.map +1 -0
- package/dist/src/core/logger.test.d.ts +6 -0
- package/dist/src/core/logger.test.js +591 -0
- package/dist/src/core/logger.test.js.map +1 -0
- package/dist/src/core/loggingContentGenerator.d.ts +25 -0
- package/dist/src/core/loggingContentGenerator.js +97 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.d.ts +10 -0
- package/dist/src/core/nonInteractiveToolExecutor.js +24 -0
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.d.ts +6 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js +236 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/constants.d.ts +2 -0
- package/dist/src/core/openaiContentGenerator/constants.js +3 -0
- package/dist/src/core/openaiContentGenerator/constants.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/converter.d.ts +107 -0
- package/dist/src/core/openaiContentGenerator/converter.js +802 -0
- package/dist/src/core/openaiContentGenerator/converter.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/converter.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/converter.test.js +47 -0
- package/dist/src/core/openaiContentGenerator/converter.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/errorHandler.d.ts +20 -0
- package/dist/src/core/openaiContentGenerator/errorHandler.js +82 -0
- package/dist/src/core/openaiContentGenerator/errorHandler.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/errorHandler.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/errorHandler.test.js +287 -0
- package/dist/src/core/openaiContentGenerator/errorHandler.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/index.d.ts +22 -0
- package/dist/src/core/openaiContentGenerator/index.js +41 -0
- package/dist/src/core/openaiContentGenerator/index.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/openaiContentGenerator.d.ts +21 -0
- package/dist/src/core/openaiContentGenerator/openaiContentGenerator.js +105 -0
- package/dist/src/core/openaiContentGenerator/openaiContentGenerator.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/openaiContentGenerator.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/openaiContentGenerator.test.js +230 -0
- package/dist/src/core/openaiContentGenerator/openaiContentGenerator.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/pipeline.d.ts +66 -0
- package/dist/src/core/openaiContentGenerator/pipeline.js +256 -0
- package/dist/src/core/openaiContentGenerator/pipeline.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/pipeline.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/pipeline.test.js +977 -0
- package/dist/src/core/openaiContentGenerator/pipeline.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/README.md +61 -0
- package/dist/src/core/openaiContentGenerator/provider/dashscope.d.ts +63 -0
- package/dist/src/core/openaiContentGenerator/provider/dashscope.js +241 -0
- package/dist/src/core/openaiContentGenerator/provider/dashscope.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/dashscope.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/provider/dashscope.test.js +707 -0
- package/dist/src/core/openaiContentGenerator/provider/dashscope.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/deepseek.d.ts +14 -0
- package/dist/src/core/openaiContentGenerator/provider/deepseek.js +52 -0
- package/dist/src/core/openaiContentGenerator/provider/deepseek.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/deepseek.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/provider/deepseek.test.js +103 -0
- package/dist/src/core/openaiContentGenerator/provider/deepseek.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/default.d.ts +15 -0
- package/dist/src/core/openaiContentGenerator/provider/default.js +38 -0
- package/dist/src/core/openaiContentGenerator/provider/default.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/default.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/provider/default.test.js +176 -0
- package/dist/src/core/openaiContentGenerator/provider/default.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/index.d.ts +5 -0
- package/dist/src/core/openaiContentGenerator/provider/index.js +5 -0
- package/dist/src/core/openaiContentGenerator/provider/index.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/openrouter.d.ts +8 -0
- package/dist/src/core/openaiContentGenerator/provider/openrouter.js +21 -0
- package/dist/src/core/openaiContentGenerator/provider/openrouter.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/openrouter.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/provider/openrouter.test.js +152 -0
- package/dist/src/core/openaiContentGenerator/provider/openrouter.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/provider/types.d.ts +23 -0
- package/dist/src/core/openaiContentGenerator/provider/types.js +2 -0
- package/dist/src/core/openaiContentGenerator/provider/types.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/streamingToolCallParser.d.ts +142 -0
- package/dist/src/core/openaiContentGenerator/streamingToolCallParser.js +363 -0
- package/dist/src/core/openaiContentGenerator/streamingToolCallParser.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/streamingToolCallParser.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/streamingToolCallParser.test.js +537 -0
- package/dist/src/core/openaiContentGenerator/streamingToolCallParser.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/telemetryService.d.ts +35 -0
- package/dist/src/core/openaiContentGenerator/telemetryService.js +146 -0
- package/dist/src/core/openaiContentGenerator/telemetryService.js.map +1 -0
- package/dist/src/core/openaiContentGenerator/telemetryService.test.d.ts +6 -0
- package/dist/src/core/openaiContentGenerator/telemetryService.test.js +978 -0
- package/dist/src/core/openaiContentGenerator/telemetryService.test.js.map +1 -0
- package/dist/src/core/prompts.d.ts +76 -0
- package/dist/src/core/prompts.js +860 -0
- package/dist/src/core/prompts.js.map +1 -0
- package/dist/src/core/prompts.test.d.ts +6 -0
- package/dist/src/core/prompts.test.js +436 -0
- package/dist/src/core/prompts.test.js.map +1 -0
- package/dist/src/core/tokenLimits.d.ts +25 -0
- package/dist/src/core/tokenLimits.js +175 -0
- package/dist/src/core/tokenLimits.js.map +1 -0
- package/dist/src/core/tokenLimits.test.d.ts +1 -0
- package/dist/src/core/tokenLimits.test.js +261 -0
- package/dist/src/core/tokenLimits.test.js.map +1 -0
- package/dist/src/core/turn.d.ts +140 -0
- package/dist/src/core/turn.js +168 -0
- package/dist/src/core/turn.js.map +1 -0
- package/dist/src/core/turn.test.d.ts +6 -0
- package/dist/src/core/turn.test.js +450 -0
- package/dist/src/core/turn.test.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +7 -0
- package/dist/src/generated/git-commit.js +10 -0
- package/dist/src/generated/git-commit.js.map +1 -0
- package/dist/src/ide/constants.d.ts +6 -0
- package/dist/src/ide/constants.js +7 -0
- package/dist/src/ide/constants.js.map +1 -0
- package/dist/src/ide/detect-ide.d.ts +25 -0
- package/dist/src/ide/detect-ide.js +104 -0
- package/dist/src/ide/detect-ide.js.map +1 -0
- package/dist/src/ide/detect-ide.test.d.ts +6 -0
- package/dist/src/ide/detect-ide.test.js +120 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -0
- package/dist/src/ide/ide-client.d.ts +67 -0
- package/dist/src/ide/ide-client.js +424 -0
- package/dist/src/ide/ide-client.js.map +1 -0
- package/dist/src/ide/ide-client.test.d.ts +6 -0
- package/dist/src/ide/ide-client.test.js +165 -0
- package/dist/src/ide/ide-client.test.js.map +1 -0
- package/dist/src/ide/ide-installer.d.ts +14 -0
- package/dist/src/ide/ide-installer.js +107 -0
- package/dist/src/ide/ide-installer.js.map +1 -0
- package/dist/src/ide/ide-installer.test.d.ts +6 -0
- package/dist/src/ide/ide-installer.test.js +113 -0
- package/dist/src/ide/ide-installer.test.js.map +1 -0
- package/dist/src/ide/ideContext.d.ts +374 -0
- package/dist/src/ide/ideContext.js +147 -0
- package/dist/src/ide/ideContext.js.map +1 -0
- package/dist/src/ide/ideContext.test.d.ts +6 -0
- package/dist/src/ide/ideContext.test.js +265 -0
- package/dist/src/ide/ideContext.test.js.map +1 -0
- package/dist/src/ide/process-utils.d.ts +21 -0
- package/dist/src/ide/process-utils.js +164 -0
- package/dist/src/ide/process-utils.js.map +1 -0
- package/dist/src/ide/process-utils.test.d.ts +6 -0
- package/dist/src/ide/process-utils.test.js +158 -0
- package/dist/src/ide/process-utils.test.js.map +1 -0
- package/dist/src/index.d.ts +86 -0
- package/dist/src/index.js +97 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.test.d.ts +6 -0
- package/dist/src/index.test.js +12 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/mcp/google-auth-provider.d.ts +23 -0
- package/dist/src/mcp/google-auth-provider.js +72 -0
- package/dist/src/mcp/google-auth-provider.js.map +1 -0
- package/dist/src/mcp/google-auth-provider.test.d.ts +6 -0
- package/dist/src/mcp/google-auth-provider.test.js +89 -0
- package/dist/src/mcp/google-auth-provider.test.js.map +1 -0
- package/dist/src/mcp/oauth-provider.d.ts +146 -0
- package/dist/src/mcp/oauth-provider.js +601 -0
- package/dist/src/mcp/oauth-provider.js.map +1 -0
- package/dist/src/mcp/oauth-provider.test.d.ts +6 -0
- package/dist/src/mcp/oauth-provider.test.js +672 -0
- package/dist/src/mcp/oauth-provider.test.js.map +1 -0
- package/dist/src/mcp/oauth-token-storage.d.ts +61 -0
- package/dist/src/mcp/oauth-token-storage.js +148 -0
- package/dist/src/mcp/oauth-token-storage.js.map +1 -0
- package/dist/src/mcp/oauth-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/oauth-token-storage.test.js +208 -0
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -0
- package/dist/src/mcp/oauth-utils.d.ts +119 -0
- package/dist/src/mcp/oauth-utils.js +235 -0
- package/dist/src/mcp/oauth-utils.js.map +1 -0
- package/dist/src/mcp/oauth-utils.test.d.ts +6 -0
- package/dist/src/mcp/oauth-utils.test.js +199 -0
- package/dist/src/mcp/oauth-utils.test.js.map +1 -0
- package/dist/src/mcp/token-storage/base-token-storage.d.ts +19 -0
- package/dist/src/mcp/token-storage/base-token-storage.js +36 -0
- package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js +160 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/types.d.ts +34 -0
- package/dist/src/mcp/token-storage/types.js +7 -0
- package/dist/src/mcp/token-storage/types.js.map +1 -0
- package/dist/src/mocks/msw.d.ts +6 -0
- package/dist/src/mocks/msw.js +8 -0
- package/dist/src/mocks/msw.js.map +1 -0
- package/dist/src/prompts/mcp-prompts.d.ts +8 -0
- package/dist/src/prompts/mcp-prompts.js +13 -0
- package/dist/src/prompts/mcp-prompts.js.map +1 -0
- package/dist/src/prompts/prompt-registry.d.ts +34 -0
- package/dist/src/prompts/prompt-registry.js +63 -0
- package/dist/src/prompts/prompt-registry.js.map +1 -0
- package/dist/src/services/chatRecordingService.d.ts +150 -0
- package/dist/src/services/chatRecordingService.js +321 -0
- package/dist/src/services/chatRecordingService.js.map +1 -0
- package/dist/src/services/chatRecordingService.test.d.ts +6 -0
- package/dist/src/services/chatRecordingService.test.js +290 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -0
- package/dist/src/services/fileDiscoveryService.d.ts +35 -0
- package/dist/src/services/fileDiscoveryService.js +91 -0
- package/dist/src/services/fileDiscoveryService.js.map +1 -0
- package/dist/src/services/fileDiscoveryService.test.d.ts +6 -0
- package/dist/src/services/fileDiscoveryService.test.js +143 -0
- package/dist/src/services/fileDiscoveryService.test.js.map +1 -0
- package/dist/src/services/fileSystemService.d.ts +31 -0
- package/dist/src/services/fileSystemService.js +18 -0
- package/dist/src/services/fileSystemService.js.map +1 -0
- package/dist/src/services/fileSystemService.test.d.ts +6 -0
- package/dist/src/services/fileSystemService.test.js +41 -0
- package/dist/src/services/fileSystemService.test.js.map +1 -0
- package/dist/src/services/gitService.d.ts +23 -0
- package/dist/src/services/gitService.js +110 -0
- package/dist/src/services/gitService.js.map +1 -0
- package/dist/src/services/gitService.test.d.ts +6 -0
- package/dist/src/services/gitService.test.js +212 -0
- package/dist/src/services/gitService.test.js.map +1 -0
- package/dist/src/services/loopDetectionService.d.ts +98 -0
- package/dist/src/services/loopDetectionService.js +363 -0
- package/dist/src/services/loopDetectionService.js.map +1 -0
- package/dist/src/services/loopDetectionService.test.d.ts +6 -0
- package/dist/src/services/loopDetectionService.test.js +560 -0
- package/dist/src/services/loopDetectionService.test.js.map +1 -0
- package/dist/src/services/shellExecutionService.d.ts +68 -0
- package/dist/src/services/shellExecutionService.js +332 -0
- package/dist/src/services/shellExecutionService.js.map +1 -0
- package/dist/src/services/shellExecutionService.test.d.ts +6 -0
- package/dist/src/services/shellExecutionService.test.js +517 -0
- package/dist/src/services/shellExecutionService.test.js.map +1 -0
- package/dist/src/subagents/builtin-agents.d.ts +35 -0
- package/dist/src/subagents/builtin-agents.js +85 -0
- package/dist/src/subagents/builtin-agents.js.map +1 -0
- package/dist/src/subagents/builtin-agents.test.d.ts +6 -0
- package/dist/src/subagents/builtin-agents.test.js +78 -0
- package/dist/src/subagents/builtin-agents.test.js.map +1 -0
- package/dist/src/subagents/index.d.ts +29 -0
- package/dist/src/subagents/index.js +15 -0
- package/dist/src/subagents/index.js.map +1 -0
- package/dist/src/subagents/subagent-events.d.ts +93 -0
- package/dist/src/subagents/subagent-events.js +31 -0
- package/dist/src/subagents/subagent-events.js.map +1 -0
- package/dist/src/subagents/subagent-hooks.d.ts +29 -0
- package/dist/src/subagents/subagent-hooks.js +7 -0
- package/dist/src/subagents/subagent-hooks.js.map +1 -0
- package/dist/src/subagents/subagent-manager.d.ts +170 -0
- package/dist/src/subagents/subagent-manager.js +593 -0
- package/dist/src/subagents/subagent-manager.js.map +1 -0
- package/dist/src/subagents/subagent-manager.test.d.ts +6 -0
- package/dist/src/subagents/subagent-manager.test.js +822 -0
- package/dist/src/subagents/subagent-manager.test.js.map +1 -0
- package/dist/src/subagents/subagent-statistics.d.ts +46 -0
- package/dist/src/subagents/subagent-statistics.js +193 -0
- package/dist/src/subagents/subagent-statistics.js.map +1 -0
- package/dist/src/subagents/subagent-statistics.test.d.ts +6 -0
- package/dist/src/subagents/subagent-statistics.test.js +231 -0
- package/dist/src/subagents/subagent-statistics.test.js.map +1 -0
- package/dist/src/subagents/subagent.d.ts +161 -0
- package/dist/src/subagents/subagent.js +667 -0
- package/dist/src/subagents/subagent.js.map +1 -0
- package/dist/src/subagents/subagent.test.d.ts +6 -0
- package/dist/src/subagents/subagent.test.js +487 -0
- package/dist/src/subagents/subagent.test.js.map +1 -0
- package/dist/src/subagents/types.d.ts +218 -0
- package/dist/src/subagents/types.js +58 -0
- package/dist/src/subagents/types.js.map +1 -0
- package/dist/src/subagents/types.test.d.ts +6 -0
- package/dist/src/subagents/types.test.js +31 -0
- package/dist/src/subagents/types.test.js.map +1 -0
- package/dist/src/subagents/validation.d.ts +63 -0
- package/dist/src/subagents/validation.js +293 -0
- package/dist/src/subagents/validation.js.map +1 -0
- package/dist/src/subagents/validation.test.d.ts +6 -0
- package/dist/src/subagents/validation.test.js +330 -0
- package/dist/src/subagents/validation.test.js.map +1 -0
- package/dist/src/telemetry/blackbox-logger/blackbox-logger.d.ts +80 -0
- package/dist/src/telemetry/blackbox-logger/blackbox-logger.js +583 -0
- package/dist/src/telemetry/blackbox-logger/blackbox-logger.js.map +1 -0
- package/dist/src/telemetry/blackbox-logger/blackbox-logger.test.d.ts +6 -0
- package/dist/src/telemetry/blackbox-logger/blackbox-logger.test.js +301 -0
- package/dist/src/telemetry/blackbox-logger/blackbox-logger.test.js.map +1 -0
- package/dist/src/telemetry/blackbox-logger/event-types.d.ts +73 -0
- package/dist/src/telemetry/blackbox-logger/event-types.js +2 -0
- package/dist/src/telemetry/blackbox-logger/event-types.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +121 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +773 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +17 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +420 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +90 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +229 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -0
- package/dist/src/telemetry/constants.d.ts +34 -0
- package/dist/src/telemetry/constants.js +35 -0
- package/dist/src/telemetry/constants.js.map +1 -0
- package/dist/src/telemetry/file-exporters.d.ts +29 -0
- package/dist/src/telemetry/file-exporters.js +62 -0
- package/dist/src/telemetry/file-exporters.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +20 -0
- package/dist/src/telemetry/index.js +21 -0
- package/dist/src/telemetry/index.js.map +1 -0
- package/dist/src/telemetry/integration.test.circular.d.ts +6 -0
- package/dist/src/telemetry/integration.test.circular.js +95 -0
- package/dist/src/telemetry/integration.test.circular.js.map +1 -0
- package/dist/src/telemetry/loggers.d.ts +26 -0
- package/dist/src/telemetry/loggers.js +406 -0
- package/dist/src/telemetry/loggers.js.map +1 -0
- package/dist/src/telemetry/loggers.test.circular.d.ts +6 -0
- package/dist/src/telemetry/loggers.test.circular.js +107 -0
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -0
- package/dist/src/telemetry/loggers.test.d.ts +6 -0
- package/dist/src/telemetry/loggers.test.js +638 -0
- package/dist/src/telemetry/loggers.test.js.map +1 -0
- package/dist/src/telemetry/metrics.d.ts +40 -0
- package/dist/src/telemetry/metrics.js +229 -0
- package/dist/src/telemetry/metrics.js.map +1 -0
- package/dist/src/telemetry/metrics.test.d.ts +6 -0
- package/dist/src/telemetry/metrics.test.js +242 -0
- package/dist/src/telemetry/metrics.test.js.map +1 -0
- package/dist/src/telemetry/sdk.d.ts +9 -0
- package/dist/src/telemetry/sdk.js +161 -0
- package/dist/src/telemetry/sdk.js.map +1 -0
- package/dist/src/telemetry/sdk.test.d.ts +6 -0
- package/dist/src/telemetry/sdk.test.js +82 -0
- package/dist/src/telemetry/sdk.test.js.map +1 -0
- package/dist/src/telemetry/telemetry-utils.d.ts +6 -0
- package/dist/src/telemetry/telemetry-utils.js +14 -0
- package/dist/src/telemetry/telemetry-utils.js.map +1 -0
- package/dist/src/telemetry/telemetry-utils.test.d.ts +6 -0
- package/dist/src/telemetry/telemetry-utils.test.js +40 -0
- package/dist/src/telemetry/telemetry-utils.test.js.map +1 -0
- package/dist/src/telemetry/telemetry.test.d.ts +6 -0
- package/dist/src/telemetry/telemetry.test.js +50 -0
- package/dist/src/telemetry/telemetry.test.js.map +1 -0
- package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
- package/dist/src/telemetry/tool-call-decision.js +29 -0
- package/dist/src/telemetry/tool-call-decision.js.map +1 -0
- package/dist/src/telemetry/types.d.ts +236 -0
- package/dist/src/telemetry/types.js +405 -0
- package/dist/src/telemetry/types.js.map +1 -0
- package/dist/src/telemetry/uiTelemetry.d.ts +75 -0
- package/dist/src/telemetry/uiTelemetry.js +153 -0
- package/dist/src/telemetry/uiTelemetry.js.map +1 -0
- package/dist/src/telemetry/uiTelemetry.test.d.ts +6 -0
- package/dist/src/telemetry/uiTelemetry.test.js +558 -0
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -0
- package/dist/src/test-utils/config.d.ts +17 -0
- package/dist/src/test-utils/config.js +32 -0
- package/dist/src/test-utils/config.js.map +1 -0
- package/dist/src/test-utils/mockWorkspaceContext.d.ts +13 -0
- package/dist/src/test-utils/mockWorkspaceContext.js +24 -0
- package/dist/src/test-utils/mockWorkspaceContext.js.map +1 -0
- package/dist/src/test-utils/tools.d.ts +45 -0
- package/dist/src/test-utils/tools.js +105 -0
- package/dist/src/test-utils/tools.js.map +1 -0
- package/dist/src/tools/diffOptions.d.ts +9 -0
- package/dist/src/tools/diffOptions.js +38 -0
- package/dist/src/tools/diffOptions.js.map +1 -0
- package/dist/src/tools/diffOptions.test.d.ts +6 -0
- package/dist/src/tools/diffOptions.test.js +119 -0
- package/dist/src/tools/diffOptions.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +56 -0
- package/dist/src/tools/edit.js +434 -0
- package/dist/src/tools/edit.js.map +1 -0
- package/dist/src/tools/edit.test.d.ts +6 -0
- package/dist/src/tools/edit.test.js +569 -0
- package/dist/src/tools/edit.test.js.map +1 -0
- package/dist/src/tools/exitPlanMode.d.ts +28 -0
- package/dist/src/tools/exitPlanMode.js +137 -0
- package/dist/src/tools/exitPlanMode.js.map +1 -0
- package/dist/src/tools/exitPlanMode.test.d.ts +6 -0
- package/dist/src/tools/exitPlanMode.test.js +219 -0
- package/dist/src/tools/exitPlanMode.test.js.map +1 -0
- package/dist/src/tools/glob.d.ts +52 -0
- package/dist/src/tools/glob.js +237 -0
- package/dist/src/tools/glob.js.map +1 -0
- package/dist/src/tools/glob.test.d.ts +6 -0
- package/dist/src/tools/glob.test.js +375 -0
- package/dist/src/tools/glob.test.js.map +1 -0
- package/dist/src/tools/grep.d.ts +51 -0
- package/dist/src/tools/grep.js +566 -0
- package/dist/src/tools/grep.js.map +1 -0
- package/dist/src/tools/grep.test.d.ts +6 -0
- package/dist/src/tools/grep.test.js +356 -0
- package/dist/src/tools/grep.test.js.map +1 -0
- package/dist/src/tools/ls.d.ts +68 -0
- package/dist/src/tools/ls.js +227 -0
- package/dist/src/tools/ls.js.map +1 -0
- package/dist/src/tools/ls.test.d.ts +6 -0
- package/dist/src/tools/ls.test.js +389 -0
- package/dist/src/tools/ls.test.js.map +1 -0
- package/dist/src/tools/mcp-client-manager.d.ts +38 -0
- package/dist/src/tools/mcp-client-manager.js +74 -0
- package/dist/src/tools/mcp-client-manager.js.map +1 -0
- package/dist/src/tools/mcp-client-manager.test.d.ts +6 -0
- package/dist/src/tools/mcp-client-manager.test.js +39 -0
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -0
- package/dist/src/tools/mcp-client.d.ts +199 -0
- package/dist/src/tools/mcp-client.js +995 -0
- package/dist/src/tools/mcp-client.js.map +1 -0
- package/dist/src/tools/mcp-client.test.d.ts +6 -0
- package/dist/src/tools/mcp-client.test.js +454 -0
- package/dist/src/tools/mcp-client.test.js.map +1 -0
- package/dist/src/tools/mcp-tool.d.ts +23 -0
- package/dist/src/tools/mcp-tool.js +240 -0
- package/dist/src/tools/mcp-tool.js.map +1 -0
- package/dist/src/tools/mcp-tool.test.d.ts +6 -0
- package/dist/src/tools/mcp-tool.test.js +576 -0
- package/dist/src/tools/mcp-tool.test.js.map +1 -0
- package/dist/src/tools/memoryTool.d.ts +41 -0
- package/dist/src/tools/memoryTool.js +435 -0
- package/dist/src/tools/memoryTool.js.map +1 -0
- package/dist/src/tools/memoryTool.test.d.ts +6 -0
- package/dist/src/tools/memoryTool.test.js +420 -0
- package/dist/src/tools/memoryTool.test.js.map +1 -0
- package/dist/src/tools/modifiable-tool.d.ts +32 -0
- package/dist/src/tools/modifiable-tool.js +88 -0
- package/dist/src/tools/modifiable-tool.js.map +1 -0
- package/dist/src/tools/modifiable-tool.test.d.ts +6 -0
- package/dist/src/tools/modifiable-tool.test.js +193 -0
- package/dist/src/tools/modifiable-tool.test.js.map +1 -0
- package/dist/src/tools/read-file.d.ts +35 -0
- package/dist/src/tools/read-file.js +128 -0
- package/dist/src/tools/read-file.js.map +1 -0
- package/dist/src/tools/read-file.test.d.ts +6 -0
- package/dist/src/tools/read-file.test.js +311 -0
- package/dist/src/tools/read-file.test.js.map +1 -0
- package/dist/src/tools/read-many-files.d.ts +60 -0
- package/dist/src/tools/read-many-files.js +416 -0
- package/dist/src/tools/read-many-files.js.map +1 -0
- package/dist/src/tools/read-many-files.test.d.ts +6 -0
- package/dist/src/tools/read-many-files.test.js +565 -0
- package/dist/src/tools/read-many-files.test.js.map +1 -0
- package/dist/src/tools/ripGrep.d.ts +47 -0
- package/dist/src/tools/ripGrep.js +375 -0
- package/dist/src/tools/ripGrep.js.map +1 -0
- package/dist/src/tools/ripGrep.test.d.ts +6 -0
- package/dist/src/tools/ripGrep.test.js +874 -0
- package/dist/src/tools/ripGrep.test.js.map +1 -0
- package/dist/src/tools/shell.d.ts +23 -0
- package/dist/src/tools/shell.js +387 -0
- package/dist/src/tools/shell.js.map +1 -0
- package/dist/src/tools/shell.test.d.ts +6 -0
- package/dist/src/tools/shell.test.js +632 -0
- package/dist/src/tools/shell.test.js.map +1 -0
- package/dist/src/tools/task.d.ts +59 -0
- package/dist/src/tools/task.js +412 -0
- package/dist/src/tools/task.js.map +1 -0
- package/dist/src/tools/task.test.d.ts +6 -0
- package/dist/src/tools/task.test.js +369 -0
- package/dist/src/tools/task.test.js.map +1 -0
- package/dist/src/tools/todoWrite.d.ts +42 -0
- package/dist/src/tools/todoWrite.js +385 -0
- package/dist/src/tools/todoWrite.js.map +1 -0
- package/dist/src/tools/todoWrite.test.d.ts +6 -0
- package/dist/src/tools/todoWrite.test.js +222 -0
- package/dist/src/tools/todoWrite.test.js.map +1 -0
- package/dist/src/tools/tool-error.d.ts +43 -0
- package/dist/src/tools/tool-error.js +58 -0
- package/dist/src/tools/tool-error.js.map +1 -0
- package/dist/src/tools/tool-names.d.ts +23 -0
- package/dist/src/tools/tool-names.js +24 -0
- package/dist/src/tools/tool-names.js.map +1 -0
- package/dist/src/tools/tool-registry.d.ts +86 -0
- package/dist/src/tools/tool-registry.js +369 -0
- package/dist/src/tools/tool-registry.js.map +1 -0
- package/dist/src/tools/tool-registry.test.d.ts +6 -0
- package/dist/src/tools/tool-registry.test.js +332 -0
- package/dist/src/tools/tool-registry.test.js.map +1 -0
- package/dist/src/tools/tools.d.ts +316 -0
- package/dist/src/tools/tools.js +251 -0
- package/dist/src/tools/tools.js.map +1 -0
- package/dist/src/tools/tools.test.d.ts +6 -0
- package/dist/src/tools/tools.test.js +205 -0
- package/dist/src/tools/tools.test.js.map +1 -0
- package/dist/src/tools/web-fetch.d.ts +31 -0
- package/dist/src/tools/web-fetch.js +161 -0
- package/dist/src/tools/web-fetch.js.map +1 -0
- package/dist/src/tools/web-fetch.test.d.ts +6 -0
- package/dist/src/tools/web-fetch.test.js +133 -0
- package/dist/src/tools/web-fetch.test.js.map +1 -0
- package/dist/src/tools/web-search.d.ts +40 -0
- package/dist/src/tools/web-search.js +134 -0
- package/dist/src/tools/web-search.js.map +1 -0
- package/dist/src/tools/web-search.test.d.ts +6 -0
- package/dist/src/tools/web-search.test.js +125 -0
- package/dist/src/tools/web-search.test.js.map +1 -0
- package/dist/src/tools/write-file.d.ts +52 -0
- package/dist/src/tools/write-file.js +298 -0
- package/dist/src/tools/write-file.js.map +1 -0
- package/dist/src/tools/write-file.test.d.ts +6 -0
- package/dist/src/tools/write-file.test.js +436 -0
- package/dist/src/tools/write-file.test.js.map +1 -0
- package/dist/src/utils/LruCache.d.ts +13 -0
- package/dist/src/utils/LruCache.js +38 -0
- package/dist/src/utils/LruCache.js.map +1 -0
- package/dist/src/utils/bfsFileSearch.d.ts +24 -0
- package/dist/src/utils/bfsFileSearch.js +89 -0
- package/dist/src/utils/bfsFileSearch.js.map +1 -0
- package/dist/src/utils/bfsFileSearch.test.d.ts +6 -0
- package/dist/src/utils/bfsFileSearch.test.js +163 -0
- package/dist/src/utils/bfsFileSearch.test.js.map +1 -0
- package/dist/src/utils/browser.d.ts +13 -0
- package/dist/src/utils/browser.js +50 -0
- package/dist/src/utils/browser.js.map +1 -0
- package/dist/src/utils/editor.d.ts +28 -0
- package/dist/src/utils/editor.js +186 -0
- package/dist/src/utils/editor.js.map +1 -0
- package/dist/src/utils/editor.test.d.ts +6 -0
- package/dist/src/utils/editor.test.js +445 -0
- package/dist/src/utils/editor.test.js.map +1 -0
- package/dist/src/utils/environmentContext.d.ts +21 -0
- package/dist/src/utils/environmentContext.js +90 -0
- package/dist/src/utils/environmentContext.js.map +1 -0
- package/dist/src/utils/environmentContext.test.d.ts +6 -0
- package/dist/src/utils/environmentContext.test.js +148 -0
- package/dist/src/utils/environmentContext.test.js.map +1 -0
- package/dist/src/utils/errorParsing.d.ts +8 -0
- package/dist/src/utils/errorParsing.js +93 -0
- package/dist/src/utils/errorParsing.js.map +1 -0
- package/dist/src/utils/errorParsing.test.d.ts +6 -0
- package/dist/src/utils/errorParsing.test.js +172 -0
- package/dist/src/utils/errorParsing.test.js.map +1 -0
- package/dist/src/utils/errorReporting.d.ts +14 -0
- package/dist/src/utils/errorReporting.js +88 -0
- package/dist/src/utils/errorReporting.js.map +1 -0
- package/dist/src/utils/errorReporting.test.d.ts +6 -0
- package/dist/src/utils/errorReporting.test.js +130 -0
- package/dist/src/utils/errorReporting.test.js.map +1 -0
- package/dist/src/utils/errors.d.ts +33 -0
- package/dist/src/utils/errors.js +86 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/fetch.d.ts +11 -0
- package/dist/src/utils/fetch.js +51 -0
- package/dist/src/utils/fetch.js.map +1 -0
- package/dist/src/utils/fileUtils.d.ts +53 -0
- package/dist/src/utils/fileUtils.js +283 -0
- package/dist/src/utils/fileUtils.js.map +1 -0
- package/dist/src/utils/fileUtils.test.d.ts +6 -0
- package/dist/src/utils/fileUtils.test.js +364 -0
- package/dist/src/utils/fileUtils.test.js.map +1 -0
- package/dist/src/utils/filesearch/crawlCache.d.ts +25 -0
- package/dist/src/utils/filesearch/crawlCache.js +57 -0
- package/dist/src/utils/filesearch/crawlCache.js.map +1 -0
- package/dist/src/utils/filesearch/crawlCache.test.d.ts +6 -0
- package/dist/src/utils/filesearch/crawlCache.test.js +103 -0
- package/dist/src/utils/filesearch/crawlCache.test.js.map +1 -0
- package/dist/src/utils/filesearch/crawler.d.ts +15 -0
- package/dist/src/utils/filesearch/crawler.js +50 -0
- package/dist/src/utils/filesearch/crawler.js.map +1 -0
- package/dist/src/utils/filesearch/crawler.test.d.ts +6 -0
- package/dist/src/utils/filesearch/crawler.test.js +468 -0
- package/dist/src/utils/filesearch/crawler.test.js.map +1 -0
- package/dist/src/utils/filesearch/fileSearch.d.ts +38 -0
- package/dist/src/utils/filesearch/fileSearch.js +191 -0
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -0
- package/dist/src/utils/filesearch/fileSearch.test.d.ts +6 -0
- package/dist/src/utils/filesearch/fileSearch.test.js +642 -0
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -0
- package/dist/src/utils/filesearch/ignore.d.ts +42 -0
- package/dist/src/utils/filesearch/ignore.js +106 -0
- package/dist/src/utils/filesearch/ignore.js.map +1 -0
- package/dist/src/utils/filesearch/ignore.test.d.ts +6 -0
- package/dist/src/utils/filesearch/ignore.test.js +144 -0
- package/dist/src/utils/filesearch/ignore.test.js.map +1 -0
- package/dist/src/utils/filesearch/result-cache.d.ts +33 -0
- package/dist/src/utils/filesearch/result-cache.js +59 -0
- package/dist/src/utils/filesearch/result-cache.js.map +1 -0
- package/dist/src/utils/filesearch/result-cache.test.d.ts +6 -0
- package/dist/src/utils/filesearch/result-cache.test.js +46 -0
- package/dist/src/utils/filesearch/result-cache.test.js.map +1 -0
- package/dist/src/utils/flashFallback.integration.test.d.ts +6 -0
- package/dist/src/utils/flashFallback.integration.test.js +119 -0
- package/dist/src/utils/flashFallback.integration.test.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +6 -0
- package/dist/src/utils/formatters.js +16 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/generateContentResponseUtilities.d.ts +13 -0
- package/dist/src/utils/generateContentResponseUtilities.js +80 -0
- package/dist/src/utils/generateContentResponseUtilities.js.map +1 -0
- package/dist/src/utils/generateContentResponseUtilities.test.d.ts +6 -0
- package/dist/src/utils/generateContentResponseUtilities.test.js +235 -0
- package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -0
- package/dist/src/utils/getFolderStructure.d.ts +31 -0
- package/dist/src/utils/getFolderStructure.js +246 -0
- package/dist/src/utils/getFolderStructure.js.map +1 -0
- package/dist/src/utils/getFolderStructure.test.d.ts +6 -0
- package/dist/src/utils/getFolderStructure.test.js +282 -0
- package/dist/src/utils/getFolderStructure.test.js.map +1 -0
- package/dist/src/utils/getPty.d.ts +19 -0
- package/dist/src/utils/getPty.js +23 -0
- package/dist/src/utils/getPty.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.d.ts +20 -0
- package/dist/src/utils/gitIgnoreParser.js +61 -0
- package/dist/src/utils/gitIgnoreParser.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.test.d.ts +6 -0
- package/dist/src/utils/gitIgnoreParser.test.js +154 -0
- package/dist/src/utils/gitIgnoreParser.test.js.map +1 -0
- package/dist/src/utils/gitUtils.d.ts +17 -0
- package/dist/src/utils/gitUtils.js +61 -0
- package/dist/src/utils/gitUtils.js.map +1 -0
- package/dist/src/utils/ignorePatterns.d.ts +103 -0
- package/dist/src/utils/ignorePatterns.js +220 -0
- package/dist/src/utils/ignorePatterns.js.map +1 -0
- package/dist/src/utils/ignorePatterns.test.d.ts +6 -0
- package/dist/src/utils/ignorePatterns.test.js +250 -0
- package/dist/src/utils/ignorePatterns.test.js.map +1 -0
- package/dist/src/utils/installationManager.d.ts +16 -0
- package/dist/src/utils/installationManager.js +50 -0
- package/dist/src/utils/installationManager.js.map +1 -0
- package/dist/src/utils/installationManager.test.d.ts +6 -0
- package/dist/src/utils/installationManager.test.js +83 -0
- package/dist/src/utils/installationManager.test.js.map +1 -0
- package/dist/src/utils/language-detection.d.ts +6 -0
- package/dist/src/utils/language-detection.js +101 -0
- package/dist/src/utils/language-detection.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.d.ts +15 -0
- package/dist/src/utils/memoryDiscovery.js +271 -0
- package/dist/src/utils/memoryDiscovery.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.test.d.ts +6 -0
- package/dist/src/utils/memoryDiscovery.test.js +219 -0
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -0
- package/dist/src/utils/memoryImportProcessor.d.ts +42 -0
- package/dist/src/utils/memoryImportProcessor.js +296 -0
- package/dist/src/utils/memoryImportProcessor.js.map +1 -0
- package/dist/src/utils/memoryImportProcessor.test.d.ts +6 -0
- package/dist/src/utils/memoryImportProcessor.test.js +573 -0
- package/dist/src/utils/memoryImportProcessor.test.js.map +1 -0
- package/dist/src/utils/messageInspectors.d.ts +8 -0
- package/dist/src/utils/messageInspectors.js +16 -0
- package/dist/src/utils/messageInspectors.js.map +1 -0
- package/dist/src/utils/nextSpeakerChecker.d.ts +12 -0
- package/dist/src/utils/nextSpeakerChecker.js +91 -0
- package/dist/src/utils/nextSpeakerChecker.js.map +1 -0
- package/dist/src/utils/nextSpeakerChecker.test.d.ts +6 -0
- package/dist/src/utils/nextSpeakerChecker.test.js +168 -0
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -0
- package/dist/src/utils/openaiLogger.d.ts +42 -0
- package/dist/src/utils/openaiLogger.js +123 -0
- package/dist/src/utils/openaiLogger.js.map +1 -0
- package/dist/src/utils/partUtils.d.ts +35 -0
- package/dist/src/utils/partUtils.js +133 -0
- package/dist/src/utils/partUtils.js.map +1 -0
- package/dist/src/utils/partUtils.test.d.ts +6 -0
- package/dist/src/utils/partUtils.test.js +241 -0
- package/dist/src/utils/partUtils.test.js.map +1 -0
- package/dist/src/utils/pathReader.d.ts +17 -0
- package/dist/src/utils/pathReader.js +92 -0
- package/dist/src/utils/pathReader.js.map +1 -0
- package/dist/src/utils/pathReader.test.d.ts +6 -0
- package/dist/src/utils/pathReader.test.js +363 -0
- package/dist/src/utils/pathReader.test.js.map +1 -0
- package/dist/src/utils/paths.d.ts +58 -0
- package/dist/src/utils/paths.js +159 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/utils/paths.test.d.ts +6 -0
- package/dist/src/utils/paths.test.js +225 -0
- package/dist/src/utils/paths.test.js.map +1 -0
- package/dist/src/utils/projectSummary.d.ts +22 -0
- package/dist/src/utils/projectSummary.js +86 -0
- package/dist/src/utils/projectSummary.js.map +1 -0
- package/dist/src/utils/quotaErrorDetection.d.ts +20 -0
- package/dist/src/utils/quotaErrorDetection.js +114 -0
- package/dist/src/utils/quotaErrorDetection.js.map +1 -0
- package/dist/src/utils/quotaErrorDetection.test.d.ts +6 -0
- package/dist/src/utils/quotaErrorDetection.test.js +153 -0
- package/dist/src/utils/quotaErrorDetection.test.js.map +1 -0
- package/dist/src/utils/request-tokenizer/imageTokenizer.d.ts +112 -0
- package/dist/src/utils/request-tokenizer/imageTokenizer.js +401 -0
- package/dist/src/utils/request-tokenizer/imageTokenizer.js.map +1 -0
- package/dist/src/utils/request-tokenizer/imageTokenizer.test.d.ts +6 -0
- package/dist/src/utils/request-tokenizer/imageTokenizer.test.js +114 -0
- package/dist/src/utils/request-tokenizer/imageTokenizer.test.js.map +1 -0
- package/dist/src/utils/request-tokenizer/index.d.ts +18 -0
- package/dist/src/utils/request-tokenizer/index.js +30 -0
- package/dist/src/utils/request-tokenizer/index.js.map +1 -0
- package/dist/src/utils/request-tokenizer/requestTokenizer.d.ts +56 -0
- package/dist/src/utils/request-tokenizer/requestTokenizer.js +263 -0
- package/dist/src/utils/request-tokenizer/requestTokenizer.js.map +1 -0
- package/dist/src/utils/request-tokenizer/requestTokenizer.test.d.ts +6 -0
- package/dist/src/utils/request-tokenizer/requestTokenizer.test.js +245 -0
- package/dist/src/utils/request-tokenizer/requestTokenizer.test.js.map +1 -0
- package/dist/src/utils/request-tokenizer/supportedImageFormats.d.ts +30 -0
- package/dist/src/utils/request-tokenizer/supportedImageFormats.js +41 -0
- package/dist/src/utils/request-tokenizer/supportedImageFormats.js.map +1 -0
- package/dist/src/utils/request-tokenizer/textTokenizer.d.ts +29 -0
- package/dist/src/utils/request-tokenizer/textTokenizer.js +88 -0
- package/dist/src/utils/request-tokenizer/textTokenizer.js.map +1 -0
- package/dist/src/utils/request-tokenizer/textTokenizer.test.d.ts +6 -0
- package/dist/src/utils/request-tokenizer/textTokenizer.test.js +253 -0
- package/dist/src/utils/request-tokenizer/textTokenizer.test.js.map +1 -0
- package/dist/src/utils/request-tokenizer/types.d.ts +55 -0
- package/dist/src/utils/request-tokenizer/types.js +7 -0
- package/dist/src/utils/request-tokenizer/types.js.map +1 -0
- package/dist/src/utils/retry.d.ts +30 -0
- package/dist/src/utils/retry.js +288 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/utils/retry.test.d.ts +6 -0
- package/dist/src/utils/retry.test.js +452 -0
- package/dist/src/utils/retry.test.js.map +1 -0
- package/dist/src/utils/safeJsonParse.d.ts +15 -0
- package/dist/src/utils/safeJsonParse.js +41 -0
- package/dist/src/utils/safeJsonParse.js.map +1 -0
- package/dist/src/utils/safeJsonParse.test.d.ts +6 -0
- package/dist/src/utils/safeJsonParse.test.js +112 -0
- package/dist/src/utils/safeJsonParse.test.js.map +1 -0
- package/dist/src/utils/safeJsonStringify.d.ts +13 -0
- package/dist/src/utils/safeJsonStringify.js +25 -0
- package/dist/src/utils/safeJsonStringify.js.map +1 -0
- package/dist/src/utils/safeJsonStringify.test.d.ts +6 -0
- package/dist/src/utils/safeJsonStringify.test.js +61 -0
- package/dist/src/utils/safeJsonStringify.test.js.map +1 -0
- package/dist/src/utils/schemaValidator.d.ts +15 -0
- package/dist/src/utils/schemaValidator.js +57 -0
- package/dist/src/utils/schemaValidator.js.map +1 -0
- package/dist/src/utils/secure-browser-launcher.d.ts +23 -0
- package/dist/src/utils/secure-browser-launcher.js +165 -0
- package/dist/src/utils/secure-browser-launcher.js.map +1 -0
- package/dist/src/utils/secure-browser-launcher.test.d.ts +6 -0
- package/dist/src/utils/secure-browser-launcher.test.js +149 -0
- package/dist/src/utils/secure-browser-launcher.test.js.map +1 -0
- package/dist/src/utils/session.d.ts +6 -0
- package/dist/src/utils/session.js +8 -0
- package/dist/src/utils/session.js.map +1 -0
- package/dist/src/utils/shell-utils.d.ts +121 -0
- package/dist/src/utils/shell-utils.js +381 -0
- package/dist/src/utils/shell-utils.js.map +1 -0
- package/dist/src/utils/shell-utils.test.d.ts +6 -0
- package/dist/src/utils/shell-utils.test.js +346 -0
- package/dist/src/utils/shell-utils.test.js.map +1 -0
- package/dist/src/utils/shellReadOnlyChecker.d.ts +6 -0
- package/dist/src/utils/shellReadOnlyChecker.js +247 -0
- package/dist/src/utils/shellReadOnlyChecker.js.map +1 -0
- package/dist/src/utils/shellReadOnlyChecker.test.d.ts +6 -0
- package/dist/src/utils/shellReadOnlyChecker.test.js +47 -0
- package/dist/src/utils/shellReadOnlyChecker.test.js.map +1 -0
- package/dist/src/utils/subagentGenerator.d.ts +20 -0
- package/dist/src/utils/subagentGenerator.js +116 -0
- package/dist/src/utils/subagentGenerator.js.map +1 -0
- package/dist/src/utils/subagentGenerator.test.d.ts +6 -0
- package/dist/src/utils/subagentGenerator.test.js +158 -0
- package/dist/src/utils/subagentGenerator.test.js.map +1 -0
- package/dist/src/utils/summarizer.d.ts +25 -0
- package/dist/src/utils/summarizer.js +51 -0
- package/dist/src/utils/summarizer.js.map +1 -0
- package/dist/src/utils/summarizer.test.d.ts +6 -0
- package/dist/src/utils/summarizer.test.js +131 -0
- package/dist/src/utils/summarizer.test.js.map +1 -0
- package/dist/src/utils/systemEncoding.d.ts +40 -0
- package/dist/src/utils/systemEncoding.js +149 -0
- package/dist/src/utils/systemEncoding.js.map +1 -0
- package/dist/src/utils/systemEncoding.test.d.ts +6 -0
- package/dist/src/utils/systemEncoding.test.js +368 -0
- package/dist/src/utils/systemEncoding.test.js.map +1 -0
- package/dist/src/utils/testUtils.d.ts +29 -0
- package/dist/src/utils/testUtils.js +70 -0
- package/dist/src/utils/testUtils.js.map +1 -0
- package/dist/src/utils/textUtils.d.ts +13 -0
- package/dist/src/utils/textUtils.js +28 -0
- package/dist/src/utils/textUtils.js.map +1 -0
- package/dist/src/utils/tool-utils.d.ts +19 -0
- package/dist/src/utils/tool-utils.js +58 -0
- package/dist/src/utils/tool-utils.js.map +1 -0
- package/dist/src/utils/tool-utils.test.d.ts +6 -0
- package/dist/src/utils/tool-utils.test.js +61 -0
- package/dist/src/utils/tool-utils.test.js.map +1 -0
- package/dist/src/utils/userAccountManager.d.ts +20 -0
- package/dist/src/utils/userAccountManager.js +114 -0
- package/dist/src/utils/userAccountManager.js.map +1 -0
- package/dist/src/utils/userAccountManager.test.d.ts +6 -0
- package/dist/src/utils/userAccountManager.test.js +223 -0
- package/dist/src/utils/userAccountManager.test.js.map +1 -0
- package/dist/src/utils/workspaceContext.d.ts +66 -0
- package/dist/src/utils/workspaceContext.js +171 -0
- package/dist/src/utils/workspaceContext.js.map +1 -0
- package/dist/src/utils/workspaceContext.test.d.ts +6 -0
- package/dist/src/utils/workspaceContext.test.js +318 -0
- package/dist/src/utils/workspaceContext.test.js.map +1 -0
- package/dist/src/utils/yaml-parser.d.ts +29 -0
- package/dist/src/utils/yaml-parser.js +172 -0
- package/dist/src/utils/yaml-parser.js.map +1 -0
- package/dist/src/utils/yaml-parser.test.d.ts +6 -0
- package/dist/src/utils/yaml-parser.test.js +170 -0
- package/dist/src/utils/yaml-parser.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,1228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { ApprovalMode, BaseDeclarativeTool, BaseToolInvocation, Kind, ToolConfirmationOutcome, } from '../index.js';
|
|
8
|
+
import { MockModifiableTool, MockTool } from '../test-utils/tools.js';
|
|
9
|
+
import { CoreToolScheduler, convertToFunctionResponse, } from './coreToolScheduler.js';
|
|
10
|
+
import { getPlanModeSystemReminder } from './prompts.js';
|
|
11
|
+
class TestApprovalTool extends BaseDeclarativeTool {
|
|
12
|
+
config;
|
|
13
|
+
static Name = 'testApprovalTool';
|
|
14
|
+
constructor(config) {
|
|
15
|
+
super(TestApprovalTool.Name, 'TestApprovalTool', 'A tool for testing approval logic', Kind.Edit, {
|
|
16
|
+
properties: { id: { type: 'string' } },
|
|
17
|
+
required: ['id'],
|
|
18
|
+
type: 'object',
|
|
19
|
+
});
|
|
20
|
+
this.config = config;
|
|
21
|
+
}
|
|
22
|
+
createInvocation(params) {
|
|
23
|
+
return new TestApprovalInvocation(this.config, params);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
class TestApprovalInvocation extends BaseToolInvocation {
|
|
27
|
+
config;
|
|
28
|
+
constructor(config, params) {
|
|
29
|
+
super(params);
|
|
30
|
+
this.config = config;
|
|
31
|
+
}
|
|
32
|
+
getDescription() {
|
|
33
|
+
return `Test tool ${this.params.id}`;
|
|
34
|
+
}
|
|
35
|
+
async shouldConfirmExecute() {
|
|
36
|
+
// Need confirmation unless approval mode is AUTO_EDIT
|
|
37
|
+
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
type: 'edit',
|
|
42
|
+
title: `Confirm Test Tool ${this.params.id}`,
|
|
43
|
+
fileName: `test-${this.params.id}.txt`,
|
|
44
|
+
filePath: `/test-${this.params.id}.txt`,
|
|
45
|
+
fileDiff: 'Test diff content',
|
|
46
|
+
originalContent: '',
|
|
47
|
+
newContent: 'Test content',
|
|
48
|
+
onConfirm: async (outcome) => {
|
|
49
|
+
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
|
|
50
|
+
this.config.setApprovalMode(ApprovalMode.AUTO_EDIT);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
async execute() {
|
|
56
|
+
return {
|
|
57
|
+
llmContent: `Executed test tool ${this.params.id}`,
|
|
58
|
+
returnDisplay: `Executed test tool ${this.params.id}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
class SimpleToolInvocation extends BaseToolInvocation {
|
|
63
|
+
executeImpl;
|
|
64
|
+
constructor(params, executeImpl) {
|
|
65
|
+
super(params);
|
|
66
|
+
this.executeImpl = executeImpl;
|
|
67
|
+
}
|
|
68
|
+
getDescription() {
|
|
69
|
+
return 'simple tool invocation';
|
|
70
|
+
}
|
|
71
|
+
async execute() {
|
|
72
|
+
return await Promise.resolve(this.executeImpl());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
class SimpleTool extends BaseDeclarativeTool {
|
|
76
|
+
executeImpl;
|
|
77
|
+
constructor(name, kind, executeImpl) {
|
|
78
|
+
super(name, name, 'Simple test tool', kind, {
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {},
|
|
81
|
+
additionalProperties: true,
|
|
82
|
+
});
|
|
83
|
+
this.executeImpl = executeImpl;
|
|
84
|
+
}
|
|
85
|
+
createInvocation(params) {
|
|
86
|
+
return new SimpleToolInvocation(params, this.executeImpl);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function waitForStatus(onToolCallsUpdate, status, timeout = 5000) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const startTime = Date.now();
|
|
92
|
+
const check = () => {
|
|
93
|
+
if (Date.now() - startTime > timeout) {
|
|
94
|
+
const seenStatuses = onToolCallsUpdate.mock.calls
|
|
95
|
+
.flatMap((call) => call[0])
|
|
96
|
+
.map((toolCall) => toolCall.status);
|
|
97
|
+
reject(new Error(`Timed out waiting for status "${status}". Seen statuses: ${seenStatuses.join(', ')}`));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const foundCall = onToolCallsUpdate.mock.calls
|
|
101
|
+
.flatMap((call) => call[0])
|
|
102
|
+
.find((toolCall) => toolCall.status === status);
|
|
103
|
+
if (foundCall) {
|
|
104
|
+
resolve(foundCall);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
setTimeout(check, 10); // Check again in 10ms
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
check();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
describe('CoreToolScheduler', () => {
|
|
114
|
+
it('should cancel a tool call if the signal is aborted before confirmation', async () => {
|
|
115
|
+
const mockTool = new MockTool();
|
|
116
|
+
mockTool.shouldConfirm = true;
|
|
117
|
+
const declarativeTool = mockTool;
|
|
118
|
+
const mockToolRegistry = {
|
|
119
|
+
getTool: () => declarativeTool,
|
|
120
|
+
getFunctionDeclarations: () => [],
|
|
121
|
+
tools: new Map(),
|
|
122
|
+
discovery: {},
|
|
123
|
+
registerTool: () => { },
|
|
124
|
+
getToolByName: () => declarativeTool,
|
|
125
|
+
getToolByDisplayName: () => declarativeTool,
|
|
126
|
+
getTools: () => [],
|
|
127
|
+
discoverTools: async () => { },
|
|
128
|
+
getAllTools: () => [],
|
|
129
|
+
getToolsByServer: () => [],
|
|
130
|
+
};
|
|
131
|
+
const onAllToolCallsComplete = vi.fn();
|
|
132
|
+
const onToolCallsUpdate = vi.fn();
|
|
133
|
+
const mockConfig = {
|
|
134
|
+
getSessionId: () => 'test-session-id',
|
|
135
|
+
getUsageStatisticsEnabled: () => true,
|
|
136
|
+
getDebugMode: () => false,
|
|
137
|
+
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
138
|
+
getAllowedTools: () => [],
|
|
139
|
+
getContentGeneratorConfig: () => ({
|
|
140
|
+
model: 'test-model',
|
|
141
|
+
authType: 'oauth-personal',
|
|
142
|
+
}),
|
|
143
|
+
getToolRegistry: () => mockToolRegistry,
|
|
144
|
+
};
|
|
145
|
+
const scheduler = new CoreToolScheduler({
|
|
146
|
+
config: mockConfig,
|
|
147
|
+
onAllToolCallsComplete,
|
|
148
|
+
onToolCallsUpdate,
|
|
149
|
+
getPreferredEditor: () => 'vscode',
|
|
150
|
+
onEditorClose: vi.fn(),
|
|
151
|
+
});
|
|
152
|
+
const abortController = new AbortController();
|
|
153
|
+
const request = {
|
|
154
|
+
callId: '1',
|
|
155
|
+
name: 'mockTool',
|
|
156
|
+
args: {},
|
|
157
|
+
isClientInitiated: false,
|
|
158
|
+
prompt_id: 'prompt-id-1',
|
|
159
|
+
};
|
|
160
|
+
abortController.abort();
|
|
161
|
+
await scheduler.schedule([request], abortController.signal);
|
|
162
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
163
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
164
|
+
.calls[0][0];
|
|
165
|
+
expect(completedCalls[0].status).toBe('cancelled');
|
|
166
|
+
});
|
|
167
|
+
describe('plan mode enforcement', () => {
|
|
168
|
+
it('returns plan reminder and skips execution for edit tools', async () => {
|
|
169
|
+
const executeSpy = vi.fn().mockResolvedValue({
|
|
170
|
+
llmContent: 'should not execute',
|
|
171
|
+
returnDisplay: 'should not execute',
|
|
172
|
+
});
|
|
173
|
+
// Use MockTool with shouldConfirm=true to simulate a tool that requires confirmation
|
|
174
|
+
const tool = new MockTool('write_file');
|
|
175
|
+
tool.shouldConfirm = true;
|
|
176
|
+
tool.executeFn = executeSpy;
|
|
177
|
+
const mockToolRegistry = {
|
|
178
|
+
getTool: vi.fn().mockReturnValue(tool),
|
|
179
|
+
getAllToolNames: vi.fn().mockReturnValue([tool.name]),
|
|
180
|
+
};
|
|
181
|
+
const onAllToolCallsComplete = vi.fn();
|
|
182
|
+
const onToolCallsUpdate = vi.fn();
|
|
183
|
+
const mockConfig = {
|
|
184
|
+
getSessionId: () => 'plan-session',
|
|
185
|
+
getUsageStatisticsEnabled: () => true,
|
|
186
|
+
getDebugMode: () => false,
|
|
187
|
+
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.PLAN),
|
|
188
|
+
getAllowedTools: () => [],
|
|
189
|
+
getContentGeneratorConfig: () => ({
|
|
190
|
+
model: 'test-model',
|
|
191
|
+
authType: 'oauth-personal',
|
|
192
|
+
}),
|
|
193
|
+
getToolRegistry: () => mockToolRegistry,
|
|
194
|
+
};
|
|
195
|
+
const scheduler = new CoreToolScheduler({
|
|
196
|
+
config: mockConfig,
|
|
197
|
+
onAllToolCallsComplete,
|
|
198
|
+
onToolCallsUpdate,
|
|
199
|
+
getPreferredEditor: () => 'vscode',
|
|
200
|
+
onEditorClose: vi.fn(),
|
|
201
|
+
});
|
|
202
|
+
const request = {
|
|
203
|
+
callId: 'plan-1',
|
|
204
|
+
name: 'write_file',
|
|
205
|
+
args: {},
|
|
206
|
+
isClientInitiated: false,
|
|
207
|
+
prompt_id: 'prompt-plan',
|
|
208
|
+
};
|
|
209
|
+
await scheduler.schedule([request], new AbortController().signal);
|
|
210
|
+
const errorCall = (await waitForStatus(onToolCallsUpdate, 'error'));
|
|
211
|
+
expect(executeSpy).not.toHaveBeenCalled();
|
|
212
|
+
expect(errorCall.response.responseParts[0]?.functionResponse?.response?.['output']).toBe(getPlanModeSystemReminder());
|
|
213
|
+
expect(errorCall.response.resultDisplay).toContain('Plan mode');
|
|
214
|
+
});
|
|
215
|
+
it('allows read tools to execute in plan mode', async () => {
|
|
216
|
+
const executeSpy = vi.fn().mockResolvedValue({
|
|
217
|
+
llmContent: 'read ok',
|
|
218
|
+
returnDisplay: 'read ok',
|
|
219
|
+
});
|
|
220
|
+
const tool = new SimpleTool('read_file', Kind.Read, executeSpy);
|
|
221
|
+
const mockToolRegistry = {
|
|
222
|
+
getTool: vi.fn().mockReturnValue(tool),
|
|
223
|
+
getAllToolNames: vi.fn().mockReturnValue([tool.name]),
|
|
224
|
+
};
|
|
225
|
+
const onAllToolCallsComplete = vi.fn();
|
|
226
|
+
const onToolCallsUpdate = vi.fn();
|
|
227
|
+
const mockConfig = {
|
|
228
|
+
getSessionId: () => 'plan-session',
|
|
229
|
+
getUsageStatisticsEnabled: () => true,
|
|
230
|
+
getDebugMode: () => false,
|
|
231
|
+
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.PLAN),
|
|
232
|
+
getAllowedTools: () => [],
|
|
233
|
+
getContentGeneratorConfig: () => ({
|
|
234
|
+
model: 'test-model',
|
|
235
|
+
authType: 'oauth-personal',
|
|
236
|
+
}),
|
|
237
|
+
getToolRegistry: () => mockToolRegistry,
|
|
238
|
+
};
|
|
239
|
+
const scheduler = new CoreToolScheduler({
|
|
240
|
+
config: mockConfig,
|
|
241
|
+
onAllToolCallsComplete,
|
|
242
|
+
onToolCallsUpdate,
|
|
243
|
+
getPreferredEditor: () => 'vscode',
|
|
244
|
+
onEditorClose: vi.fn(),
|
|
245
|
+
});
|
|
246
|
+
const request = {
|
|
247
|
+
callId: 'plan-2',
|
|
248
|
+
name: tool.name,
|
|
249
|
+
args: {},
|
|
250
|
+
isClientInitiated: false,
|
|
251
|
+
prompt_id: 'prompt-plan',
|
|
252
|
+
};
|
|
253
|
+
await scheduler.schedule([request], new AbortController().signal);
|
|
254
|
+
const successCall = (await waitForStatus(onToolCallsUpdate, 'success'));
|
|
255
|
+
expect(executeSpy).toHaveBeenCalledTimes(1);
|
|
256
|
+
expect(successCall.response.responseParts[0]?.functionResponse?.response?.['output']).toBe('read ok');
|
|
257
|
+
});
|
|
258
|
+
it('enforces shell command restrictions in plan mode', async () => {
|
|
259
|
+
const executeSpyAllowed = vi.fn().mockResolvedValue({
|
|
260
|
+
llmContent: 'shell ok',
|
|
261
|
+
returnDisplay: 'shell ok',
|
|
262
|
+
});
|
|
263
|
+
const allowedTool = new SimpleTool('run_shell_command', Kind.Execute, executeSpyAllowed);
|
|
264
|
+
const allowedToolRegistry = {
|
|
265
|
+
getTool: vi.fn().mockReturnValue(allowedTool),
|
|
266
|
+
getAllToolNames: vi.fn().mockReturnValue([allowedTool.name]),
|
|
267
|
+
};
|
|
268
|
+
const allowedConfig = {
|
|
269
|
+
getSessionId: () => 'plan-session',
|
|
270
|
+
getUsageStatisticsEnabled: () => true,
|
|
271
|
+
getDebugMode: () => false,
|
|
272
|
+
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.PLAN),
|
|
273
|
+
getAllowedTools: () => [],
|
|
274
|
+
getContentGeneratorConfig: () => ({
|
|
275
|
+
model: 'test-model',
|
|
276
|
+
authType: 'oauth-personal',
|
|
277
|
+
}),
|
|
278
|
+
getToolRegistry: () => allowedToolRegistry,
|
|
279
|
+
};
|
|
280
|
+
const allowedUpdates = vi.fn();
|
|
281
|
+
const allowedScheduler = new CoreToolScheduler({
|
|
282
|
+
config: allowedConfig,
|
|
283
|
+
onAllToolCallsComplete: vi.fn(),
|
|
284
|
+
onToolCallsUpdate: allowedUpdates,
|
|
285
|
+
getPreferredEditor: () => 'vscode',
|
|
286
|
+
onEditorClose: vi.fn(),
|
|
287
|
+
});
|
|
288
|
+
const allowedRequest = {
|
|
289
|
+
callId: 'plan-shell-allowed',
|
|
290
|
+
name: allowedTool.name,
|
|
291
|
+
args: { command: 'ls -la' },
|
|
292
|
+
isClientInitiated: false,
|
|
293
|
+
prompt_id: 'prompt-plan',
|
|
294
|
+
};
|
|
295
|
+
await allowedScheduler.schedule([allowedRequest], new AbortController().signal);
|
|
296
|
+
await waitForStatus(allowedUpdates, 'success');
|
|
297
|
+
expect(executeSpyAllowed).toHaveBeenCalledTimes(1);
|
|
298
|
+
const executeSpyBlocked = vi.fn().mockResolvedValue({
|
|
299
|
+
llmContent: 'blocked',
|
|
300
|
+
returnDisplay: 'blocked',
|
|
301
|
+
});
|
|
302
|
+
// Use MockTool with shouldConfirm=true to simulate a shell tool that requires confirmation
|
|
303
|
+
const blockedTool = new MockTool('run_shell_command');
|
|
304
|
+
blockedTool.shouldConfirm = true;
|
|
305
|
+
blockedTool.executeFn = executeSpyBlocked;
|
|
306
|
+
const blockedToolRegistry = {
|
|
307
|
+
getTool: vi.fn().mockReturnValue(blockedTool),
|
|
308
|
+
getAllToolNames: vi.fn().mockReturnValue([blockedTool.name]),
|
|
309
|
+
};
|
|
310
|
+
const blockedConfig = {
|
|
311
|
+
getSessionId: () => 'plan-session',
|
|
312
|
+
getUsageStatisticsEnabled: () => true,
|
|
313
|
+
getDebugMode: () => false,
|
|
314
|
+
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.PLAN),
|
|
315
|
+
getAllowedTools: () => [],
|
|
316
|
+
getContentGeneratorConfig: () => ({
|
|
317
|
+
model: 'test-model',
|
|
318
|
+
authType: 'oauth-personal',
|
|
319
|
+
}),
|
|
320
|
+
getToolRegistry: () => blockedToolRegistry,
|
|
321
|
+
};
|
|
322
|
+
const blockedUpdates = vi.fn();
|
|
323
|
+
const blockedScheduler = new CoreToolScheduler({
|
|
324
|
+
config: blockedConfig,
|
|
325
|
+
onAllToolCallsComplete: vi.fn(),
|
|
326
|
+
onToolCallsUpdate: blockedUpdates,
|
|
327
|
+
getPreferredEditor: () => 'vscode',
|
|
328
|
+
onEditorClose: vi.fn(),
|
|
329
|
+
});
|
|
330
|
+
const blockedRequest = {
|
|
331
|
+
callId: 'plan-shell-blocked',
|
|
332
|
+
name: 'run_shell_command',
|
|
333
|
+
args: { command: 'rm -rf tmp' },
|
|
334
|
+
isClientInitiated: false,
|
|
335
|
+
prompt_id: 'prompt-plan',
|
|
336
|
+
};
|
|
337
|
+
await blockedScheduler.schedule([blockedRequest], new AbortController().signal);
|
|
338
|
+
const blockedCall = (await waitForStatus(blockedUpdates, 'error'));
|
|
339
|
+
expect(executeSpyBlocked).not.toHaveBeenCalled();
|
|
340
|
+
expect(blockedCall.response.responseParts[0]?.functionResponse?.response?.['output']).toBe(getPlanModeSystemReminder());
|
|
341
|
+
const observedStatuses = blockedUpdates.mock.calls
|
|
342
|
+
.flatMap((call) => call[0])
|
|
343
|
+
.map((tc) => tc.status);
|
|
344
|
+
expect(observedStatuses).not.toContain('awaiting_approval');
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
describe('getToolSuggestion', () => {
|
|
348
|
+
it('should suggest the top N closest tool names for a typo', () => {
|
|
349
|
+
// Create mocked tool registry
|
|
350
|
+
const mockConfig = {
|
|
351
|
+
getToolRegistry: () => mockToolRegistry,
|
|
352
|
+
};
|
|
353
|
+
const mockToolRegistry = {
|
|
354
|
+
getAllToolNames: () => ['list_files', 'read_file', 'write_file'],
|
|
355
|
+
};
|
|
356
|
+
// Create scheduler
|
|
357
|
+
const scheduler = new CoreToolScheduler({
|
|
358
|
+
config: mockConfig,
|
|
359
|
+
getPreferredEditor: () => 'vscode',
|
|
360
|
+
onEditorClose: vi.fn(),
|
|
361
|
+
});
|
|
362
|
+
// Test that the right tool is selected, with only 1 result, for typos
|
|
363
|
+
// @ts-expect-error accessing private method
|
|
364
|
+
const misspelledTool = scheduler.getToolSuggestion('list_fils', 1);
|
|
365
|
+
expect(misspelledTool).toBe(' Did you mean "list_files"?');
|
|
366
|
+
// Test that the right tool is selected, with only 1 result, for prefixes
|
|
367
|
+
// @ts-expect-error accessing private method
|
|
368
|
+
const prefixedTool = scheduler.getToolSuggestion('github.list_files', 1);
|
|
369
|
+
expect(prefixedTool).toBe(' Did you mean "list_files"?');
|
|
370
|
+
// Test that the right tool is first
|
|
371
|
+
// @ts-expect-error accessing private method
|
|
372
|
+
const suggestionMultiple = scheduler.getToolSuggestion('list_fils');
|
|
373
|
+
expect(suggestionMultiple).toBe(' Did you mean one of: "list_files", "read_file", "write_file"?');
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
describe('CoreToolScheduler with payload', () => {
|
|
378
|
+
it('should update args and diff and execute tool when payload is provided', async () => {
|
|
379
|
+
const mockTool = new MockModifiableTool();
|
|
380
|
+
const declarativeTool = mockTool;
|
|
381
|
+
const mockToolRegistry = {
|
|
382
|
+
getTool: () => declarativeTool,
|
|
383
|
+
getFunctionDeclarations: () => [],
|
|
384
|
+
tools: new Map(),
|
|
385
|
+
discovery: {},
|
|
386
|
+
registerTool: () => { },
|
|
387
|
+
getToolByName: () => declarativeTool,
|
|
388
|
+
getToolByDisplayName: () => declarativeTool,
|
|
389
|
+
getTools: () => [],
|
|
390
|
+
discoverTools: async () => { },
|
|
391
|
+
getAllTools: () => [],
|
|
392
|
+
getToolsByServer: () => [],
|
|
393
|
+
};
|
|
394
|
+
const onAllToolCallsComplete = vi.fn();
|
|
395
|
+
const onToolCallsUpdate = vi.fn();
|
|
396
|
+
const mockConfig = {
|
|
397
|
+
getSessionId: () => 'test-session-id',
|
|
398
|
+
getUsageStatisticsEnabled: () => true,
|
|
399
|
+
getDebugMode: () => false,
|
|
400
|
+
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
401
|
+
getAllowedTools: () => [],
|
|
402
|
+
getContentGeneratorConfig: () => ({
|
|
403
|
+
model: 'test-model',
|
|
404
|
+
authType: 'oauth-personal',
|
|
405
|
+
}),
|
|
406
|
+
getToolRegistry: () => mockToolRegistry,
|
|
407
|
+
};
|
|
408
|
+
const scheduler = new CoreToolScheduler({
|
|
409
|
+
config: mockConfig,
|
|
410
|
+
onAllToolCallsComplete,
|
|
411
|
+
onToolCallsUpdate,
|
|
412
|
+
getPreferredEditor: () => 'vscode',
|
|
413
|
+
onEditorClose: vi.fn(),
|
|
414
|
+
});
|
|
415
|
+
const abortController = new AbortController();
|
|
416
|
+
const request = {
|
|
417
|
+
callId: '1',
|
|
418
|
+
name: 'mockModifiableTool',
|
|
419
|
+
args: {},
|
|
420
|
+
isClientInitiated: false,
|
|
421
|
+
prompt_id: 'prompt-id-2',
|
|
422
|
+
};
|
|
423
|
+
await scheduler.schedule([request], abortController.signal);
|
|
424
|
+
const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
|
|
425
|
+
const confirmationDetails = awaitingCall.confirmationDetails;
|
|
426
|
+
if (confirmationDetails) {
|
|
427
|
+
const payload = { newContent: 'final version' };
|
|
428
|
+
await confirmationDetails.onConfirm(ToolConfirmationOutcome.ProceedOnce, payload);
|
|
429
|
+
}
|
|
430
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
431
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
432
|
+
.calls[0][0];
|
|
433
|
+
expect(completedCalls[0].status).toBe('success');
|
|
434
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({
|
|
435
|
+
newContent: 'final version',
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
describe('convertToFunctionResponse', () => {
|
|
440
|
+
const toolName = 'testTool';
|
|
441
|
+
const callId = 'call1';
|
|
442
|
+
it('should handle simple string llmContent', () => {
|
|
443
|
+
const llmContent = 'Simple text output';
|
|
444
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
445
|
+
expect(result).toEqual([
|
|
446
|
+
{
|
|
447
|
+
functionResponse: {
|
|
448
|
+
name: toolName,
|
|
449
|
+
id: callId,
|
|
450
|
+
response: { output: 'Simple text output' },
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
]);
|
|
454
|
+
});
|
|
455
|
+
it('should handle llmContent as a single Part with text', () => {
|
|
456
|
+
const llmContent = { text: 'Text from Part object' };
|
|
457
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
458
|
+
expect(result).toEqual([
|
|
459
|
+
{
|
|
460
|
+
functionResponse: {
|
|
461
|
+
name: toolName,
|
|
462
|
+
id: callId,
|
|
463
|
+
response: { output: 'Text from Part object' },
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
]);
|
|
467
|
+
});
|
|
468
|
+
it('should handle llmContent as a PartListUnion array with a single text Part', () => {
|
|
469
|
+
const llmContent = [{ text: 'Text from array' }];
|
|
470
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
471
|
+
expect(result).toEqual([
|
|
472
|
+
{
|
|
473
|
+
functionResponse: {
|
|
474
|
+
name: toolName,
|
|
475
|
+
id: callId,
|
|
476
|
+
response: { output: 'Text from array' },
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
]);
|
|
480
|
+
});
|
|
481
|
+
it('should handle llmContent with inlineData', () => {
|
|
482
|
+
const llmContent = {
|
|
483
|
+
inlineData: { mimeType: 'image/png', data: 'base64...' },
|
|
484
|
+
};
|
|
485
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
486
|
+
expect(result).toEqual([
|
|
487
|
+
{
|
|
488
|
+
functionResponse: {
|
|
489
|
+
name: toolName,
|
|
490
|
+
id: callId,
|
|
491
|
+
response: {
|
|
492
|
+
output: 'Binary content of type image/png was processed.',
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
llmContent,
|
|
497
|
+
]);
|
|
498
|
+
});
|
|
499
|
+
it('should handle llmContent with fileData', () => {
|
|
500
|
+
const llmContent = {
|
|
501
|
+
fileData: { mimeType: 'application/pdf', fileUri: 'gs://...' },
|
|
502
|
+
};
|
|
503
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
504
|
+
expect(result).toEqual([
|
|
505
|
+
{
|
|
506
|
+
functionResponse: {
|
|
507
|
+
name: toolName,
|
|
508
|
+
id: callId,
|
|
509
|
+
response: {
|
|
510
|
+
output: 'Binary content of type application/pdf was processed.',
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
llmContent,
|
|
515
|
+
]);
|
|
516
|
+
});
|
|
517
|
+
it('should handle llmContent as an array of multiple Parts (text and inlineData)', () => {
|
|
518
|
+
const llmContent = [
|
|
519
|
+
{ text: 'Some textual description' },
|
|
520
|
+
{ inlineData: { mimeType: 'image/jpeg', data: 'base64data...' } },
|
|
521
|
+
{ text: 'Another text part' },
|
|
522
|
+
];
|
|
523
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
524
|
+
expect(result).toEqual([
|
|
525
|
+
{
|
|
526
|
+
functionResponse: {
|
|
527
|
+
name: toolName,
|
|
528
|
+
id: callId,
|
|
529
|
+
response: { output: 'Tool execution succeeded.' },
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
...llmContent,
|
|
533
|
+
]);
|
|
534
|
+
});
|
|
535
|
+
it('should handle llmContent as an array with a single inlineData Part', () => {
|
|
536
|
+
const llmContent = [
|
|
537
|
+
{ inlineData: { mimeType: 'image/gif', data: 'gifdata...' } },
|
|
538
|
+
];
|
|
539
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
540
|
+
expect(result).toEqual([
|
|
541
|
+
{
|
|
542
|
+
functionResponse: {
|
|
543
|
+
name: toolName,
|
|
544
|
+
id: callId,
|
|
545
|
+
response: {
|
|
546
|
+
output: 'Binary content of type image/gif was processed.',
|
|
547
|
+
},
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
...llmContent,
|
|
551
|
+
]);
|
|
552
|
+
});
|
|
553
|
+
it('should handle llmContent as a generic Part (not text, inlineData, or fileData)', () => {
|
|
554
|
+
const llmContent = { functionCall: { name: 'test', args: {} } };
|
|
555
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
556
|
+
expect(result).toEqual([
|
|
557
|
+
{
|
|
558
|
+
functionResponse: {
|
|
559
|
+
name: toolName,
|
|
560
|
+
id: callId,
|
|
561
|
+
response: { output: 'Tool execution succeeded.' },
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
]);
|
|
565
|
+
});
|
|
566
|
+
it('should handle empty string llmContent', () => {
|
|
567
|
+
const llmContent = '';
|
|
568
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
569
|
+
expect(result).toEqual([
|
|
570
|
+
{
|
|
571
|
+
functionResponse: {
|
|
572
|
+
name: toolName,
|
|
573
|
+
id: callId,
|
|
574
|
+
response: { output: '' },
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
]);
|
|
578
|
+
});
|
|
579
|
+
it('should handle llmContent as an empty array', () => {
|
|
580
|
+
const llmContent = [];
|
|
581
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
582
|
+
expect(result).toEqual([
|
|
583
|
+
{
|
|
584
|
+
functionResponse: {
|
|
585
|
+
name: toolName,
|
|
586
|
+
id: callId,
|
|
587
|
+
response: { output: 'Tool execution succeeded.' },
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
]);
|
|
591
|
+
});
|
|
592
|
+
it('should handle llmContent as a Part with undefined inlineData/fileData/text', () => {
|
|
593
|
+
const llmContent = {}; // An empty part object
|
|
594
|
+
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
595
|
+
expect(result).toEqual([
|
|
596
|
+
{
|
|
597
|
+
functionResponse: {
|
|
598
|
+
name: toolName,
|
|
599
|
+
id: callId,
|
|
600
|
+
response: { output: 'Tool execution succeeded.' },
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
]);
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
class MockEditToolInvocation extends BaseToolInvocation {
|
|
607
|
+
constructor(params) {
|
|
608
|
+
super(params);
|
|
609
|
+
}
|
|
610
|
+
getDescription() {
|
|
611
|
+
return 'A mock edit tool invocation';
|
|
612
|
+
}
|
|
613
|
+
async shouldConfirmExecute(_abortSignal) {
|
|
614
|
+
return {
|
|
615
|
+
type: 'edit',
|
|
616
|
+
title: 'Confirm Edit',
|
|
617
|
+
fileName: 'test.txt',
|
|
618
|
+
filePath: 'test.txt',
|
|
619
|
+
fileDiff: '--- test.txt\n+++ test.txt\n@@ -1,1 +1,1 @@\n-old content\n+new content',
|
|
620
|
+
originalContent: 'old content',
|
|
621
|
+
newContent: 'new content',
|
|
622
|
+
onConfirm: async () => { },
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
async execute(_abortSignal) {
|
|
626
|
+
return {
|
|
627
|
+
llmContent: 'Edited successfully',
|
|
628
|
+
returnDisplay: 'Edited successfully',
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
class MockEditTool extends BaseDeclarativeTool {
|
|
633
|
+
constructor() {
|
|
634
|
+
super('mockEditTool', 'mockEditTool', 'A mock edit tool', Kind.Edit, {});
|
|
635
|
+
}
|
|
636
|
+
createInvocation(params) {
|
|
637
|
+
return new MockEditToolInvocation(params);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
describe('CoreToolScheduler edit cancellation', () => {
|
|
641
|
+
it('should preserve diff when an edit is cancelled', async () => {
|
|
642
|
+
const mockEditTool = new MockEditTool();
|
|
643
|
+
const mockToolRegistry = {
|
|
644
|
+
getTool: () => mockEditTool,
|
|
645
|
+
getFunctionDeclarations: () => [],
|
|
646
|
+
tools: new Map(),
|
|
647
|
+
discovery: {},
|
|
648
|
+
registerTool: () => { },
|
|
649
|
+
getToolByName: () => mockEditTool,
|
|
650
|
+
getToolByDisplayName: () => mockEditTool,
|
|
651
|
+
getTools: () => [],
|
|
652
|
+
discoverTools: async () => { },
|
|
653
|
+
getAllTools: () => [],
|
|
654
|
+
getToolsByServer: () => [],
|
|
655
|
+
};
|
|
656
|
+
const onAllToolCallsComplete = vi.fn();
|
|
657
|
+
const onToolCallsUpdate = vi.fn();
|
|
658
|
+
const mockConfig = {
|
|
659
|
+
getSessionId: () => 'test-session-id',
|
|
660
|
+
getUsageStatisticsEnabled: () => true,
|
|
661
|
+
getDebugMode: () => false,
|
|
662
|
+
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
663
|
+
getAllowedTools: () => [],
|
|
664
|
+
getContentGeneratorConfig: () => ({
|
|
665
|
+
model: 'test-model',
|
|
666
|
+
authType: 'oauth-personal',
|
|
667
|
+
}),
|
|
668
|
+
getToolRegistry: () => mockToolRegistry,
|
|
669
|
+
};
|
|
670
|
+
const scheduler = new CoreToolScheduler({
|
|
671
|
+
config: mockConfig,
|
|
672
|
+
onAllToolCallsComplete,
|
|
673
|
+
onToolCallsUpdate,
|
|
674
|
+
getPreferredEditor: () => 'vscode',
|
|
675
|
+
onEditorClose: vi.fn(),
|
|
676
|
+
});
|
|
677
|
+
const abortController = new AbortController();
|
|
678
|
+
const request = {
|
|
679
|
+
callId: '1',
|
|
680
|
+
name: 'mockEditTool',
|
|
681
|
+
args: {},
|
|
682
|
+
isClientInitiated: false,
|
|
683
|
+
prompt_id: 'prompt-id-1',
|
|
684
|
+
};
|
|
685
|
+
await scheduler.schedule([request], abortController.signal);
|
|
686
|
+
const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
|
|
687
|
+
// Cancel the edit
|
|
688
|
+
const confirmationDetails = awaitingCall.confirmationDetails;
|
|
689
|
+
if (confirmationDetails) {
|
|
690
|
+
await confirmationDetails.onConfirm(ToolConfirmationOutcome.Cancel);
|
|
691
|
+
}
|
|
692
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
693
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
694
|
+
.calls[0][0];
|
|
695
|
+
expect(completedCalls[0].status).toBe('cancelled');
|
|
696
|
+
// Check that the diff is preserved
|
|
697
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
698
|
+
const cancelledCall = completedCalls[0];
|
|
699
|
+
expect(cancelledCall.response.resultDisplay).toBeDefined();
|
|
700
|
+
expect(cancelledCall.response.resultDisplay.fileDiff).toBe('--- test.txt\n+++ test.txt\n@@ -1,1 +1,1 @@\n-old content\n+new content');
|
|
701
|
+
expect(cancelledCall.response.resultDisplay.fileName).toBe('test.txt');
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
describe('CoreToolScheduler YOLO mode', () => {
|
|
705
|
+
it('should execute tool requiring confirmation directly without waiting', async () => {
|
|
706
|
+
// Arrange
|
|
707
|
+
const mockTool = new MockTool();
|
|
708
|
+
mockTool.executeFn.mockReturnValue({
|
|
709
|
+
llmContent: 'Tool executed',
|
|
710
|
+
returnDisplay: 'Tool executed',
|
|
711
|
+
});
|
|
712
|
+
// This tool would normally require confirmation.
|
|
713
|
+
mockTool.shouldConfirm = true;
|
|
714
|
+
const declarativeTool = mockTool;
|
|
715
|
+
const mockToolRegistry = {
|
|
716
|
+
getTool: () => declarativeTool,
|
|
717
|
+
getToolByName: () => declarativeTool,
|
|
718
|
+
// Other properties are not needed for this test but are included for type consistency.
|
|
719
|
+
getFunctionDeclarations: () => [],
|
|
720
|
+
tools: new Map(),
|
|
721
|
+
discovery: {},
|
|
722
|
+
registerTool: () => { },
|
|
723
|
+
getToolByDisplayName: () => declarativeTool,
|
|
724
|
+
getTools: () => [],
|
|
725
|
+
discoverTools: async () => { },
|
|
726
|
+
getAllTools: () => [],
|
|
727
|
+
getToolsByServer: () => [],
|
|
728
|
+
};
|
|
729
|
+
const onAllToolCallsComplete = vi.fn();
|
|
730
|
+
const onToolCallsUpdate = vi.fn();
|
|
731
|
+
// Configure the scheduler for YOLO mode.
|
|
732
|
+
const mockConfig = {
|
|
733
|
+
getSessionId: () => 'test-session-id',
|
|
734
|
+
getUsageStatisticsEnabled: () => true,
|
|
735
|
+
getDebugMode: () => false,
|
|
736
|
+
getApprovalMode: () => ApprovalMode.YOLO,
|
|
737
|
+
getAllowedTools: () => [],
|
|
738
|
+
getContentGeneratorConfig: () => ({
|
|
739
|
+
model: 'test-model',
|
|
740
|
+
authType: 'oauth-personal',
|
|
741
|
+
}),
|
|
742
|
+
getToolRegistry: () => mockToolRegistry,
|
|
743
|
+
};
|
|
744
|
+
const scheduler = new CoreToolScheduler({
|
|
745
|
+
config: mockConfig,
|
|
746
|
+
onAllToolCallsComplete,
|
|
747
|
+
onToolCallsUpdate,
|
|
748
|
+
getPreferredEditor: () => 'vscode',
|
|
749
|
+
onEditorClose: vi.fn(),
|
|
750
|
+
});
|
|
751
|
+
const abortController = new AbortController();
|
|
752
|
+
const request = {
|
|
753
|
+
callId: '1',
|
|
754
|
+
name: 'mockTool',
|
|
755
|
+
args: { param: 'value' },
|
|
756
|
+
isClientInitiated: false,
|
|
757
|
+
prompt_id: 'prompt-id-yolo',
|
|
758
|
+
};
|
|
759
|
+
// Act
|
|
760
|
+
await scheduler.schedule([request], abortController.signal);
|
|
761
|
+
// Assert
|
|
762
|
+
// 1. The tool's execute method was called directly.
|
|
763
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({ param: 'value' });
|
|
764
|
+
// 2. The tool call status never entered 'awaiting_approval'.
|
|
765
|
+
const statusUpdates = onToolCallsUpdate.mock.calls
|
|
766
|
+
.map((call) => call[0][0]?.status)
|
|
767
|
+
.filter(Boolean);
|
|
768
|
+
expect(statusUpdates).not.toContain('awaiting_approval');
|
|
769
|
+
expect(statusUpdates).toEqual([
|
|
770
|
+
'validating',
|
|
771
|
+
'scheduled',
|
|
772
|
+
'executing',
|
|
773
|
+
'success',
|
|
774
|
+
]);
|
|
775
|
+
// 3. The final callback indicates the tool call was successful.
|
|
776
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
777
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
778
|
+
.calls[0][0];
|
|
779
|
+
expect(completedCalls).toHaveLength(1);
|
|
780
|
+
const completedCall = completedCalls[0];
|
|
781
|
+
expect(completedCall.status).toBe('success');
|
|
782
|
+
if (completedCall.status === 'success') {
|
|
783
|
+
expect(completedCall.response.resultDisplay).toBe('Tool executed');
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
describe('CoreToolScheduler cancellation during executing with live output', () => {
|
|
788
|
+
it('sets status to cancelled and preserves last output', async () => {
|
|
789
|
+
class StreamingInvocation extends BaseToolInvocation {
|
|
790
|
+
getDescription() {
|
|
791
|
+
return `Streaming tool ${this.params.id}`;
|
|
792
|
+
}
|
|
793
|
+
async execute(signal, updateOutput) {
|
|
794
|
+
updateOutput?.('hello');
|
|
795
|
+
// Wait until aborted to emulate a long-running task
|
|
796
|
+
await new Promise((resolve) => {
|
|
797
|
+
if (signal.aborted)
|
|
798
|
+
return resolve();
|
|
799
|
+
const onAbort = () => {
|
|
800
|
+
signal.removeEventListener('abort', onAbort);
|
|
801
|
+
resolve();
|
|
802
|
+
};
|
|
803
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
804
|
+
});
|
|
805
|
+
// Return a normal (non-error) result; scheduler should still mark cancelled
|
|
806
|
+
return { llmContent: 'done', returnDisplay: 'done' };
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
class StreamingTool extends BaseDeclarativeTool {
|
|
810
|
+
constructor() {
|
|
811
|
+
super('stream-tool', 'Stream Tool', 'Emits live output and waits for abort', Kind.Other, {
|
|
812
|
+
type: 'object',
|
|
813
|
+
properties: { id: { type: 'string' } },
|
|
814
|
+
required: ['id'],
|
|
815
|
+
}, true, true);
|
|
816
|
+
}
|
|
817
|
+
createInvocation(params) {
|
|
818
|
+
return new StreamingInvocation(params);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
const tool = new StreamingTool();
|
|
822
|
+
const mockToolRegistry = {
|
|
823
|
+
getTool: () => tool,
|
|
824
|
+
getFunctionDeclarations: () => [],
|
|
825
|
+
tools: new Map(),
|
|
826
|
+
discovery: {},
|
|
827
|
+
registerTool: () => { },
|
|
828
|
+
getToolByName: () => tool,
|
|
829
|
+
getToolByDisplayName: () => tool,
|
|
830
|
+
getTools: () => [],
|
|
831
|
+
discoverTools: async () => { },
|
|
832
|
+
getAllTools: () => [],
|
|
833
|
+
getToolsByServer: () => [],
|
|
834
|
+
};
|
|
835
|
+
const onAllToolCallsComplete = vi.fn();
|
|
836
|
+
const onToolCallsUpdate = vi.fn();
|
|
837
|
+
const mockConfig = {
|
|
838
|
+
getSessionId: () => 'test-session-id',
|
|
839
|
+
getUsageStatisticsEnabled: () => true,
|
|
840
|
+
getDebugMode: () => false,
|
|
841
|
+
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
842
|
+
getContentGeneratorConfig: () => ({
|
|
843
|
+
model: 'test-model',
|
|
844
|
+
authType: 'oauth-personal',
|
|
845
|
+
}),
|
|
846
|
+
getToolRegistry: () => mockToolRegistry,
|
|
847
|
+
};
|
|
848
|
+
const scheduler = new CoreToolScheduler({
|
|
849
|
+
config: mockConfig,
|
|
850
|
+
onAllToolCallsComplete,
|
|
851
|
+
onToolCallsUpdate,
|
|
852
|
+
getPreferredEditor: () => 'vscode',
|
|
853
|
+
onEditorClose: vi.fn(),
|
|
854
|
+
});
|
|
855
|
+
const abortController = new AbortController();
|
|
856
|
+
const request = {
|
|
857
|
+
callId: '1',
|
|
858
|
+
name: 'stream-tool',
|
|
859
|
+
args: { id: 'x' },
|
|
860
|
+
isClientInitiated: true,
|
|
861
|
+
prompt_id: 'prompt-stream',
|
|
862
|
+
};
|
|
863
|
+
const schedulePromise = scheduler.schedule([request], abortController.signal);
|
|
864
|
+
// Wait until executing
|
|
865
|
+
await vi.waitFor(() => {
|
|
866
|
+
const calls = onToolCallsUpdate.mock.calls;
|
|
867
|
+
const last = calls[calls.length - 1]?.[0][0];
|
|
868
|
+
expect(last?.status).toBe('executing');
|
|
869
|
+
});
|
|
870
|
+
// Now abort
|
|
871
|
+
abortController.abort();
|
|
872
|
+
await schedulePromise;
|
|
873
|
+
await vi.waitFor(() => {
|
|
874
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
875
|
+
});
|
|
876
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
877
|
+
.calls[0][0];
|
|
878
|
+
expect(completedCalls[0].status).toBe('cancelled');
|
|
879
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
880
|
+
const cancelled = completedCalls[0];
|
|
881
|
+
expect(cancelled.response.resultDisplay).toBe('hello');
|
|
882
|
+
});
|
|
883
|
+
});
|
|
884
|
+
describe('CoreToolScheduler request queueing', () => {
|
|
885
|
+
it('should queue a request if another is running', async () => {
|
|
886
|
+
let resolveFirstCall;
|
|
887
|
+
const firstCallPromise = new Promise((resolve) => {
|
|
888
|
+
resolveFirstCall = resolve;
|
|
889
|
+
});
|
|
890
|
+
const mockTool = new MockTool();
|
|
891
|
+
mockTool.executeFn.mockImplementation(() => firstCallPromise);
|
|
892
|
+
const declarativeTool = mockTool;
|
|
893
|
+
const mockToolRegistry = {
|
|
894
|
+
getTool: () => declarativeTool,
|
|
895
|
+
getToolByName: () => declarativeTool,
|
|
896
|
+
getFunctionDeclarations: () => [],
|
|
897
|
+
tools: new Map(),
|
|
898
|
+
discovery: {},
|
|
899
|
+
registerTool: () => { },
|
|
900
|
+
getToolByDisplayName: () => declarativeTool,
|
|
901
|
+
getTools: () => [],
|
|
902
|
+
discoverTools: async () => { },
|
|
903
|
+
getAllTools: () => [],
|
|
904
|
+
getToolsByServer: () => [],
|
|
905
|
+
};
|
|
906
|
+
const onAllToolCallsComplete = vi.fn();
|
|
907
|
+
const onToolCallsUpdate = vi.fn();
|
|
908
|
+
const mockConfig = {
|
|
909
|
+
getSessionId: () => 'test-session-id',
|
|
910
|
+
getUsageStatisticsEnabled: () => true,
|
|
911
|
+
getDebugMode: () => false,
|
|
912
|
+
getApprovalMode: () => ApprovalMode.YOLO, // Use YOLO to avoid confirmation prompts
|
|
913
|
+
getAllowedTools: () => [],
|
|
914
|
+
getContentGeneratorConfig: () => ({
|
|
915
|
+
model: 'test-model',
|
|
916
|
+
authType: 'oauth-personal',
|
|
917
|
+
}),
|
|
918
|
+
getToolRegistry: () => mockToolRegistry,
|
|
919
|
+
};
|
|
920
|
+
const scheduler = new CoreToolScheduler({
|
|
921
|
+
config: mockConfig,
|
|
922
|
+
onAllToolCallsComplete,
|
|
923
|
+
onToolCallsUpdate,
|
|
924
|
+
getPreferredEditor: () => 'vscode',
|
|
925
|
+
onEditorClose: vi.fn(),
|
|
926
|
+
});
|
|
927
|
+
const abortController = new AbortController();
|
|
928
|
+
const request1 = {
|
|
929
|
+
callId: '1',
|
|
930
|
+
name: 'mockTool',
|
|
931
|
+
args: { a: 1 },
|
|
932
|
+
isClientInitiated: false,
|
|
933
|
+
prompt_id: 'prompt-1',
|
|
934
|
+
};
|
|
935
|
+
const request2 = {
|
|
936
|
+
callId: '2',
|
|
937
|
+
name: 'mockTool',
|
|
938
|
+
args: { b: 2 },
|
|
939
|
+
isClientInitiated: false,
|
|
940
|
+
prompt_id: 'prompt-2',
|
|
941
|
+
};
|
|
942
|
+
// Schedule the first call, which will pause execution.
|
|
943
|
+
scheduler.schedule([request1], abortController.signal);
|
|
944
|
+
// Wait for the first call to be in the 'executing' state.
|
|
945
|
+
await waitForStatus(onToolCallsUpdate, 'executing');
|
|
946
|
+
// Schedule the second call while the first is "running".
|
|
947
|
+
const schedulePromise2 = scheduler.schedule([request2], abortController.signal);
|
|
948
|
+
// Ensure the second tool call hasn't been executed yet.
|
|
949
|
+
expect(mockTool.executeFn).toHaveBeenCalledTimes(1);
|
|
950
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({ a: 1 });
|
|
951
|
+
// Complete the first tool call.
|
|
952
|
+
resolveFirstCall({
|
|
953
|
+
llmContent: 'First call complete',
|
|
954
|
+
returnDisplay: 'First call complete',
|
|
955
|
+
});
|
|
956
|
+
// Wait for the second schedule promise to resolve.
|
|
957
|
+
await schedulePromise2;
|
|
958
|
+
// Let the second call finish.
|
|
959
|
+
const secondCallResult = {
|
|
960
|
+
llmContent: 'Second call complete',
|
|
961
|
+
returnDisplay: 'Second call complete',
|
|
962
|
+
};
|
|
963
|
+
// Since the mock is shared, we need to resolve the current promise.
|
|
964
|
+
// In a real scenario, a new promise would be created for the second call.
|
|
965
|
+
resolveFirstCall(secondCallResult);
|
|
966
|
+
await vi.waitFor(() => {
|
|
967
|
+
// Now the second tool call should have been executed.
|
|
968
|
+
expect(mockTool.executeFn).toHaveBeenCalledTimes(2);
|
|
969
|
+
});
|
|
970
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({ b: 2 });
|
|
971
|
+
// Wait for the second completion.
|
|
972
|
+
await vi.waitFor(() => {
|
|
973
|
+
expect(onAllToolCallsComplete).toHaveBeenCalledTimes(2);
|
|
974
|
+
});
|
|
975
|
+
// Verify the completion callbacks were called correctly.
|
|
976
|
+
expect(onAllToolCallsComplete.mock.calls[0][0][0].status).toBe('success');
|
|
977
|
+
expect(onAllToolCallsComplete.mock.calls[1][0][0].status).toBe('success');
|
|
978
|
+
});
|
|
979
|
+
it('should auto-approve a tool call if it is on the allowedTools list', async () => {
|
|
980
|
+
// Arrange
|
|
981
|
+
const mockTool = new MockTool('mockTool');
|
|
982
|
+
mockTool.executeFn.mockReturnValue({
|
|
983
|
+
llmContent: 'Tool executed',
|
|
984
|
+
returnDisplay: 'Tool executed',
|
|
985
|
+
});
|
|
986
|
+
// This tool would normally require confirmation.
|
|
987
|
+
mockTool.shouldConfirm = true;
|
|
988
|
+
const declarativeTool = mockTool;
|
|
989
|
+
const toolRegistry = {
|
|
990
|
+
getTool: () => declarativeTool,
|
|
991
|
+
getToolByName: () => declarativeTool,
|
|
992
|
+
getFunctionDeclarations: () => [],
|
|
993
|
+
tools: new Map(),
|
|
994
|
+
discovery: {},
|
|
995
|
+
registerTool: () => { },
|
|
996
|
+
getToolByDisplayName: () => declarativeTool,
|
|
997
|
+
getTools: () => [],
|
|
998
|
+
discoverTools: async () => { },
|
|
999
|
+
getAllTools: () => [],
|
|
1000
|
+
getToolsByServer: () => [],
|
|
1001
|
+
};
|
|
1002
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1003
|
+
const onToolCallsUpdate = vi.fn();
|
|
1004
|
+
// Configure the scheduler to auto-approve the specific tool call.
|
|
1005
|
+
const mockConfig = {
|
|
1006
|
+
getSessionId: () => 'test-session-id',
|
|
1007
|
+
getUsageStatisticsEnabled: () => true,
|
|
1008
|
+
getDebugMode: () => false,
|
|
1009
|
+
getApprovalMode: () => ApprovalMode.DEFAULT, // Not YOLO mode
|
|
1010
|
+
getAllowedTools: () => ['mockTool'], // Auto-approve this tool
|
|
1011
|
+
getToolRegistry: () => toolRegistry,
|
|
1012
|
+
getContentGeneratorConfig: () => ({
|
|
1013
|
+
model: 'test-model',
|
|
1014
|
+
authType: 'oauth-personal',
|
|
1015
|
+
}),
|
|
1016
|
+
};
|
|
1017
|
+
const scheduler = new CoreToolScheduler({
|
|
1018
|
+
config: mockConfig,
|
|
1019
|
+
onAllToolCallsComplete,
|
|
1020
|
+
onToolCallsUpdate,
|
|
1021
|
+
getPreferredEditor: () => 'vscode',
|
|
1022
|
+
onEditorClose: vi.fn(),
|
|
1023
|
+
});
|
|
1024
|
+
const abortController = new AbortController();
|
|
1025
|
+
const request = {
|
|
1026
|
+
callId: '1',
|
|
1027
|
+
name: 'mockTool',
|
|
1028
|
+
args: { param: 'value' },
|
|
1029
|
+
isClientInitiated: false,
|
|
1030
|
+
prompt_id: 'prompt-auto-approved',
|
|
1031
|
+
};
|
|
1032
|
+
// Act
|
|
1033
|
+
await scheduler.schedule([request], abortController.signal);
|
|
1034
|
+
// Assert
|
|
1035
|
+
// 1. The tool's execute method was called directly.
|
|
1036
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({ param: 'value' });
|
|
1037
|
+
// 2. The tool call status never entered 'awaiting_approval'.
|
|
1038
|
+
const statusUpdates = onToolCallsUpdate.mock.calls
|
|
1039
|
+
.map((call) => call[0][0]?.status)
|
|
1040
|
+
.filter(Boolean);
|
|
1041
|
+
expect(statusUpdates).not.toContain('awaiting_approval');
|
|
1042
|
+
expect(statusUpdates).toEqual([
|
|
1043
|
+
'validating',
|
|
1044
|
+
'scheduled',
|
|
1045
|
+
'executing',
|
|
1046
|
+
'success',
|
|
1047
|
+
]);
|
|
1048
|
+
// 3. The final callback indicates the tool call was successful.
|
|
1049
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
1050
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
1051
|
+
.calls[0][0];
|
|
1052
|
+
expect(completedCalls).toHaveLength(1);
|
|
1053
|
+
const completedCall = completedCalls[0];
|
|
1054
|
+
expect(completedCall.status).toBe('success');
|
|
1055
|
+
if (completedCall.status === 'success') {
|
|
1056
|
+
expect(completedCall.response.resultDisplay).toBe('Tool executed');
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
it('should handle two synchronous calls to schedule', async () => {
|
|
1060
|
+
const mockTool = new MockTool();
|
|
1061
|
+
const declarativeTool = mockTool;
|
|
1062
|
+
const mockToolRegistry = {
|
|
1063
|
+
getTool: () => declarativeTool,
|
|
1064
|
+
getToolByName: () => declarativeTool,
|
|
1065
|
+
getFunctionDeclarations: () => [],
|
|
1066
|
+
tools: new Map(),
|
|
1067
|
+
discovery: {},
|
|
1068
|
+
registerTool: () => { },
|
|
1069
|
+
getToolByDisplayName: () => declarativeTool,
|
|
1070
|
+
getTools: () => [],
|
|
1071
|
+
discoverTools: async () => { },
|
|
1072
|
+
getAllTools: () => [],
|
|
1073
|
+
getToolsByServer: () => [],
|
|
1074
|
+
};
|
|
1075
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1076
|
+
const onToolCallsUpdate = vi.fn();
|
|
1077
|
+
const mockConfig = {
|
|
1078
|
+
getSessionId: () => 'test-session-id',
|
|
1079
|
+
getUsageStatisticsEnabled: () => true,
|
|
1080
|
+
getDebugMode: () => false,
|
|
1081
|
+
getApprovalMode: () => ApprovalMode.YOLO,
|
|
1082
|
+
getAllowedTools: () => [],
|
|
1083
|
+
getContentGeneratorConfig: () => ({
|
|
1084
|
+
model: 'test-model',
|
|
1085
|
+
authType: 'oauth-personal',
|
|
1086
|
+
}),
|
|
1087
|
+
getToolRegistry: () => mockToolRegistry,
|
|
1088
|
+
};
|
|
1089
|
+
const scheduler = new CoreToolScheduler({
|
|
1090
|
+
config: mockConfig,
|
|
1091
|
+
onAllToolCallsComplete,
|
|
1092
|
+
onToolCallsUpdate,
|
|
1093
|
+
getPreferredEditor: () => 'vscode',
|
|
1094
|
+
onEditorClose: vi.fn(),
|
|
1095
|
+
});
|
|
1096
|
+
const abortController = new AbortController();
|
|
1097
|
+
const request1 = {
|
|
1098
|
+
callId: '1',
|
|
1099
|
+
name: 'mockTool',
|
|
1100
|
+
args: { a: 1 },
|
|
1101
|
+
isClientInitiated: false,
|
|
1102
|
+
prompt_id: 'prompt-1',
|
|
1103
|
+
};
|
|
1104
|
+
const request2 = {
|
|
1105
|
+
callId: '2',
|
|
1106
|
+
name: 'mockTool',
|
|
1107
|
+
args: { b: 2 },
|
|
1108
|
+
isClientInitiated: false,
|
|
1109
|
+
prompt_id: 'prompt-2',
|
|
1110
|
+
};
|
|
1111
|
+
// Schedule two calls synchronously.
|
|
1112
|
+
const schedulePromise1 = scheduler.schedule([request1], abortController.signal);
|
|
1113
|
+
const schedulePromise2 = scheduler.schedule([request2], abortController.signal);
|
|
1114
|
+
// Wait for both promises to resolve.
|
|
1115
|
+
await Promise.all([schedulePromise1, schedulePromise2]);
|
|
1116
|
+
// Ensure the tool was called twice with the correct arguments.
|
|
1117
|
+
expect(mockTool.executeFn).toHaveBeenCalledTimes(2);
|
|
1118
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({ a: 1 });
|
|
1119
|
+
expect(mockTool.executeFn).toHaveBeenCalledWith({ b: 2 });
|
|
1120
|
+
// Ensure completion callbacks were called twice.
|
|
1121
|
+
expect(onAllToolCallsComplete).toHaveBeenCalledTimes(2);
|
|
1122
|
+
});
|
|
1123
|
+
it('should auto-approve remaining tool calls when first tool call is approved with ProceedAlways', async () => {
|
|
1124
|
+
let approvalMode = ApprovalMode.DEFAULT;
|
|
1125
|
+
const mockConfig = {
|
|
1126
|
+
getSessionId: () => 'test-session-id',
|
|
1127
|
+
getUsageStatisticsEnabled: () => true,
|
|
1128
|
+
getDebugMode: () => false,
|
|
1129
|
+
getApprovalMode: () => approvalMode,
|
|
1130
|
+
getAllowedTools: () => [],
|
|
1131
|
+
setApprovalMode: (mode) => {
|
|
1132
|
+
approvalMode = mode;
|
|
1133
|
+
},
|
|
1134
|
+
};
|
|
1135
|
+
const testTool = new TestApprovalTool(mockConfig);
|
|
1136
|
+
const toolRegistry = {
|
|
1137
|
+
getTool: () => testTool,
|
|
1138
|
+
getFunctionDeclarations: () => [],
|
|
1139
|
+
getFunctionDeclarationsFiltered: () => [],
|
|
1140
|
+
registerTool: () => { },
|
|
1141
|
+
discoverAllTools: async () => { },
|
|
1142
|
+
discoverMcpTools: async () => { },
|
|
1143
|
+
discoverToolsForServer: async () => { },
|
|
1144
|
+
removeMcpToolsByServer: () => { },
|
|
1145
|
+
getAllTools: () => [],
|
|
1146
|
+
getToolsByServer: () => [],
|
|
1147
|
+
tools: new Map(),
|
|
1148
|
+
config: mockConfig,
|
|
1149
|
+
mcpClientManager: undefined,
|
|
1150
|
+
getToolByName: () => testTool,
|
|
1151
|
+
getToolByDisplayName: () => testTool,
|
|
1152
|
+
getTools: () => [],
|
|
1153
|
+
discoverTools: async () => { },
|
|
1154
|
+
discovery: {},
|
|
1155
|
+
};
|
|
1156
|
+
mockConfig.getToolRegistry = () => toolRegistry;
|
|
1157
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1158
|
+
const onToolCallsUpdate = vi.fn();
|
|
1159
|
+
const pendingConfirmations = [];
|
|
1160
|
+
const scheduler = new CoreToolScheduler({
|
|
1161
|
+
config: mockConfig,
|
|
1162
|
+
onAllToolCallsComplete,
|
|
1163
|
+
onToolCallsUpdate: (toolCalls) => {
|
|
1164
|
+
onToolCallsUpdate(toolCalls);
|
|
1165
|
+
// Capture confirmation handlers for awaiting_approval tools
|
|
1166
|
+
toolCalls.forEach((call) => {
|
|
1167
|
+
if (call.status === 'awaiting_approval') {
|
|
1168
|
+
const waitingCall = call;
|
|
1169
|
+
if (waitingCall.confirmationDetails?.onConfirm) {
|
|
1170
|
+
const originalHandler = pendingConfirmations.find((h) => h === waitingCall.confirmationDetails.onConfirm);
|
|
1171
|
+
if (!originalHandler) {
|
|
1172
|
+
pendingConfirmations.push(waitingCall.confirmationDetails.onConfirm);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
},
|
|
1178
|
+
getPreferredEditor: () => 'vscode',
|
|
1179
|
+
onEditorClose: vi.fn(),
|
|
1180
|
+
});
|
|
1181
|
+
const abortController = new AbortController();
|
|
1182
|
+
// Schedule multiple tools that need confirmation
|
|
1183
|
+
const requests = [
|
|
1184
|
+
{
|
|
1185
|
+
callId: '1',
|
|
1186
|
+
name: 'testApprovalTool',
|
|
1187
|
+
args: { id: 'first' },
|
|
1188
|
+
isClientInitiated: false,
|
|
1189
|
+
prompt_id: 'prompt-1',
|
|
1190
|
+
},
|
|
1191
|
+
{
|
|
1192
|
+
callId: '2',
|
|
1193
|
+
name: 'testApprovalTool',
|
|
1194
|
+
args: { id: 'second' },
|
|
1195
|
+
isClientInitiated: false,
|
|
1196
|
+
prompt_id: 'prompt-2',
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
callId: '3',
|
|
1200
|
+
name: 'testApprovalTool',
|
|
1201
|
+
args: { id: 'third' },
|
|
1202
|
+
isClientInitiated: false,
|
|
1203
|
+
prompt_id: 'prompt-3',
|
|
1204
|
+
},
|
|
1205
|
+
];
|
|
1206
|
+
await scheduler.schedule(requests, abortController.signal);
|
|
1207
|
+
// Wait for all tools to be awaiting approval
|
|
1208
|
+
await vi.waitFor(() => {
|
|
1209
|
+
const calls = onToolCallsUpdate.mock.calls.at(-1)?.[0];
|
|
1210
|
+
expect(calls?.length).toBe(3);
|
|
1211
|
+
expect(calls?.every((call) => call.status === 'awaiting_approval')).toBe(true);
|
|
1212
|
+
});
|
|
1213
|
+
expect(pendingConfirmations.length).toBe(3);
|
|
1214
|
+
// Approve the first tool with ProceedAlways
|
|
1215
|
+
const firstConfirmation = pendingConfirmations[0];
|
|
1216
|
+
firstConfirmation(ToolConfirmationOutcome.ProceedAlways);
|
|
1217
|
+
// Wait for all tools to be completed
|
|
1218
|
+
await vi.waitFor(() => {
|
|
1219
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
1220
|
+
const completedCalls = onAllToolCallsComplete.mock.calls.at(-1)?.[0];
|
|
1221
|
+
expect(completedCalls?.length).toBe(3);
|
|
1222
|
+
expect(completedCalls?.every((call) => call.status === 'success')).toBe(true);
|
|
1223
|
+
});
|
|
1224
|
+
// Verify approval mode was changed
|
|
1225
|
+
expect(approvalMode).toBe(ApprovalMode.AUTO_EDIT);
|
|
1226
|
+
});
|
|
1227
|
+
});
|
|
1228
|
+
//# sourceMappingURL=coreToolScheduler.test.js.map
|