@machina.ai/cell-cli-core 1.0.21-rc4 → 1.4.0-rc1
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 +6 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/package.json +25 -11
- package/dist/src/code_assist/codeAssist.d.ts +6 -3
- package/dist/src/code_assist/codeAssist.js +12 -0
- package/dist/src/code_assist/codeAssist.js.map +1 -1
- package/dist/src/code_assist/converter.d.ts +3 -1
- package/dist/src/code_assist/converter.js +37 -5
- package/dist/src/code_assist/converter.js.map +1 -1
- package/dist/src/code_assist/converter.test.js +83 -0
- package/dist/src/code_assist/converter.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.d.ts +2 -1
- package/dist/src/code_assist/oauth2.js +85 -49
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +317 -15
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +5 -5
- package/dist/src/code_assist/server.js +1 -1
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/setup.d.ts +1 -1
- package/dist/src/code_assist/setup.js +1 -1
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/config/config.d.ts +53 -15
- package/dist/src/config/config.js +127 -47
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +151 -6
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +1 -0
- package/dist/src/config/models.js +2 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/storage.d.ts +32 -0
- package/dist/src/config/storage.js +90 -0
- package/dist/src/config/storage.js.map +1 -0
- package/dist/src/config/storage.test.js +43 -0
- package/dist/src/config/storage.test.js.map +1 -0
- package/dist/src/core/client.d.ts +21 -11
- package/dist/src/core/client.js +83 -26
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +398 -88
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +6 -6
- package/dist/src/core/contentGenerator.js +4 -3
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +14 -5
- package/dist/src/core/coreToolScheduler.js +120 -49
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +383 -72
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +48 -15
- package/dist/src/core/geminiChat.js +327 -154
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +1041 -257
- 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 +4 -2
- package/dist/src/core/logger.js +4 -3
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/logger.test.js +19 -18
- package/dist/src/core/logger.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +3 -3
- package/dist/src/core/loggingContentGenerator.js +11 -9
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.d.ts +3 -5
- package/dist/src/core/nonInteractiveToolExecutor.js +15 -123
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +116 -90
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +8 -7
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +21 -21
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/subagent.d.ts +24 -18
- package/dist/src/core/subagent.js +126 -89
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/core/subagent.test.js +51 -35
- package/dist/src/core/subagent.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +33 -8
- package/dist/src/core/turn.js +59 -14
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +349 -90
- package/dist/src/core/turn.test.js.map +1 -1
- 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/ide/constants.d.ts +1 -1
- package/dist/src/ide/constants.js +1 -1
- package/dist/src/ide/constants.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +8 -3
- package/dist/src/ide/detect-ide.js +29 -11
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +96 -52
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +18 -9
- package/dist/src/ide/ide-client.js +151 -33
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.js +147 -25
- package/dist/src/ide/ide-client.test.js.map +1 -1
- package/dist/src/ide/ide-installer.d.ts +1 -1
- package/dist/src/ide/ide-installer.js +31 -22
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +82 -22
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +12 -0
- package/dist/src/ide/ideContext.js +1 -0
- package/dist/src/ide/ideContext.js.map +1 -1
- package/dist/src/ide/process-utils.d.ts +13 -6
- package/dist/src/ide/process-utils.js +142 -35
- package/dist/src/ide/process-utils.js.map +1 -1
- package/dist/src/ide/process-utils.test.js +158 -0
- package/dist/src/ide/process-utils.test.js.map +1 -0
- package/dist/src/index.d.ts +12 -2
- package/dist/src/index.js +11 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.d.ts +3 -3
- package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-provider.d.ts +13 -13
- package/dist/src/mcp/oauth-provider.js +32 -31
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +75 -36
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.d.ts +9 -31
- package/dist/src/mcp/oauth-token-storage.js +10 -13
- package/dist/src/mcp/oauth-token-storage.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.test.js +30 -27
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
- package/dist/src/mcp/oauth-utils.d.ts +9 -1
- package/dist/src/mcp/oauth-utils.js +41 -27
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/oauth-utils.test.js +41 -1
- package/dist/src/mcp/oauth-utils.test.js.map +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.d.ts +19 -0
- package/dist/src/mcp/token-storage/base-token-storage.js +36 -0
- package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js +160 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
- package/dist/src/mcp/token-storage/file-token-storage.js +144 -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 +235 -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/keychain-token-storage.d.ts +31 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.js +190 -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 +254 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/types.d.ts +38 -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/prompts/mcp-prompts.d.ts +2 -2
- package/dist/src/prompts/prompt-registry.d.ts +1 -1
- package/dist/src/services/chatRecordingService.d.ts +6 -13
- package/dist/src/services/chatRecordingService.js +31 -19
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +64 -25
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.js +1 -1
- package/dist/src/services/fileDiscoveryService.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.test.js +3 -3
- package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
- package/dist/src/services/fileSystemService.js +1 -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 +21 -12
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +22 -19
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +3 -2
- package/dist/src/services/loopDetectionService.js +28 -4
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +23 -1
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.d.ts +8 -10
- package/dist/src/services/shellExecutionService.js +292 -135
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +277 -42
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +18 -4
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +171 -11
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +103 -11
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +31 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +75 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/constants.d.ts +9 -0
- package/dist/src/telemetry/constants.js +9 -0
- 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/index.d.ts +5 -2
- package/dist/src/telemetry/index.js +3 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +8 -2
- package/dist/src/telemetry/loggers.js +130 -2
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +105 -9
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +15 -4
- package/dist/src/telemetry/metrics.js +46 -8
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +5 -25
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/sdk.d.ts +1 -1
- package/dist/src/telemetry/sdk.js +3 -3
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/telemetry-utils.d.ts +6 -0
- package/dist/src/telemetry/telemetry-utils.js +14 -0
- package/dist/src/telemetry/telemetry-utils.js.map +1 -0
- package/dist/src/telemetry/telemetry-utils.test.d.ts +6 -0
- package/dist/src/telemetry/telemetry-utils.test.js +40 -0
- package/dist/src/telemetry/telemetry-utils.test.js.map +1 -0
- package/dist/src/telemetry/types.d.ts +61 -6
- package/dist/src/telemetry/types.js +105 -4
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +2 -2
- package/dist/src/telemetry/uiTelemetry.js +5 -5
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +20 -16
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/test-utils/config.d.ts +2 -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 +41 -0
- package/dist/src/test-utils/mock-tool.js +51 -0
- package/dist/src/test-utils/mock-tool.js.map +1 -0
- package/dist/src/test-utils/mockWorkspaceContext.d.ts +1 -1
- package/dist/src/test-utils/tools.d.ts +3 -2
- package/dist/src/test-utils/tools.js.map +1 -1
- 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 +6 -5
- package/dist/src/tools/edit.js +47 -36
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +77 -12
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +3 -2
- package/dist/src/tools/glob.js +17 -6
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +29 -4
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +3 -2
- package/dist/src/tools/grep.js +35 -15
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +26 -3
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +3 -2
- package/dist/src/tools/ls.js +12 -7
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +7 -2
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +8 -6
- package/dist/src/tools/mcp-client-manager.js +30 -5
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +20 -1
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +18 -11
- package/dist/src/tools/mcp-client.js +67 -57
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +29 -4
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +6 -4
- package/dist/src/tools/mcp-tool.js +21 -11
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +49 -12
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +4 -3
- package/dist/src/tools/memoryTool.js +15 -38
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +24 -12
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/modifiable-tool.d.ts +2 -2
- package/dist/src/tools/modifiable-tool.js +3 -3
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.test.js +4 -4
- package/dist/src/tools/modifiable-tool.test.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +3 -2
- package/dist/src/tools/read-file.js +12 -34
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +9 -6
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +3 -2
- package/dist/src/tools/read-many-files.js +35 -58
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +64 -11
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +47 -0
- package/dist/src/tools/ripGrep.js +368 -0
- package/dist/src/tools/ripGrep.js.map +1 -0
- package/dist/src/tools/ripGrep.test.d.ts +6 -0
- package/dist/src/tools/ripGrep.test.js +874 -0
- package/dist/src/tools/ripGrep.test.js.map +1 -0
- package/dist/src/tools/shell.d.ts +3 -2
- package/dist/src/tools/shell.js +30 -25
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +34 -25
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +73 -0
- package/dist/src/tools/smart-edit.js +607 -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 +405 -0
- package/dist/src/tools/smart-edit.test.js.map +1 -0
- package/dist/src/tools/tool-error.d.ts +17 -1
- package/dist/src/tools/tool-error.js +26 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +10 -4
- package/dist/src/tools/tool-registry.js +19 -7
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +86 -3
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +15 -9
- package/dist/src/tools/tools.js +12 -0
- 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 +3 -2
- package/dist/src/tools/web-fetch.js +14 -10
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +55 -16
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +4 -3
- package/dist/src/tools/web-search.js +31 -8
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.js +69 -1
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +4 -3
- package/dist/src/tools/write-file.js +14 -14
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +14 -14
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.d.ts +2 -2
- package/dist/src/utils/bfsFileSearch.js +2 -2
- 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/editCorrector.d.ts +2 -2
- package/dist/src/utils/editCorrector.js +1 -1
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +3 -3
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.js +2 -2
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +2 -2
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/environmentContext.d.ts +2 -2
- package/dist/src/utils/environmentContext.js +1 -1
- package/dist/src/utils/environmentContext.js.map +1 -1
- package/dist/src/utils/environmentContext.test.js +1 -1
- package/dist/src/utils/environmentContext.test.js.map +1 -1
- package/dist/src/utils/errorReporting.d.ts +1 -1
- package/dist/src/utils/errors.d.ts +19 -0
- package/dist/src/utils/errors.js +32 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/fetch.js +1 -1
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +23 -12
- package/dist/src/utils/fileUtils.js +160 -79
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +314 -21
- 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/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 +2 -2
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/getFolderStructure.test.js +13 -13
- package/dist/src/utils/getFolderStructure.test.js.map +1 -1
- package/dist/src/utils/getPty.d.ts +19 -0
- package/dist/src/utils/getPty.js +23 -0
- package/dist/src/utils/getPty.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.d.ts +1 -0
- package/dist/src/utils/gitIgnoreParser.js +104 -13
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +69 -3
- 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/ide-trust.d.ts +10 -0
- package/dist/src/utils/ide-trust.js +14 -0
- package/dist/src/utils/ide-trust.js.map +1 -0
- package/dist/src/utils/ignorePatterns.d.ts +103 -0
- package/dist/src/utils/ignorePatterns.js +220 -0
- package/dist/src/utils/ignorePatterns.js.map +1 -0
- package/dist/src/utils/ignorePatterns.test.d.ts +6 -0
- package/dist/src/utils/ignorePatterns.test.js +250 -0
- package/dist/src/utils/ignorePatterns.test.js.map +1 -0
- package/dist/src/utils/installationManager.d.ts +16 -0
- package/dist/src/utils/installationManager.js +50 -0
- package/dist/src/utils/installationManager.js.map +1 -0
- package/dist/src/utils/installationManager.test.d.ts +6 -0
- package/dist/src/utils/installationManager.test.js +83 -0
- package/dist/src/utils/installationManager.test.js.map +1 -0
- package/dist/src/utils/language-detection.d.ts +6 -0
- package/dist/src/utils/language-detection.js +101 -0
- package/dist/src/utils/language-detection.js.map +1 -0
- package/dist/src/utils/llm-edit-fixer.d.ts +25 -0
- package/dist/src/utils/llm-edit-fixer.js +112 -0
- package/dist/src/utils/llm-edit-fixer.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.d.ts +7 -6
- package/dist/src/utils/memoryDiscovery.js +68 -33
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +76 -20
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +2 -2
- package/dist/src/utils/memoryImportProcessor.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.test.js +2 -141
- 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 +2 -2
- package/dist/src/utils/nextSpeakerChecker.test.js +33 -0
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
- 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/pathReader.d.ts +17 -0
- package/dist/src/utils/pathReader.js +92 -0
- package/dist/src/utils/pathReader.js.map +1 -0
- package/dist/src/utils/pathReader.test.d.ts +6 -0
- package/dist/src/utils/pathReader.test.js +363 -0
- package/dist/src/utils/pathReader.test.js.map +1 -0
- package/dist/src/utils/paths.d.ts +1 -18
- package/dist/src/utils/paths.js +3 -29
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/quotaErrorDetection.d.ts +1 -1
- package/dist/src/utils/retry.test.js +4 -1
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/schemaValidator.js +4 -0
- package/dist/src/utils/schemaValidator.js.map +1 -1
- 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 +1 -1
- package/dist/src/utils/shell-utils.js +23 -29
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +7 -0
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/summarizer.d.ts +2 -2
- package/dist/src/utils/summarizer.test.js.map +1 -1
- package/dist/src/utils/systemEncoding.js +2 -2
- package/dist/src/utils/systemEncoding.js.map +1 -1
- package/dist/src/utils/systemEncoding.test.js +2 -2
- package/dist/src/utils/systemEncoding.test.js.map +1 -1
- package/dist/src/utils/tool-utils.d.ts +19 -0
- package/dist/src/utils/tool-utils.js +58 -0
- package/dist/src/utils/tool-utils.js.map +1 -0
- package/dist/src/utils/tool-utils.test.d.ts +6 -0
- package/dist/src/utils/tool-utils.test.js +61 -0
- package/dist/src/utils/tool-utils.test.js.map +1 -0
- package/dist/src/utils/userAccountManager.d.ts +20 -0
- package/dist/src/utils/userAccountManager.js +114 -0
- package/dist/src/utils/userAccountManager.js.map +1 -0
- package/dist/src/utils/userAccountManager.test.d.ts +6 -0
- package/dist/src/utils/{user_account.test.js → userAccountManager.test.js} +33 -30
- package/dist/src/utils/userAccountManager.test.js.map +1 -0
- package/dist/src/utils/workspaceContext.js +13 -7
- package/dist/src/utils/workspaceContext.js.map +1 -1
- package/dist/src/utils/workspaceContext.test.js +41 -16
- package/dist/src/utils/workspaceContext.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +27 -13
- 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/user_account.test.d.ts → config/storage.test.d.ts} +0 -0
- /package/dist/src/{utils/user_id.test.d.ts → ide/process-utils.test.d.ts} +0 -0
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
7
|
-
import { GoogleGenAI
|
|
8
|
-
import { findIndexAfterFraction, GeminiClient } from './client.js';
|
|
9
|
-
import { AuthType } from './contentGenerator.js';
|
|
6
|
+
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
7
|
+
import { GoogleGenAI } from '@google/genai';
|
|
8
|
+
import { findIndexAfterFraction, isThinkingDefault, isThinkingSupported, GeminiClient, } from './client.js';
|
|
9
|
+
import { AuthType, } from './contentGenerator.js';
|
|
10
|
+
import {} from './geminiChat.js';
|
|
10
11
|
import { Config } from '../config/config.js';
|
|
11
|
-
import { GeminiEventType, Turn } from './turn.js';
|
|
12
|
+
import { CompressionStatus, GeminiEventType, Turn, } from './turn.js';
|
|
12
13
|
import { getCoreSystemPrompt } from './prompts.js';
|
|
13
14
|
import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
|
|
14
15
|
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
|
@@ -16,13 +17,37 @@ import { setSimulate429 } from '../utils/testUtils.js';
|
|
|
16
17
|
import { tokenLimit } from './tokenLimits.js';
|
|
17
18
|
import { ideContext } from '../ide/ideContext.js';
|
|
18
19
|
import { ClearcutLogger } from '../telemetry/clearcut-logger/clearcut-logger.js';
|
|
20
|
+
// Mock fs module to prevent actual file system operations during tests
|
|
21
|
+
const mockFileSystem = new Map();
|
|
22
|
+
vi.mock('node:fs', () => {
|
|
23
|
+
const fsModule = {
|
|
24
|
+
mkdirSync: vi.fn(),
|
|
25
|
+
writeFileSync: vi.fn((path, data) => {
|
|
26
|
+
mockFileSystem.set(path, data);
|
|
27
|
+
}),
|
|
28
|
+
readFileSync: vi.fn((path) => {
|
|
29
|
+
if (mockFileSystem.has(path)) {
|
|
30
|
+
return mockFileSystem.get(path);
|
|
31
|
+
}
|
|
32
|
+
throw Object.assign(new Error('ENOENT: no such file or directory'), {
|
|
33
|
+
code: 'ENOENT',
|
|
34
|
+
});
|
|
35
|
+
}),
|
|
36
|
+
existsSync: vi.fn((path) => mockFileSystem.has(path)),
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
default: fsModule,
|
|
40
|
+
...fsModule,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
19
43
|
// --- Mocks ---
|
|
20
44
|
const mockChatCreateFn = vi.fn();
|
|
21
45
|
const mockGenerateContentFn = vi.fn();
|
|
22
46
|
const mockEmbedContentFn = vi.fn();
|
|
23
47
|
const mockTurnRunFn = vi.fn();
|
|
24
48
|
vi.mock('@google/genai');
|
|
25
|
-
vi.mock('./turn', () => {
|
|
49
|
+
vi.mock('./turn', async (importOriginal) => {
|
|
50
|
+
const actual = await importOriginal();
|
|
26
51
|
// Define a mock class that has the same shape as the real Turn
|
|
27
52
|
class MockTurn {
|
|
28
53
|
pendingToolCalls = [];
|
|
@@ -34,11 +59,8 @@ vi.mock('./turn', () => {
|
|
|
34
59
|
}
|
|
35
60
|
// Export the mock class as 'Turn'
|
|
36
61
|
return {
|
|
62
|
+
...actual,
|
|
37
63
|
Turn: MockTurn,
|
|
38
|
-
GeminiEventType: {
|
|
39
|
-
MaxSessionTurns: 'MaxSessionTurns',
|
|
40
|
-
ChatCompressed: 'ChatCompressed',
|
|
41
|
-
},
|
|
42
64
|
};
|
|
43
65
|
});
|
|
44
66
|
vi.mock('../config/config.js');
|
|
@@ -60,6 +82,18 @@ vi.mock('../telemetry/index.js', () => ({
|
|
|
60
82
|
logApiError: vi.fn(),
|
|
61
83
|
}));
|
|
62
84
|
vi.mock('../ide/ideContext.js');
|
|
85
|
+
/**
|
|
86
|
+
* Array.fromAsync ponyfill, which will be available in es 2024.
|
|
87
|
+
*
|
|
88
|
+
* Buffers an async generator into an array and returns the result.
|
|
89
|
+
*/
|
|
90
|
+
async function fromAsync(promise) {
|
|
91
|
+
const results = [];
|
|
92
|
+
for await (const result of promise) {
|
|
93
|
+
results.push(result);
|
|
94
|
+
}
|
|
95
|
+
return results;
|
|
96
|
+
}
|
|
63
97
|
describe('findIndexAfterFraction', () => {
|
|
64
98
|
const history = [
|
|
65
99
|
{ role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66
|
|
@@ -106,6 +140,33 @@ describe('findIndexAfterFraction', () => {
|
|
|
106
140
|
expect(findIndexAfterFraction(historyWithEmptyParts, 0.5)).toBe(1);
|
|
107
141
|
});
|
|
108
142
|
});
|
|
143
|
+
describe('isThinkingSupported', () => {
|
|
144
|
+
it('should return true for gemini-2.5', () => {
|
|
145
|
+
expect(isThinkingSupported('gemini-2.5')).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('should return true for gemini-2.5-pro', () => {
|
|
148
|
+
expect(isThinkingSupported('gemini-2.5-pro')).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
it('should return false for other models', () => {
|
|
151
|
+
expect(isThinkingSupported('gemini-1.5-flash')).toBe(false);
|
|
152
|
+
expect(isThinkingSupported('some-other-model')).toBe(false);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe('isThinkingDefault', () => {
|
|
156
|
+
it('should return false for gemini-2.5-flash-lite', () => {
|
|
157
|
+
expect(isThinkingDefault('gemini-2.5-flash-lite')).toBe(false);
|
|
158
|
+
});
|
|
159
|
+
it('should return true for gemini-2.5', () => {
|
|
160
|
+
expect(isThinkingDefault('gemini-2.5')).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
it('should return true for gemini-2.5-pro', () => {
|
|
163
|
+
expect(isThinkingDefault('gemini-2.5-pro')).toBe(true);
|
|
164
|
+
});
|
|
165
|
+
it('should return false for other models', () => {
|
|
166
|
+
expect(isThinkingDefault('gemini-1.5-flash')).toBe(false);
|
|
167
|
+
expect(isThinkingDefault('some-other-model')).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
109
170
|
describe('Gemini Client (client.ts)', () => {
|
|
110
171
|
let client;
|
|
111
172
|
beforeEach(async () => {
|
|
@@ -152,7 +213,7 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
152
213
|
getContentGeneratorConfig: vi
|
|
153
214
|
.fn()
|
|
154
215
|
.mockReturnValue(contentGeneratorConfig),
|
|
155
|
-
getToolRegistry: vi.fn().
|
|
216
|
+
getToolRegistry: vi.fn().mockReturnValue(mockToolRegistry),
|
|
156
217
|
getModel: vi.fn().mockReturnValue('test-model'),
|
|
157
218
|
getEmbeddingModel: vi.fn().mockReturnValue('test-embedding-model'),
|
|
158
219
|
getApiKey: vi.fn().mockReturnValue('test-key'),
|
|
@@ -178,6 +239,12 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
178
239
|
getGeminiClient: vi.fn(),
|
|
179
240
|
setFallbackMode: vi.fn(),
|
|
180
241
|
getChatCompression: vi.fn().mockReturnValue(undefined),
|
|
242
|
+
getSkipNextSpeakerCheck: vi.fn().mockReturnValue(false),
|
|
243
|
+
getUseSmartEdit: vi.fn().mockReturnValue(false),
|
|
244
|
+
getProjectRoot: vi.fn().mockReturnValue('/test/project/root'),
|
|
245
|
+
storage: {
|
|
246
|
+
getProjectTempDir: vi.fn().mockReturnValue('/test/temp'),
|
|
247
|
+
},
|
|
181
248
|
};
|
|
182
249
|
const MockedConfig = vi.mocked(Config, true);
|
|
183
250
|
MockedConfig.mockImplementation(() => mockConfigObject);
|
|
@@ -274,30 +341,6 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
274
341
|
await expect(client.generateEmbedding(texts)).rejects.toThrow('API Failure');
|
|
275
342
|
});
|
|
276
343
|
});
|
|
277
|
-
describe('generateContent', () => {
|
|
278
|
-
it('should call generateContent with the correct parameters', async () => {
|
|
279
|
-
const contents = [{ role: 'user', parts: [{ text: 'hello' }] }];
|
|
280
|
-
const generationConfig = { temperature: 0.5 };
|
|
281
|
-
const abortSignal = new AbortController().signal;
|
|
282
|
-
// Mock countTokens
|
|
283
|
-
const mockGenerator = {
|
|
284
|
-
countTokens: vi.fn().mockResolvedValue({ totalTokens: 1 }),
|
|
285
|
-
generateContent: mockGenerateContentFn,
|
|
286
|
-
};
|
|
287
|
-
client['contentGenerator'] = mockGenerator;
|
|
288
|
-
await client.generateContent(contents, generationConfig, abortSignal);
|
|
289
|
-
expect(mockGenerateContentFn).toHaveBeenCalledWith({
|
|
290
|
-
model: 'test-model',
|
|
291
|
-
config: {
|
|
292
|
-
abortSignal,
|
|
293
|
-
systemInstruction: getCoreSystemPrompt(''),
|
|
294
|
-
temperature: 0.5,
|
|
295
|
-
topP: 1,
|
|
296
|
-
},
|
|
297
|
-
contents,
|
|
298
|
-
}, 'test-session-id');
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
344
|
describe('generateJson', () => {
|
|
302
345
|
it('should call generateContent with the correct parameters', async () => {
|
|
303
346
|
const contents = [{ role: 'user', parts: [{ text: 'hello' }] }];
|
|
@@ -309,9 +352,9 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
309
352
|
generateContent: mockGenerateContentFn,
|
|
310
353
|
};
|
|
311
354
|
client['contentGenerator'] = mockGenerator;
|
|
312
|
-
await client.generateJson(contents, schema, abortSignal);
|
|
355
|
+
await client.generateJson(contents, schema, abortSignal, DEFAULT_GEMINI_FLASH_MODEL);
|
|
313
356
|
expect(mockGenerateContentFn).toHaveBeenCalledWith({
|
|
314
|
-
model:
|
|
357
|
+
model: DEFAULT_GEMINI_FLASH_MODEL,
|
|
315
358
|
config: {
|
|
316
359
|
abortSignal,
|
|
317
360
|
systemInstruction: getCoreSystemPrompt(''),
|
|
@@ -324,7 +367,9 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
324
367
|
}, 'test-session-id');
|
|
325
368
|
});
|
|
326
369
|
it('should allow overriding model and config', async () => {
|
|
327
|
-
const contents = [
|
|
370
|
+
const contents = [
|
|
371
|
+
{ role: 'user', parts: [{ text: 'hello' }] },
|
|
372
|
+
];
|
|
328
373
|
const schema = { type: 'string' };
|
|
329
374
|
const abortSignal = new AbortController().signal;
|
|
330
375
|
const customModel = 'custom-json-model';
|
|
@@ -404,6 +449,106 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
404
449
|
sendMessage: mockSendMessage,
|
|
405
450
|
};
|
|
406
451
|
});
|
|
452
|
+
function setup({ chatHistory = [
|
|
453
|
+
{ role: 'user', parts: [{ text: 'Long conversation' }] },
|
|
454
|
+
{ role: 'model', parts: [{ text: 'Long response' }] },
|
|
455
|
+
], } = {}) {
|
|
456
|
+
const mockChat = {
|
|
457
|
+
getHistory: vi.fn().mockReturnValue(chatHistory),
|
|
458
|
+
setHistory: vi.fn(),
|
|
459
|
+
sendMessage: vi.fn().mockResolvedValue({ text: 'Summary' }),
|
|
460
|
+
};
|
|
461
|
+
const mockCountTokens = vi
|
|
462
|
+
.fn()
|
|
463
|
+
.mockResolvedValueOnce({ totalTokens: 1000 })
|
|
464
|
+
.mockResolvedValueOnce({ totalTokens: 5000 });
|
|
465
|
+
const mockGenerator = {
|
|
466
|
+
countTokens: mockCountTokens,
|
|
467
|
+
};
|
|
468
|
+
client['chat'] = mockChat;
|
|
469
|
+
client['contentGenerator'] = mockGenerator;
|
|
470
|
+
client['startChat'] = vi.fn().mockResolvedValue({ ...mockChat });
|
|
471
|
+
return { client, mockChat, mockGenerator };
|
|
472
|
+
}
|
|
473
|
+
describe('when compression inflates the token count', () => {
|
|
474
|
+
it('uses the truncated history for compression');
|
|
475
|
+
it('allows compression to be forced/manual after a failure', async () => {
|
|
476
|
+
const { client, mockGenerator } = setup();
|
|
477
|
+
mockGenerator.countTokens?.mockResolvedValue({
|
|
478
|
+
totalTokens: 1000,
|
|
479
|
+
});
|
|
480
|
+
await client.tryCompressChat('prompt-id-4'); // Fails
|
|
481
|
+
const result = await client.tryCompressChat('prompt-id-4', true);
|
|
482
|
+
expect(result).toEqual({
|
|
483
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
484
|
+
newTokenCount: 1000,
|
|
485
|
+
originalTokenCount: 1000,
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
it('yields the result even if the compression inflated the tokens', async () => {
|
|
489
|
+
const { client } = setup();
|
|
490
|
+
const result = await client.tryCompressChat('prompt-id-4', true);
|
|
491
|
+
expect(result).toEqual({
|
|
492
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
493
|
+
newTokenCount: 5000,
|
|
494
|
+
originalTokenCount: 1000,
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
it('does not manipulate the source chat', async () => {
|
|
498
|
+
const { client, mockChat } = setup();
|
|
499
|
+
await client.tryCompressChat('prompt-id-4', true);
|
|
500
|
+
expect(client['chat']).toBe(mockChat); // a new chat session was not created
|
|
501
|
+
});
|
|
502
|
+
it('restores the history back to the original', async () => {
|
|
503
|
+
vi.mocked(tokenLimit).mockReturnValue(1000);
|
|
504
|
+
mockCountTokens.mockResolvedValue({
|
|
505
|
+
totalTokens: 999,
|
|
506
|
+
});
|
|
507
|
+
const originalHistory = [
|
|
508
|
+
{ role: 'user', parts: [{ text: 'what is your wisdom?' }] },
|
|
509
|
+
{ role: 'model', parts: [{ text: 'some wisdom' }] },
|
|
510
|
+
{ role: 'user', parts: [{ text: 'ahh that is a good a wisdom' }] },
|
|
511
|
+
];
|
|
512
|
+
const { client } = setup({
|
|
513
|
+
chatHistory: originalHistory,
|
|
514
|
+
});
|
|
515
|
+
const { compressionStatus } = await client.tryCompressChat('prompt-id-4');
|
|
516
|
+
expect(compressionStatus).toBe(CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT);
|
|
517
|
+
expect(client['chat']?.setHistory).toHaveBeenCalledWith(originalHistory);
|
|
518
|
+
});
|
|
519
|
+
it('will not attempt to compress context after a failure', async () => {
|
|
520
|
+
const { client, mockGenerator } = setup();
|
|
521
|
+
await client.tryCompressChat('prompt-id-4');
|
|
522
|
+
const result = await client.tryCompressChat('prompt-id-5');
|
|
523
|
+
// it counts tokens for {original, compressed} and then never again
|
|
524
|
+
expect(mockGenerator.countTokens).toHaveBeenCalledTimes(2);
|
|
525
|
+
expect(result).toEqual({
|
|
526
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
527
|
+
newTokenCount: 0,
|
|
528
|
+
originalTokenCount: 0,
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
it('attempts to compress with a maxOutputTokens set to the original token count', async () => {
|
|
533
|
+
vi.mocked(tokenLimit).mockReturnValue(1000);
|
|
534
|
+
mockCountTokens.mockResolvedValue({
|
|
535
|
+
totalTokens: 999,
|
|
536
|
+
});
|
|
537
|
+
mockGetHistory.mockReturnValue([
|
|
538
|
+
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
539
|
+
]);
|
|
540
|
+
// Mock the summary response from the chat
|
|
541
|
+
mockSendMessage.mockResolvedValue({
|
|
542
|
+
role: 'model',
|
|
543
|
+
parts: [{ text: 'This is a summary.' }],
|
|
544
|
+
});
|
|
545
|
+
await client.tryCompressChat('prompt-id-2', true);
|
|
546
|
+
expect(mockSendMessage).toHaveBeenCalledWith(expect.objectContaining({
|
|
547
|
+
config: expect.objectContaining({
|
|
548
|
+
maxOutputTokens: 999,
|
|
549
|
+
}),
|
|
550
|
+
}), 'prompt-id-2');
|
|
551
|
+
});
|
|
407
552
|
it('should not trigger summarization if token count is below threshold', async () => {
|
|
408
553
|
const MOCKED_TOKEN_LIMIT = 1000;
|
|
409
554
|
vi.mocked(tokenLimit).mockReturnValue(MOCKED_TOKEN_LIMIT);
|
|
@@ -417,7 +562,11 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
417
562
|
const result = await client.tryCompressChat('prompt-id-2');
|
|
418
563
|
const newChat = client.getChat();
|
|
419
564
|
expect(tokenLimit).toHaveBeenCalled();
|
|
420
|
-
expect(result).
|
|
565
|
+
expect(result).toEqual({
|
|
566
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
567
|
+
newTokenCount: 699,
|
|
568
|
+
originalTokenCount: 699,
|
|
569
|
+
});
|
|
421
570
|
expect(newChat).toBe(initialChat);
|
|
422
571
|
});
|
|
423
572
|
it('logs a telemetry event when compressing', async () => {
|
|
@@ -474,6 +623,7 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
474
623
|
expect(mockSendMessage).toHaveBeenCalled();
|
|
475
624
|
// Assert that summarization happened and returned the correct stats
|
|
476
625
|
expect(result).toEqual({
|
|
626
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
477
627
|
originalTokenCount,
|
|
478
628
|
newTokenCount,
|
|
479
629
|
});
|
|
@@ -518,6 +668,7 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
518
668
|
expect(mockSendMessage).toHaveBeenCalled();
|
|
519
669
|
// Assert that summarization happened and returned the correct stats
|
|
520
670
|
expect(result).toEqual({
|
|
671
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
521
672
|
originalTokenCount,
|
|
522
673
|
newTokenCount,
|
|
523
674
|
});
|
|
@@ -549,14 +700,129 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
549
700
|
const newChat = client.getChat();
|
|
550
701
|
expect(mockSendMessage).toHaveBeenCalled();
|
|
551
702
|
expect(result).toEqual({
|
|
703
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
552
704
|
originalTokenCount,
|
|
553
705
|
newTokenCount,
|
|
554
706
|
});
|
|
555
707
|
// Assert that the chat was reset
|
|
556
708
|
expect(newChat).not.toBe(initialChat);
|
|
557
709
|
});
|
|
710
|
+
it('should use current model from config for token counting after sendMessage', async () => {
|
|
711
|
+
const initialModel = client['config'].getModel();
|
|
712
|
+
const mockCountTokens = vi
|
|
713
|
+
.fn()
|
|
714
|
+
.mockResolvedValueOnce({ totalTokens: 100000 })
|
|
715
|
+
.mockResolvedValueOnce({ totalTokens: 5000 });
|
|
716
|
+
const mockSendMessage = vi.fn().mockResolvedValue({ text: 'Summary' });
|
|
717
|
+
const mockChatHistory = [
|
|
718
|
+
{ role: 'user', parts: [{ text: 'Long conversation' }] },
|
|
719
|
+
{ role: 'model', parts: [{ text: 'Long response' }] },
|
|
720
|
+
];
|
|
721
|
+
const mockChat = {
|
|
722
|
+
getHistory: vi.fn().mockReturnValue(mockChatHistory),
|
|
723
|
+
setHistory: vi.fn(),
|
|
724
|
+
sendMessage: mockSendMessage,
|
|
725
|
+
};
|
|
726
|
+
const mockGenerator = {
|
|
727
|
+
countTokens: mockCountTokens,
|
|
728
|
+
};
|
|
729
|
+
// mock the model has been changed between calls of `countTokens`
|
|
730
|
+
const firstCurrentModel = initialModel + '-changed-1';
|
|
731
|
+
const secondCurrentModel = initialModel + '-changed-2';
|
|
732
|
+
vi.spyOn(client['config'], 'getModel')
|
|
733
|
+
.mockReturnValueOnce(firstCurrentModel)
|
|
734
|
+
.mockReturnValueOnce(secondCurrentModel);
|
|
735
|
+
client['chat'] = mockChat;
|
|
736
|
+
client['contentGenerator'] = mockGenerator;
|
|
737
|
+
client['startChat'] = vi.fn().mockResolvedValue(mockChat);
|
|
738
|
+
const result = await client.tryCompressChat('prompt-id-4', true);
|
|
739
|
+
expect(mockCountTokens).toHaveBeenCalledTimes(2);
|
|
740
|
+
expect(mockCountTokens).toHaveBeenNthCalledWith(1, {
|
|
741
|
+
model: firstCurrentModel,
|
|
742
|
+
contents: mockChatHistory,
|
|
743
|
+
});
|
|
744
|
+
expect(mockCountTokens).toHaveBeenNthCalledWith(2, {
|
|
745
|
+
model: secondCurrentModel,
|
|
746
|
+
contents: expect.any(Array),
|
|
747
|
+
});
|
|
748
|
+
expect(result).toEqual({
|
|
749
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
750
|
+
originalTokenCount: 100000,
|
|
751
|
+
newTokenCount: 5000,
|
|
752
|
+
});
|
|
753
|
+
});
|
|
558
754
|
});
|
|
559
755
|
describe('sendMessageStream', () => {
|
|
756
|
+
it('emits a compression event when the context was automatically compressed', async () => {
|
|
757
|
+
// Arrange
|
|
758
|
+
const mockStream = (async function* () {
|
|
759
|
+
yield { type: 'content', value: 'Hello' };
|
|
760
|
+
})();
|
|
761
|
+
mockTurnRunFn.mockReturnValue(mockStream);
|
|
762
|
+
const mockChat = {
|
|
763
|
+
addHistory: vi.fn(),
|
|
764
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
765
|
+
};
|
|
766
|
+
client['chat'] = mockChat;
|
|
767
|
+
const mockGenerator = {
|
|
768
|
+
countTokens: vi.fn().mockResolvedValue({ totalTokens: 0 }),
|
|
769
|
+
generateContent: mockGenerateContentFn,
|
|
770
|
+
};
|
|
771
|
+
client['contentGenerator'] = mockGenerator;
|
|
772
|
+
const compressionInfo = {
|
|
773
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
774
|
+
originalTokenCount: 1000,
|
|
775
|
+
newTokenCount: 500,
|
|
776
|
+
};
|
|
777
|
+
vi.spyOn(client, 'tryCompressChat').mockResolvedValueOnce(compressionInfo);
|
|
778
|
+
// Act
|
|
779
|
+
const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-1');
|
|
780
|
+
const events = await fromAsync(stream);
|
|
781
|
+
// Assert
|
|
782
|
+
expect(events).toContainEqual({
|
|
783
|
+
type: GeminiEventType.ChatCompressed,
|
|
784
|
+
value: compressionInfo,
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
it.each([
|
|
788
|
+
{
|
|
789
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
790
|
+
},
|
|
791
|
+
{ compressionStatus: CompressionStatus.NOOP },
|
|
792
|
+
{
|
|
793
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_TOKEN_COUNT_ERROR,
|
|
794
|
+
},
|
|
795
|
+
])('does not emit a compression event when the status is $compressionStatus', async ({ compressionStatus }) => {
|
|
796
|
+
// Arrange
|
|
797
|
+
const mockStream = (async function* () {
|
|
798
|
+
yield { type: 'content', value: 'Hello' };
|
|
799
|
+
})();
|
|
800
|
+
mockTurnRunFn.mockReturnValue(mockStream);
|
|
801
|
+
const mockChat = {
|
|
802
|
+
addHistory: vi.fn(),
|
|
803
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
804
|
+
};
|
|
805
|
+
client['chat'] = mockChat;
|
|
806
|
+
const mockGenerator = {
|
|
807
|
+
countTokens: vi.fn().mockResolvedValue({ totalTokens: 0 }),
|
|
808
|
+
generateContent: mockGenerateContentFn,
|
|
809
|
+
};
|
|
810
|
+
client['contentGenerator'] = mockGenerator;
|
|
811
|
+
const compressionInfo = {
|
|
812
|
+
compressionStatus,
|
|
813
|
+
originalTokenCount: 1000,
|
|
814
|
+
newTokenCount: 500,
|
|
815
|
+
};
|
|
816
|
+
vi.spyOn(client, 'tryCompressChat').mockResolvedValueOnce(compressionInfo);
|
|
817
|
+
// Act
|
|
818
|
+
const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-1');
|
|
819
|
+
const events = await fromAsync(stream);
|
|
820
|
+
// Assert
|
|
821
|
+
expect(events).not.toContainEqual({
|
|
822
|
+
type: GeminiEventType.ChatCompressed,
|
|
823
|
+
value: expect.anything(),
|
|
824
|
+
});
|
|
825
|
+
});
|
|
560
826
|
it('should include editor context when ideMode is enabled', async () => {
|
|
561
827
|
// Arrange
|
|
562
828
|
vi.mocked(ideContext.getIdeContext).mockReturnValue({
|
|
@@ -976,7 +1242,11 @@ ${JSON.stringify({
|
|
|
976
1242
|
})();
|
|
977
1243
|
beforeEach(() => {
|
|
978
1244
|
client['forceFullIdeContext'] = false; // Reset before each delta test
|
|
979
|
-
vi.spyOn(client, 'tryCompressChat').mockResolvedValue(
|
|
1245
|
+
vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
|
|
1246
|
+
originalTokenCount: 0,
|
|
1247
|
+
newTokenCount: 0,
|
|
1248
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
1249
|
+
});
|
|
980
1250
|
vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
|
|
981
1251
|
mockTurnRunFn.mockReturnValue(mockStream);
|
|
982
1252
|
const mockChat = {
|
|
@@ -1189,7 +1459,11 @@ ${JSON.stringify({
|
|
|
1189
1459
|
describe('IDE context with pending tool calls', () => {
|
|
1190
1460
|
let mockChat;
|
|
1191
1461
|
beforeEach(() => {
|
|
1192
|
-
vi.spyOn(client, 'tryCompressChat').mockResolvedValue(
|
|
1462
|
+
vi.spyOn(client, 'tryCompressChat').mockResolvedValue({
|
|
1463
|
+
originalTokenCount: 0,
|
|
1464
|
+
newTokenCount: 0,
|
|
1465
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
1466
|
+
});
|
|
1193
1467
|
const mockStream = (async function* () {
|
|
1194
1468
|
yield { type: 'content', value: 'response' };
|
|
1195
1469
|
})();
|
|
@@ -1452,8 +1726,89 @@ ${JSON.stringify({
|
|
|
1452
1726
|
expect(JSON.stringify(finalCall)).toContain('fileC.ts');
|
|
1453
1727
|
});
|
|
1454
1728
|
});
|
|
1729
|
+
it('should not call checkNextSpeaker when turn.run() yields an error', async () => {
|
|
1730
|
+
// Arrange
|
|
1731
|
+
const { checkNextSpeaker } = await import('../utils/nextSpeakerChecker.js');
|
|
1732
|
+
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
|
|
1733
|
+
const mockStream = (async function* () {
|
|
1734
|
+
yield {
|
|
1735
|
+
type: GeminiEventType.Error,
|
|
1736
|
+
value: { error: { message: 'test error' } },
|
|
1737
|
+
};
|
|
1738
|
+
})();
|
|
1739
|
+
mockTurnRunFn.mockReturnValue(mockStream);
|
|
1740
|
+
const mockChat = {
|
|
1741
|
+
addHistory: vi.fn(),
|
|
1742
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
1743
|
+
};
|
|
1744
|
+
client['chat'] = mockChat;
|
|
1745
|
+
const mockGenerator = {
|
|
1746
|
+
countTokens: vi.fn().mockResolvedValue({ totalTokens: 0 }),
|
|
1747
|
+
generateContent: mockGenerateContentFn,
|
|
1748
|
+
};
|
|
1749
|
+
client['contentGenerator'] = mockGenerator;
|
|
1750
|
+
// Act
|
|
1751
|
+
const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-error');
|
|
1752
|
+
for await (const _ of stream) {
|
|
1753
|
+
// consume stream
|
|
1754
|
+
}
|
|
1755
|
+
// Assert
|
|
1756
|
+
expect(mockCheckNextSpeaker).not.toHaveBeenCalled();
|
|
1757
|
+
});
|
|
1758
|
+
it('should not call checkNextSpeaker when turn.run() yields a value then an error', async () => {
|
|
1759
|
+
// Arrange
|
|
1760
|
+
const { checkNextSpeaker } = await import('../utils/nextSpeakerChecker.js');
|
|
1761
|
+
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
|
|
1762
|
+
const mockStream = (async function* () {
|
|
1763
|
+
yield { type: GeminiEventType.Content, value: 'some content' };
|
|
1764
|
+
yield {
|
|
1765
|
+
type: GeminiEventType.Error,
|
|
1766
|
+
value: { error: { message: 'test error' } },
|
|
1767
|
+
};
|
|
1768
|
+
})();
|
|
1769
|
+
mockTurnRunFn.mockReturnValue(mockStream);
|
|
1770
|
+
const mockChat = {
|
|
1771
|
+
addHistory: vi.fn(),
|
|
1772
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
1773
|
+
};
|
|
1774
|
+
client['chat'] = mockChat;
|
|
1775
|
+
const mockGenerator = {
|
|
1776
|
+
countTokens: vi.fn().mockResolvedValue({ totalTokens: 0 }),
|
|
1777
|
+
generateContent: mockGenerateContentFn,
|
|
1778
|
+
};
|
|
1779
|
+
client['contentGenerator'] = mockGenerator;
|
|
1780
|
+
// Act
|
|
1781
|
+
const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-id-error');
|
|
1782
|
+
for await (const _ of stream) {
|
|
1783
|
+
// consume stream
|
|
1784
|
+
}
|
|
1785
|
+
// Assert
|
|
1786
|
+
expect(mockCheckNextSpeaker).not.toHaveBeenCalled();
|
|
1787
|
+
});
|
|
1455
1788
|
});
|
|
1456
1789
|
describe('generateContent', () => {
|
|
1790
|
+
it('should call generateContent with the correct parameters', async () => {
|
|
1791
|
+
const contents = [{ role: 'user', parts: [{ text: 'hello' }] }];
|
|
1792
|
+
const generationConfig = { temperature: 0.5 };
|
|
1793
|
+
const abortSignal = new AbortController().signal;
|
|
1794
|
+
// Mock countTokens
|
|
1795
|
+
const mockGenerator = {
|
|
1796
|
+
countTokens: vi.fn().mockResolvedValue({ totalTokens: 1 }),
|
|
1797
|
+
generateContent: mockGenerateContentFn,
|
|
1798
|
+
};
|
|
1799
|
+
client['contentGenerator'] = mockGenerator;
|
|
1800
|
+
await client.generateContent(contents, generationConfig, abortSignal, DEFAULT_GEMINI_FLASH_MODEL);
|
|
1801
|
+
expect(mockGenerateContentFn).toHaveBeenCalledWith({
|
|
1802
|
+
model: DEFAULT_GEMINI_FLASH_MODEL,
|
|
1803
|
+
config: {
|
|
1804
|
+
abortSignal,
|
|
1805
|
+
systemInstruction: getCoreSystemPrompt(''),
|
|
1806
|
+
temperature: 0.5,
|
|
1807
|
+
topP: 1,
|
|
1808
|
+
},
|
|
1809
|
+
contents,
|
|
1810
|
+
}, 'test-session-id');
|
|
1811
|
+
});
|
|
1457
1812
|
it('should use current model from config for content generation', async () => {
|
|
1458
1813
|
const initialModel = client['config'].getModel();
|
|
1459
1814
|
const contents = [{ role: 'user', parts: [{ text: 'test' }] }];
|
|
@@ -1464,64 +1819,19 @@ ${JSON.stringify({
|
|
|
1464
1819
|
generateContent: mockGenerateContentFn,
|
|
1465
1820
|
};
|
|
1466
1821
|
client['contentGenerator'] = mockGenerator;
|
|
1467
|
-
await client.generateContent(contents, {}, new AbortController().signal);
|
|
1822
|
+
await client.generateContent(contents, {}, new AbortController().signal, DEFAULT_GEMINI_FLASH_MODEL);
|
|
1468
1823
|
expect(mockGenerateContentFn).not.toHaveBeenCalledWith({
|
|
1469
1824
|
model: initialModel,
|
|
1470
1825
|
config: expect.any(Object),
|
|
1471
1826
|
contents,
|
|
1472
1827
|
});
|
|
1473
1828
|
expect(mockGenerateContentFn).toHaveBeenCalledWith({
|
|
1474
|
-
model:
|
|
1829
|
+
model: DEFAULT_GEMINI_FLASH_MODEL,
|
|
1475
1830
|
config: expect.any(Object),
|
|
1476
1831
|
contents,
|
|
1477
1832
|
}, 'test-session-id');
|
|
1478
1833
|
});
|
|
1479
1834
|
});
|
|
1480
|
-
describe('tryCompressChat', () => {
|
|
1481
|
-
it('should use current model from config for token counting after sendMessage', async () => {
|
|
1482
|
-
const initialModel = client['config'].getModel();
|
|
1483
|
-
const mockCountTokens = vi
|
|
1484
|
-
.fn()
|
|
1485
|
-
.mockResolvedValueOnce({ totalTokens: 100000 })
|
|
1486
|
-
.mockResolvedValueOnce({ totalTokens: 5000 });
|
|
1487
|
-
const mockSendMessage = vi.fn().mockResolvedValue({ text: 'Summary' });
|
|
1488
|
-
const mockChatHistory = [
|
|
1489
|
-
{ role: 'user', parts: [{ text: 'Long conversation' }] },
|
|
1490
|
-
{ role: 'model', parts: [{ text: 'Long response' }] },
|
|
1491
|
-
];
|
|
1492
|
-
const mockChat = {
|
|
1493
|
-
getHistory: vi.fn().mockReturnValue(mockChatHistory),
|
|
1494
|
-
setHistory: vi.fn(),
|
|
1495
|
-
sendMessage: mockSendMessage,
|
|
1496
|
-
};
|
|
1497
|
-
const mockGenerator = {
|
|
1498
|
-
countTokens: mockCountTokens,
|
|
1499
|
-
};
|
|
1500
|
-
// mock the model has been changed between calls of `countTokens`
|
|
1501
|
-
const firstCurrentModel = initialModel + '-changed-1';
|
|
1502
|
-
const secondCurrentModel = initialModel + '-changed-2';
|
|
1503
|
-
vi.spyOn(client['config'], 'getModel')
|
|
1504
|
-
.mockReturnValueOnce(firstCurrentModel)
|
|
1505
|
-
.mockReturnValueOnce(secondCurrentModel);
|
|
1506
|
-
client['chat'] = mockChat;
|
|
1507
|
-
client['contentGenerator'] = mockGenerator;
|
|
1508
|
-
client['startChat'] = vi.fn().mockResolvedValue(mockChat);
|
|
1509
|
-
const result = await client.tryCompressChat('prompt-id-4', true);
|
|
1510
|
-
expect(mockCountTokens).toHaveBeenCalledTimes(2);
|
|
1511
|
-
expect(mockCountTokens).toHaveBeenNthCalledWith(1, {
|
|
1512
|
-
model: firstCurrentModel,
|
|
1513
|
-
contents: mockChatHistory,
|
|
1514
|
-
});
|
|
1515
|
-
expect(mockCountTokens).toHaveBeenNthCalledWith(2, {
|
|
1516
|
-
model: secondCurrentModel,
|
|
1517
|
-
contents: expect.any(Array),
|
|
1518
|
-
});
|
|
1519
|
-
expect(result).toEqual({
|
|
1520
|
-
originalTokenCount: 100000,
|
|
1521
|
-
newTokenCount: 5000,
|
|
1522
|
-
});
|
|
1523
|
-
});
|
|
1524
|
-
});
|
|
1525
1835
|
describe('handleFlashFallback', () => {
|
|
1526
1836
|
it('should use current model from config when checking for fallback', async () => {
|
|
1527
1837
|
const initialModel = client['config'].getModel();
|