@machina.ai/cell-cli-core 1.11.0-rc1 → 1.13.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 +5 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/package.json +9 -3
- package/dist/src/agents/executor.d.ts +19 -0
- package/dist/src/agents/executor.js +226 -32
- package/dist/src/agents/executor.js.map +1 -1
- package/dist/src/agents/executor.test.js +335 -9
- package/dist/src/agents/executor.test.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js +2 -4
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
- package/dist/src/agents/types.d.ts +2 -1
- package/dist/src/agents/types.js +1 -0
- package/dist/src/agents/types.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 +49 -0
- package/dist/src/code_assist/experiments/client_metadata.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/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.js +5 -4
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
- package/dist/src/code_assist/oauth-credential-storage.test.js +15 -3
- package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.d.ts +2 -2
- package/dist/src/code_assist/oauth2.js +53 -41
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +65 -33
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +6 -4
- package/dist/src/code_assist/server.js +11 -0
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +17 -0
- 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.map +1 -1
- package/dist/src/code_assist/types.d.ts +1 -1
- 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 +72 -24
- package/dist/src/config/config.js +168 -55
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +59 -23
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +1 -1
- package/dist/src/config/models.js +2 -2
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/storage.d.ts +3 -0
- package/dist/src/config/storage.js +20 -0
- package/dist/src/config/storage.js.map +1 -1
- 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/client.d.ts +2 -11
- package/dist/src/core/client.js +28 -168
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +107 -409
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.js +64 -59
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +38 -4
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +7 -8
- package/dist/src/core/coreToolScheduler.js +316 -187
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +240 -10
- 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 +2 -0
- package/dist/src/core/geminiChat.js +6 -2
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +15 -3
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/logger.js +10 -9
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +1 -0
- package/dist/src/core/loggingContentGenerator.js +113 -33
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.js +5 -4
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/prompts.js +104 -55
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +30 -108
- 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/fallback/handler.js +2 -0
- package/dist/src/fallback/handler.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/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/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 +35 -0
- package/dist/src/hooks/types.test.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +14 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.d.ts +2 -0
- 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/mcpLauncher.d.ts +26 -0
- package/dist/src/mcp/mcpLauncher.js +238 -0
- package/dist/src/mcp/mcpLauncher.js.map +1 -0
- package/dist/src/mcp/oauth-provider.d.ts +8 -5
- package/dist/src/mcp/oauth-provider.js +120 -36
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +191 -2
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.js +5 -4
- package/dist/src/mcp/oauth-token-storage.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.test.js +17 -11
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
- package/dist/src/mcp/oauth-utils.d.ts +7 -0
- package/dist/src/mcp/oauth-utils.js +19 -0
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/oauth-utils.test.js +32 -0
- package/dist/src/mcp/oauth-utils.test.js.map +1 -1
- package/dist/src/mcp/sa-impersonation-provider.d.ts +0 -6
- package/dist/src/mcp/sa-impersonation-provider.js +6 -23
- package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.test.js +75 -84
- package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.js +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.test.js +7 -5
- package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -1
- package/dist/src/mcp/token-storage/hybrid-token-storage.js +1 -1
- package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -1
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +2 -2
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -1
- package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +6 -2
- package/dist/src/mcp/token-storage/keychain-token-storage.js +63 -7
- package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js +54 -3
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -1
- package/dist/src/mcp/token-storage/types.d.ts +6 -0
- package/dist/src/mcp/token-storage/types.js.map +1 -1
- package/dist/src/policy/config.d.ts +31 -0
- package/dist/src/policy/config.js +197 -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 +404 -0
- package/dist/src/policy/config.test.js.map +1 -0
- package/dist/src/policy/index.d.ts +2 -0
- package/dist/src/policy/index.js +2 -0
- package/dist/src/policy/index.js.map +1 -1
- package/dist/src/policy/policies/read-only.toml +56 -0
- package/dist/src/policy/policies/write.toml +63 -0
- package/dist/src/policy/policies/yolo.toml +31 -0
- package/dist/src/policy/policy-engine.js +4 -0
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/toml-loader.d.ts +46 -0
- package/dist/src/policy/toml-loader.js +314 -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 +522 -0
- package/dist/src/policy/toml-loader.test.js.map +1 -0
- package/dist/src/policy/types.d.ts +18 -0
- package/dist/src/policy/types.js +6 -0
- package/dist/src/policy/types.js.map +1 -1
- 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 +209 -0
- package/dist/src/services/chatCompressionService.test.js.map +1 -0
- package/dist/src/services/chatRecordingService.js +9 -8
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.d.ts +2 -14
- package/dist/src/services/fileDiscoveryService.js +19 -55
- package/dist/src/services/fileDiscoveryService.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.test.js +91 -11
- package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +1 -1
- package/dist/src/services/loopDetectionService.js +26 -13
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +119 -11
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +22 -6
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +32 -6
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +4 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +84 -33
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +40 -61
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +4 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +6 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/gcp-exporters.js +0 -1
- package/dist/src/telemetry/gcp-exporters.js.map +1 -1
- package/dist/src/telemetry/gcp-exporters.test.js +1 -1
- package/dist/src/telemetry/gcp-exporters.test.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +2 -1
- package/dist/src/telemetry/index.js +3 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +2 -1
- package/dist/src/telemetry/loggers.js +37 -26
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +199 -44
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +55 -6
- package/dist/src/telemetry/metrics.js +89 -1
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +172 -213
- package/dist/src/telemetry/metrics.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.test.js +29 -28
- package/dist/src/telemetry/telemetry-utils.test.js.map +1 -1
- 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 +64 -28
- package/dist/src/telemetry/types.js +163 -55
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.js +6 -6
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +88 -66
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/tools/edit.d.ts +3 -2
- package/dist/src/tools/edit.js +16 -12
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +78 -1
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.js +9 -13
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +203 -199
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.js +2 -2
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.js +7 -13
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +2 -9
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +49 -4
- package/dist/src/tools/mcp-client-manager.js +209 -23
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +130 -33
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +5 -1
- package/dist/src/tools/mcp-client.js +72 -92
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +65 -6
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +4 -2
- package/dist/src/tools/mcp-tool.js +14 -10
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +5 -3
- package/dist/src/tools/memoryTool.js +10 -8
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.js +3 -2
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/read-file.js +7 -3
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +25 -2
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.js +8 -29
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/shell.d.ts +6 -4
- package/dist/src/tools/shell.js +23 -16
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +8 -1
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +3 -2
- package/dist/src/tools/smart-edit.js +23 -12
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/smart-edit.test.js +62 -1
- package/dist/src/tools/smart-edit.test.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +6 -19
- package/dist/src/tools/tool-registry.js +11 -47
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +2 -24
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +8 -1
- package/dist/src/tools/tools.js +32 -18
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.js +4 -18
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +3 -3
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +2 -1
- package/dist/src/tools/write-file.js +7 -7
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +1 -1
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +2 -1
- package/dist/src/tools/write-todos.js +5 -2
- package/dist/src/tools/write-todos.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/environmentContext.d.ts +2 -1
- package/dist/src/utils/environmentContext.js +18 -0
- package/dist/src/utils/environmentContext.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/errors.d.ts +3 -0
- package/dist/src/utils/errors.js +6 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/events.d.ts +88 -0
- package/dist/src/utils/events.js +77 -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 +131 -0
- package/dist/src/utils/events.test.js.map +1 -0
- package/dist/src/utils/extensionLoader.d.ts +78 -0
- package/dist/src/utils/extensionLoader.js +162 -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 +90 -0
- package/dist/src/utils/extensionLoader.test.js.map +1 -0
- package/dist/src/utils/fetch.js +1 -6
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/flashFallback.test.js +26 -45
- package/dist/src/utils/flashFallback.test.js.map +1 -1
- package/dist/src/utils/getFolderStructure.js +7 -16
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.d.ts +4 -1
- package/dist/src/utils/gitIgnoreParser.js +21 -4
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +28 -0
- package/dist/src/utils/gitIgnoreParser.test.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 +36 -0
- package/dist/src/utils/googleQuotaErrors.js +149 -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/ignorePatterns.test.js +26 -30
- package/dist/src/utils/ignorePatterns.test.js.map +1 -1
- package/dist/src/utils/installationManager.js +2 -1
- package/dist/src/utils/installationManager.js.map +1 -1
- package/dist/src/utils/installationManager.test.js +3 -3
- package/dist/src/utils/installationManager.test.js.map +1 -1
- package/dist/src/utils/llm-edit-fixer.d.ts +1 -1
- package/dist/src/utils/llm-edit-fixer.js +27 -3
- package/dist/src/utils/llm-edit-fixer.js.map +1 -1
- package/dist/src/utils/llm-edit-fixer.test.js +21 -0
- package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.d.ts +11 -2
- package/dist/src/utils/memoryDiscovery.js +140 -2
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +153 -37
- package/dist/src/utils/memoryDiscovery.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/paths.js +126 -26
- 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/quotaErrorDetection.d.ts +0 -2
- package/dist/src/utils/quotaErrorDetection.js +0 -46
- package/dist/src/utils/quotaErrorDetection.js.map +1 -1
- package/dist/src/utils/retry.js +41 -145
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +31 -110
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/shell-utils.js +29 -1
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +88 -0
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/summarizer.js +2 -1
- package/dist/src/utils/summarizer.js.map +1 -1
- package/dist/src/utils/summarizer.test.js +0 -1
- package/dist/src/utils/summarizer.test.js.map +1 -1
- package/dist/src/utils/workspaceContext.js +1 -1
- package/dist/src/utils/workspaceContext.js.map +1 -1
- package/dist/src/utils/workspaceContext.test.js +2 -2
- package/dist/src/utils/workspaceContext.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -3
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
7
|
-
import {
|
|
7
|
+
import { isThinkingDefault, isThinkingSupported, GeminiClient, } from './client.js';
|
|
8
8
|
import { AuthType, } from './contentGenerator.js';
|
|
9
9
|
import {} from './geminiChat.js';
|
|
10
10
|
import { CompressionStatus, GeminiEventType, Turn, } from './turn.js';
|
|
@@ -14,8 +14,9 @@ import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
|
|
14
14
|
import { setSimulate429 } from '../utils/testUtils.js';
|
|
15
15
|
import { tokenLimit } from './tokenLimits.js';
|
|
16
16
|
import { ideContextStore } from '../ide/ideContext.js';
|
|
17
|
-
import { ClearcutLogger } from '../telemetry/clearcut-logger/clearcut-logger.js';
|
|
18
17
|
import { uiTelemetryService } from '../telemetry/uiTelemetry.js';
|
|
18
|
+
import { ChatCompressionService } from '../services/chatCompressionService.js';
|
|
19
|
+
vi.mock('../services/chatCompressionService.js');
|
|
19
20
|
// Mock fs module to prevent actual file system operations during tests
|
|
20
21
|
const mockFileSystem = new Map();
|
|
21
22
|
vi.mock('node:fs', () => {
|
|
@@ -95,70 +96,6 @@ async function fromAsync(promise) {
|
|
|
95
96
|
}
|
|
96
97
|
return results;
|
|
97
98
|
}
|
|
98
|
-
describe('findCompressSplitPoint', () => {
|
|
99
|
-
it('should throw an error for non-positive numbers', () => {
|
|
100
|
-
expect(() => findCompressSplitPoint([], 0)).toThrow('Fraction must be between 0 and 1');
|
|
101
|
-
});
|
|
102
|
-
it('should throw an error for a fraction greater than or equal to 1', () => {
|
|
103
|
-
expect(() => findCompressSplitPoint([], 1)).toThrow('Fraction must be between 0 and 1');
|
|
104
|
-
});
|
|
105
|
-
it('should handle an empty history', () => {
|
|
106
|
-
expect(findCompressSplitPoint([], 0.5)).toBe(0);
|
|
107
|
-
});
|
|
108
|
-
it('should handle a fraction in the middle', () => {
|
|
109
|
-
const history = [
|
|
110
|
-
{ role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66 (19%)
|
|
111
|
-
{ role: 'model', parts: [{ text: 'This is the second message.' }] }, // JSON length: 68 (40%)
|
|
112
|
-
{ role: 'user', parts: [{ text: 'This is the third message.' }] }, // JSON length: 66 (60%)
|
|
113
|
-
{ role: 'model', parts: [{ text: 'This is the fourth message.' }] }, // JSON length: 68 (80%)
|
|
114
|
-
{ role: 'user', parts: [{ text: 'This is the fifth message.' }] }, // JSON length: 65 (100%)
|
|
115
|
-
];
|
|
116
|
-
expect(findCompressSplitPoint(history, 0.5)).toBe(4);
|
|
117
|
-
});
|
|
118
|
-
it('should handle a fraction of last index', () => {
|
|
119
|
-
const history = [
|
|
120
|
-
{ role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66 (19%)
|
|
121
|
-
{ role: 'model', parts: [{ text: 'This is the second message.' }] }, // JSON length: 68 (40%)
|
|
122
|
-
{ role: 'user', parts: [{ text: 'This is the third message.' }] }, // JSON length: 66 (60%)
|
|
123
|
-
{ role: 'model', parts: [{ text: 'This is the fourth message.' }] }, // JSON length: 68 (80%)
|
|
124
|
-
{ role: 'user', parts: [{ text: 'This is the fifth message.' }] }, // JSON length: 65 (100%)
|
|
125
|
-
];
|
|
126
|
-
expect(findCompressSplitPoint(history, 0.9)).toBe(4);
|
|
127
|
-
});
|
|
128
|
-
it('should handle a fraction of after last index', () => {
|
|
129
|
-
const history = [
|
|
130
|
-
{ role: 'user', parts: [{ text: 'This is the first message.' }] }, // JSON length: 66 (24%%)
|
|
131
|
-
{ role: 'model', parts: [{ text: 'This is the second message.' }] }, // JSON length: 68 (50%)
|
|
132
|
-
{ role: 'user', parts: [{ text: 'This is the third message.' }] }, // JSON length: 66 (74%)
|
|
133
|
-
{ role: 'model', parts: [{ text: 'This is the fourth message.' }] }, // JSON length: 68 (100%)
|
|
134
|
-
];
|
|
135
|
-
expect(findCompressSplitPoint(history, 0.8)).toBe(4);
|
|
136
|
-
});
|
|
137
|
-
it('should return earlier splitpoint if no valid ones are after threshhold', () => {
|
|
138
|
-
const history = [
|
|
139
|
-
{ role: 'user', parts: [{ text: 'This is the first message.' }] },
|
|
140
|
-
{ role: 'model', parts: [{ text: 'This is the second message.' }] },
|
|
141
|
-
{ role: 'user', parts: [{ text: 'This is the third message.' }] },
|
|
142
|
-
{ role: 'model', parts: [{ functionCall: {} }] },
|
|
143
|
-
];
|
|
144
|
-
// Can't return 4 because the previous item has a function call.
|
|
145
|
-
expect(findCompressSplitPoint(history, 0.99)).toBe(2);
|
|
146
|
-
});
|
|
147
|
-
it('should handle a history with only one item', () => {
|
|
148
|
-
const historyWithEmptyParts = [
|
|
149
|
-
{ role: 'user', parts: [{ text: 'Message 1' }] },
|
|
150
|
-
];
|
|
151
|
-
expect(findCompressSplitPoint(historyWithEmptyParts, 0.5)).toBe(0);
|
|
152
|
-
});
|
|
153
|
-
it('should handle history with weird parts', () => {
|
|
154
|
-
const historyWithEmptyParts = [
|
|
155
|
-
{ role: 'user', parts: [{ text: 'Message 1' }] },
|
|
156
|
-
{ role: 'model', parts: [{ fileData: { fileUri: 'derp' } }] },
|
|
157
|
-
{ role: 'user', parts: [{ text: 'Message 2' }] },
|
|
158
|
-
];
|
|
159
|
-
expect(findCompressSplitPoint(historyWithEmptyParts, 0.5)).toBe(2);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
99
|
describe('isThinkingSupported', () => {
|
|
163
100
|
it('should return true for gemini-2.5', () => {
|
|
164
101
|
expect(isThinkingSupported('gemini-2.5')).toBe(true);
|
|
@@ -194,6 +131,14 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
194
131
|
beforeEach(async () => {
|
|
195
132
|
vi.resetAllMocks();
|
|
196
133
|
vi.mocked(uiTelemetryService.setLastPromptTokenCount).mockClear();
|
|
134
|
+
vi.mocked(ChatCompressionService.prototype.compress).mockResolvedValue({
|
|
135
|
+
newHistory: null,
|
|
136
|
+
info: {
|
|
137
|
+
originalTokenCount: 0,
|
|
138
|
+
newTokenCount: 0,
|
|
139
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
197
142
|
mockGenerateContentFn = vi.fn().mockResolvedValue({
|
|
198
143
|
candidates: [{ content: { parts: [{ text: '{"key": "value"}' }] } }],
|
|
199
144
|
});
|
|
@@ -269,6 +214,7 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
269
214
|
client = new GeminiClient(mockConfig);
|
|
270
215
|
await client.initialize();
|
|
271
216
|
vi.mocked(mockConfig.getGeminiClient).mockReturnValue(client);
|
|
217
|
+
vi.mocked(uiTelemetryService.setLastPromptTokenCount).mockClear();
|
|
272
218
|
});
|
|
273
219
|
afterEach(() => {
|
|
274
220
|
vi.restoreAllMocks();
|
|
@@ -319,87 +265,64 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
319
265
|
getHistory: mockGetHistory,
|
|
320
266
|
addHistory: vi.fn(),
|
|
321
267
|
setHistory: vi.fn(),
|
|
268
|
+
getLastPromptTokenCount: vi.fn(),
|
|
322
269
|
};
|
|
323
270
|
});
|
|
324
271
|
function setup({ chatHistory = [
|
|
325
272
|
{ role: 'user', parts: [{ text: 'Long conversation' }] },
|
|
326
273
|
{ role: 'model', parts: [{ text: 'Long response' }] },
|
|
327
|
-
], originalTokenCount = 1000,
|
|
274
|
+
], originalTokenCount = 1000, newTokenCount = 500, compressionStatus = CompressionStatus.COMPRESSED, } = {}) {
|
|
328
275
|
const mockOriginalChat = {
|
|
329
276
|
getHistory: vi.fn((_curated) => chatHistory),
|
|
330
277
|
setHistory: vi.fn(),
|
|
278
|
+
getLastPromptTokenCount: vi.fn().mockReturnValue(originalTokenCount),
|
|
331
279
|
};
|
|
332
280
|
client['chat'] = mockOriginalChat;
|
|
333
281
|
vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
content: {
|
|
338
|
-
role: 'model',
|
|
339
|
-
parts: [{ text: summaryText }],
|
|
340
|
-
},
|
|
341
|
-
},
|
|
342
|
-
],
|
|
343
|
-
});
|
|
344
|
-
// Calculate what the new history will be
|
|
345
|
-
const splitPoint = findCompressSplitPoint(chatHistory, 0.7); // 1 - 0.3
|
|
346
|
-
const historyToKeep = chatHistory.slice(splitPoint);
|
|
347
|
-
// This is the history that the new chat will have.
|
|
348
|
-
// It includes the default startChat history + the extra history from tryCompressChat
|
|
349
|
-
const newCompressedHistory = [
|
|
350
|
-
// Mocked envParts + canned response from startChat
|
|
351
|
-
{
|
|
352
|
-
role: 'user',
|
|
353
|
-
parts: [{ text: 'Mocked env context' }],
|
|
354
|
-
},
|
|
355
|
-
{
|
|
356
|
-
role: 'model',
|
|
357
|
-
parts: [{ text: 'Got it. Thanks for the context!' }],
|
|
358
|
-
},
|
|
359
|
-
// extraHistory from tryCompressChat
|
|
360
|
-
{
|
|
361
|
-
role: 'user',
|
|
362
|
-
parts: [{ text: summaryText }],
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
role: 'model',
|
|
366
|
-
parts: [{ text: 'Got it. Thanks for the additional context!' }],
|
|
367
|
-
},
|
|
368
|
-
...historyToKeep,
|
|
282
|
+
const newHistory = [
|
|
283
|
+
{ role: 'user', parts: [{ text: 'Summary' }] },
|
|
284
|
+
{ role: 'model', parts: [{ text: 'Got it' }] },
|
|
369
285
|
];
|
|
286
|
+
vi.mocked(ChatCompressionService.prototype.compress).mockResolvedValue({
|
|
287
|
+
newHistory: compressionStatus === CompressionStatus.COMPRESSED
|
|
288
|
+
? newHistory
|
|
289
|
+
: null,
|
|
290
|
+
info: {
|
|
291
|
+
originalTokenCount,
|
|
292
|
+
newTokenCount,
|
|
293
|
+
compressionStatus,
|
|
294
|
+
},
|
|
295
|
+
});
|
|
370
296
|
const mockNewChat = {
|
|
371
|
-
getHistory: vi.fn().mockReturnValue(
|
|
297
|
+
getHistory: vi.fn().mockReturnValue(newHistory),
|
|
372
298
|
setHistory: vi.fn(),
|
|
299
|
+
getLastPromptTokenCount: vi.fn().mockReturnValue(newTokenCount),
|
|
373
300
|
};
|
|
374
301
|
client['startChat'] = vi
|
|
375
302
|
.fn()
|
|
376
303
|
.mockResolvedValue(mockNewChat);
|
|
377
|
-
const totalChars = newCompressedHistory.reduce((total, content) => total + JSON.stringify(content).length, 0);
|
|
378
|
-
const estimatedNewTokenCount = Math.floor(totalChars / 4);
|
|
379
304
|
return {
|
|
380
305
|
client,
|
|
381
306
|
mockOriginalChat,
|
|
382
307
|
mockNewChat,
|
|
383
|
-
estimatedNewTokenCount,
|
|
308
|
+
estimatedNewTokenCount: newTokenCount,
|
|
384
309
|
};
|
|
385
310
|
}
|
|
386
311
|
describe('when compression inflates the token count', () => {
|
|
387
312
|
it('allows compression to be forced/manual after a failure', async () => {
|
|
388
|
-
// Call 1 (Fails): Setup with
|
|
389
|
-
|
|
390
|
-
const { client, estimatedNewTokenCount: inflatedTokenCount } = setup({
|
|
313
|
+
// Call 1 (Fails): Setup with inflated tokens
|
|
314
|
+
setup({
|
|
391
315
|
originalTokenCount: 100,
|
|
392
|
-
|
|
316
|
+
newTokenCount: 200,
|
|
317
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
393
318
|
});
|
|
394
|
-
expect(inflatedTokenCount).toBeGreaterThan(100); // Ensure setup is correct
|
|
395
319
|
await client.tryCompressChat('prompt-id-4', false); // Fails
|
|
396
|
-
// Call 2 (Forced): Re-setup with
|
|
397
|
-
const shortSummary = 'short';
|
|
320
|
+
// Call 2 (Forced): Re-setup with compressed tokens
|
|
398
321
|
const { estimatedNewTokenCount: compressedTokenCount } = setup({
|
|
399
322
|
originalTokenCount: 100,
|
|
400
|
-
|
|
323
|
+
newTokenCount: 50,
|
|
324
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
401
325
|
});
|
|
402
|
-
expect(compressedTokenCount).toBeLessThanOrEqual(100); // Ensure setup is correct
|
|
403
326
|
const result = await client.tryCompressChat('prompt-id-4', true); // Forced
|
|
404
327
|
expect(result).toEqual({
|
|
405
328
|
compressionStatus: CompressionStatus.COMPRESSED,
|
|
@@ -408,12 +331,11 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
408
331
|
});
|
|
409
332
|
});
|
|
410
333
|
it('yields the result even if the compression inflated the tokens', async () => {
|
|
411
|
-
const longSummary = 'long summary '.repeat(100);
|
|
412
334
|
const { client, estimatedNewTokenCount } = setup({
|
|
413
335
|
originalTokenCount: 100,
|
|
414
|
-
|
|
336
|
+
newTokenCount: 200,
|
|
337
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
415
338
|
});
|
|
416
|
-
expect(estimatedNewTokenCount).toBeGreaterThan(100); // Ensure setup is correct
|
|
417
339
|
const result = await client.tryCompressChat('prompt-id-4', false);
|
|
418
340
|
expect(result).toEqual({
|
|
419
341
|
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
@@ -424,47 +346,52 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
424
346
|
expect(uiTelemetryService.setLastPromptTokenCount).not.toHaveBeenCalled();
|
|
425
347
|
});
|
|
426
348
|
it('does not manipulate the source chat', async () => {
|
|
427
|
-
const
|
|
428
|
-
const { client, mockOriginalChat, estimatedNewTokenCount } = setup({
|
|
349
|
+
const { client, mockOriginalChat } = setup({
|
|
429
350
|
originalTokenCount: 100,
|
|
430
|
-
|
|
351
|
+
newTokenCount: 200,
|
|
352
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
431
353
|
});
|
|
432
|
-
expect(estimatedNewTokenCount).toBeGreaterThan(100); // Ensure setup is correct
|
|
433
354
|
await client.tryCompressChat('prompt-id-4', false);
|
|
434
355
|
// On failure, the chat should NOT be replaced
|
|
435
356
|
expect(client['chat']).toBe(mockOriginalChat);
|
|
436
357
|
});
|
|
437
|
-
it('will not attempt to compress context after a failure', async () => {
|
|
438
|
-
const
|
|
439
|
-
const { client, estimatedNewTokenCount } = setup({
|
|
358
|
+
it.skip('will not attempt to compress context after a failure', async () => {
|
|
359
|
+
const { client } = setup({
|
|
440
360
|
originalTokenCount: 100,
|
|
441
|
-
|
|
361
|
+
newTokenCount: 200,
|
|
362
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
442
363
|
});
|
|
443
|
-
expect(estimatedNewTokenCount).toBeGreaterThan(100); // Ensure setup is correct
|
|
444
364
|
await client.tryCompressChat('prompt-id-4', false); // This fails and sets hasFailedCompressionAttempt = true
|
|
365
|
+
// Mock the next call to return NOOP
|
|
366
|
+
vi.mocked(ChatCompressionService.prototype.compress).mockResolvedValueOnce({
|
|
367
|
+
newHistory: null,
|
|
368
|
+
info: {
|
|
369
|
+
originalTokenCount: 0,
|
|
370
|
+
newTokenCount: 0,
|
|
371
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
372
|
+
},
|
|
373
|
+
});
|
|
445
374
|
// This call should now be a NOOP
|
|
446
375
|
const result = await client.tryCompressChat('prompt-id-5', false);
|
|
447
|
-
|
|
448
|
-
expect(
|
|
449
|
-
expect(
|
|
450
|
-
compressionStatus: CompressionStatus.NOOP,
|
|
451
|
-
newTokenCount: 0,
|
|
452
|
-
originalTokenCount: 0,
|
|
453
|
-
});
|
|
376
|
+
expect(result.compressionStatus).toBe(CompressionStatus.NOOP);
|
|
377
|
+
expect(ChatCompressionService.prototype.compress).toHaveBeenCalledTimes(2);
|
|
378
|
+
expect(ChatCompressionService.prototype.compress).toHaveBeenLastCalledWith(expect.anything(), 'prompt-id-5', false, expect.anything(), expect.anything(), true);
|
|
454
379
|
});
|
|
455
380
|
});
|
|
456
381
|
it('should not trigger summarization if token count is below threshold', async () => {
|
|
457
382
|
const MOCKED_TOKEN_LIMIT = 1000;
|
|
458
|
-
vi.mocked(tokenLimit).mockReturnValue(MOCKED_TOKEN_LIMIT);
|
|
459
|
-
mockGetHistory.mockReturnValue([
|
|
460
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
461
|
-
]);
|
|
462
383
|
const originalTokenCount = MOCKED_TOKEN_LIMIT * 0.699;
|
|
463
|
-
vi.mocked(
|
|
384
|
+
vi.mocked(ChatCompressionService.prototype.compress).mockResolvedValue({
|
|
385
|
+
newHistory: null,
|
|
386
|
+
info: {
|
|
387
|
+
originalTokenCount,
|
|
388
|
+
newTokenCount: originalTokenCount,
|
|
389
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
464
392
|
const initialChat = client.getChat();
|
|
465
393
|
const result = await client.tryCompressChat('prompt-id-2', false);
|
|
466
394
|
const newChat = client.getChat();
|
|
467
|
-
expect(tokenLimit).toHaveBeenCalled();
|
|
468
395
|
expect(result).toEqual({
|
|
469
396
|
compressionStatus: CompressionStatus.NOOP,
|
|
470
397
|
newTokenCount: originalTokenCount,
|
|
@@ -476,6 +403,8 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
476
403
|
const { client } = setup({
|
|
477
404
|
chatHistory: [{ role: 'user', parts: [{ text: 'hi' }] }],
|
|
478
405
|
originalTokenCount: 50,
|
|
406
|
+
newTokenCount: 50,
|
|
407
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
479
408
|
});
|
|
480
409
|
const result = await client.tryCompressChat('prompt-id-noop', false);
|
|
481
410
|
expect(result).toEqual({
|
|
@@ -483,270 +412,6 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
483
412
|
originalTokenCount: 50,
|
|
484
413
|
newTokenCount: 50,
|
|
485
414
|
});
|
|
486
|
-
expect(mockGenerateContentFn).not.toHaveBeenCalled();
|
|
487
|
-
});
|
|
488
|
-
it('logs a telemetry event when compressing', async () => {
|
|
489
|
-
vi.spyOn(ClearcutLogger.prototype, 'logChatCompressionEvent');
|
|
490
|
-
const MOCKED_TOKEN_LIMIT = 1000;
|
|
491
|
-
const MOCKED_CONTEXT_PERCENTAGE_THRESHOLD = 0.5;
|
|
492
|
-
vi.spyOn(client['config'], 'getChatCompression').mockReturnValue({
|
|
493
|
-
contextPercentageThreshold: MOCKED_CONTEXT_PERCENTAGE_THRESHOLD,
|
|
494
|
-
});
|
|
495
|
-
const history = [
|
|
496
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
497
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
498
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
499
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
500
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
501
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
502
|
-
];
|
|
503
|
-
mockGetHistory.mockReturnValue(history);
|
|
504
|
-
const originalTokenCount = MOCKED_TOKEN_LIMIT * MOCKED_CONTEXT_PERCENTAGE_THRESHOLD;
|
|
505
|
-
vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
|
|
506
|
-
// We need to control the estimated new token count.
|
|
507
|
-
// We mock startChat to return a chat with a known history.
|
|
508
|
-
const summaryText = 'This is a summary.';
|
|
509
|
-
const splitPoint = findCompressSplitPoint(history, 0.7);
|
|
510
|
-
const historyToKeep = history.slice(splitPoint);
|
|
511
|
-
const newCompressedHistory = [
|
|
512
|
-
{ role: 'user', parts: [{ text: 'Mocked env context' }] },
|
|
513
|
-
{ role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
|
|
514
|
-
{ role: 'user', parts: [{ text: summaryText }] },
|
|
515
|
-
{
|
|
516
|
-
role: 'model',
|
|
517
|
-
parts: [{ text: 'Got it. Thanks for the additional context!' }],
|
|
518
|
-
},
|
|
519
|
-
...historyToKeep,
|
|
520
|
-
];
|
|
521
|
-
const mockNewChat = {
|
|
522
|
-
getHistory: vi.fn().mockReturnValue(newCompressedHistory),
|
|
523
|
-
};
|
|
524
|
-
client['startChat'] = vi
|
|
525
|
-
.fn()
|
|
526
|
-
.mockResolvedValue(mockNewChat);
|
|
527
|
-
const totalChars = newCompressedHistory.reduce((total, content) => total + JSON.stringify(content).length, 0);
|
|
528
|
-
const newTokenCount = Math.floor(totalChars / 4);
|
|
529
|
-
// Mock the summary response from the chat
|
|
530
|
-
mockGenerateContentFn.mockResolvedValue({
|
|
531
|
-
candidates: [
|
|
532
|
-
{
|
|
533
|
-
content: {
|
|
534
|
-
role: 'model',
|
|
535
|
-
parts: [{ text: summaryText }],
|
|
536
|
-
},
|
|
537
|
-
},
|
|
538
|
-
],
|
|
539
|
-
});
|
|
540
|
-
await client.tryCompressChat('prompt-id-3', false);
|
|
541
|
-
expect(ClearcutLogger.prototype.logChatCompressionEvent).toHaveBeenCalledWith(expect.objectContaining({
|
|
542
|
-
tokens_before: originalTokenCount,
|
|
543
|
-
tokens_after: newTokenCount,
|
|
544
|
-
}));
|
|
545
|
-
expect(uiTelemetryService.setLastPromptTokenCount).toHaveBeenCalledWith(newTokenCount);
|
|
546
|
-
expect(uiTelemetryService.setLastPromptTokenCount).toHaveBeenCalledTimes(1);
|
|
547
|
-
});
|
|
548
|
-
it('should trigger summarization if token count is at threshold with contextPercentageThreshold setting', async () => {
|
|
549
|
-
const MOCKED_TOKEN_LIMIT = 1000;
|
|
550
|
-
const MOCKED_CONTEXT_PERCENTAGE_THRESHOLD = 0.5;
|
|
551
|
-
vi.mocked(tokenLimit).mockReturnValue(MOCKED_TOKEN_LIMIT);
|
|
552
|
-
vi.spyOn(client['config'], 'getChatCompression').mockReturnValue({
|
|
553
|
-
contextPercentageThreshold: MOCKED_CONTEXT_PERCENTAGE_THRESHOLD,
|
|
554
|
-
});
|
|
555
|
-
const history = [
|
|
556
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
557
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
558
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
559
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
560
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
561
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
562
|
-
];
|
|
563
|
-
mockGetHistory.mockReturnValue(history);
|
|
564
|
-
const originalTokenCount = MOCKED_TOKEN_LIMIT * MOCKED_CONTEXT_PERCENTAGE_THRESHOLD;
|
|
565
|
-
vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
|
|
566
|
-
// Mock summary and new chat
|
|
567
|
-
const summaryText = 'This is a summary.';
|
|
568
|
-
const splitPoint = findCompressSplitPoint(history, 0.7);
|
|
569
|
-
const historyToKeep = history.slice(splitPoint);
|
|
570
|
-
const newCompressedHistory = [
|
|
571
|
-
{ role: 'user', parts: [{ text: 'Mocked env context' }] },
|
|
572
|
-
{ role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
|
|
573
|
-
{ role: 'user', parts: [{ text: summaryText }] },
|
|
574
|
-
{
|
|
575
|
-
role: 'model',
|
|
576
|
-
parts: [{ text: 'Got it. Thanks for the additional context!' }],
|
|
577
|
-
},
|
|
578
|
-
...historyToKeep,
|
|
579
|
-
];
|
|
580
|
-
const mockNewChat = {
|
|
581
|
-
getHistory: vi.fn().mockReturnValue(newCompressedHistory),
|
|
582
|
-
};
|
|
583
|
-
client['startChat'] = vi
|
|
584
|
-
.fn()
|
|
585
|
-
.mockResolvedValue(mockNewChat);
|
|
586
|
-
const totalChars = newCompressedHistory.reduce((total, content) => total + JSON.stringify(content).length, 0);
|
|
587
|
-
const newTokenCount = Math.floor(totalChars / 4);
|
|
588
|
-
// Mock the summary response from the chat
|
|
589
|
-
mockGenerateContentFn.mockResolvedValue({
|
|
590
|
-
candidates: [
|
|
591
|
-
{
|
|
592
|
-
content: {
|
|
593
|
-
role: 'model',
|
|
594
|
-
parts: [{ text: summaryText }],
|
|
595
|
-
},
|
|
596
|
-
},
|
|
597
|
-
],
|
|
598
|
-
});
|
|
599
|
-
const initialChat = client.getChat();
|
|
600
|
-
const result = await client.tryCompressChat('prompt-id-3', false);
|
|
601
|
-
const newChat = client.getChat();
|
|
602
|
-
expect(tokenLimit).toHaveBeenCalled();
|
|
603
|
-
expect(mockGenerateContentFn).toHaveBeenCalled();
|
|
604
|
-
// Assert that summarization happened and returned the correct stats
|
|
605
|
-
expect(result).toEqual({
|
|
606
|
-
compressionStatus: CompressionStatus.COMPRESSED,
|
|
607
|
-
originalTokenCount,
|
|
608
|
-
newTokenCount,
|
|
609
|
-
});
|
|
610
|
-
// Assert that the chat was reset
|
|
611
|
-
expect(newChat).not.toBe(initialChat);
|
|
612
|
-
});
|
|
613
|
-
it('should not compress across a function call response', async () => {
|
|
614
|
-
const MOCKED_TOKEN_LIMIT = 1000;
|
|
615
|
-
vi.mocked(tokenLimit).mockReturnValue(MOCKED_TOKEN_LIMIT);
|
|
616
|
-
const history = [
|
|
617
|
-
{ role: 'user', parts: [{ text: '...history 1...' }] },
|
|
618
|
-
{ role: 'model', parts: [{ text: '...history 2...' }] },
|
|
619
|
-
{ role: 'user', parts: [{ text: '...history 3...' }] },
|
|
620
|
-
{ role: 'model', parts: [{ text: '...history 4...' }] },
|
|
621
|
-
{ role: 'user', parts: [{ text: '...history 5...' }] },
|
|
622
|
-
{ role: 'model', parts: [{ text: '...history 6...' }] },
|
|
623
|
-
{ role: 'user', parts: [{ text: '...history 7...' }] },
|
|
624
|
-
{ role: 'model', parts: [{ text: '...history 8...' }] },
|
|
625
|
-
// Normally we would break here, but we have a function response.
|
|
626
|
-
{
|
|
627
|
-
role: 'user',
|
|
628
|
-
parts: [{ functionResponse: { name: '...history 8...' } }],
|
|
629
|
-
},
|
|
630
|
-
{ role: 'model', parts: [{ text: '...history 10...' }] },
|
|
631
|
-
// Instead we will break here.
|
|
632
|
-
{ role: 'user', parts: [{ text: '...history 10...' }] },
|
|
633
|
-
];
|
|
634
|
-
mockGetHistory.mockReturnValue(history);
|
|
635
|
-
const originalTokenCount = 1000 * 0.7;
|
|
636
|
-
vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
|
|
637
|
-
// Mock summary and new chat
|
|
638
|
-
const summaryText = 'This is a summary.';
|
|
639
|
-
const splitPoint = findCompressSplitPoint(history, 0.7); // This should be 10
|
|
640
|
-
expect(splitPoint).toBe(10); // Verify split point logic
|
|
641
|
-
const historyToKeep = history.slice(splitPoint); // Should keep last user message
|
|
642
|
-
expect(historyToKeep).toEqual([
|
|
643
|
-
{ role: 'user', parts: [{ text: '...history 10...' }] },
|
|
644
|
-
]);
|
|
645
|
-
const newCompressedHistory = [
|
|
646
|
-
{ role: 'user', parts: [{ text: 'Mocked env context' }] },
|
|
647
|
-
{ role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
|
|
648
|
-
{ role: 'user', parts: [{ text: summaryText }] },
|
|
649
|
-
{
|
|
650
|
-
role: 'model',
|
|
651
|
-
parts: [{ text: 'Got it. Thanks for the additional context!' }],
|
|
652
|
-
},
|
|
653
|
-
...historyToKeep,
|
|
654
|
-
];
|
|
655
|
-
const mockNewChat = {
|
|
656
|
-
getHistory: vi.fn().mockReturnValue(newCompressedHistory),
|
|
657
|
-
};
|
|
658
|
-
client['startChat'] = vi
|
|
659
|
-
.fn()
|
|
660
|
-
.mockResolvedValue(mockNewChat);
|
|
661
|
-
const totalChars = newCompressedHistory.reduce((total, content) => total + JSON.stringify(content).length, 0);
|
|
662
|
-
const newTokenCount = Math.floor(totalChars / 4);
|
|
663
|
-
// Mock the summary response from the chat
|
|
664
|
-
mockGenerateContentFn.mockResolvedValue({
|
|
665
|
-
candidates: [
|
|
666
|
-
{
|
|
667
|
-
content: {
|
|
668
|
-
role: 'model',
|
|
669
|
-
parts: [{ text: summaryText }],
|
|
670
|
-
},
|
|
671
|
-
},
|
|
672
|
-
],
|
|
673
|
-
});
|
|
674
|
-
const initialChat = client.getChat();
|
|
675
|
-
const result = await client.tryCompressChat('prompt-id-3', false);
|
|
676
|
-
const newChat = client.getChat();
|
|
677
|
-
expect(tokenLimit).toHaveBeenCalled();
|
|
678
|
-
expect(mockGenerateContentFn).toHaveBeenCalled();
|
|
679
|
-
// Assert that summarization happened and returned the correct stats
|
|
680
|
-
expect(result).toEqual({
|
|
681
|
-
compressionStatus: CompressionStatus.COMPRESSED,
|
|
682
|
-
originalTokenCount,
|
|
683
|
-
newTokenCount,
|
|
684
|
-
});
|
|
685
|
-
// Assert that the chat was reset
|
|
686
|
-
expect(newChat).not.toBe(initialChat);
|
|
687
|
-
// 1. standard start context message (env)
|
|
688
|
-
// 2. standard canned model response
|
|
689
|
-
// 3. compressed summary message (user)
|
|
690
|
-
// 4. standard canned model response
|
|
691
|
-
// 5. The last user message (historyToKeep)
|
|
692
|
-
expect(newChat.getHistory().length).toEqual(5);
|
|
693
|
-
});
|
|
694
|
-
it('should always trigger summarization when force is true, regardless of token count', async () => {
|
|
695
|
-
const history = [
|
|
696
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
697
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
698
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
699
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
700
|
-
{ role: 'user', parts: [{ text: '...history...' }] },
|
|
701
|
-
{ role: 'model', parts: [{ text: '...history...' }] },
|
|
702
|
-
];
|
|
703
|
-
mockGetHistory.mockReturnValue(history);
|
|
704
|
-
const originalTokenCount = 100; // Well below threshold, but > estimated new count
|
|
705
|
-
vi.mocked(uiTelemetryService.getLastPromptTokenCount).mockReturnValue(originalTokenCount);
|
|
706
|
-
// Mock summary and new chat
|
|
707
|
-
const summaryText = 'This is a summary.';
|
|
708
|
-
const splitPoint = findCompressSplitPoint(history, 0.7);
|
|
709
|
-
const historyToKeep = history.slice(splitPoint);
|
|
710
|
-
const newCompressedHistory = [
|
|
711
|
-
{ role: 'user', parts: [{ text: 'Mocked env context' }] },
|
|
712
|
-
{ role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
|
|
713
|
-
{ role: 'user', parts: [{ text: summaryText }] },
|
|
714
|
-
{
|
|
715
|
-
role: 'model',
|
|
716
|
-
parts: [{ text: 'Got it. Thanks for the additional context!' }],
|
|
717
|
-
},
|
|
718
|
-
...historyToKeep,
|
|
719
|
-
];
|
|
720
|
-
const mockNewChat = {
|
|
721
|
-
getHistory: vi.fn().mockReturnValue(newCompressedHistory),
|
|
722
|
-
};
|
|
723
|
-
client['startChat'] = vi
|
|
724
|
-
.fn()
|
|
725
|
-
.mockResolvedValue(mockNewChat);
|
|
726
|
-
const totalChars = newCompressedHistory.reduce((total, content) => total + JSON.stringify(content).length, 0);
|
|
727
|
-
const newTokenCount = Math.floor(totalChars / 4);
|
|
728
|
-
// Mock the summary response from the chat
|
|
729
|
-
mockGenerateContentFn.mockResolvedValue({
|
|
730
|
-
candidates: [
|
|
731
|
-
{
|
|
732
|
-
content: {
|
|
733
|
-
role: 'model',
|
|
734
|
-
parts: [{ text: summaryText }],
|
|
735
|
-
},
|
|
736
|
-
},
|
|
737
|
-
],
|
|
738
|
-
});
|
|
739
|
-
const initialChat = client.getChat();
|
|
740
|
-
const result = await client.tryCompressChat('prompt-id-1', true); // force = true
|
|
741
|
-
const newChat = client.getChat();
|
|
742
|
-
expect(mockGenerateContentFn).toHaveBeenCalled();
|
|
743
|
-
expect(result).toEqual({
|
|
744
|
-
compressionStatus: CompressionStatus.COMPRESSED,
|
|
745
|
-
originalTokenCount,
|
|
746
|
-
newTokenCount,
|
|
747
|
-
});
|
|
748
|
-
// Assert that the chat was reset
|
|
749
|
-
expect(newChat).not.toBe(initialChat);
|
|
750
415
|
});
|
|
751
416
|
});
|
|
752
417
|
describe('sendMessageStream', () => {
|
|
@@ -831,6 +496,7 @@ describe('Gemini Client (client.ts)', () => {
|
|
|
831
496
|
const mockChat = {
|
|
832
497
|
addHistory: vi.fn(),
|
|
833
498
|
getHistory: vi.fn().mockReturnValue([]),
|
|
499
|
+
getLastPromptTokenCount: vi.fn(),
|
|
834
500
|
};
|
|
835
501
|
client['chat'] = mockChat;
|
|
836
502
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -878,6 +544,7 @@ ${JSON.stringify({
|
|
|
878
544
|
const mockChat = {
|
|
879
545
|
addHistory: vi.fn(),
|
|
880
546
|
getHistory: vi.fn().mockReturnValue([]),
|
|
547
|
+
getLastPromptTokenCount: vi.fn(),
|
|
881
548
|
};
|
|
882
549
|
client['chat'] = mockChat;
|
|
883
550
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -922,6 +589,7 @@ ${JSON.stringify({
|
|
|
922
589
|
const mockChat = {
|
|
923
590
|
addHistory: vi.fn(),
|
|
924
591
|
getHistory: vi.fn().mockReturnValue([]),
|
|
592
|
+
getLastPromptTokenCount: vi.fn(),
|
|
925
593
|
};
|
|
926
594
|
client['chat'] = mockChat;
|
|
927
595
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -982,6 +650,7 @@ ${JSON.stringify({
|
|
|
982
650
|
const mockChat = {
|
|
983
651
|
addHistory: vi.fn(),
|
|
984
652
|
getHistory: vi.fn().mockReturnValue([]),
|
|
653
|
+
getLastPromptTokenCount: vi.fn(),
|
|
985
654
|
};
|
|
986
655
|
client['chat'] = mockChat;
|
|
987
656
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -1015,6 +684,7 @@ ${JSON.stringify({
|
|
|
1015
684
|
const mockChat = {
|
|
1016
685
|
addHistory: vi.fn(),
|
|
1017
686
|
getHistory: vi.fn().mockReturnValue([]),
|
|
687
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1018
688
|
};
|
|
1019
689
|
client['chat'] = mockChat;
|
|
1020
690
|
// Act
|
|
@@ -1048,6 +718,7 @@ ${JSON.stringify({
|
|
|
1048
718
|
const mockChat = {
|
|
1049
719
|
addHistory: vi.fn(),
|
|
1050
720
|
getHistory: vi.fn().mockReturnValue([]),
|
|
721
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1051
722
|
};
|
|
1052
723
|
client['chat'] = mockChat;
|
|
1053
724
|
// Use a signal that never gets aborted
|
|
@@ -1093,6 +764,7 @@ ${JSON.stringify({
|
|
|
1093
764
|
const mockChat = {
|
|
1094
765
|
addHistory: vi.fn(),
|
|
1095
766
|
getHistory: vi.fn().mockReturnValue([]),
|
|
767
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1096
768
|
};
|
|
1097
769
|
client['chat'] = mockChat;
|
|
1098
770
|
// Act & Assert
|
|
@@ -1131,6 +803,7 @@ ${JSON.stringify({
|
|
|
1131
803
|
const mockChat = {
|
|
1132
804
|
addHistory: vi.fn(),
|
|
1133
805
|
getHistory: vi.fn().mockReturnValue([]),
|
|
806
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1134
807
|
};
|
|
1135
808
|
client['chat'] = mockChat;
|
|
1136
809
|
// Use a signal that never gets aborted
|
|
@@ -1158,9 +831,8 @@ ${JSON.stringify({
|
|
|
1158
831
|
}
|
|
1159
832
|
}
|
|
1160
833
|
}
|
|
1161
|
-
catch (
|
|
834
|
+
catch (_) {
|
|
1162
835
|
// If the test framework times out, that also demonstrates the infinite loop
|
|
1163
|
-
console.error('Test timed out or errored:', error);
|
|
1164
836
|
}
|
|
1165
837
|
// Assert that the fix works - the loop should stop at MAX_TURNS
|
|
1166
838
|
const callCount = mockCheckNextSpeaker.mock.calls.length;
|
|
@@ -1175,7 +847,11 @@ ${JSON.stringify({
|
|
|
1175
847
|
vi.mocked(tokenLimit).mockReturnValue(MOCKED_TOKEN_LIMIT);
|
|
1176
848
|
// Set last prompt token count
|
|
1177
849
|
const lastPromptTokenCount = 900;
|
|
1178
|
-
|
|
850
|
+
const mockChat = {
|
|
851
|
+
getLastPromptTokenCount: vi.fn().mockReturnValue(lastPromptTokenCount),
|
|
852
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
853
|
+
};
|
|
854
|
+
client['chat'] = mockChat;
|
|
1179
855
|
// Remaining = 100. Threshold (95%) = 95.
|
|
1180
856
|
// We need a request > 95 tokens.
|
|
1181
857
|
// A string of length 400 is roughly 100 tokens.
|
|
@@ -1218,7 +894,11 @@ ${JSON.stringify({
|
|
|
1218
894
|
client['currentSequenceModel'] = STICKY_MODEL;
|
|
1219
895
|
// Set token count
|
|
1220
896
|
const lastPromptTokenCount = 900;
|
|
1221
|
-
|
|
897
|
+
const mockChat = {
|
|
898
|
+
getLastPromptTokenCount: vi.fn().mockReturnValue(lastPromptTokenCount),
|
|
899
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
900
|
+
};
|
|
901
|
+
client['chat'] = mockChat;
|
|
1222
902
|
// Remaining (sticky) = 100. Threshold (95%) = 95.
|
|
1223
903
|
// We need a request > 95 tokens.
|
|
1224
904
|
const longText = 'a'.repeat(400);
|
|
@@ -1257,6 +937,12 @@ ${JSON.stringify({
|
|
|
1257
937
|
mockTurnRunFn.mockReturnValue((async function* () {
|
|
1258
938
|
yield { type: 'content', value: 'Hello' };
|
|
1259
939
|
})());
|
|
940
|
+
const mockChat = {
|
|
941
|
+
addHistory: vi.fn(),
|
|
942
|
+
getHistory: vi.fn().mockReturnValue([]),
|
|
943
|
+
getLastPromptTokenCount: vi.fn(),
|
|
944
|
+
};
|
|
945
|
+
client['chat'] = mockChat;
|
|
1260
946
|
});
|
|
1261
947
|
it('should use the model router service to select a model on the first turn', async () => {
|
|
1262
948
|
const stream = client.sendMessageStream([{ text: 'Hi' }], new AbortController().signal, 'prompt-1');
|
|
@@ -1345,6 +1031,7 @@ ${JSON.stringify({
|
|
|
1345
1031
|
const mockChat = {
|
|
1346
1032
|
addHistory: vi.fn(),
|
|
1347
1033
|
getHistory: vi.fn().mockReturnValue([]),
|
|
1034
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1348
1035
|
};
|
|
1349
1036
|
client['chat'] = mockChat;
|
|
1350
1037
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -1375,6 +1062,7 @@ ${JSON.stringify({
|
|
|
1375
1062
|
const mockChat = {
|
|
1376
1063
|
addHistory: vi.fn(),
|
|
1377
1064
|
getHistory: vi.fn().mockReturnValue([]),
|
|
1065
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1378
1066
|
};
|
|
1379
1067
|
client['chat'] = mockChat;
|
|
1380
1068
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -1398,6 +1086,7 @@ ${JSON.stringify({
|
|
|
1398
1086
|
const mockChat = {
|
|
1399
1087
|
addHistory: vi.fn(),
|
|
1400
1088
|
getHistory: vi.fn().mockReturnValue([]),
|
|
1089
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1401
1090
|
};
|
|
1402
1091
|
client['chat'] = mockChat;
|
|
1403
1092
|
const initialRequest = [{ text: 'Hi' }];
|
|
@@ -1435,6 +1124,7 @@ ${JSON.stringify({
|
|
|
1435
1124
|
.mockReturnValue([
|
|
1436
1125
|
{ role: 'user', parts: [{ text: 'previous message' }] },
|
|
1437
1126
|
]),
|
|
1127
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1438
1128
|
};
|
|
1439
1129
|
client['chat'] = mockChat;
|
|
1440
1130
|
});
|
|
@@ -1555,7 +1245,11 @@ ${JSON.stringify({
|
|
|
1555
1245
|
vi.mocked(ideContextStore.get).mockReturnValue({
|
|
1556
1246
|
workspaceState: {
|
|
1557
1247
|
openFiles: [
|
|
1558
|
-
{
|
|
1248
|
+
{
|
|
1249
|
+
...currentActiveFile,
|
|
1250
|
+
isActive: true,
|
|
1251
|
+
timestamp: Date.now(),
|
|
1252
|
+
},
|
|
1559
1253
|
],
|
|
1560
1254
|
},
|
|
1561
1255
|
});
|
|
@@ -1643,6 +1337,7 @@ ${JSON.stringify({
|
|
|
1643
1337
|
addHistory: vi.fn(),
|
|
1644
1338
|
getHistory: vi.fn().mockReturnValue([]), // Default empty history
|
|
1645
1339
|
setHistory: vi.fn(),
|
|
1340
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1646
1341
|
};
|
|
1647
1342
|
client['chat'] = mockChat;
|
|
1648
1343
|
vi.spyOn(client['config'], 'getIdeMode').mockReturnValue(true);
|
|
@@ -1906,6 +1601,7 @@ ${JSON.stringify({
|
|
|
1906
1601
|
const mockChat = {
|
|
1907
1602
|
addHistory: vi.fn(),
|
|
1908
1603
|
getHistory: vi.fn().mockReturnValue([]),
|
|
1604
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1909
1605
|
};
|
|
1910
1606
|
client['chat'] = mockChat;
|
|
1911
1607
|
// Act
|
|
@@ -1931,6 +1627,7 @@ ${JSON.stringify({
|
|
|
1931
1627
|
const mockChat = {
|
|
1932
1628
|
addHistory: vi.fn(),
|
|
1933
1629
|
getHistory: vi.fn().mockReturnValue([]),
|
|
1630
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1934
1631
|
};
|
|
1935
1632
|
client['chat'] = mockChat;
|
|
1936
1633
|
// Act
|
|
@@ -1958,6 +1655,7 @@ ${JSON.stringify({
|
|
|
1958
1655
|
const mockChat = {
|
|
1959
1656
|
addHistory: vi.fn(),
|
|
1960
1657
|
getHistory: vi.fn().mockReturnValue([]),
|
|
1658
|
+
getLastPromptTokenCount: vi.fn(),
|
|
1961
1659
|
};
|
|
1962
1660
|
client['chat'] = mockChat;
|
|
1963
1661
|
// Act
|