@office-ai/aioncli-core 0.2.3 → 0.18.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/dist/index.d.ts +16 -3
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/src/agents/codebase-investigator.d.ts +46 -0
- package/dist/src/agents/codebase-investigator.js +132 -0
- package/dist/src/agents/codebase-investigator.js.map +1 -0
- package/dist/src/agents/codebase-investigator.test.js +35 -0
- package/dist/src/agents/codebase-investigator.test.js.map +1 -0
- package/dist/src/agents/executor.d.ts +114 -0
- package/dist/src/agents/executor.js +779 -0
- package/dist/src/agents/executor.js.map +1 -0
- package/dist/src/agents/executor.test.js +1362 -0
- package/dist/src/agents/executor.test.js.map +1 -0
- package/dist/src/agents/invocation.d.ts +46 -0
- package/dist/src/agents/invocation.js +102 -0
- package/dist/src/agents/invocation.js.map +1 -0
- package/dist/src/agents/invocation.test.js +215 -0
- package/dist/src/agents/invocation.test.js.map +1 -0
- package/dist/src/agents/registry.d.ts +40 -0
- package/dist/src/agents/registry.js +105 -0
- package/dist/src/agents/registry.js.map +1 -0
- package/dist/src/agents/registry.test.d.ts +6 -0
- package/dist/src/agents/registry.test.js +160 -0
- package/dist/src/agents/registry.test.js.map +1 -0
- package/dist/src/agents/schema-utils.d.ts +39 -0
- package/dist/src/agents/schema-utils.js +57 -0
- package/dist/src/agents/schema-utils.js.map +1 -0
- package/dist/src/agents/schema-utils.test.d.ts +6 -0
- package/dist/src/agents/schema-utils.test.js +144 -0
- package/dist/src/agents/schema-utils.test.js.map +1 -0
- package/dist/src/agents/subagent-tool-wrapper.d.ts +38 -0
- package/dist/src/agents/subagent-tool-wrapper.js +48 -0
- package/dist/src/agents/subagent-tool-wrapper.js.map +1 -0
- package/dist/src/agents/subagent-tool-wrapper.test.d.ts +6 -0
- package/dist/src/agents/subagent-tool-wrapper.test.js +110 -0
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -0
- package/dist/src/agents/types.d.ts +146 -0
- package/dist/src/agents/types.js +19 -0
- package/dist/src/agents/types.js.map +1 -0
- package/dist/src/agents/utils.d.ts +15 -0
- package/dist/src/agents/utils.js +29 -0
- package/dist/src/agents/utils.js.map +1 -0
- package/dist/src/agents/utils.test.d.ts +6 -0
- package/dist/src/agents/utils.test.js +87 -0
- package/dist/src/agents/utils.test.js.map +1 -0
- package/dist/src/code_assist/codeAssist.d.ts +6 -3
- package/dist/src/code_assist/codeAssist.js +13 -1
- package/dist/src/code_assist/codeAssist.js.map +1 -1
- package/dist/src/code_assist/codeAssist.test.d.ts +6 -0
- package/dist/src/code_assist/codeAssist.test.js +99 -0
- package/dist/src/code_assist/codeAssist.test.js.map +1 -0
- package/dist/src/code_assist/converter.d.ts +5 -1
- package/dist/src/code_assist/converter.js +39 -5
- package/dist/src/code_assist/converter.js.map +1 -1
- package/dist/src/code_assist/converter.test.js +112 -0
- package/dist/src/code_assist/converter.test.js.map +1 -1
- package/dist/src/code_assist/experiments/client_metadata.d.ts +12 -0
- package/dist/src/code_assist/experiments/client_metadata.js +50 -0
- package/dist/src/code_assist/experiments/client_metadata.js.map +1 -0
- package/dist/src/code_assist/experiments/client_metadata.test.d.ts +6 -0
- package/dist/src/code_assist/experiments/client_metadata.test.js +99 -0
- package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -0
- package/dist/src/code_assist/experiments/experiments.d.ts +17 -0
- package/dist/src/code_assist/experiments/experiments.js +36 -0
- package/dist/src/code_assist/experiments/experiments.js.map +1 -0
- package/dist/src/code_assist/experiments/experiments.test.d.ts +6 -0
- package/dist/src/code_assist/experiments/experiments.test.js +92 -0
- package/dist/src/code_assist/experiments/experiments.test.js.map +1 -0
- package/dist/src/code_assist/experiments/flagNames.d.ts +13 -0
- package/dist/src/code_assist/experiments/flagNames.js +13 -0
- package/dist/src/code_assist/experiments/flagNames.js.map +1 -0
- package/dist/src/code_assist/experiments/types.d.ts +35 -0
- package/dist/src/code_assist/experiments/types.js +7 -0
- package/dist/src/code_assist/experiments/types.js.map +1 -0
- package/dist/src/code_assist/oauth-credential-storage.d.ts +25 -0
- package/dist/src/code_assist/oauth-credential-storage.js +110 -0
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -0
- package/dist/src/code_assist/oauth-credential-storage.test.d.ts +6 -0
- package/dist/src/code_assist/oauth-credential-storage.test.js +198 -0
- package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -0
- package/dist/src/code_assist/oauth2.d.ts +3 -3
- package/dist/src/code_assist/oauth2.js +252 -125
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +788 -350
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +8 -6
- package/dist/src/code_assist/server.js +41 -10
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +151 -28
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/code_assist/setup.d.ts +2 -2
- package/dist/src/code_assist/setup.js +5 -3
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +18 -3
- package/dist/src/code_assist/types.js.map +1 -1
- package/dist/src/commands/extensions.d.ts +7 -0
- package/dist/src/commands/extensions.js +9 -0
- package/dist/src/commands/extensions.js.map +1 -0
- package/dist/src/commands/extensions.test.d.ts +6 -0
- package/dist/src/commands/extensions.test.js +19 -0
- package/dist/src/commands/extensions.test.js.map +1 -0
- package/dist/src/config/config.d.ts +282 -60
- package/dist/src/config/config.js +677 -129
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +1020 -146
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/constants.d.ts +11 -0
- package/dist/src/config/constants.js +16 -0
- package/dist/src/config/constants.js.map +1 -0
- package/dist/src/config/defaultModelConfigs.d.ts +7 -0
- package/dist/src/config/defaultModelConfigs.js +185 -0
- package/dist/src/config/defaultModelConfigs.js.map +1 -0
- package/dist/src/config/models.d.ts +37 -0
- package/dist/src/config/models.js +72 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.d.ts +6 -0
- package/dist/src/config/models.test.js +116 -0
- package/dist/src/config/models.test.js.map +1 -0
- package/dist/src/config/storage.d.ts +36 -0
- package/dist/src/config/storage.js +115 -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 +48 -0
- package/dist/src/config/storage.test.js.map +1 -0
- package/dist/src/confirmation-bus/index.d.ts +7 -0
- package/dist/src/confirmation-bus/index.js +8 -0
- package/dist/src/confirmation-bus/index.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.d.ts +18 -0
- package/dist/src/confirmation-bus/message-bus.js +87 -0
- package/dist/src/confirmation-bus/message-bus.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.test.d.ts +6 -0
- package/dist/src/confirmation-bus/message-bus.test.js +170 -0
- package/dist/src/confirmation-bus/message-bus.test.js.map +1 -0
- package/dist/src/confirmation-bus/types.d.ts +49 -0
- package/dist/src/confirmation-bus/types.js +16 -0
- package/dist/src/confirmation-bus/types.js.map +1 -0
- package/dist/src/core/apiKeyCredentialStorage.d.ts +17 -0
- package/dist/src/core/apiKeyCredentialStorage.js +64 -0
- package/dist/src/core/apiKeyCredentialStorage.js.map +1 -0
- package/dist/src/core/apiKeyCredentialStorage.test.d.ts +6 -0
- package/dist/src/core/apiKeyCredentialStorage.test.js +71 -0
- package/dist/src/core/apiKeyCredentialStorage.test.js.map +1 -0
- package/dist/src/core/baseLlmClient.d.ts +50 -0
- package/dist/src/core/baseLlmClient.js +185 -0
- package/dist/src/core/baseLlmClient.js.map +1 -0
- package/dist/src/core/baseLlmClient.test.d.ts +6 -0
- package/dist/src/core/baseLlmClient.test.js +311 -0
- package/dist/src/core/baseLlmClient.test.js.map +1 -0
- package/dist/src/core/client.d.ts +30 -42
- package/dist/src/core/client.js +178 -477
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +739 -617
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +7 -6
- package/dist/src/core/contentGenerator.js +59 -45
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +50 -4
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +28 -11
- package/dist/src/core/coreToolScheduler.js +493 -161
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +995 -163
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/fakeContentGenerator.d.ts +33 -0
- package/dist/src/core/fakeContentGenerator.js +58 -0
- package/dist/src/core/fakeContentGenerator.js.map +1 -0
- package/dist/src/core/fakeContentGenerator.test.d.ts +6 -0
- package/dist/src/core/fakeContentGenerator.test.js +127 -0
- package/dist/src/core/fakeContentGenerator.test.js.map +1 -0
- package/dist/src/core/geminiChat.d.ts +61 -55
- package/dist/src/core/geminiChat.js +388 -366
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +1600 -355
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiRequest.js +1 -0
- package/dist/src/core/geminiRequest.js.map +1 -1
- package/dist/src/core/logger.d.ts +11 -4
- package/dist/src/core/logger.js +39 -30
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/logger.test.js +62 -45
- package/dist/src/core/logger.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +4 -3
- package/dist/src/core/loggingContentGenerator.js +116 -37
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.d.ts +6 -0
- package/dist/src/core/loggingContentGenerator.test.js +180 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.d.ts +4 -5
- package/dist/src/core/nonInteractiveToolExecutor.js +17 -120
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +168 -84
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/openaiContentGenerator.d.ts +4 -3
- package/dist/src/core/openaiContentGenerator.js +49 -19
- package/dist/src/core/openaiContentGenerator.js.map +1 -1
- package/dist/src/core/openaiContentGenerator.test.js +1 -0
- package/dist/src/core/openaiContentGenerator.test.js.map +1 -1
- package/dist/src/core/prompts.d.ts +7 -1
- package/dist/src/core/prompts.js +198 -195
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +172 -104
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/recordingContentGenerator.d.ts +18 -0
- package/dist/src/core/recordingContentGenerator.js +77 -0
- package/dist/src/core/recordingContentGenerator.js.map +1 -0
- package/dist/src/core/recordingContentGenerator.test.d.ts +6 -0
- package/dist/src/core/recordingContentGenerator.test.js +101 -0
- package/dist/src/core/recordingContentGenerator.test.js.map +1 -0
- package/dist/src/core/subagent.d.ts +24 -18
- package/dist/src/core/subagent.js +125 -90
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/core/subagent.test.js +59 -44
- package/dist/src/core/subagent.test.js.map +1 -1
- package/dist/src/core/tokenLimits.test.d.ts +6 -0
- package/dist/src/core/tokenLimits.test.js +26 -0
- package/dist/src/core/tokenLimits.test.js.map +1 -0
- package/dist/src/core/turn.d.ts +57 -13
- package/dist/src/core/turn.js +79 -35
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +373 -120
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/fallback/handler.d.ts +7 -0
- package/dist/src/fallback/handler.js +181 -0
- package/dist/src/fallback/handler.js.map +1 -0
- package/dist/src/fallback/handler.test.d.ts +6 -0
- package/dist/src/fallback/handler.test.js +245 -0
- package/dist/src/fallback/handler.test.js.map +1 -0
- package/dist/src/fallback/types.d.ts +14 -0
- package/dist/src/fallback/types.js +7 -0
- package/dist/src/fallback/types.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/hooks/hookAggregator.d.ts +68 -0
- package/dist/src/hooks/hookAggregator.js +262 -0
- package/dist/src/hooks/hookAggregator.js.map +1 -0
- package/dist/src/hooks/hookAggregator.test.d.ts +6 -0
- package/dist/src/hooks/hookAggregator.test.js +387 -0
- package/dist/src/hooks/hookAggregator.test.js.map +1 -0
- package/dist/src/hooks/hookPlanner.d.ts +46 -0
- package/dist/src/hooks/hookPlanner.js +108 -0
- package/dist/src/hooks/hookPlanner.js.map +1 -0
- package/dist/src/hooks/hookPlanner.test.d.ts +6 -0
- package/dist/src/hooks/hookPlanner.test.js +255 -0
- package/dist/src/hooks/hookPlanner.test.js.map +1 -0
- package/dist/src/hooks/hookRegistry.d.ts +87 -0
- package/dist/src/hooks/hookRegistry.js +198 -0
- package/dist/src/hooks/hookRegistry.js.map +1 -0
- package/dist/src/hooks/hookRegistry.test.d.ts +6 -0
- package/dist/src/hooks/hookRegistry.test.js +341 -0
- package/dist/src/hooks/hookRegistry.test.js.map +1 -0
- package/dist/src/hooks/hookRunner.d.ts +42 -0
- package/dist/src/hooks/hookRunner.js +272 -0
- package/dist/src/hooks/hookRunner.js.map +1 -0
- package/dist/src/hooks/hookRunner.test.d.ts +6 -0
- package/dist/src/hooks/hookRunner.test.js +468 -0
- package/dist/src/hooks/hookRunner.test.js.map +1 -0
- package/dist/src/hooks/hookTranslator.d.ts +113 -0
- package/dist/src/hooks/hookTranslator.js +232 -0
- package/dist/src/hooks/hookTranslator.js.map +1 -0
- package/dist/src/hooks/hookTranslator.test.d.ts +6 -0
- package/dist/src/hooks/hookTranslator.test.js +192 -0
- package/dist/src/hooks/hookTranslator.test.js.map +1 -0
- package/dist/src/hooks/types.d.ts +384 -0
- package/dist/src/hooks/types.js +284 -0
- package/dist/src/hooks/types.js.map +1 -0
- package/dist/src/hooks/types.test.d.ts +6 -0
- package/dist/src/hooks/types.test.js +313 -0
- package/dist/src/hooks/types.test.js.map +1 -0
- package/dist/src/ide/constants.d.ts +3 -0
- package/dist/src/ide/constants.js +3 -0
- package/dist/src/ide/constants.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +52 -12
- package/dist/src/ide/detect-ide.js +51 -65
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +95 -52
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +72 -24
- package/dist/src/ide/ide-client.js +380 -84
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.js +539 -35
- package/dist/src/ide/ide-client.test.js.map +1 -1
- package/dist/src/ide/ide-installer.d.ts +2 -2
- package/dist/src/ide/ide-installer.js +93 -35
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +157 -26
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +35 -365
- package/dist/src/ide/ideContext.js +60 -106
- package/dist/src/ide/ideContext.js.map +1 -1
- package/dist/src/ide/ideContext.test.js +152 -24
- package/dist/src/ide/ideContext.test.js.map +1 -1
- package/dist/src/ide/process-utils.d.ts +7 -5
- package/dist/src/ide/process-utils.js +108 -67
- package/dist/src/ide/process-utils.js.map +1 -1
- package/dist/src/ide/process-utils.test.d.ts +6 -0
- package/dist/src/ide/process-utils.test.js +151 -0
- package/dist/src/ide/process-utils.test.js.map +1 -0
- package/dist/src/ide/types.d.ts +486 -0
- package/dist/src/ide/types.js +138 -0
- package/dist/src/ide/types.js.map +1 -0
- package/dist/src/index.d.ts +41 -2
- package/dist/src/index.js +44 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.d.ts +5 -3
- package/dist/src/mcp/google-auth-provider.js +21 -3
- package/dist/src/mcp/google-auth-provider.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.test.js +42 -9
- package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-provider.d.ts +25 -18
- package/dist/src/mcp/oauth-provider.js +194 -97
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +581 -39
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.d.ts +14 -32
- package/dist/src/mcp/oauth-token-storage.js +58 -28
- package/dist/src/mcp/oauth-token-storage.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.test.js +262 -162
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
- package/dist/src/mcp/oauth-utils.d.ts +16 -1
- package/dist/src/mcp/oauth-utils.js +68 -33
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/oauth-utils.test.js +86 -3
- package/dist/src/mcp/oauth-utils.test.js.map +1 -1
- package/dist/src/mcp/sa-impersonation-provider.d.ts +27 -0
- package/dist/src/mcp/sa-impersonation-provider.js +113 -0
- package/dist/src/mcp/sa-impersonation-provider.js.map +1 -0
- package/dist/src/mcp/sa-impersonation-provider.test.d.ts +6 -0
- package/dist/src/mcp/sa-impersonation-provider.test.js +117 -0
- package/dist/src/mcp/sa-impersonation-provider.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 +151 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
- package/dist/src/mcp/token-storage/file-token-storage.js +145 -0
- package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/file-token-storage.test.js +238 -0
- package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.d.ts +23 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.js +78 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +193 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/index.d.ts +11 -0
- package/dist/src/mcp/token-storage/index.js +12 -0
- package/dist/src/mcp/token-storage/index.js.map +1 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +35 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.js +246 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js +305 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/types.d.ts +44 -0
- package/dist/src/mcp/token-storage/types.js +11 -0
- package/dist/src/mcp/token-storage/types.js.map +1 -0
- package/dist/src/output/json-formatter.d.ts +11 -0
- package/dist/src/output/json-formatter.js +30 -0
- package/dist/src/output/json-formatter.js.map +1 -0
- package/dist/src/output/json-formatter.test.d.ts +6 -0
- package/dist/src/output/json-formatter.test.js +266 -0
- package/dist/src/output/json-formatter.test.js.map +1 -0
- package/dist/src/output/stream-json-formatter.d.ts +32 -0
- package/dist/src/output/stream-json-formatter.js +52 -0
- package/dist/src/output/stream-json-formatter.js.map +1 -0
- package/dist/src/output/stream-json-formatter.test.d.ts +6 -0
- package/dist/src/output/stream-json-formatter.test.js +479 -0
- package/dist/src/output/stream-json-formatter.test.js.map +1 -0
- package/dist/src/output/types.d.ts +82 -0
- package/dist/src/output/types.js +22 -0
- package/dist/src/output/types.js.map +1 -0
- package/dist/src/policy/config.d.ts +31 -0
- package/dist/src/policy/config.js +199 -0
- package/dist/src/policy/config.js.map +1 -0
- package/dist/src/policy/config.test.d.ts +6 -0
- package/dist/src/policy/config.test.js +538 -0
- package/dist/src/policy/config.test.js.map +1 -0
- package/dist/src/policy/index.d.ts +9 -0
- package/dist/src/policy/index.js +10 -0
- package/dist/src/policy/index.js.map +1 -0
- package/dist/src/policy/policies/discovered.toml +8 -0
- package/dist/src/policy/policies/read-only.toml +56 -0
- package/dist/src/policy/policies/write.toml +73 -0
- package/dist/src/policy/policies/yolo.toml +31 -0
- package/dist/src/policy/policy-engine.d.ts +39 -0
- package/dist/src/policy/policy-engine.js +158 -0
- package/dist/src/policy/policy-engine.js.map +1 -0
- package/dist/src/policy/policy-engine.test.d.ts +6 -0
- package/dist/src/policy/policy-engine.test.js +899 -0
- package/dist/src/policy/policy-engine.test.js.map +1 -0
- package/dist/src/policy/stable-stringify.d.ts +58 -0
- package/dist/src/policy/stable-stringify.js +122 -0
- package/dist/src/policy/stable-stringify.js.map +1 -0
- package/dist/src/policy/toml-loader.d.ts +47 -0
- package/dist/src/policy/toml-loader.js +411 -0
- package/dist/src/policy/toml-loader.js.map +1 -0
- package/dist/src/policy/toml-loader.test.d.ts +6 -0
- package/dist/src/policy/toml-loader.test.js +376 -0
- package/dist/src/policy/toml-loader.test.js.map +1 -0
- package/dist/src/policy/types.d.ts +130 -0
- package/dist/src/policy/types.js +22 -0
- package/dist/src/policy/types.js.map +1 -0
- package/dist/src/prompts/mcp-prompts.d.ts +2 -2
- package/dist/src/prompts/mcp-prompts.test.d.ts +6 -0
- package/dist/src/prompts/mcp-prompts.test.js +39 -0
- package/dist/src/prompts/mcp-prompts.test.js.map +1 -0
- package/dist/src/prompts/prompt-registry.d.ts +1 -1
- package/dist/src/prompts/prompt-registry.js +2 -1
- package/dist/src/prompts/prompt-registry.js.map +1 -1
- package/dist/src/prompts/prompt-registry.test.d.ts +6 -0
- package/dist/src/prompts/prompt-registry.test.js +96 -0
- package/dist/src/prompts/prompt-registry.test.js.map +1 -0
- package/dist/src/routing/modelRouterService.d.ts +23 -0
- package/dist/src/routing/modelRouterService.js +85 -0
- package/dist/src/routing/modelRouterService.js.map +1 -0
- package/dist/src/routing/modelRouterService.test.d.ts +6 -0
- package/dist/src/routing/modelRouterService.test.js +160 -0
- package/dist/src/routing/modelRouterService.test.js.map +1 -0
- package/dist/src/routing/routingStrategy.d.ts +62 -0
- package/dist/src/routing/routingStrategy.js +7 -0
- package/dist/src/routing/routingStrategy.js.map +1 -0
- package/dist/src/routing/strategies/classifierStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/classifierStrategy.js +166 -0
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -0
- package/dist/src/routing/strategies/classifierStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js +196 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/compositeStrategy.d.ts +26 -0
- package/dist/src/routing/strategies/compositeStrategy.js +68 -0
- package/dist/src/routing/strategies/compositeStrategy.js.map +1 -0
- package/dist/src/routing/strategies/compositeStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/compositeStrategy.test.js +123 -0
- package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/defaultStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/defaultStrategy.js +20 -0
- package/dist/src/routing/strategies/defaultStrategy.js.map +1 -0
- package/dist/src/routing/strategies/defaultStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/defaultStrategy.test.js +26 -0
- package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/fallbackStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/fallbackStrategy.js +25 -0
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js +59 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/overrideStrategy.d.ts +15 -0
- package/dist/src/routing/strategies/overrideStrategy.js +28 -0
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -0
- package/dist/src/routing/strategies/overrideStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js +45 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -0
- package/dist/src/safety/built-in.d.ts +21 -0
- package/dist/src/safety/built-in.js +106 -0
- package/dist/src/safety/built-in.js.map +1 -0
- package/dist/src/safety/built-in.test.d.ts +6 -0
- package/dist/src/safety/built-in.test.js +199 -0
- package/dist/src/safety/built-in.test.js.map +1 -0
- package/dist/src/safety/checker-runner.d.ts +48 -0
- package/dist/src/safety/checker-runner.js +208 -0
- package/dist/src/safety/checker-runner.js.map +1 -0
- package/dist/src/safety/checker-runner.test.d.ts +6 -0
- package/dist/src/safety/checker-runner.test.js +238 -0
- package/dist/src/safety/checker-runner.test.js.map +1 -0
- package/dist/src/safety/context-builder.d.ts +23 -0
- package/dist/src/safety/context-builder.js +47 -0
- package/dist/src/safety/context-builder.js.map +1 -0
- package/dist/src/safety/context-builder.test.d.ts +6 -0
- package/dist/src/safety/context-builder.test.js +49 -0
- package/dist/src/safety/context-builder.test.js.map +1 -0
- package/dist/src/safety/protocol.d.ts +88 -0
- package/dist/src/safety/protocol.js +15 -0
- package/dist/src/safety/protocol.js.map +1 -0
- package/dist/src/safety/registry.d.ts +26 -0
- package/dist/src/safety/registry.js +65 -0
- package/dist/src/safety/registry.js.map +1 -0
- package/dist/src/safety/registry.test.d.ts +6 -0
- package/dist/src/safety/registry.test.js +31 -0
- package/dist/src/safety/registry.test.js.map +1 -0
- package/dist/src/services/chatCompressionService.d.ts +32 -0
- package/dist/src/services/chatCompressionService.js +162 -0
- package/dist/src/services/chatCompressionService.js.map +1 -0
- package/dist/src/services/chatCompressionService.test.d.ts +6 -0
- package/dist/src/services/chatCompressionService.test.js +210 -0
- package/dist/src/services/chatCompressionService.test.js.map +1 -0
- package/dist/src/services/chatRecordingService.d.ts +10 -15
- package/dist/src/services/chatRecordingService.js +43 -29
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +69 -25
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.d.ts +8 -10
- package/dist/src/services/fileDiscoveryService.js +31 -53
- package/dist/src/services/fileDiscoveryService.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.test.js +94 -14
- package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
- package/dist/src/services/fileSystemService.d.ts +9 -0
- package/dist/src/services/fileSystemService.js +12 -1
- package/dist/src/services/fileSystemService.js.map +1 -1
- package/dist/src/services/fileSystemService.test.js +1 -1
- package/dist/src/services/fileSystemService.test.js.map +1 -1
- package/dist/src/services/gitService.d.ts +3 -1
- package/dist/src/services/gitService.js +30 -24
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +30 -37
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +12 -3
- package/dist/src/services/loopDetectionService.js +148 -55
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +280 -21
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/modelConfig.golden.test.d.ts +6 -0
- package/dist/src/services/modelConfig.golden.test.js +42 -0
- package/dist/src/services/modelConfig.golden.test.js.map +1 -0
- package/dist/src/services/modelConfig.integration.test.d.ts +6 -0
- package/dist/src/services/modelConfig.integration.test.js +247 -0
- package/dist/src/services/modelConfig.integration.test.js.map +1 -0
- package/dist/src/services/modelConfigService.d.ts +48 -0
- package/dist/src/services/modelConfigService.js +151 -0
- package/dist/src/services/modelConfigService.js.map +1 -0
- package/dist/src/services/modelConfigService.test.d.ts +6 -0
- package/dist/src/services/modelConfigService.test.js +531 -0
- package/dist/src/services/modelConfigService.test.js.map +1 -0
- package/dist/src/services/shellExecutionService.d.ts +37 -2
- package/dist/src/services/shellExecutionService.js +361 -67
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +333 -71
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/services/test-data/resolved-aliases.golden.json +202 -0
- package/dist/src/telemetry/activity-detector.d.ts +41 -0
- package/dist/src/telemetry/activity-detector.js +61 -0
- package/dist/src/telemetry/activity-detector.js.map +1 -0
- package/dist/src/telemetry/activity-detector.test.d.ts +6 -0
- package/dist/src/telemetry/activity-detector.test.js +136 -0
- package/dist/src/telemetry/activity-detector.test.js.map +1 -0
- package/dist/src/telemetry/activity-monitor.d.ts +116 -0
- package/dist/src/telemetry/activity-monitor.js +209 -0
- package/dist/src/telemetry/activity-monitor.js.map +1 -0
- package/dist/src/telemetry/activity-monitor.test.d.ts +6 -0
- package/dist/src/telemetry/activity-monitor.test.js +251 -0
- package/dist/src/telemetry/activity-monitor.test.js.map +1 -0
- package/dist/src/telemetry/activity-types.d.ts +19 -0
- package/dist/src/telemetry/activity-types.js +21 -0
- package/dist/src/telemetry/activity-types.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +53 -5
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +581 -56
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +2 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +467 -31
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +75 -4
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +182 -6
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/config.d.ts +31 -0
- package/dist/src/telemetry/config.js +76 -0
- package/dist/src/telemetry/config.js.map +1 -0
- package/dist/src/telemetry/config.test.d.ts +6 -0
- package/dist/src/telemetry/config.test.js +124 -0
- package/dist/src/telemetry/config.test.js.map +1 -0
- package/dist/src/telemetry/constants.d.ts +0 -18
- package/dist/src/telemetry/constants.js +0 -18
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/file-exporters.d.ts +5 -4
- package/dist/src/telemetry/file-exporters.js +1 -1
- package/dist/src/telemetry/file-exporters.js.map +1 -1
- package/dist/src/telemetry/gcp-exporters.d.ts +34 -0
- package/dist/src/telemetry/gcp-exporters.js +116 -0
- package/dist/src/telemetry/gcp-exporters.js.map +1 -0
- package/dist/src/telemetry/gcp-exporters.test.d.ts +6 -0
- package/dist/src/telemetry/gcp-exporters.test.js +318 -0
- package/dist/src/telemetry/gcp-exporters.test.js.map +1 -0
- package/dist/src/telemetry/high-water-mark-tracker.d.ts +43 -0
- package/dist/src/telemetry/high-water-mark-tracker.js +88 -0
- package/dist/src/telemetry/high-water-mark-tracker.js.map +1 -0
- package/dist/src/telemetry/high-water-mark-tracker.test.d.ts +6 -0
- package/dist/src/telemetry/high-water-mark-tracker.test.js +152 -0
- package/dist/src/telemetry/high-water-mark-tracker.test.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +16 -2
- package/dist/src/telemetry/index.js +25 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +25 -3
- package/dist/src/telemetry/loggers.js +333 -154
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js +3 -4
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +868 -63
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/memory-monitor.d.ts +149 -0
- package/dist/src/telemetry/memory-monitor.js +335 -0
- package/dist/src/telemetry/memory-monitor.js.map +1 -0
- package/dist/src/telemetry/memory-monitor.test.d.ts +6 -0
- package/dist/src/telemetry/memory-monitor.test.js +472 -0
- package/dist/src/telemetry/memory-monitor.test.js.map +1 -0
- package/dist/src/telemetry/metrics.d.ts +498 -11
- package/dist/src/telemetry/metrics.js +729 -84
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +964 -101
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/rate-limiter.d.ts +48 -0
- package/dist/src/telemetry/rate-limiter.js +100 -0
- package/dist/src/telemetry/rate-limiter.js.map +1 -0
- package/dist/src/telemetry/rate-limiter.test.d.ts +6 -0
- package/dist/src/telemetry/rate-limiter.test.js +207 -0
- package/dist/src/telemetry/rate-limiter.test.js.map +1 -0
- package/dist/src/telemetry/sdk.d.ts +1 -1
- package/dist/src/telemetry/sdk.js +23 -4
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/sdk.test.js +108 -0
- package/dist/src/telemetry/sdk.test.js.map +1 -1
- package/dist/src/telemetry/semantic.d.ts +82 -0
- package/dist/src/telemetry/semantic.js +269 -0
- package/dist/src/telemetry/semantic.js.map +1 -0
- package/dist/src/telemetry/semantic.test.d.ts +6 -0
- package/dist/src/telemetry/semantic.test.js +387 -0
- package/dist/src/telemetry/semantic.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 +41 -0
- package/dist/src/telemetry/telemetry-utils.test.js.map +1 -0
- package/dist/src/telemetry/telemetryAttributes.d.ts +8 -0
- package/dist/src/telemetry/telemetryAttributes.js +19 -0
- package/dist/src/telemetry/telemetryAttributes.js.map +1 -0
- package/dist/src/telemetry/trace.d.ts +46 -0
- package/dist/src/telemetry/trace.js +121 -0
- package/dist/src/telemetry/trace.js.map +1 -0
- package/dist/src/telemetry/types.d.ts +351 -25
- package/dist/src/telemetry/types.js +1071 -63
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +4 -4
- package/dist/src/telemetry/uiTelemetry.js +14 -15
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +122 -96
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/test-utils/config.d.ts +3 -2
- package/dist/src/test-utils/config.js +1 -1
- package/dist/src/test-utils/config.js.map +1 -1
- package/dist/src/test-utils/index.d.ts +6 -0
- package/dist/src/test-utils/index.js +7 -0
- package/dist/src/test-utils/index.js.map +1 -0
- package/dist/src/test-utils/mock-tool.d.ts +66 -0
- package/dist/src/test-utils/{tools.js → mock-tool.js} +45 -29
- package/dist/src/test-utils/mock-tool.js.map +1 -0
- package/dist/src/test-utils/mockWorkspaceContext.d.ts +1 -1
- package/dist/src/tools/base-tool-invocation.test.d.ts +6 -0
- package/dist/src/tools/base-tool-invocation.test.js +85 -0
- package/dist/src/tools/base-tool-invocation.test.js.map +1 -0
- package/dist/src/tools/diffOptions.d.ts +1 -1
- package/dist/src/tools/diffOptions.js +21 -13
- package/dist/src/tools/diffOptions.js.map +1 -1
- package/dist/src/tools/diffOptions.test.js +58 -22
- package/dist/src/tools/diffOptions.test.js.map +1 -1
- package/dist/src/tools/edit.d.ts +10 -8
- package/dist/src/tools/edit.js +100 -79
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +429 -163
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +11 -5
- package/dist/src/tools/glob.js +58 -42
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +249 -166
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +7 -5
- package/dist/src/tools/grep.js +66 -40
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +41 -15
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +7 -5
- package/dist/src/tools/ls.js +54 -68
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +150 -293
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +52 -12
- package/dist/src/tools/mcp-client-manager.js +196 -27
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +139 -13
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +28 -24
- package/dist/src/tools/mcp-client.js +338 -351
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +380 -193
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +11 -5
- package/dist/src/tools/mcp-tool.js +66 -17
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +278 -211
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +10 -7
- package/dist/src/tools/memoryTool.js +28 -49
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +26 -13
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/message-bus-integration.test.d.ts +6 -0
- package/dist/src/tools/message-bus-integration.test.js +196 -0
- package/dist/src/tools/message-bus-integration.test.js.map +1 -0
- package/dist/src/tools/modifiable-tool.d.ts +7 -3
- package/dist/src/tools/modifiable-tool.js +41 -19
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.test.js +70 -35
- package/dist/src/tools/modifiable-tool.test.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +9 -7
- package/dist/src/tools/read-file.js +39 -60
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +103 -36
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +9 -14
- package/dist/src/tools/read-many-files.js +71 -155
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +98 -44
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +73 -0
- package/dist/src/tools/ripGrep.js +395 -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 +1305 -0
- package/dist/src/tools/ripGrep.test.js.map +1 -0
- package/dist/src/tools/shell.d.ts +19 -6
- package/dist/src/tools/shell.js +92 -56
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +176 -103
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +78 -0
- package/dist/src/tools/smart-edit.js +717 -0
- package/dist/src/tools/smart-edit.js.map +1 -0
- package/dist/src/tools/smart-edit.test.d.ts +6 -0
- package/dist/src/tools/smart-edit.test.js +592 -0
- package/dist/src/tools/smart-edit.test.js.map +1 -0
- package/dist/src/tools/tool-error.d.ts +39 -1
- package/dist/src/tools/tool-error.js +54 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-names.d.ts +17 -0
- package/dist/src/tools/tool-names.js +21 -0
- package/dist/src/tools/tool-names.js.map +1 -0
- package/dist/src/tools/tool-registry.d.ts +38 -20
- package/dist/src/tools/tool-registry.js +134 -77
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +218 -58
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +49 -17
- package/dist/src/tools/tools.js +150 -8
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/tools.test.js +1 -2
- package/dist/src/tools/tools.test.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +14 -5
- package/dist/src/tools/web-fetch.js +90 -44
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +388 -20
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +8 -6
- package/dist/src/tools/web-search.js +40 -15
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.js +75 -1
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +7 -5
- package/dist/src/tools/write-file.js +54 -54
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +237 -146
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +50 -0
- package/dist/src/tools/write-todos.js +193 -0
- package/dist/src/tools/write-todos.js.map +1 -0
- package/dist/src/tools/write-todos.test.d.ts +6 -0
- package/dist/src/tools/write-todos.test.js +89 -0
- package/dist/src/tools/write-todos.test.js.map +1 -0
- package/dist/src/utils/bfsFileSearch.d.ts +2 -2
- package/dist/src/utils/bfsFileSearch.js +16 -9
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.test.js +3 -3
- package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
- package/dist/src/utils/channel.d.ts +19 -0
- package/dist/src/utils/channel.js +49 -0
- package/dist/src/utils/channel.js.map +1 -0
- package/dist/src/utils/channel.test.d.ts +6 -0
- package/dist/src/utils/channel.test.js +170 -0
- package/dist/src/utils/channel.test.js.map +1 -0
- package/dist/src/utils/debugLogger.d.ts +25 -0
- package/dist/src/utils/debugLogger.js +33 -0
- package/dist/src/utils/debugLogger.js.map +1 -0
- package/dist/src/utils/debugLogger.test.d.ts +6 -0
- package/dist/src/utils/debugLogger.test.js +69 -0
- package/dist/src/utils/debugLogger.test.js.map +1 -0
- package/dist/src/utils/delay.d.ts +16 -0
- package/dist/src/utils/delay.js +43 -0
- package/dist/src/utils/delay.js.map +1 -0
- package/dist/src/utils/delay.test.d.ts +6 -0
- package/dist/src/utils/delay.test.js +88 -0
- package/dist/src/utils/delay.test.js.map +1 -0
- package/dist/src/utils/editCorrector.d.ts +9 -8
- package/dist/src/utils/editCorrector.js +62 -34
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +52 -87
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.d.ts +4 -2
- package/dist/src/utils/editor.js +56 -55
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +47 -88
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/environmentContext.d.ts +3 -2
- package/dist/src/utils/environmentContext.js +20 -33
- package/dist/src/utils/environmentContext.js.map +1 -1
- package/dist/src/utils/environmentContext.test.js +6 -34
- package/dist/src/utils/environmentContext.test.js.map +1 -1
- package/dist/src/utils/errorParsing.d.ts +1 -1
- package/dist/src/utils/errorParsing.js +5 -33
- package/dist/src/utils/errorParsing.js.map +1 -1
- package/dist/src/utils/errorParsing.test.js +0 -88
- package/dist/src/utils/errorParsing.test.js.map +1 -1
- package/dist/src/utils/errorReporting.d.ts +1 -1
- package/dist/src/utils/errors.d.ts +28 -0
- package/dist/src/utils/errors.js +48 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/events.d.ts +121 -0
- package/dist/src/utils/events.js +84 -0
- package/dist/src/utils/events.js.map +1 -0
- package/dist/src/utils/events.test.d.ts +6 -0
- package/dist/src/utils/events.test.js +212 -0
- package/dist/src/utils/events.test.js.map +1 -0
- package/dist/src/utils/extensionLoader.d.ts +86 -0
- package/dist/src/utils/extensionLoader.js +208 -0
- package/dist/src/utils/extensionLoader.js.map +1 -0
- package/dist/src/utils/extensionLoader.test.d.ts +6 -0
- package/dist/src/utils/extensionLoader.test.js +154 -0
- package/dist/src/utils/extensionLoader.test.js.map +1 -0
- package/dist/src/utils/fetch.d.ts +1 -0
- package/dist/src/utils/fetch.js +5 -1
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +28 -12
- package/dist/src/utils/fileUtils.js +204 -81
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +426 -82
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/filesearch/crawler.d.ts +1 -1
- package/dist/src/utils/filesearch/crawler.test.js +2 -2
- package/dist/src/utils/filesearch/crawler.test.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.d.ts +1 -0
- package/dist/src/utils/filesearch/fileSearch.js +14 -9
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.test.js +90 -0
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
- package/dist/src/utils/flashFallback.test.d.ts +6 -0
- package/dist/src/utils/flashFallback.test.js +103 -0
- package/dist/src/utils/flashFallback.test.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +1 -0
- package/dist/src/utils/formatters.js +2 -1
- package/dist/src/utils/formatters.js.map +1 -1
- package/dist/src/utils/formatters.test.d.ts +6 -0
- package/dist/src/utils/formatters.test.js +26 -0
- package/dist/src/utils/formatters.test.js.map +1 -0
- package/dist/src/utils/geminiIgnoreParser.d.ts +18 -0
- package/dist/src/utils/geminiIgnoreParser.js +61 -0
- package/dist/src/utils/geminiIgnoreParser.js.map +1 -0
- package/dist/src/utils/geminiIgnoreParser.test.d.ts +6 -0
- package/dist/src/utils/geminiIgnoreParser.test.js +50 -0
- package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -0
- package/dist/src/utils/generateContentResponseUtilities.d.ts +1 -2
- package/dist/src/utils/generateContentResponseUtilities.js +1 -13
- package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
- package/dist/src/utils/generateContentResponseUtilities.test.js +2 -40
- package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -1
- package/dist/src/utils/getFolderStructure.d.ts +2 -2
- package/dist/src/utils/getFolderStructure.js +12 -20
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/getFolderStructure.test.js +11 -10
- package/dist/src/utils/getFolderStructure.test.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.d.ts +7 -8
- package/dist/src/utils/gitIgnoreParser.js +145 -36
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +127 -38
- package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
- package/dist/src/utils/gitUtils.js +2 -2
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/googleErrors.d.ts +104 -0
- package/dist/src/utils/googleErrors.js +152 -0
- package/dist/src/utils/googleErrors.js.map +1 -0
- package/dist/src/utils/googleErrors.test.d.ts +6 -0
- package/dist/src/utils/googleErrors.test.js +301 -0
- package/dist/src/utils/googleErrors.test.js.map +1 -0
- package/dist/src/utils/googleQuotaErrors.d.ts +37 -0
- package/dist/src/utils/googleQuotaErrors.js +157 -0
- package/dist/src/utils/googleQuotaErrors.js.map +1 -0
- package/dist/src/utils/googleQuotaErrors.test.d.ts +6 -0
- package/dist/src/utils/googleQuotaErrors.test.js +311 -0
- package/dist/src/utils/googleQuotaErrors.test.js.map +1 -0
- package/dist/src/utils/httpErrors.d.ts +18 -0
- package/dist/src/utils/httpErrors.js +36 -0
- package/dist/src/utils/httpErrors.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 +246 -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 +51 -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 +85 -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/llm-edit-fixer.d.ts +26 -0
- package/dist/src/utils/llm-edit-fixer.js +155 -0
- package/dist/src/utils/llm-edit-fixer.js.map +1 -0
- package/dist/src/utils/llm-edit-fixer.test.d.ts +6 -0
- package/dist/src/utils/llm-edit-fixer.test.js +223 -0
- package/dist/src/utils/llm-edit-fixer.test.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.d.ts +26 -6
- package/dist/src/utils/memoryDiscovery.js +239 -40
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +365 -44
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +19 -25
- package/dist/src/utils/memoryImportProcessor.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.test.js +24 -155
- package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
- package/dist/src/utils/messageInspectors.d.ts +1 -1
- package/dist/src/utils/nextSpeakerChecker.d.ts +3 -3
- package/dist/src/utils/nextSpeakerChecker.js +10 -4
- package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.test.js +85 -66
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
- package/dist/src/utils/package.d.ts +12 -0
- package/dist/src/utils/package.js +15 -0
- package/dist/src/utils/package.js.map +1 -0
- package/dist/src/utils/partUtils.d.ts +22 -1
- package/dist/src/utils/partUtils.js +68 -0
- package/dist/src/utils/partUtils.js.map +1 -1
- package/dist/src/utils/partUtils.test.js +112 -1
- package/dist/src/utils/partUtils.test.js.map +1 -1
- package/dist/src/utils/pathCorrector.d.ts +25 -0
- package/dist/src/utils/pathCorrector.js +33 -0
- package/dist/src/utils/pathCorrector.js.map +1 -0
- package/dist/src/utils/pathCorrector.test.d.ts +6 -0
- package/dist/src/utils/pathCorrector.test.js +83 -0
- package/dist/src/utils/pathCorrector.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 +406 -0
- package/dist/src/utils/pathReader.test.js.map +1 -0
- package/dist/src/utils/paths.d.ts +1 -18
- package/dist/src/utils/paths.js +133 -57
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/paths.test.js +200 -68
- package/dist/src/utils/paths.test.js.map +1 -1
- package/dist/src/utils/promptIdContext.d.ts +7 -0
- package/dist/src/utils/promptIdContext.js +8 -0
- package/dist/src/utils/promptIdContext.js.map +1 -0
- package/dist/src/utils/quotaErrorDetection.d.ts +1 -3
- package/dist/src/utils/quotaErrorDetection.js +0 -46
- package/dist/src/utils/quotaErrorDetection.js.map +1 -1
- package/dist/src/utils/retry.d.ts +5 -10
- package/dist/src/utils/retry.js +114 -197
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +196 -130
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/safeJsonStringify.d.ts +4 -4
- package/dist/src/utils/safeJsonStringify.js +31 -7
- package/dist/src/utils/safeJsonStringify.js.map +1 -1
- package/dist/src/utils/schemaValidator.js +15 -1
- package/dist/src/utils/schemaValidator.js.map +1 -1
- package/dist/src/utils/schemaValidator.test.d.ts +6 -0
- package/dist/src/utils/schemaValidator.test.js +113 -0
- package/dist/src/utils/schemaValidator.test.js.map +1 -0
- package/dist/src/utils/session.js +1 -1
- package/dist/src/utils/session.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +21 -3
- package/dist/src/utils/shell-utils.js +427 -159
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +250 -59
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/stdio.d.ts +32 -0
- package/dist/src/utils/stdio.js +85 -0
- package/dist/src/utils/stdio.js.map +1 -0
- package/dist/src/utils/stdio.test.d.ts +6 -0
- package/dist/src/utils/stdio.test.js +47 -0
- package/dist/src/utils/stdio.test.js.map +1 -0
- package/dist/src/utils/summarizer.d.ts +6 -4
- package/dist/src/utils/summarizer.js +8 -9
- package/dist/src/utils/summarizer.js.map +1 -1
- package/dist/src/utils/summarizer.test.js +32 -12
- package/dist/src/utils/summarizer.test.js.map +1 -1
- package/dist/src/utils/systemEncoding.js +7 -6
- package/dist/src/utils/systemEncoding.js.map +1 -1
- package/dist/src/utils/systemEncoding.test.js +4 -3
- package/dist/src/utils/systemEncoding.test.js.map +1 -1
- package/dist/src/utils/terminal.d.ts +14 -0
- package/dist/src/utils/terminal.js +38 -0
- package/dist/src/utils/terminal.js.map +1 -0
- package/dist/src/utils/terminalSerializer.d.ts +25 -0
- package/dist/src/utils/terminalSerializer.js +432 -0
- package/dist/src/utils/terminalSerializer.js.map +1 -0
- package/dist/src/utils/terminalSerializer.test.d.ts +6 -0
- package/dist/src/utils/terminalSerializer.test.js +176 -0
- package/dist/src/utils/terminalSerializer.test.js.map +1 -0
- package/dist/src/utils/textUtils.d.ts +5 -0
- package/dist/src/utils/textUtils.js +14 -0
- package/dist/src/utils/textUtils.js.map +1 -1
- package/dist/src/utils/textUtils.test.d.ts +6 -0
- package/dist/src/utils/textUtils.test.js +59 -0
- package/dist/src/utils/textUtils.test.js.map +1 -0
- package/dist/src/utils/thoughtUtils.d.ts +21 -0
- package/dist/src/utils/thoughtUtils.js +39 -0
- package/dist/src/utils/thoughtUtils.js.map +1 -0
- package/dist/src/utils/thoughtUtils.test.d.ts +6 -0
- package/dist/src/utils/thoughtUtils.test.js +78 -0
- package/dist/src/utils/thoughtUtils.test.js.map +1 -0
- package/dist/src/utils/tool-utils.d.ts +19 -0
- package/dist/src/utils/tool-utils.js +67 -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 +69 -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 +115 -0
- package/dist/src/utils/userAccountManager.js.map +1 -0
- package/dist/src/utils/userAccountManager.test.d.ts +6 -0
- package/dist/src/utils/{user_account.test.js → userAccountManager.test.js} +41 -36
- package/dist/src/utils/userAccountManager.test.js.map +1 -0
- package/dist/src/utils/workspaceContext.d.ts +4 -3
- package/dist/src/utils/workspaceContext.js +23 -17
- package/dist/src/utils/workspaceContext.js.map +1 -1
- package/dist/src/utils/workspaceContext.test.js +45 -19
- package/dist/src/utils/workspaceContext.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -10
- package/dist/src/core/modelCheck.d.ts +0 -14
- package/dist/src/core/modelCheck.js +0 -62
- package/dist/src/core/modelCheck.js.map +0 -1
- package/dist/src/test-utils/tools.d.ts +0 -44
- package/dist/src/test-utils/tools.js.map +0 -1
- package/dist/src/utils/flashFallback.integration.test.js +0 -118
- package/dist/src/utils/flashFallback.integration.test.js.map +0 -1
- package/dist/src/utils/user_account.d.ts +0 -9
- package/dist/src/utils/user_account.js +0 -109
- package/dist/src/utils/user_account.js.map +0 -1
- package/dist/src/utils/user_account.test.js.map +0 -1
- package/dist/src/utils/user_id.d.ts +0 -11
- package/dist/src/utils/user_id.js +0 -49
- package/dist/src/utils/user_id.js.map +0 -1
- package/dist/src/utils/user_id.test.js +0 -21
- package/dist/src/utils/user_id.test.js.map +0 -1
- /package/dist/src/{utils/flashFallback.integration.test.d.ts → agents/codebase-investigator.test.d.ts} +0 -0
- /package/dist/src/{utils/user_account.test.d.ts → agents/executor.test.d.ts} +0 -0
- /package/dist/src/{utils/user_id.test.d.ts → agents/invocation.test.d.ts} +0 -0
|
@@ -3,10 +3,17 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
7
|
-
import { CoreToolScheduler, convertToFunctionResponse, } from './coreToolScheduler.js';
|
|
8
|
-
import { BaseDeclarativeTool, BaseToolInvocation, ToolConfirmationOutcome, Kind, ApprovalMode, } from '../index.js';
|
|
9
|
-
import { MockModifiableTool, MockTool } from '../test-utils/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
7
|
+
import { CoreToolScheduler, convertToFunctionResponse, truncateAndSaveToFile, } from './coreToolScheduler.js';
|
|
8
|
+
import { DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES, DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD, BaseDeclarativeTool, BaseToolInvocation, ToolConfirmationOutcome, Kind, ApprovalMode, } from '../index.js';
|
|
9
|
+
import { MockModifiableTool, MockTool, MOCK_TOOL_SHOULD_CONFIRM_EXECUTE, } from '../test-utils/mock-tool.js';
|
|
10
|
+
import * as modifiableToolModule from '../tools/modifiable-tool.js';
|
|
11
|
+
import * as fs from 'node:fs/promises';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import { isShellInvocationAllowlisted } from '../utils/shell-utils.js';
|
|
14
|
+
vi.mock('fs/promises', () => ({
|
|
15
|
+
writeFile: vi.fn(),
|
|
16
|
+
}));
|
|
10
17
|
class TestApprovalTool extends BaseDeclarativeTool {
|
|
11
18
|
config;
|
|
12
19
|
static Name = 'testApprovalTool';
|
|
@@ -58,10 +65,114 @@ class TestApprovalInvocation extends BaseToolInvocation {
|
|
|
58
65
|
};
|
|
59
66
|
}
|
|
60
67
|
}
|
|
68
|
+
class AbortDuringConfirmationInvocation extends BaseToolInvocation {
|
|
69
|
+
abortController;
|
|
70
|
+
abortError;
|
|
71
|
+
constructor(abortController, abortError, params) {
|
|
72
|
+
super(params);
|
|
73
|
+
this.abortController = abortController;
|
|
74
|
+
this.abortError = abortError;
|
|
75
|
+
}
|
|
76
|
+
async shouldConfirmExecute(_signal) {
|
|
77
|
+
this.abortController.abort();
|
|
78
|
+
throw this.abortError;
|
|
79
|
+
}
|
|
80
|
+
async execute(_abortSignal) {
|
|
81
|
+
throw new Error('execute should not be called when confirmation fails');
|
|
82
|
+
}
|
|
83
|
+
getDescription() {
|
|
84
|
+
return 'Abort during confirmation invocation';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
class AbortDuringConfirmationTool extends BaseDeclarativeTool {
|
|
88
|
+
abortController;
|
|
89
|
+
abortError;
|
|
90
|
+
constructor(abortController, abortError) {
|
|
91
|
+
super('abortDuringConfirmationTool', 'Abort During Confirmation Tool', 'A tool that aborts while confirming execution.', Kind.Other, {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {},
|
|
94
|
+
});
|
|
95
|
+
this.abortController = abortController;
|
|
96
|
+
this.abortError = abortError;
|
|
97
|
+
}
|
|
98
|
+
createInvocation(params) {
|
|
99
|
+
return new AbortDuringConfirmationInvocation(this.abortController, this.abortError, params);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function waitForStatus(onToolCallsUpdate, status, timeout = 5000) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const startTime = Date.now();
|
|
105
|
+
const check = () => {
|
|
106
|
+
if (Date.now() - startTime > timeout) {
|
|
107
|
+
const seenStatuses = onToolCallsUpdate.mock.calls
|
|
108
|
+
.flatMap((call) => call[0])
|
|
109
|
+
.map((toolCall) => toolCall.status);
|
|
110
|
+
reject(new Error(`Timed out waiting for status "${status}". Seen statuses: ${seenStatuses.join(', ')}`));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const foundCall = onToolCallsUpdate.mock.calls
|
|
114
|
+
.flatMap((call) => call[0])
|
|
115
|
+
.find((toolCall) => toolCall.status === status);
|
|
116
|
+
if (foundCall) {
|
|
117
|
+
resolve(foundCall);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
setTimeout(check, 10); // Check again in 10ms
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
check();
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function createMockConfig(overrides = {}) {
|
|
127
|
+
const defaultToolRegistry = {
|
|
128
|
+
getTool: () => undefined,
|
|
129
|
+
getToolByName: () => undefined,
|
|
130
|
+
getFunctionDeclarations: () => [],
|
|
131
|
+
tools: new Map(),
|
|
132
|
+
discovery: {},
|
|
133
|
+
registerTool: () => { },
|
|
134
|
+
getToolByDisplayName: () => undefined,
|
|
135
|
+
getTools: () => [],
|
|
136
|
+
discoverTools: async () => { },
|
|
137
|
+
getAllTools: () => [],
|
|
138
|
+
getToolsByServer: () => [],
|
|
139
|
+
};
|
|
140
|
+
const baseConfig = {
|
|
141
|
+
getSessionId: () => 'test-session-id',
|
|
142
|
+
getUsageStatisticsEnabled: () => true,
|
|
143
|
+
getDebugMode: () => false,
|
|
144
|
+
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
145
|
+
setApprovalMode: () => { },
|
|
146
|
+
getAllowedTools: () => [],
|
|
147
|
+
getContentGeneratorConfig: () => ({
|
|
148
|
+
model: 'test-model',
|
|
149
|
+
authType: 'oauth-personal',
|
|
150
|
+
}),
|
|
151
|
+
getShellExecutionConfig: () => ({
|
|
152
|
+
terminalWidth: 90,
|
|
153
|
+
terminalHeight: 30,
|
|
154
|
+
}),
|
|
155
|
+
storage: {
|
|
156
|
+
getProjectTempDir: () => '/tmp',
|
|
157
|
+
},
|
|
158
|
+
getTruncateToolOutputThreshold: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
|
|
159
|
+
getTruncateToolOutputLines: () => DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
|
|
160
|
+
getToolRegistry: () => defaultToolRegistry,
|
|
161
|
+
getUseSmartEdit: () => false,
|
|
162
|
+
getUseModelRouter: () => false,
|
|
163
|
+
getGeminiClient: () => null,
|
|
164
|
+
getEnableMessageBusIntegration: () => false,
|
|
165
|
+
getMessageBus: () => null,
|
|
166
|
+
getPolicyEngine: () => null,
|
|
167
|
+
};
|
|
168
|
+
return { ...baseConfig, ...overrides };
|
|
169
|
+
}
|
|
61
170
|
describe('CoreToolScheduler', () => {
|
|
62
171
|
it('should cancel a tool call if the signal is aborted before confirmation', async () => {
|
|
63
|
-
const mockTool = new MockTool(
|
|
64
|
-
|
|
172
|
+
const mockTool = new MockTool({
|
|
173
|
+
name: 'mockTool',
|
|
174
|
+
shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
|
|
175
|
+
});
|
|
65
176
|
const declarativeTool = mockTool;
|
|
66
177
|
const mockToolRegistry = {
|
|
67
178
|
getTool: () => declarativeTool,
|
|
@@ -78,23 +189,15 @@ describe('CoreToolScheduler', () => {
|
|
|
78
189
|
};
|
|
79
190
|
const onAllToolCallsComplete = vi.fn();
|
|
80
191
|
const onToolCallsUpdate = vi.fn();
|
|
81
|
-
const mockConfig = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
86
|
-
getContentGeneratorConfig: () => ({
|
|
87
|
-
model: 'test-model',
|
|
88
|
-
authType: 'oauth-personal',
|
|
89
|
-
}),
|
|
90
|
-
};
|
|
192
|
+
const mockConfig = createMockConfig({
|
|
193
|
+
getToolRegistry: () => mockToolRegistry,
|
|
194
|
+
isInteractive: () => false,
|
|
195
|
+
});
|
|
91
196
|
const scheduler = new CoreToolScheduler({
|
|
92
197
|
config: mockConfig,
|
|
93
|
-
toolRegistry: mockToolRegistry,
|
|
94
198
|
onAllToolCallsComplete,
|
|
95
199
|
onToolCallsUpdate,
|
|
96
200
|
getPreferredEditor: () => 'vscode',
|
|
97
|
-
onEditorClose: vi.fn(),
|
|
98
201
|
});
|
|
99
202
|
const abortController = new AbortController();
|
|
100
203
|
const request = {
|
|
@@ -111,10 +214,262 @@ describe('CoreToolScheduler', () => {
|
|
|
111
214
|
.calls[0][0];
|
|
112
215
|
expect(completedCalls[0].status).toBe('cancelled');
|
|
113
216
|
});
|
|
217
|
+
it('should cancel all tools when cancelAll is called', async () => {
|
|
218
|
+
const mockTool1 = new MockTool({
|
|
219
|
+
name: 'mockTool1',
|
|
220
|
+
shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
|
|
221
|
+
});
|
|
222
|
+
const mockTool2 = new MockTool({ name: 'mockTool2' });
|
|
223
|
+
const mockTool3 = new MockTool({ name: 'mockTool3' });
|
|
224
|
+
const mockToolRegistry = {
|
|
225
|
+
getTool: (name) => {
|
|
226
|
+
if (name === 'mockTool1')
|
|
227
|
+
return mockTool1;
|
|
228
|
+
if (name === 'mockTool2')
|
|
229
|
+
return mockTool2;
|
|
230
|
+
if (name === 'mockTool3')
|
|
231
|
+
return mockTool3;
|
|
232
|
+
return undefined;
|
|
233
|
+
},
|
|
234
|
+
getFunctionDeclarations: () => [],
|
|
235
|
+
tools: new Map(),
|
|
236
|
+
discovery: {},
|
|
237
|
+
registerTool: () => { },
|
|
238
|
+
getToolByName: (name) => {
|
|
239
|
+
if (name === 'mockTool1')
|
|
240
|
+
return mockTool1;
|
|
241
|
+
if (name === 'mockTool2')
|
|
242
|
+
return mockTool2;
|
|
243
|
+
if (name === 'mockTool3')
|
|
244
|
+
return mockTool3;
|
|
245
|
+
return undefined;
|
|
246
|
+
},
|
|
247
|
+
getToolByDisplayName: () => undefined,
|
|
248
|
+
getTools: () => [],
|
|
249
|
+
discoverTools: async () => { },
|
|
250
|
+
getAllTools: () => [],
|
|
251
|
+
getToolsByServer: () => [],
|
|
252
|
+
};
|
|
253
|
+
const onAllToolCallsComplete = vi.fn();
|
|
254
|
+
const onToolCallsUpdate = vi.fn();
|
|
255
|
+
const mockConfig = createMockConfig({
|
|
256
|
+
getToolRegistry: () => mockToolRegistry,
|
|
257
|
+
isInteractive: () => false,
|
|
258
|
+
});
|
|
259
|
+
const scheduler = new CoreToolScheduler({
|
|
260
|
+
config: mockConfig,
|
|
261
|
+
onAllToolCallsComplete,
|
|
262
|
+
onToolCallsUpdate,
|
|
263
|
+
getPreferredEditor: () => 'vscode',
|
|
264
|
+
});
|
|
265
|
+
const abortController = new AbortController();
|
|
266
|
+
const requests = [
|
|
267
|
+
{
|
|
268
|
+
callId: '1',
|
|
269
|
+
name: 'mockTool1',
|
|
270
|
+
args: {},
|
|
271
|
+
isClientInitiated: false,
|
|
272
|
+
prompt_id: 'prompt-id-1',
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
callId: '2',
|
|
276
|
+
name: 'mockTool2',
|
|
277
|
+
args: {},
|
|
278
|
+
isClientInitiated: false,
|
|
279
|
+
prompt_id: 'prompt-id-1',
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
callId: '3',
|
|
283
|
+
name: 'mockTool3',
|
|
284
|
+
args: {},
|
|
285
|
+
isClientInitiated: false,
|
|
286
|
+
prompt_id: 'prompt-id-1',
|
|
287
|
+
},
|
|
288
|
+
];
|
|
289
|
+
// Don't await, let it run in the background
|
|
290
|
+
void scheduler.schedule(requests, abortController.signal);
|
|
291
|
+
// Wait for the first tool to be awaiting approval
|
|
292
|
+
await waitForStatus(onToolCallsUpdate, 'awaiting_approval');
|
|
293
|
+
// Cancel all operations
|
|
294
|
+
scheduler.cancelAll(abortController.signal);
|
|
295
|
+
abortController.abort(); // Also fire the signal
|
|
296
|
+
await vi.waitFor(() => {
|
|
297
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
298
|
+
});
|
|
299
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
300
|
+
.calls[0][0];
|
|
301
|
+
expect(completedCalls).toHaveLength(3);
|
|
302
|
+
expect(completedCalls.find((c) => c.request.callId === '1')?.status).toBe('cancelled');
|
|
303
|
+
expect(completedCalls.find((c) => c.request.callId === '2')?.status).toBe('cancelled');
|
|
304
|
+
expect(completedCalls.find((c) => c.request.callId === '3')?.status).toBe('cancelled');
|
|
305
|
+
});
|
|
306
|
+
it('should cancel all tools in a batch when one is cancelled via confirmation', async () => {
|
|
307
|
+
const mockTool1 = new MockTool({
|
|
308
|
+
name: 'mockTool1',
|
|
309
|
+
shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
|
|
310
|
+
});
|
|
311
|
+
const mockTool2 = new MockTool({ name: 'mockTool2' });
|
|
312
|
+
const mockTool3 = new MockTool({ name: 'mockTool3' });
|
|
313
|
+
const mockToolRegistry = {
|
|
314
|
+
getTool: (name) => {
|
|
315
|
+
if (name === 'mockTool1')
|
|
316
|
+
return mockTool1;
|
|
317
|
+
if (name === 'mockTool2')
|
|
318
|
+
return mockTool2;
|
|
319
|
+
if (name === 'mockTool3')
|
|
320
|
+
return mockTool3;
|
|
321
|
+
return undefined;
|
|
322
|
+
},
|
|
323
|
+
getFunctionDeclarations: () => [],
|
|
324
|
+
tools: new Map(),
|
|
325
|
+
discovery: {},
|
|
326
|
+
registerTool: () => { },
|
|
327
|
+
getToolByName: (name) => {
|
|
328
|
+
if (name === 'mockTool1')
|
|
329
|
+
return mockTool1;
|
|
330
|
+
if (name === 'mockTool2')
|
|
331
|
+
return mockTool2;
|
|
332
|
+
if (name === 'mockTool3')
|
|
333
|
+
return mockTool3;
|
|
334
|
+
return undefined;
|
|
335
|
+
},
|
|
336
|
+
getToolByDisplayName: () => undefined,
|
|
337
|
+
getTools: () => [],
|
|
338
|
+
discoverTools: async () => { },
|
|
339
|
+
getAllTools: () => [],
|
|
340
|
+
getToolsByServer: () => [],
|
|
341
|
+
};
|
|
342
|
+
const onAllToolCallsComplete = vi.fn();
|
|
343
|
+
const onToolCallsUpdate = vi.fn();
|
|
344
|
+
const mockConfig = createMockConfig({
|
|
345
|
+
getToolRegistry: () => mockToolRegistry,
|
|
346
|
+
isInteractive: () => false,
|
|
347
|
+
});
|
|
348
|
+
const scheduler = new CoreToolScheduler({
|
|
349
|
+
config: mockConfig,
|
|
350
|
+
onAllToolCallsComplete,
|
|
351
|
+
onToolCallsUpdate,
|
|
352
|
+
getPreferredEditor: () => 'vscode',
|
|
353
|
+
});
|
|
354
|
+
const abortController = new AbortController();
|
|
355
|
+
const requests = [
|
|
356
|
+
{
|
|
357
|
+
callId: '1',
|
|
358
|
+
name: 'mockTool1',
|
|
359
|
+
args: {},
|
|
360
|
+
isClientInitiated: false,
|
|
361
|
+
prompt_id: 'prompt-id-1',
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
callId: '2',
|
|
365
|
+
name: 'mockTool2',
|
|
366
|
+
args: {},
|
|
367
|
+
isClientInitiated: false,
|
|
368
|
+
prompt_id: 'prompt-id-1',
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
callId: '3',
|
|
372
|
+
name: 'mockTool3',
|
|
373
|
+
args: {},
|
|
374
|
+
isClientInitiated: false,
|
|
375
|
+
prompt_id: 'prompt-id-1',
|
|
376
|
+
},
|
|
377
|
+
];
|
|
378
|
+
// Don't await, let it run in the background
|
|
379
|
+
void scheduler.schedule(requests, abortController.signal);
|
|
380
|
+
// Wait for the first tool to be awaiting approval
|
|
381
|
+
const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
|
|
382
|
+
// Cancel the first tool via its confirmation handler
|
|
383
|
+
await awaitingCall.confirmationDetails.onConfirm(ToolConfirmationOutcome.Cancel);
|
|
384
|
+
abortController.abort(); // User cancelling often involves an abort signal
|
|
385
|
+
await vi.waitFor(() => {
|
|
386
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
387
|
+
});
|
|
388
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
389
|
+
.calls[0][0];
|
|
390
|
+
expect(completedCalls).toHaveLength(3);
|
|
391
|
+
expect(completedCalls.find((c) => c.request.callId === '1')?.status).toBe('cancelled');
|
|
392
|
+
expect(completedCalls.find((c) => c.request.callId === '2')?.status).toBe('cancelled');
|
|
393
|
+
expect(completedCalls.find((c) => c.request.callId === '3')?.status).toBe('cancelled');
|
|
394
|
+
});
|
|
395
|
+
it('should mark tool call as cancelled when abort happens during confirmation error', async () => {
|
|
396
|
+
const abortController = new AbortController();
|
|
397
|
+
const abortError = new Error('Abort requested during confirmation');
|
|
398
|
+
const declarativeTool = new AbortDuringConfirmationTool(abortController, abortError);
|
|
399
|
+
const mockToolRegistry = {
|
|
400
|
+
getTool: () => declarativeTool,
|
|
401
|
+
getFunctionDeclarations: () => [],
|
|
402
|
+
tools: new Map(),
|
|
403
|
+
discovery: {},
|
|
404
|
+
registerTool: () => { },
|
|
405
|
+
getToolByName: () => declarativeTool,
|
|
406
|
+
getToolByDisplayName: () => declarativeTool,
|
|
407
|
+
getTools: () => [],
|
|
408
|
+
discoverTools: async () => { },
|
|
409
|
+
getAllTools: () => [],
|
|
410
|
+
getToolsByServer: () => [],
|
|
411
|
+
};
|
|
412
|
+
const onAllToolCallsComplete = vi.fn();
|
|
413
|
+
const onToolCallsUpdate = vi.fn();
|
|
414
|
+
const mockConfig = createMockConfig({
|
|
415
|
+
getToolRegistry: () => mockToolRegistry,
|
|
416
|
+
isInteractive: () => false,
|
|
417
|
+
});
|
|
418
|
+
const scheduler = new CoreToolScheduler({
|
|
419
|
+
config: mockConfig,
|
|
420
|
+
onAllToolCallsComplete,
|
|
421
|
+
onToolCallsUpdate,
|
|
422
|
+
getPreferredEditor: () => 'vscode',
|
|
423
|
+
});
|
|
424
|
+
const request = {
|
|
425
|
+
callId: 'abort-1',
|
|
426
|
+
name: 'abortDuringConfirmationTool',
|
|
427
|
+
args: {},
|
|
428
|
+
isClientInitiated: false,
|
|
429
|
+
prompt_id: 'prompt-id-abort',
|
|
430
|
+
};
|
|
431
|
+
await scheduler.schedule([request], abortController.signal);
|
|
432
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
433
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
434
|
+
.calls[0][0];
|
|
435
|
+
expect(completedCalls[0].status).toBe('cancelled');
|
|
436
|
+
const statuses = onToolCallsUpdate.mock.calls.flatMap((call) => call[0].map((toolCall) => toolCall.status));
|
|
437
|
+
expect(statuses).not.toContain('error');
|
|
438
|
+
});
|
|
439
|
+
describe('getToolSuggestion', () => {
|
|
440
|
+
it('should suggest the top N closest tool names for a typo', () => {
|
|
441
|
+
// Create mocked tool registry
|
|
442
|
+
const mockToolRegistry = {
|
|
443
|
+
getAllToolNames: () => ['list_files', 'read_file', 'write_file'],
|
|
444
|
+
};
|
|
445
|
+
const mockConfig = createMockConfig({
|
|
446
|
+
getToolRegistry: () => mockToolRegistry,
|
|
447
|
+
isInteractive: () => false,
|
|
448
|
+
});
|
|
449
|
+
// Create scheduler
|
|
450
|
+
const scheduler = new CoreToolScheduler({
|
|
451
|
+
config: mockConfig,
|
|
452
|
+
getPreferredEditor: () => 'vscode',
|
|
453
|
+
});
|
|
454
|
+
// Test that the right tool is selected, with only 1 result, for typos
|
|
455
|
+
// @ts-expect-error accessing private method
|
|
456
|
+
const misspelledTool = scheduler.getToolSuggestion('list_fils', 1);
|
|
457
|
+
expect(misspelledTool).toBe(' Did you mean "list_files"?');
|
|
458
|
+
// Test that the right tool is selected, with only 1 result, for prefixes
|
|
459
|
+
// @ts-expect-error accessing private method
|
|
460
|
+
const prefixedTool = scheduler.getToolSuggestion('github.list_files', 1);
|
|
461
|
+
expect(prefixedTool).toBe(' Did you mean "list_files"?');
|
|
462
|
+
// Test that the right tool is first
|
|
463
|
+
// @ts-expect-error accessing private method
|
|
464
|
+
const suggestionMultiple = scheduler.getToolSuggestion('list_fils');
|
|
465
|
+
expect(suggestionMultiple).toBe(' Did you mean one of: "list_files", "read_file", "write_file"?');
|
|
466
|
+
});
|
|
467
|
+
});
|
|
114
468
|
});
|
|
115
469
|
describe('CoreToolScheduler with payload', () => {
|
|
116
470
|
it('should update args and diff and execute tool when payload is provided', async () => {
|
|
117
471
|
const mockTool = new MockModifiableTool();
|
|
472
|
+
mockTool.executeFn = vi.fn();
|
|
118
473
|
const declarativeTool = mockTool;
|
|
119
474
|
const mockToolRegistry = {
|
|
120
475
|
getTool: () => declarativeTool,
|
|
@@ -131,23 +486,15 @@ describe('CoreToolScheduler with payload', () => {
|
|
|
131
486
|
};
|
|
132
487
|
const onAllToolCallsComplete = vi.fn();
|
|
133
488
|
const onToolCallsUpdate = vi.fn();
|
|
134
|
-
const mockConfig = {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
139
|
-
getContentGeneratorConfig: () => ({
|
|
140
|
-
model: 'test-model',
|
|
141
|
-
authType: 'oauth-personal',
|
|
142
|
-
}),
|
|
143
|
-
};
|
|
489
|
+
const mockConfig = createMockConfig({
|
|
490
|
+
getToolRegistry: () => mockToolRegistry,
|
|
491
|
+
isInteractive: () => false,
|
|
492
|
+
});
|
|
144
493
|
const scheduler = new CoreToolScheduler({
|
|
145
494
|
config: mockConfig,
|
|
146
|
-
toolRegistry: mockToolRegistry,
|
|
147
495
|
onAllToolCallsComplete,
|
|
148
496
|
onToolCallsUpdate,
|
|
149
497
|
getPreferredEditor: () => 'vscode',
|
|
150
|
-
onEditorClose: vi.fn(),
|
|
151
498
|
});
|
|
152
499
|
const abortController = new AbortController();
|
|
153
500
|
const request = {
|
|
@@ -158,17 +505,16 @@ describe('CoreToolScheduler with payload', () => {
|
|
|
158
505
|
prompt_id: 'prompt-id-2',
|
|
159
506
|
};
|
|
160
507
|
await scheduler.schedule([request], abortController.signal);
|
|
161
|
-
await
|
|
162
|
-
const awaitingCall = onToolCallsUpdate.mock.calls.find((call) => call[0][0].status === 'awaiting_approval')?.[0][0];
|
|
163
|
-
expect(awaitingCall).toBeDefined();
|
|
164
|
-
});
|
|
165
|
-
const awaitingCall = onToolCallsUpdate.mock.calls.find((call) => call[0][0].status === 'awaiting_approval')?.[0][0];
|
|
508
|
+
const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
|
|
166
509
|
const confirmationDetails = awaitingCall.confirmationDetails;
|
|
167
510
|
if (confirmationDetails) {
|
|
168
511
|
const payload = { newContent: 'final version' };
|
|
169
512
|
await confirmationDetails.onConfirm(ToolConfirmationOutcome.ProceedOnce, payload);
|
|
170
513
|
}
|
|
171
|
-
|
|
514
|
+
// Wait for the tool execution to complete
|
|
515
|
+
await vi.waitFor(() => {
|
|
516
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
517
|
+
});
|
|
172
518
|
const completedCalls = onAllToolCallsComplete.mock
|
|
173
519
|
.calls[0][0];
|
|
174
520
|
expect(completedCalls[0].status).toBe('success');
|
|
@@ -183,35 +529,41 @@ describe('convertToFunctionResponse', () => {
|
|
|
183
529
|
it('should handle simple string llmContent', () => {
|
|
184
530
|
const llmContent = 'Simple text output';
|
|
185
531
|
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
186
|
-
expect(result).toEqual(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
532
|
+
expect(result).toEqual([
|
|
533
|
+
{
|
|
534
|
+
functionResponse: {
|
|
535
|
+
name: toolName,
|
|
536
|
+
id: callId,
|
|
537
|
+
response: { output: 'Simple text output' },
|
|
538
|
+
},
|
|
191
539
|
},
|
|
192
|
-
|
|
540
|
+
]);
|
|
193
541
|
});
|
|
194
542
|
it('should handle llmContent as a single Part with text', () => {
|
|
195
543
|
const llmContent = { text: 'Text from Part object' };
|
|
196
544
|
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
197
|
-
expect(result).toEqual(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
545
|
+
expect(result).toEqual([
|
|
546
|
+
{
|
|
547
|
+
functionResponse: {
|
|
548
|
+
name: toolName,
|
|
549
|
+
id: callId,
|
|
550
|
+
response: { output: 'Text from Part object' },
|
|
551
|
+
},
|
|
202
552
|
},
|
|
203
|
-
|
|
553
|
+
]);
|
|
204
554
|
});
|
|
205
555
|
it('should handle llmContent as a PartListUnion array with a single text Part', () => {
|
|
206
556
|
const llmContent = [{ text: 'Text from array' }];
|
|
207
557
|
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
208
|
-
expect(result).toEqual(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
558
|
+
expect(result).toEqual([
|
|
559
|
+
{
|
|
560
|
+
functionResponse: {
|
|
561
|
+
name: toolName,
|
|
562
|
+
id: callId,
|
|
563
|
+
response: { output: 'Text from array' },
|
|
564
|
+
},
|
|
213
565
|
},
|
|
214
|
-
|
|
566
|
+
]);
|
|
215
567
|
});
|
|
216
568
|
it('should handle llmContent with inlineData', () => {
|
|
217
569
|
const llmContent = {
|
|
@@ -288,24 +640,28 @@ describe('convertToFunctionResponse', () => {
|
|
|
288
640
|
it('should handle llmContent as a generic Part (not text, inlineData, or fileData)', () => {
|
|
289
641
|
const llmContent = { functionCall: { name: 'test', args: {} } };
|
|
290
642
|
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
291
|
-
expect(result).toEqual(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
643
|
+
expect(result).toEqual([
|
|
644
|
+
{
|
|
645
|
+
functionResponse: {
|
|
646
|
+
name: toolName,
|
|
647
|
+
id: callId,
|
|
648
|
+
response: { output: 'Tool execution succeeded.' },
|
|
649
|
+
},
|
|
296
650
|
},
|
|
297
|
-
|
|
651
|
+
]);
|
|
298
652
|
});
|
|
299
653
|
it('should handle empty string llmContent', () => {
|
|
300
654
|
const llmContent = '';
|
|
301
655
|
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
302
|
-
expect(result).toEqual(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
656
|
+
expect(result).toEqual([
|
|
657
|
+
{
|
|
658
|
+
functionResponse: {
|
|
659
|
+
name: toolName,
|
|
660
|
+
id: callId,
|
|
661
|
+
response: { output: '' },
|
|
662
|
+
},
|
|
307
663
|
},
|
|
308
|
-
|
|
664
|
+
]);
|
|
309
665
|
});
|
|
310
666
|
it('should handle llmContent as an empty array', () => {
|
|
311
667
|
const llmContent = [];
|
|
@@ -323,13 +679,15 @@ describe('convertToFunctionResponse', () => {
|
|
|
323
679
|
it('should handle llmContent as a Part with undefined inlineData/fileData/text', () => {
|
|
324
680
|
const llmContent = {}; // An empty part object
|
|
325
681
|
const result = convertToFunctionResponse(toolName, callId, llmContent);
|
|
326
|
-
expect(result).toEqual(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
682
|
+
expect(result).toEqual([
|
|
683
|
+
{
|
|
684
|
+
functionResponse: {
|
|
685
|
+
name: toolName,
|
|
686
|
+
id: callId,
|
|
687
|
+
response: { output: 'Tool execution succeeded.' },
|
|
688
|
+
},
|
|
331
689
|
},
|
|
332
|
-
|
|
690
|
+
]);
|
|
333
691
|
});
|
|
334
692
|
});
|
|
335
693
|
class MockEditToolInvocation extends BaseToolInvocation {
|
|
@@ -369,15 +727,14 @@ class MockEditTool extends BaseDeclarativeTool {
|
|
|
369
727
|
describe('CoreToolScheduler edit cancellation', () => {
|
|
370
728
|
it('should preserve diff when an edit is cancelled', async () => {
|
|
371
729
|
const mockEditTool = new MockEditTool();
|
|
372
|
-
const declarativeTool = mockEditTool;
|
|
373
730
|
const mockToolRegistry = {
|
|
374
|
-
getTool: () =>
|
|
731
|
+
getTool: () => mockEditTool,
|
|
375
732
|
getFunctionDeclarations: () => [],
|
|
376
733
|
tools: new Map(),
|
|
377
734
|
discovery: {},
|
|
378
735
|
registerTool: () => { },
|
|
379
|
-
getToolByName: () =>
|
|
380
|
-
getToolByDisplayName: () =>
|
|
736
|
+
getToolByName: () => mockEditTool,
|
|
737
|
+
getToolByDisplayName: () => mockEditTool,
|
|
381
738
|
getTools: () => [],
|
|
382
739
|
discoverTools: async () => { },
|
|
383
740
|
getAllTools: () => [],
|
|
@@ -385,23 +742,15 @@ describe('CoreToolScheduler edit cancellation', () => {
|
|
|
385
742
|
};
|
|
386
743
|
const onAllToolCallsComplete = vi.fn();
|
|
387
744
|
const onToolCallsUpdate = vi.fn();
|
|
388
|
-
const mockConfig = {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
getApprovalMode: () => ApprovalMode.DEFAULT,
|
|
393
|
-
getContentGeneratorConfig: () => ({
|
|
394
|
-
model: 'test-model',
|
|
395
|
-
authType: 'oauth-personal',
|
|
396
|
-
}),
|
|
397
|
-
};
|
|
745
|
+
const mockConfig = createMockConfig({
|
|
746
|
+
getToolRegistry: () => mockToolRegistry,
|
|
747
|
+
isInteractive: () => false,
|
|
748
|
+
});
|
|
398
749
|
const scheduler = new CoreToolScheduler({
|
|
399
750
|
config: mockConfig,
|
|
400
|
-
toolRegistry: mockToolRegistry,
|
|
401
751
|
onAllToolCallsComplete,
|
|
402
752
|
onToolCallsUpdate,
|
|
403
753
|
getPreferredEditor: () => 'vscode',
|
|
404
|
-
onEditorClose: vi.fn(),
|
|
405
754
|
});
|
|
406
755
|
const abortController = new AbortController();
|
|
407
756
|
const request = {
|
|
@@ -412,9 +761,7 @@ describe('CoreToolScheduler edit cancellation', () => {
|
|
|
412
761
|
prompt_id: 'prompt-id-1',
|
|
413
762
|
};
|
|
414
763
|
await scheduler.schedule([request], abortController.signal);
|
|
415
|
-
|
|
416
|
-
const awaitingCall = onToolCallsUpdate.mock.calls.find((call) => call[0][0].status === 'awaiting_approval')?.[0][0];
|
|
417
|
-
expect(awaitingCall).toBeDefined();
|
|
764
|
+
const awaitingCall = (await waitForStatus(onToolCallsUpdate, 'awaiting_approval'));
|
|
418
765
|
// Cancel the edit
|
|
419
766
|
const confirmationDetails = awaitingCall.confirmationDetails;
|
|
420
767
|
if (confirmationDetails) {
|
|
@@ -435,13 +782,15 @@ describe('CoreToolScheduler edit cancellation', () => {
|
|
|
435
782
|
describe('CoreToolScheduler YOLO mode', () => {
|
|
436
783
|
it('should execute tool requiring confirmation directly without waiting', async () => {
|
|
437
784
|
// Arrange
|
|
438
|
-
const
|
|
439
|
-
mockTool.executeFn.mockReturnValue({
|
|
785
|
+
const executeFn = vi.fn().mockResolvedValue({
|
|
440
786
|
llmContent: 'Tool executed',
|
|
441
787
|
returnDisplay: 'Tool executed',
|
|
442
788
|
});
|
|
443
|
-
|
|
444
|
-
|
|
789
|
+
const mockTool = new MockTool({
|
|
790
|
+
name: 'mockTool',
|
|
791
|
+
execute: executeFn,
|
|
792
|
+
shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
|
|
793
|
+
});
|
|
445
794
|
const declarativeTool = mockTool;
|
|
446
795
|
const mockToolRegistry = {
|
|
447
796
|
getTool: () => declarativeTool,
|
|
@@ -460,23 +809,16 @@ describe('CoreToolScheduler YOLO mode', () => {
|
|
|
460
809
|
const onAllToolCallsComplete = vi.fn();
|
|
461
810
|
const onToolCallsUpdate = vi.fn();
|
|
462
811
|
// Configure the scheduler for YOLO mode.
|
|
463
|
-
const mockConfig = {
|
|
464
|
-
|
|
465
|
-
getUsageStatisticsEnabled: () => true,
|
|
466
|
-
getDebugMode: () => false,
|
|
812
|
+
const mockConfig = createMockConfig({
|
|
813
|
+
getToolRegistry: () => mockToolRegistry,
|
|
467
814
|
getApprovalMode: () => ApprovalMode.YOLO,
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
authType: 'oauth-personal',
|
|
471
|
-
}),
|
|
472
|
-
};
|
|
815
|
+
isInteractive: () => false,
|
|
816
|
+
});
|
|
473
817
|
const scheduler = new CoreToolScheduler({
|
|
474
818
|
config: mockConfig,
|
|
475
|
-
toolRegistry: mockToolRegistry,
|
|
476
819
|
onAllToolCallsComplete,
|
|
477
820
|
onToolCallsUpdate,
|
|
478
821
|
getPreferredEditor: () => 'vscode',
|
|
479
|
-
onEditorClose: vi.fn(),
|
|
480
822
|
});
|
|
481
823
|
const abortController = new AbortController();
|
|
482
824
|
const request = {
|
|
@@ -488,9 +830,13 @@ describe('CoreToolScheduler YOLO mode', () => {
|
|
|
488
830
|
};
|
|
489
831
|
// Act
|
|
490
832
|
await scheduler.schedule([request], abortController.signal);
|
|
833
|
+
// Wait for the tool execution to complete
|
|
834
|
+
await vi.waitFor(() => {
|
|
835
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
836
|
+
});
|
|
491
837
|
// Assert
|
|
492
838
|
// 1. The tool's execute method was called directly.
|
|
493
|
-
expect(
|
|
839
|
+
expect(executeFn).toHaveBeenCalledWith({ param: 'value' });
|
|
494
840
|
// 2. The tool call status never entered 'awaiting_approval'.
|
|
495
841
|
const statusUpdates = onToolCallsUpdate.mock.calls
|
|
496
842
|
.map((call) => call[0][0]?.status)
|
|
@@ -503,7 +849,6 @@ describe('CoreToolScheduler YOLO mode', () => {
|
|
|
503
849
|
'success',
|
|
504
850
|
]);
|
|
505
851
|
// 3. The final callback indicates the tool call was successful.
|
|
506
|
-
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
507
852
|
const completedCalls = onAllToolCallsComplete.mock
|
|
508
853
|
.calls[0][0];
|
|
509
854
|
expect(completedCalls).toHaveLength(1);
|
|
@@ -520,8 +865,8 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
520
865
|
const firstCallPromise = new Promise((resolve) => {
|
|
521
866
|
resolveFirstCall = resolve;
|
|
522
867
|
});
|
|
523
|
-
const
|
|
524
|
-
mockTool
|
|
868
|
+
const executeFn = vi.fn().mockImplementation(() => firstCallPromise);
|
|
869
|
+
const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
|
|
525
870
|
const declarativeTool = mockTool;
|
|
526
871
|
const mockToolRegistry = {
|
|
527
872
|
getTool: () => declarativeTool,
|
|
@@ -538,23 +883,16 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
538
883
|
};
|
|
539
884
|
const onAllToolCallsComplete = vi.fn();
|
|
540
885
|
const onToolCallsUpdate = vi.fn();
|
|
541
|
-
const mockConfig = {
|
|
542
|
-
|
|
543
|
-
getUsageStatisticsEnabled: () => true,
|
|
544
|
-
getDebugMode: () => false,
|
|
886
|
+
const mockConfig = createMockConfig({
|
|
887
|
+
getToolRegistry: () => mockToolRegistry,
|
|
545
888
|
getApprovalMode: () => ApprovalMode.YOLO, // Use YOLO to avoid confirmation prompts
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
authType: 'oauth-personal',
|
|
549
|
-
}),
|
|
550
|
-
};
|
|
889
|
+
isInteractive: () => false,
|
|
890
|
+
});
|
|
551
891
|
const scheduler = new CoreToolScheduler({
|
|
552
892
|
config: mockConfig,
|
|
553
|
-
toolRegistry: mockToolRegistry,
|
|
554
893
|
onAllToolCallsComplete,
|
|
555
894
|
onToolCallsUpdate,
|
|
556
895
|
getPreferredEditor: () => 'vscode',
|
|
557
|
-
onEditorClose: vi.fn(),
|
|
558
896
|
});
|
|
559
897
|
const abortController = new AbortController();
|
|
560
898
|
const request1 = {
|
|
@@ -574,15 +912,11 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
574
912
|
// Schedule the first call, which will pause execution.
|
|
575
913
|
scheduler.schedule([request1], abortController.signal);
|
|
576
914
|
// Wait for the first call to be in the 'executing' state.
|
|
577
|
-
await
|
|
578
|
-
const calls = onToolCallsUpdate.mock.calls.at(-1)?.[0];
|
|
579
|
-
expect(calls?.[0]?.status).toBe('executing');
|
|
580
|
-
});
|
|
915
|
+
await waitForStatus(onToolCallsUpdate, 'executing');
|
|
581
916
|
// Schedule the second call while the first is "running".
|
|
582
917
|
const schedulePromise2 = scheduler.schedule([request2], abortController.signal);
|
|
583
918
|
// Ensure the second tool call hasn't been executed yet.
|
|
584
|
-
expect(
|
|
585
|
-
expect(mockTool.executeFn).toHaveBeenCalledWith({ a: 1 });
|
|
919
|
+
expect(executeFn).toHaveBeenCalledWith({ a: 1 });
|
|
586
920
|
// Complete the first tool call.
|
|
587
921
|
resolveFirstCall({
|
|
588
922
|
llmContent: 'First call complete',
|
|
@@ -590,14 +924,6 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
590
924
|
});
|
|
591
925
|
// Wait for the second schedule promise to resolve.
|
|
592
926
|
await schedulePromise2;
|
|
593
|
-
// Wait for the second call to be in the 'executing' state.
|
|
594
|
-
await vi.waitFor(() => {
|
|
595
|
-
const calls = onToolCallsUpdate.mock.calls.at(-1)?.[0];
|
|
596
|
-
expect(calls?.[0]?.status).toBe('executing');
|
|
597
|
-
});
|
|
598
|
-
// Now the second tool call should have been executed.
|
|
599
|
-
expect(mockTool.executeFn).toHaveBeenCalledTimes(2);
|
|
600
|
-
expect(mockTool.executeFn).toHaveBeenCalledWith({ b: 2 });
|
|
601
927
|
// Let the second call finish.
|
|
602
928
|
const secondCallResult = {
|
|
603
929
|
llmContent: 'Second call complete',
|
|
@@ -606,6 +932,11 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
606
932
|
// Since the mock is shared, we need to resolve the current promise.
|
|
607
933
|
// In a real scenario, a new promise would be created for the second call.
|
|
608
934
|
resolveFirstCall(secondCallResult);
|
|
935
|
+
await vi.waitFor(() => {
|
|
936
|
+
// Now the second tool call should have been executed.
|
|
937
|
+
expect(executeFn).toHaveBeenCalledTimes(2);
|
|
938
|
+
});
|
|
939
|
+
expect(executeFn).toHaveBeenCalledWith({ b: 2 });
|
|
609
940
|
// Wait for the second completion.
|
|
610
941
|
await vi.waitFor(() => {
|
|
611
942
|
expect(onAllToolCallsComplete).toHaveBeenCalledTimes(2);
|
|
@@ -614,8 +945,159 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
614
945
|
expect(onAllToolCallsComplete.mock.calls[0][0][0].status).toBe('success');
|
|
615
946
|
expect(onAllToolCallsComplete.mock.calls[1][0][0].status).toBe('success');
|
|
616
947
|
});
|
|
948
|
+
it('should auto-approve a tool call if it is on the allowedTools list', async () => {
|
|
949
|
+
// Arrange
|
|
950
|
+
const executeFn = vi.fn().mockResolvedValue({
|
|
951
|
+
llmContent: 'Tool executed',
|
|
952
|
+
returnDisplay: 'Tool executed',
|
|
953
|
+
});
|
|
954
|
+
const mockTool = new MockTool({
|
|
955
|
+
name: 'mockTool',
|
|
956
|
+
execute: executeFn,
|
|
957
|
+
shouldConfirmExecute: MOCK_TOOL_SHOULD_CONFIRM_EXECUTE,
|
|
958
|
+
});
|
|
959
|
+
const declarativeTool = mockTool;
|
|
960
|
+
const toolRegistry = {
|
|
961
|
+
getTool: () => declarativeTool,
|
|
962
|
+
getToolByName: () => declarativeTool,
|
|
963
|
+
getFunctionDeclarations: () => [],
|
|
964
|
+
tools: new Map(),
|
|
965
|
+
discovery: {},
|
|
966
|
+
registerTool: () => { },
|
|
967
|
+
getToolByDisplayName: () => declarativeTool,
|
|
968
|
+
getTools: () => [],
|
|
969
|
+
discoverTools: async () => { },
|
|
970
|
+
getAllTools: () => [],
|
|
971
|
+
getToolsByServer: () => [],
|
|
972
|
+
};
|
|
973
|
+
const onAllToolCallsComplete = vi.fn();
|
|
974
|
+
const onToolCallsUpdate = vi.fn();
|
|
975
|
+
// Configure the scheduler to auto-approve the specific tool call.
|
|
976
|
+
const mockConfig = createMockConfig({
|
|
977
|
+
getAllowedTools: () => ['mockTool'], // Auto-approve this tool
|
|
978
|
+
getToolRegistry: () => toolRegistry,
|
|
979
|
+
getShellExecutionConfig: () => ({
|
|
980
|
+
terminalWidth: 80,
|
|
981
|
+
terminalHeight: 24,
|
|
982
|
+
}),
|
|
983
|
+
isInteractive: () => false,
|
|
984
|
+
});
|
|
985
|
+
const scheduler = new CoreToolScheduler({
|
|
986
|
+
config: mockConfig,
|
|
987
|
+
onAllToolCallsComplete,
|
|
988
|
+
onToolCallsUpdate,
|
|
989
|
+
getPreferredEditor: () => 'vscode',
|
|
990
|
+
});
|
|
991
|
+
const abortController = new AbortController();
|
|
992
|
+
const request = {
|
|
993
|
+
callId: '1',
|
|
994
|
+
name: 'mockTool',
|
|
995
|
+
args: { param: 'value' },
|
|
996
|
+
isClientInitiated: false,
|
|
997
|
+
prompt_id: 'prompt-auto-approved',
|
|
998
|
+
};
|
|
999
|
+
// Act
|
|
1000
|
+
await scheduler.schedule([request], abortController.signal);
|
|
1001
|
+
// Wait for the tool execution to complete
|
|
1002
|
+
await vi.waitFor(() => {
|
|
1003
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
1004
|
+
});
|
|
1005
|
+
// Assert
|
|
1006
|
+
// 1. The tool's execute method was called directly.
|
|
1007
|
+
expect(executeFn).toHaveBeenCalledWith({ param: 'value' });
|
|
1008
|
+
// 2. The tool call status never entered 'awaiting_approval'.
|
|
1009
|
+
const statusUpdates = onToolCallsUpdate.mock.calls
|
|
1010
|
+
.map((call) => call[0][0]?.status)
|
|
1011
|
+
.filter(Boolean);
|
|
1012
|
+
expect(statusUpdates).not.toContain('awaiting_approval');
|
|
1013
|
+
expect(statusUpdates).toEqual([
|
|
1014
|
+
'validating',
|
|
1015
|
+
'scheduled',
|
|
1016
|
+
'executing',
|
|
1017
|
+
'success',
|
|
1018
|
+
]);
|
|
1019
|
+
// 3. The final callback indicates the tool call was successful.
|
|
1020
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
1021
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
1022
|
+
.calls[0][0];
|
|
1023
|
+
expect(completedCalls).toHaveLength(1);
|
|
1024
|
+
const completedCall = completedCalls[0];
|
|
1025
|
+
expect(completedCall.status).toBe('success');
|
|
1026
|
+
if (completedCall.status === 'success') {
|
|
1027
|
+
expect(completedCall.response.resultDisplay).toBe('Tool executed');
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
it('should require approval for a chained shell command even when prefix is allowlisted', async () => {
|
|
1031
|
+
expect(isShellInvocationAllowlisted({
|
|
1032
|
+
params: { command: 'git status && rm -rf /tmp/should-not-run' },
|
|
1033
|
+
}, ['run_shell_command(git)'])).toBe(false);
|
|
1034
|
+
const executeFn = vi.fn().mockResolvedValue({
|
|
1035
|
+
llmContent: 'Shell command executed',
|
|
1036
|
+
returnDisplay: 'Shell command executed',
|
|
1037
|
+
});
|
|
1038
|
+
const mockShellTool = new MockTool({
|
|
1039
|
+
name: 'run_shell_command',
|
|
1040
|
+
shouldConfirmExecute: (params) => Promise.resolve({
|
|
1041
|
+
type: 'exec',
|
|
1042
|
+
title: 'Confirm Shell Command',
|
|
1043
|
+
command: String(params['command'] ?? ''),
|
|
1044
|
+
rootCommand: 'git',
|
|
1045
|
+
onConfirm: async () => { },
|
|
1046
|
+
}),
|
|
1047
|
+
execute: () => executeFn({}),
|
|
1048
|
+
});
|
|
1049
|
+
const toolRegistry = {
|
|
1050
|
+
getTool: () => mockShellTool,
|
|
1051
|
+
getToolByName: () => mockShellTool,
|
|
1052
|
+
getFunctionDeclarations: () => [],
|
|
1053
|
+
tools: new Map(),
|
|
1054
|
+
discovery: {},
|
|
1055
|
+
registerTool: () => { },
|
|
1056
|
+
getToolByDisplayName: () => mockShellTool,
|
|
1057
|
+
getTools: () => [],
|
|
1058
|
+
discoverTools: async () => { },
|
|
1059
|
+
getAllTools: () => [],
|
|
1060
|
+
getToolsByServer: () => [],
|
|
1061
|
+
};
|
|
1062
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1063
|
+
const onToolCallsUpdate = vi.fn();
|
|
1064
|
+
const mockConfig = createMockConfig({
|
|
1065
|
+
getAllowedTools: () => ['run_shell_command(git)'],
|
|
1066
|
+
getShellExecutionConfig: () => ({
|
|
1067
|
+
terminalWidth: 80,
|
|
1068
|
+
terminalHeight: 24,
|
|
1069
|
+
}),
|
|
1070
|
+
getToolRegistry: () => toolRegistry,
|
|
1071
|
+
isInteractive: () => false,
|
|
1072
|
+
});
|
|
1073
|
+
const scheduler = new CoreToolScheduler({
|
|
1074
|
+
config: mockConfig,
|
|
1075
|
+
onAllToolCallsComplete,
|
|
1076
|
+
onToolCallsUpdate,
|
|
1077
|
+
getPreferredEditor: () => 'vscode',
|
|
1078
|
+
});
|
|
1079
|
+
const abortController = new AbortController();
|
|
1080
|
+
const request = {
|
|
1081
|
+
callId: 'shell-1',
|
|
1082
|
+
name: 'run_shell_command',
|
|
1083
|
+
args: { command: 'git status && rm -rf /tmp/should-not-run' },
|
|
1084
|
+
isClientInitiated: false,
|
|
1085
|
+
prompt_id: 'prompt-shell-auto-approved',
|
|
1086
|
+
};
|
|
1087
|
+
await scheduler.schedule([request], abortController.signal);
|
|
1088
|
+
const statusUpdates = onToolCallsUpdate.mock.calls
|
|
1089
|
+
.map((call) => call[0][0]?.status)
|
|
1090
|
+
.filter(Boolean);
|
|
1091
|
+
expect(statusUpdates).toContain('awaiting_approval');
|
|
1092
|
+
expect(executeFn).not.toHaveBeenCalled();
|
|
1093
|
+
expect(onAllToolCallsComplete).not.toHaveBeenCalled();
|
|
1094
|
+
}, 20000);
|
|
617
1095
|
it('should handle two synchronous calls to schedule', async () => {
|
|
618
|
-
const
|
|
1096
|
+
const executeFn = vi.fn().mockResolvedValue({
|
|
1097
|
+
llmContent: 'Tool executed',
|
|
1098
|
+
returnDisplay: 'Tool executed',
|
|
1099
|
+
});
|
|
1100
|
+
const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
|
|
619
1101
|
const declarativeTool = mockTool;
|
|
620
1102
|
const mockToolRegistry = {
|
|
621
1103
|
getTool: () => declarativeTool,
|
|
@@ -632,23 +1114,16 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
632
1114
|
};
|
|
633
1115
|
const onAllToolCallsComplete = vi.fn();
|
|
634
1116
|
const onToolCallsUpdate = vi.fn();
|
|
635
|
-
const mockConfig = {
|
|
636
|
-
|
|
637
|
-
getUsageStatisticsEnabled: () => true,
|
|
638
|
-
getDebugMode: () => false,
|
|
1117
|
+
const mockConfig = createMockConfig({
|
|
1118
|
+
getToolRegistry: () => mockToolRegistry,
|
|
639
1119
|
getApprovalMode: () => ApprovalMode.YOLO,
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
authType: 'oauth-personal',
|
|
643
|
-
}),
|
|
644
|
-
};
|
|
1120
|
+
isInteractive: () => false,
|
|
1121
|
+
});
|
|
645
1122
|
const scheduler = new CoreToolScheduler({
|
|
646
1123
|
config: mockConfig,
|
|
647
|
-
toolRegistry: mockToolRegistry,
|
|
648
1124
|
onAllToolCallsComplete,
|
|
649
1125
|
onToolCallsUpdate,
|
|
650
1126
|
getPreferredEditor: () => 'vscode',
|
|
651
|
-
onEditorClose: vi.fn(),
|
|
652
1127
|
});
|
|
653
1128
|
const abortController = new AbortController();
|
|
654
1129
|
const request1 = {
|
|
@@ -671,23 +1146,21 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
671
1146
|
// Wait for both promises to resolve.
|
|
672
1147
|
await Promise.all([schedulePromise1, schedulePromise2]);
|
|
673
1148
|
// Ensure the tool was called twice with the correct arguments.
|
|
674
|
-
expect(
|
|
675
|
-
expect(
|
|
676
|
-
expect(
|
|
1149
|
+
expect(executeFn).toHaveBeenCalledTimes(2);
|
|
1150
|
+
expect(executeFn).toHaveBeenCalledWith({ a: 1 });
|
|
1151
|
+
expect(executeFn).toHaveBeenCalledWith({ b: 2 });
|
|
677
1152
|
// Ensure completion callbacks were called twice.
|
|
678
1153
|
expect(onAllToolCallsComplete).toHaveBeenCalledTimes(2);
|
|
679
1154
|
});
|
|
680
1155
|
it('should auto-approve remaining tool calls when first tool call is approved with ProceedAlways', async () => {
|
|
681
1156
|
let approvalMode = ApprovalMode.DEFAULT;
|
|
682
|
-
const mockConfig = {
|
|
683
|
-
getSessionId: () => 'test-session-id',
|
|
684
|
-
getUsageStatisticsEnabled: () => true,
|
|
685
|
-
getDebugMode: () => false,
|
|
1157
|
+
const mockConfig = createMockConfig({
|
|
686
1158
|
getApprovalMode: () => approvalMode,
|
|
687
1159
|
setApprovalMode: (mode) => {
|
|
688
1160
|
approvalMode = mode;
|
|
689
1161
|
},
|
|
690
|
-
|
|
1162
|
+
isInteractive: () => false,
|
|
1163
|
+
});
|
|
691
1164
|
const testTool = new TestApprovalTool(mockConfig);
|
|
692
1165
|
const toolRegistry = {
|
|
693
1166
|
getTool: () => testTool,
|
|
@@ -709,12 +1182,12 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
709
1182
|
discoverTools: async () => { },
|
|
710
1183
|
discovery: {},
|
|
711
1184
|
};
|
|
1185
|
+
mockConfig.getToolRegistry = () => toolRegistry;
|
|
712
1186
|
const onAllToolCallsComplete = vi.fn();
|
|
713
1187
|
const onToolCallsUpdate = vi.fn();
|
|
714
1188
|
const pendingConfirmations = [];
|
|
715
1189
|
const scheduler = new CoreToolScheduler({
|
|
716
1190
|
config: mockConfig,
|
|
717
|
-
toolRegistry: toolRegistry,
|
|
718
1191
|
onAllToolCallsComplete,
|
|
719
1192
|
onToolCallsUpdate: (toolCalls) => {
|
|
720
1193
|
onToolCallsUpdate(toolCalls);
|
|
@@ -732,7 +1205,6 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
732
1205
|
});
|
|
733
1206
|
},
|
|
734
1207
|
getPreferredEditor: () => 'vscode',
|
|
735
|
-
onEditorClose: vi.fn(),
|
|
736
1208
|
});
|
|
737
1209
|
const abortController = new AbortController();
|
|
738
1210
|
// Schedule multiple tools that need confirmation
|
|
@@ -760,25 +1232,385 @@ describe('CoreToolScheduler request queueing', () => {
|
|
|
760
1232
|
},
|
|
761
1233
|
];
|
|
762
1234
|
await scheduler.schedule(requests, abortController.signal);
|
|
763
|
-
// Wait for
|
|
1235
|
+
// Wait for the FIRST tool to be awaiting approval
|
|
764
1236
|
await vi.waitFor(() => {
|
|
765
1237
|
const calls = onToolCallsUpdate.mock.calls.at(-1)?.[0];
|
|
1238
|
+
// With the sequential scheduler, the update includes the active call and the queue.
|
|
766
1239
|
expect(calls?.length).toBe(3);
|
|
767
|
-
expect(calls?.
|
|
1240
|
+
expect(calls?.[0].status).toBe('awaiting_approval');
|
|
1241
|
+
expect(calls?.[0].request.callId).toBe('1');
|
|
1242
|
+
// Check that the other two are in the queue (still in 'validating' state)
|
|
1243
|
+
expect(calls?.[1].status).toBe('validating');
|
|
1244
|
+
expect(calls?.[2].status).toBe('validating');
|
|
768
1245
|
});
|
|
769
|
-
expect(pendingConfirmations.length).toBe(
|
|
1246
|
+
expect(pendingConfirmations.length).toBe(1);
|
|
770
1247
|
// Approve the first tool with ProceedAlways
|
|
771
1248
|
const firstConfirmation = pendingConfirmations[0];
|
|
772
1249
|
firstConfirmation(ToolConfirmationOutcome.ProceedAlways);
|
|
773
1250
|
// Wait for all tools to be completed
|
|
774
1251
|
await vi.waitFor(() => {
|
|
775
1252
|
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
776
|
-
const completedCalls = onAllToolCallsComplete.mock.calls.at(-1)?.[0];
|
|
777
|
-
expect(completedCalls?.length).toBe(3);
|
|
778
|
-
expect(completedCalls?.every((call) => call.status === 'success')).toBe(true);
|
|
779
1253
|
});
|
|
1254
|
+
const completedCalls = onAllToolCallsComplete.mock.calls.at(-1)?.[0];
|
|
1255
|
+
expect(completedCalls?.length).toBe(3);
|
|
1256
|
+
expect(completedCalls?.every((call) => call.status === 'success')).toBe(true);
|
|
780
1257
|
// Verify approval mode was changed
|
|
781
1258
|
expect(approvalMode).toBe(ApprovalMode.AUTO_EDIT);
|
|
782
1259
|
});
|
|
783
1260
|
});
|
|
1261
|
+
describe('CoreToolScheduler Sequential Execution', () => {
|
|
1262
|
+
it('should execute tool calls in a batch sequentially', async () => {
|
|
1263
|
+
// Arrange
|
|
1264
|
+
let firstCallFinished = false;
|
|
1265
|
+
const executeFn = vi
|
|
1266
|
+
.fn()
|
|
1267
|
+
.mockImplementation(async (args) => {
|
|
1268
|
+
if (args.call === 1) {
|
|
1269
|
+
// First call, wait for a bit to simulate work
|
|
1270
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1271
|
+
firstCallFinished = true;
|
|
1272
|
+
return { llmContent: 'First call done' };
|
|
1273
|
+
}
|
|
1274
|
+
if (args.call === 2) {
|
|
1275
|
+
// Second call, should only happen after the first is finished
|
|
1276
|
+
if (!firstCallFinished) {
|
|
1277
|
+
throw new Error('Second tool call started before the first one finished!');
|
|
1278
|
+
}
|
|
1279
|
+
return { llmContent: 'Second call done' };
|
|
1280
|
+
}
|
|
1281
|
+
return { llmContent: 'default' };
|
|
1282
|
+
});
|
|
1283
|
+
const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
|
|
1284
|
+
const declarativeTool = mockTool;
|
|
1285
|
+
const mockToolRegistry = {
|
|
1286
|
+
getTool: () => declarativeTool,
|
|
1287
|
+
getToolByName: () => declarativeTool,
|
|
1288
|
+
getFunctionDeclarations: () => [],
|
|
1289
|
+
tools: new Map(),
|
|
1290
|
+
discovery: {},
|
|
1291
|
+
registerTool: () => { },
|
|
1292
|
+
getToolByDisplayName: () => declarativeTool,
|
|
1293
|
+
getTools: () => [],
|
|
1294
|
+
discoverTools: async () => { },
|
|
1295
|
+
getAllTools: () => [],
|
|
1296
|
+
getToolsByServer: () => [],
|
|
1297
|
+
};
|
|
1298
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1299
|
+
const onToolCallsUpdate = vi.fn();
|
|
1300
|
+
const mockConfig = createMockConfig({
|
|
1301
|
+
getToolRegistry: () => mockToolRegistry,
|
|
1302
|
+
getApprovalMode: () => ApprovalMode.YOLO, // Use YOLO to avoid confirmation prompts
|
|
1303
|
+
isInteractive: () => false,
|
|
1304
|
+
});
|
|
1305
|
+
const scheduler = new CoreToolScheduler({
|
|
1306
|
+
config: mockConfig,
|
|
1307
|
+
onAllToolCallsComplete,
|
|
1308
|
+
onToolCallsUpdate,
|
|
1309
|
+
getPreferredEditor: () => 'vscode',
|
|
1310
|
+
});
|
|
1311
|
+
const abortController = new AbortController();
|
|
1312
|
+
const requests = [
|
|
1313
|
+
{
|
|
1314
|
+
callId: '1',
|
|
1315
|
+
name: 'mockTool',
|
|
1316
|
+
args: { call: 1 },
|
|
1317
|
+
isClientInitiated: false,
|
|
1318
|
+
prompt_id: 'prompt-1',
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
callId: '2',
|
|
1322
|
+
name: 'mockTool',
|
|
1323
|
+
args: { call: 2 },
|
|
1324
|
+
isClientInitiated: false,
|
|
1325
|
+
prompt_id: 'prompt-1',
|
|
1326
|
+
},
|
|
1327
|
+
];
|
|
1328
|
+
// Act
|
|
1329
|
+
await scheduler.schedule(requests, abortController.signal);
|
|
1330
|
+
// Assert
|
|
1331
|
+
await vi.waitFor(() => {
|
|
1332
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
1333
|
+
});
|
|
1334
|
+
// Check that execute was called twice
|
|
1335
|
+
expect(executeFn).toHaveBeenCalledTimes(2);
|
|
1336
|
+
// Check the order of calls
|
|
1337
|
+
const calls = executeFn.mock.calls;
|
|
1338
|
+
expect(calls[0][0]).toEqual({ call: 1 });
|
|
1339
|
+
expect(calls[1][0]).toEqual({ call: 2 });
|
|
1340
|
+
// The onAllToolCallsComplete should be called once with both results
|
|
1341
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
1342
|
+
.calls[0][0];
|
|
1343
|
+
expect(completedCalls).toHaveLength(2);
|
|
1344
|
+
expect(completedCalls[0].status).toBe('success');
|
|
1345
|
+
expect(completedCalls[1].status).toBe('success');
|
|
1346
|
+
});
|
|
1347
|
+
it('should cancel subsequent tools when the signal is aborted.', async () => {
|
|
1348
|
+
// Arrange
|
|
1349
|
+
const abortController = new AbortController();
|
|
1350
|
+
let secondCallStarted = false;
|
|
1351
|
+
const executeFn = vi
|
|
1352
|
+
.fn()
|
|
1353
|
+
.mockImplementation(async (args) => {
|
|
1354
|
+
if (args.call === 1) {
|
|
1355
|
+
return { llmContent: 'First call done' };
|
|
1356
|
+
}
|
|
1357
|
+
if (args.call === 2) {
|
|
1358
|
+
secondCallStarted = true;
|
|
1359
|
+
// This call will be cancelled while it's "running".
|
|
1360
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1361
|
+
// It should not return a value because it will be cancelled.
|
|
1362
|
+
return { llmContent: 'Second call should not complete' };
|
|
1363
|
+
}
|
|
1364
|
+
if (args.call === 3) {
|
|
1365
|
+
return { llmContent: 'Third call done' };
|
|
1366
|
+
}
|
|
1367
|
+
return { llmContent: 'default' };
|
|
1368
|
+
});
|
|
1369
|
+
const mockTool = new MockTool({ name: 'mockTool', execute: executeFn });
|
|
1370
|
+
const declarativeTool = mockTool;
|
|
1371
|
+
const mockToolRegistry = {
|
|
1372
|
+
getTool: () => declarativeTool,
|
|
1373
|
+
getToolByName: () => declarativeTool,
|
|
1374
|
+
getFunctionDeclarations: () => [],
|
|
1375
|
+
tools: new Map(),
|
|
1376
|
+
discovery: {},
|
|
1377
|
+
registerTool: () => { },
|
|
1378
|
+
getToolByDisplayName: () => declarativeTool,
|
|
1379
|
+
getTools: () => [],
|
|
1380
|
+
discoverTools: async () => { },
|
|
1381
|
+
getAllTools: () => [],
|
|
1382
|
+
getToolsByServer: () => [],
|
|
1383
|
+
};
|
|
1384
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1385
|
+
const onToolCallsUpdate = vi.fn();
|
|
1386
|
+
const mockConfig = createMockConfig({
|
|
1387
|
+
getToolRegistry: () => mockToolRegistry,
|
|
1388
|
+
getApprovalMode: () => ApprovalMode.YOLO,
|
|
1389
|
+
isInteractive: () => false,
|
|
1390
|
+
});
|
|
1391
|
+
const scheduler = new CoreToolScheduler({
|
|
1392
|
+
config: mockConfig,
|
|
1393
|
+
onAllToolCallsComplete,
|
|
1394
|
+
onToolCallsUpdate,
|
|
1395
|
+
getPreferredEditor: () => 'vscode',
|
|
1396
|
+
});
|
|
1397
|
+
const requests = [
|
|
1398
|
+
{
|
|
1399
|
+
callId: '1',
|
|
1400
|
+
name: 'mockTool',
|
|
1401
|
+
args: { call: 1 },
|
|
1402
|
+
isClientInitiated: false,
|
|
1403
|
+
prompt_id: 'prompt-1',
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
callId: '2',
|
|
1407
|
+
name: 'mockTool',
|
|
1408
|
+
args: { call: 2 },
|
|
1409
|
+
isClientInitiated: false,
|
|
1410
|
+
prompt_id: 'prompt-1',
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
callId: '3',
|
|
1414
|
+
name: 'mockTool',
|
|
1415
|
+
args: { call: 3 },
|
|
1416
|
+
isClientInitiated: false,
|
|
1417
|
+
prompt_id: 'prompt-1',
|
|
1418
|
+
},
|
|
1419
|
+
];
|
|
1420
|
+
// Act
|
|
1421
|
+
const schedulePromise = scheduler.schedule(requests, abortController.signal);
|
|
1422
|
+
// Wait for the second call to start, then abort.
|
|
1423
|
+
await vi.waitFor(() => {
|
|
1424
|
+
expect(secondCallStarted).toBe(true);
|
|
1425
|
+
});
|
|
1426
|
+
abortController.abort();
|
|
1427
|
+
await schedulePromise;
|
|
1428
|
+
// Assert
|
|
1429
|
+
await vi.waitFor(() => {
|
|
1430
|
+
expect(onAllToolCallsComplete).toHaveBeenCalled();
|
|
1431
|
+
});
|
|
1432
|
+
// Check that execute was called for the first two tools only
|
|
1433
|
+
expect(executeFn).toHaveBeenCalledTimes(2);
|
|
1434
|
+
expect(executeFn).toHaveBeenCalledWith({ call: 1 });
|
|
1435
|
+
expect(executeFn).toHaveBeenCalledWith({ call: 2 });
|
|
1436
|
+
const completedCalls = onAllToolCallsComplete.mock
|
|
1437
|
+
.calls[0][0];
|
|
1438
|
+
expect(completedCalls).toHaveLength(3);
|
|
1439
|
+
const call1 = completedCalls.find((c) => c.request.callId === '1');
|
|
1440
|
+
const call2 = completedCalls.find((c) => c.request.callId === '2');
|
|
1441
|
+
const call3 = completedCalls.find((c) => c.request.callId === '3');
|
|
1442
|
+
expect(call1?.status).toBe('success');
|
|
1443
|
+
expect(call2?.status).toBe('cancelled');
|
|
1444
|
+
expect(call3?.status).toBe('cancelled');
|
|
1445
|
+
});
|
|
1446
|
+
it('should pass confirmation diff data into modifyWithEditor overrides', async () => {
|
|
1447
|
+
const modifyWithEditorSpy = vi
|
|
1448
|
+
.spyOn(modifiableToolModule, 'modifyWithEditor')
|
|
1449
|
+
.mockResolvedValue({
|
|
1450
|
+
updatedParams: { param: 'updated' },
|
|
1451
|
+
updatedDiff: 'updated diff',
|
|
1452
|
+
});
|
|
1453
|
+
const mockModifiableTool = new MockModifiableTool('mockModifiableTool');
|
|
1454
|
+
const mockToolRegistry = {
|
|
1455
|
+
getTool: () => mockModifiableTool,
|
|
1456
|
+
getToolByName: () => mockModifiableTool,
|
|
1457
|
+
getFunctionDeclarations: () => [],
|
|
1458
|
+
tools: new Map(),
|
|
1459
|
+
discovery: {},
|
|
1460
|
+
registerTool: () => { },
|
|
1461
|
+
getToolByDisplayName: () => mockModifiableTool,
|
|
1462
|
+
getTools: () => [],
|
|
1463
|
+
discoverTools: async () => { },
|
|
1464
|
+
getAllTools: () => [],
|
|
1465
|
+
getToolsByServer: () => [],
|
|
1466
|
+
};
|
|
1467
|
+
const onAllToolCallsComplete = vi.fn();
|
|
1468
|
+
const onToolCallsUpdate = vi.fn();
|
|
1469
|
+
const mockConfig = createMockConfig({
|
|
1470
|
+
getToolRegistry: () => mockToolRegistry,
|
|
1471
|
+
});
|
|
1472
|
+
const scheduler = new CoreToolScheduler({
|
|
1473
|
+
config: mockConfig,
|
|
1474
|
+
onAllToolCallsComplete,
|
|
1475
|
+
onToolCallsUpdate,
|
|
1476
|
+
getPreferredEditor: () => 'vscode',
|
|
1477
|
+
});
|
|
1478
|
+
const abortController = new AbortController();
|
|
1479
|
+
await scheduler.schedule([
|
|
1480
|
+
{
|
|
1481
|
+
callId: '1',
|
|
1482
|
+
name: 'mockModifiableTool',
|
|
1483
|
+
args: {},
|
|
1484
|
+
isClientInitiated: false,
|
|
1485
|
+
prompt_id: 'prompt-1',
|
|
1486
|
+
},
|
|
1487
|
+
], abortController.signal);
|
|
1488
|
+
const toolCall = scheduler
|
|
1489
|
+
.toolCalls[0];
|
|
1490
|
+
expect(toolCall.status).toBe('awaiting_approval');
|
|
1491
|
+
const confirmationSignal = new AbortController().signal;
|
|
1492
|
+
await scheduler.handleConfirmationResponse(toolCall.request.callId, async () => { }, ToolConfirmationOutcome.ModifyWithEditor, confirmationSignal);
|
|
1493
|
+
expect(modifyWithEditorSpy).toHaveBeenCalled();
|
|
1494
|
+
const overrides = modifyWithEditorSpy.mock.calls[modifyWithEditorSpy.mock.calls.length - 1][4];
|
|
1495
|
+
expect(overrides).toEqual({
|
|
1496
|
+
currentContent: 'originalContent',
|
|
1497
|
+
proposedContent: 'newContent',
|
|
1498
|
+
});
|
|
1499
|
+
modifyWithEditorSpy.mockRestore();
|
|
1500
|
+
});
|
|
1501
|
+
});
|
|
1502
|
+
describe('truncateAndSaveToFile', () => {
|
|
1503
|
+
const mockWriteFile = vi.mocked(fs.writeFile);
|
|
1504
|
+
const THRESHOLD = 40_000;
|
|
1505
|
+
const TRUNCATE_LINES = 1000;
|
|
1506
|
+
beforeEach(() => {
|
|
1507
|
+
vi.clearAllMocks();
|
|
1508
|
+
});
|
|
1509
|
+
it('should return content unchanged if below threshold', async () => {
|
|
1510
|
+
const content = 'Short content';
|
|
1511
|
+
const callId = 'test-call-id';
|
|
1512
|
+
const projectTempDir = '/tmp';
|
|
1513
|
+
const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1514
|
+
expect(result).toEqual({ content });
|
|
1515
|
+
expect(mockWriteFile).not.toHaveBeenCalled();
|
|
1516
|
+
});
|
|
1517
|
+
it('should truncate content by lines when content has many lines', async () => {
|
|
1518
|
+
// Create content that exceeds 100,000 character threshold with many lines
|
|
1519
|
+
const lines = Array(2000).fill('x'.repeat(100)); // 100 chars per line * 2000 lines = 200,000 chars
|
|
1520
|
+
const content = lines.join('\n');
|
|
1521
|
+
const callId = 'test-call-id';
|
|
1522
|
+
const projectTempDir = '/tmp';
|
|
1523
|
+
mockWriteFile.mockResolvedValue(undefined);
|
|
1524
|
+
const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1525
|
+
expect(result.outputFile).toBe(path.join(projectTempDir, `${callId}.output`));
|
|
1526
|
+
expect(mockWriteFile).toHaveBeenCalledWith(path.join(projectTempDir, `${callId}.output`), content);
|
|
1527
|
+
// Should contain the first and last lines with 1/5 head and 4/5 tail
|
|
1528
|
+
const head = Math.floor(TRUNCATE_LINES / 5);
|
|
1529
|
+
const beginning = lines.slice(0, head);
|
|
1530
|
+
const end = lines.slice(-(TRUNCATE_LINES - head));
|
|
1531
|
+
const expectedTruncated = beginning.join('\n') + '\n... [CONTENT TRUNCATED] ...\n' + end.join('\n');
|
|
1532
|
+
expect(result.content).toContain('Tool output was too large and has been truncated');
|
|
1533
|
+
expect(result.content).toContain('Truncated part of the output:');
|
|
1534
|
+
expect(result.content).toContain(expectedTruncated);
|
|
1535
|
+
});
|
|
1536
|
+
it('should wrap and truncate content when content has few but long lines', async () => {
|
|
1537
|
+
const content = 'a'.repeat(200_000); // A single very long line
|
|
1538
|
+
const callId = 'test-call-id';
|
|
1539
|
+
const projectTempDir = '/tmp';
|
|
1540
|
+
const wrapWidth = 120;
|
|
1541
|
+
mockWriteFile.mockResolvedValue(undefined);
|
|
1542
|
+
// Manually wrap the content to generate the expected file content
|
|
1543
|
+
const wrappedLines = [];
|
|
1544
|
+
for (let i = 0; i < content.length; i += wrapWidth) {
|
|
1545
|
+
wrappedLines.push(content.substring(i, i + wrapWidth));
|
|
1546
|
+
}
|
|
1547
|
+
const expectedFileContent = wrappedLines.join('\n');
|
|
1548
|
+
const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1549
|
+
expect(result.outputFile).toBe(path.join(projectTempDir, `${callId}.output`));
|
|
1550
|
+
// Check that the file was written with the wrapped content
|
|
1551
|
+
expect(mockWriteFile).toHaveBeenCalledWith(path.join(projectTempDir, `${callId}.output`), expectedFileContent);
|
|
1552
|
+
// Should contain the first and last lines with 1/5 head and 4/5 tail of the wrapped content
|
|
1553
|
+
const head = Math.floor(TRUNCATE_LINES / 5);
|
|
1554
|
+
const beginning = wrappedLines.slice(0, head);
|
|
1555
|
+
const end = wrappedLines.slice(-(TRUNCATE_LINES - head));
|
|
1556
|
+
const expectedTruncated = beginning.join('\n') + '\n... [CONTENT TRUNCATED] ...\n' + end.join('\n');
|
|
1557
|
+
expect(result.content).toContain('Tool output was too large and has been truncated');
|
|
1558
|
+
expect(result.content).toContain('Truncated part of the output:');
|
|
1559
|
+
expect(result.content).toContain(expectedTruncated);
|
|
1560
|
+
});
|
|
1561
|
+
it('should handle file write errors gracefully', async () => {
|
|
1562
|
+
const content = 'a'.repeat(2_000_000);
|
|
1563
|
+
const callId = 'test-call-id';
|
|
1564
|
+
const projectTempDir = '/tmp';
|
|
1565
|
+
mockWriteFile.mockRejectedValue(new Error('File write failed'));
|
|
1566
|
+
const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1567
|
+
expect(result.outputFile).toBeUndefined();
|
|
1568
|
+
expect(result.content).toContain('[Note: Could not save full output to file]');
|
|
1569
|
+
expect(mockWriteFile).toHaveBeenCalled();
|
|
1570
|
+
});
|
|
1571
|
+
it('should save to correct file path with call ID', async () => {
|
|
1572
|
+
const content = 'a'.repeat(200_000);
|
|
1573
|
+
const callId = 'unique-call-123';
|
|
1574
|
+
const projectTempDir = '/custom/temp/dir';
|
|
1575
|
+
const wrapWidth = 120;
|
|
1576
|
+
mockWriteFile.mockResolvedValue(undefined);
|
|
1577
|
+
// Manually wrap the content to generate the expected file content
|
|
1578
|
+
const wrappedLines = [];
|
|
1579
|
+
for (let i = 0; i < content.length; i += wrapWidth) {
|
|
1580
|
+
wrappedLines.push(content.substring(i, i + wrapWidth));
|
|
1581
|
+
}
|
|
1582
|
+
const expectedFileContent = wrappedLines.join('\n');
|
|
1583
|
+
const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1584
|
+
const expectedPath = path.join(projectTempDir, `${callId}.output`);
|
|
1585
|
+
expect(result.outputFile).toBe(expectedPath);
|
|
1586
|
+
expect(mockWriteFile).toHaveBeenCalledWith(expectedPath, expectedFileContent);
|
|
1587
|
+
});
|
|
1588
|
+
it('should include helpful instructions in truncated message', async () => {
|
|
1589
|
+
const content = 'a'.repeat(2_000_000);
|
|
1590
|
+
const callId = 'test-call-id';
|
|
1591
|
+
const projectTempDir = '/tmp';
|
|
1592
|
+
mockWriteFile.mockResolvedValue(undefined);
|
|
1593
|
+
const result = await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1594
|
+
expect(result.content).toContain('read_file tool with the absolute file path above');
|
|
1595
|
+
expect(result.content).toContain('read_file tool with offset=0, limit=100');
|
|
1596
|
+
expect(result.content).toContain('read_file tool with offset=N to skip N lines');
|
|
1597
|
+
expect(result.content).toContain('read_file tool with limit=M to read only M lines');
|
|
1598
|
+
});
|
|
1599
|
+
it('should sanitize callId to prevent path traversal', async () => {
|
|
1600
|
+
const content = 'a'.repeat(200_000);
|
|
1601
|
+
const callId = '../../../../../etc/passwd';
|
|
1602
|
+
const projectTempDir = '/tmp/safe_dir';
|
|
1603
|
+
const wrapWidth = 120;
|
|
1604
|
+
mockWriteFile.mockResolvedValue(undefined);
|
|
1605
|
+
// Manually wrap the content to generate the expected file content
|
|
1606
|
+
const wrappedLines = [];
|
|
1607
|
+
for (let i = 0; i < content.length; i += wrapWidth) {
|
|
1608
|
+
wrappedLines.push(content.substring(i, i + wrapWidth));
|
|
1609
|
+
}
|
|
1610
|
+
const expectedFileContent = wrappedLines.join('\n');
|
|
1611
|
+
await truncateAndSaveToFile(content, callId, projectTempDir, THRESHOLD, TRUNCATE_LINES);
|
|
1612
|
+
const expectedPath = path.join(projectTempDir, 'passwd.output');
|
|
1613
|
+
expect(mockWriteFile).toHaveBeenCalledWith(expectedPath, expectedFileContent);
|
|
1614
|
+
});
|
|
1615
|
+
});
|
|
784
1616
|
//# sourceMappingURL=coreToolScheduler.test.js.map
|