@google/gemini-cli-core 0.0.3-preview.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +310 -0
- package/dist/.last_build +0 -0
- package/dist/google-gemini-cli-core-0.3.0-preview.3.tgz +0 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/src/__mocks__/fs/promises.d.ts +11 -0
- package/dist/src/__mocks__/fs/promises.js +17 -0
- package/dist/src/__mocks__/fs/promises.js.map +1 -0
- package/dist/src/code_assist/codeAssist.d.ts +10 -0
- package/dist/src/code_assist/codeAssist.js +19 -0
- package/dist/src/code_assist/codeAssist.js.map +1 -0
- package/dist/src/code_assist/converter.d.ts +72 -0
- package/dist/src/code_assist/converter.js +159 -0
- package/dist/src/code_assist/converter.js.map +1 -0
- package/dist/src/code_assist/converter.test.d.ts +6 -0
- package/dist/src/code_assist/converter.test.js +362 -0
- package/dist/src/code_assist/converter.test.js.map +1 -0
- package/dist/src/code_assist/oauth2.d.ts +22 -0
- package/dist/src/code_assist/oauth2.js +353 -0
- package/dist/src/code_assist/oauth2.js.map +1 -0
- package/dist/src/code_assist/oauth2.test.d.ts +6 -0
- package/dist/src/code_assist/oauth2.test.js +427 -0
- package/dist/src/code_assist/oauth2.test.js.map +1 -0
- package/dist/src/code_assist/server.d.ts +37 -0
- package/dist/src/code_assist/server.js +125 -0
- package/dist/src/code_assist/server.js.map +1 -0
- package/dist/src/code_assist/server.test.d.ts +6 -0
- package/dist/src/code_assist/server.test.js +134 -0
- package/dist/src/code_assist/server.test.js.map +1 -0
- package/dist/src/code_assist/setup.d.ts +20 -0
- package/dist/src/code_assist/setup.js +101 -0
- package/dist/src/code_assist/setup.js.map +1 -0
- package/dist/src/code_assist/setup.test.d.ts +6 -0
- package/dist/src/code_assist/setup.test.js +171 -0
- package/dist/src/code_assist/setup.test.js.map +1 -0
- package/dist/src/code_assist/types.d.ts +148 -0
- package/dist/src/code_assist/types.js +46 -0
- package/dist/src/code_assist/types.js.map +1 -0
- package/dist/src/config/config.d.ts +318 -0
- package/dist/src/config/config.js +633 -0
- package/dist/src/config/config.js.map +1 -0
- package/dist/src/config/config.test.d.ts +6 -0
- package/dist/src/config/config.test.js +585 -0
- package/dist/src/config/config.test.js.map +1 -0
- package/dist/src/config/flashFallback.test.d.ts +6 -0
- package/dist/src/config/flashFallback.test.js +87 -0
- package/dist/src/config/flashFallback.test.js.map +1 -0
- package/dist/src/config/models.d.ts +9 -0
- package/dist/src/config/models.js +10 -0
- package/dist/src/config/models.js.map +1 -0
- package/dist/src/config/storage.d.ts +32 -0
- package/dist/src/config/storage.js +90 -0
- package/dist/src/config/storage.js.map +1 -0
- package/dist/src/config/storage.test.d.ts +6 -0
- package/dist/src/config/storage.test.js +43 -0
- package/dist/src/config/storage.test.js.map +1 -0
- package/dist/src/core/client.d.ts +65 -0
- package/dist/src/core/client.js +689 -0
- package/dist/src/core/client.js.map +1 -0
- package/dist/src/core/client.test.d.ts +6 -0
- package/dist/src/core/client.test.js +1857 -0
- package/dist/src/core/client.test.js.map +1 -0
- package/dist/src/core/contentGenerator.d.ts +33 -0
- package/dist/src/core/contentGenerator.js +80 -0
- package/dist/src/core/contentGenerator.js.map +1 -0
- package/dist/src/core/contentGenerator.test.d.ts +6 -0
- package/dist/src/core/contentGenerator.test.js +124 -0
- package/dist/src/core/contentGenerator.test.js.map +1 -0
- package/dist/src/core/coreToolScheduler.d.ts +126 -0
- package/dist/src/core/coreToolScheduler.js +605 -0
- package/dist/src/core/coreToolScheduler.js.map +1 -0
- package/dist/src/core/coreToolScheduler.test.d.ts +6 -0
- package/dist/src/core/coreToolScheduler.test.js +923 -0
- package/dist/src/core/coreToolScheduler.test.js.map +1 -0
- package/dist/src/core/geminiChat.d.ts +122 -0
- package/dist/src/core/geminiChat.js +547 -0
- package/dist/src/core/geminiChat.js.map +1 -0
- package/dist/src/core/geminiChat.test.d.ts +6 -0
- package/dist/src/core/geminiChat.test.js +875 -0
- package/dist/src/core/geminiChat.test.js.map +1 -0
- package/dist/src/core/geminiRequest.d.ts +13 -0
- package/dist/src/core/geminiRequest.js +11 -0
- package/dist/src/core/geminiRequest.js.map +1 -0
- package/dist/src/core/logger.d.ts +60 -0
- package/dist/src/core/logger.js +360 -0
- package/dist/src/core/logger.js.map +1 -0
- package/dist/src/core/logger.test.d.ts +6 -0
- package/dist/src/core/logger.test.js +534 -0
- package/dist/src/core/logger.test.js.map +1 -0
- package/dist/src/core/loggingContentGenerator.d.ts +25 -0
- package/dist/src/core/loggingContentGenerator.js +97 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.d.ts +10 -0
- package/dist/src/core/nonInteractiveToolExecutor.js +24 -0
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.d.ts +6 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js +236 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -0
- package/dist/src/core/prompts.d.ts +12 -0
- package/dist/src/core/prompts.js +359 -0
- package/dist/src/core/prompts.js.map +1 -0
- package/dist/src/core/prompts.test.d.ts +6 -0
- package/dist/src/core/prompts.test.js +214 -0
- package/dist/src/core/prompts.test.js.map +1 -0
- package/dist/src/core/subagent.d.ts +236 -0
- package/dist/src/core/subagent.js +485 -0
- package/dist/src/core/subagent.js.map +1 -0
- package/dist/src/core/subagent.test.d.ts +6 -0
- package/dist/src/core/subagent.test.js +520 -0
- package/dist/src/core/subagent.test.js.map +1 -0
- package/dist/src/core/tokenLimits.d.ts +10 -0
- package/dist/src/core/tokenLimits.js +28 -0
- package/dist/src/core/tokenLimits.js.map +1 -0
- package/dist/src/core/turn.d.ts +125 -0
- package/dist/src/core/turn.js +154 -0
- package/dist/src/core/turn.js.map +1 -0
- package/dist/src/core/turn.test.d.ts +6 -0
- package/dist/src/core/turn.test.js +388 -0
- package/dist/src/core/turn.test.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +7 -0
- package/dist/src/generated/git-commit.js +10 -0
- package/dist/src/generated/git-commit.js.map +1 -0
- package/dist/src/ide/constants.d.ts +6 -0
- package/dist/src/ide/constants.js +7 -0
- package/dist/src/ide/constants.js.map +1 -0
- package/dist/src/ide/detect-ide.d.ts +25 -0
- package/dist/src/ide/detect-ide.js +104 -0
- package/dist/src/ide/detect-ide.js.map +1 -0
- package/dist/src/ide/detect-ide.test.d.ts +6 -0
- package/dist/src/ide/detect-ide.test.js +109 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -0
- package/dist/src/ide/ide-client.d.ts +67 -0
- package/dist/src/ide/ide-client.js +418 -0
- package/dist/src/ide/ide-client.js.map +1 -0
- package/dist/src/ide/ide-client.test.d.ts +6 -0
- package/dist/src/ide/ide-client.test.js +155 -0
- package/dist/src/ide/ide-client.test.js.map +1 -0
- package/dist/src/ide/ide-installer.d.ts +14 -0
- package/dist/src/ide/ide-installer.js +107 -0
- package/dist/src/ide/ide-installer.js.map +1 -0
- package/dist/src/ide/ide-installer.test.d.ts +6 -0
- package/dist/src/ide/ide-installer.test.js +113 -0
- package/dist/src/ide/ide-installer.test.js.map +1 -0
- package/dist/src/ide/ideContext.d.ts +374 -0
- package/dist/src/ide/ideContext.js +147 -0
- package/dist/src/ide/ideContext.js.map +1 -0
- package/dist/src/ide/ideContext.test.d.ts +6 -0
- package/dist/src/ide/ideContext.test.js +265 -0
- package/dist/src/ide/ideContext.test.js.map +1 -0
- package/dist/src/ide/process-utils.d.ts +22 -0
- package/dist/src/ide/process-utils.js +153 -0
- package/dist/src/ide/process-utils.js.map +1 -0
- package/dist/src/ide/process-utils.test.d.ts +6 -0
- package/dist/src/ide/process-utils.test.js +72 -0
- package/dist/src/ide/process-utils.test.js.map +1 -0
- package/dist/src/index.d.ts +81 -0
- package/dist/src/index.js +90 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.test.d.ts +6 -0
- package/dist/src/index.test.js +12 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/mcp/google-auth-provider.d.ts +23 -0
- package/dist/src/mcp/google-auth-provider.js +72 -0
- package/dist/src/mcp/google-auth-provider.js.map +1 -0
- package/dist/src/mcp/google-auth-provider.test.d.ts +6 -0
- package/dist/src/mcp/google-auth-provider.test.js +89 -0
- package/dist/src/mcp/google-auth-provider.test.js.map +1 -0
- package/dist/src/mcp/oauth-provider.d.ts +146 -0
- package/dist/src/mcp/oauth-provider.js +601 -0
- package/dist/src/mcp/oauth-provider.js.map +1 -0
- package/dist/src/mcp/oauth-provider.test.d.ts +6 -0
- package/dist/src/mcp/oauth-provider.test.js +672 -0
- package/dist/src/mcp/oauth-provider.test.js.map +1 -0
- package/dist/src/mcp/oauth-token-storage.d.ts +61 -0
- package/dist/src/mcp/oauth-token-storage.js +148 -0
- package/dist/src/mcp/oauth-token-storage.js.map +1 -0
- package/dist/src/mcp/oauth-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/oauth-token-storage.test.js +206 -0
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -0
- package/dist/src/mcp/oauth-utils.d.ts +119 -0
- package/dist/src/mcp/oauth-utils.js +235 -0
- package/dist/src/mcp/oauth-utils.js.map +1 -0
- package/dist/src/mcp/oauth-utils.test.d.ts +6 -0
- package/dist/src/mcp/oauth-utils.test.js +199 -0
- package/dist/src/mcp/oauth-utils.test.js.map +1 -0
- package/dist/src/mcp/token-storage/base-token-storage.d.ts +19 -0
- package/dist/src/mcp/token-storage/base-token-storage.js +36 -0
- package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js +160 -0
- package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/types.d.ts +34 -0
- package/dist/src/mcp/token-storage/types.js +7 -0
- package/dist/src/mcp/token-storage/types.js.map +1 -0
- package/dist/src/mocks/msw.d.ts +6 -0
- package/dist/src/mocks/msw.js +8 -0
- package/dist/src/mocks/msw.js.map +1 -0
- package/dist/src/prompts/mcp-prompts.d.ts +8 -0
- package/dist/src/prompts/mcp-prompts.js +13 -0
- package/dist/src/prompts/mcp-prompts.js.map +1 -0
- package/dist/src/prompts/prompt-registry.d.ts +34 -0
- package/dist/src/prompts/prompt-registry.js +63 -0
- package/dist/src/prompts/prompt-registry.js.map +1 -0
- package/dist/src/services/chatRecordingService.d.ts +150 -0
- package/dist/src/services/chatRecordingService.js +321 -0
- package/dist/src/services/chatRecordingService.js.map +1 -0
- package/dist/src/services/chatRecordingService.test.d.ts +6 -0
- package/dist/src/services/chatRecordingService.test.js +290 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -0
- package/dist/src/services/fileDiscoveryService.d.ts +35 -0
- package/dist/src/services/fileDiscoveryService.js +91 -0
- package/dist/src/services/fileDiscoveryService.js.map +1 -0
- package/dist/src/services/fileDiscoveryService.test.d.ts +6 -0
- package/dist/src/services/fileDiscoveryService.test.js +143 -0
- package/dist/src/services/fileDiscoveryService.test.js.map +1 -0
- package/dist/src/services/fileSystemService.d.ts +31 -0
- package/dist/src/services/fileSystemService.js +18 -0
- package/dist/src/services/fileSystemService.js.map +1 -0
- package/dist/src/services/fileSystemService.test.d.ts +6 -0
- package/dist/src/services/fileSystemService.test.js +41 -0
- package/dist/src/services/fileSystemService.test.js.map +1 -0
- package/dist/src/services/gitService.d.ts +23 -0
- package/dist/src/services/gitService.js +110 -0
- package/dist/src/services/gitService.js.map +1 -0
- package/dist/src/services/gitService.test.d.ts +6 -0
- package/dist/src/services/gitService.test.js +212 -0
- package/dist/src/services/gitService.test.js.map +1 -0
- package/dist/src/services/loopDetectionService.d.ts +98 -0
- package/dist/src/services/loopDetectionService.js +363 -0
- package/dist/src/services/loopDetectionService.js.map +1 -0
- package/dist/src/services/loopDetectionService.test.d.ts +6 -0
- package/dist/src/services/loopDetectionService.test.js +558 -0
- package/dist/src/services/loopDetectionService.test.js.map +1 -0
- package/dist/src/services/shellExecutionService.d.ts +68 -0
- package/dist/src/services/shellExecutionService.js +332 -0
- package/dist/src/services/shellExecutionService.js.map +1 -0
- package/dist/src/services/shellExecutionService.test.d.ts +6 -0
- package/dist/src/services/shellExecutionService.test.js +517 -0
- package/dist/src/services/shellExecutionService.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +121 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +773 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +17 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +407 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +90 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +229 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -0
- package/dist/src/telemetry/constants.d.ts +32 -0
- package/dist/src/telemetry/constants.js +33 -0
- package/dist/src/telemetry/constants.js.map +1 -0
- package/dist/src/telemetry/file-exporters.d.ts +29 -0
- package/dist/src/telemetry/file-exporters.js +62 -0
- package/dist/src/telemetry/file-exporters.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +21 -0
- package/dist/src/telemetry/index.js +21 -0
- package/dist/src/telemetry/index.js.map +1 -0
- package/dist/src/telemetry/integration.test.circular.d.ts +6 -0
- package/dist/src/telemetry/integration.test.circular.js +54 -0
- package/dist/src/telemetry/integration.test.circular.js.map +1 -0
- package/dist/src/telemetry/loggers.d.ts +26 -0
- package/dist/src/telemetry/loggers.js +404 -0
- package/dist/src/telemetry/loggers.js.map +1 -0
- package/dist/src/telemetry/loggers.test.circular.d.ts +6 -0
- package/dist/src/telemetry/loggers.test.circular.js +107 -0
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -0
- package/dist/src/telemetry/loggers.test.d.ts +6 -0
- package/dist/src/telemetry/loggers.test.js +658 -0
- package/dist/src/telemetry/loggers.test.js.map +1 -0
- package/dist/src/telemetry/metrics.d.ts +36 -0
- package/dist/src/telemetry/metrics.js +208 -0
- package/dist/src/telemetry/metrics.js.map +1 -0
- package/dist/src/telemetry/metrics.test.d.ts +6 -0
- package/dist/src/telemetry/metrics.test.js +242 -0
- package/dist/src/telemetry/metrics.test.js.map +1 -0
- package/dist/src/telemetry/sdk.d.ts +9 -0
- package/dist/src/telemetry/sdk.js +163 -0
- package/dist/src/telemetry/sdk.js.map +1 -0
- package/dist/src/telemetry/sdk.test.d.ts +6 -0
- package/dist/src/telemetry/sdk.test.js +82 -0
- package/dist/src/telemetry/sdk.test.js.map +1 -0
- package/dist/src/telemetry/telemetry-utils.d.ts +6 -0
- package/dist/src/telemetry/telemetry-utils.js +14 -0
- package/dist/src/telemetry/telemetry-utils.js.map +1 -0
- package/dist/src/telemetry/telemetry-utils.test.d.ts +6 -0
- package/dist/src/telemetry/telemetry-utils.test.js +40 -0
- package/dist/src/telemetry/telemetry-utils.test.js.map +1 -0
- package/dist/src/telemetry/telemetry.test.d.ts +6 -0
- package/dist/src/telemetry/telemetry.test.js +50 -0
- package/dist/src/telemetry/telemetry.test.js.map +1 -0
- package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
- package/dist/src/telemetry/tool-call-decision.js +29 -0
- package/dist/src/telemetry/tool-call-decision.js.map +1 -0
- package/dist/src/telemetry/types.d.ts +220 -0
- package/dist/src/telemetry/types.js +383 -0
- package/dist/src/telemetry/types.js.map +1 -0
- package/dist/src/telemetry/uiTelemetry.d.ts +75 -0
- package/dist/src/telemetry/uiTelemetry.js +153 -0
- package/dist/src/telemetry/uiTelemetry.js.map +1 -0
- package/dist/src/telemetry/uiTelemetry.test.d.ts +6 -0
- package/dist/src/telemetry/uiTelemetry.test.js +558 -0
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -0
- package/dist/src/test-utils/config.d.ts +17 -0
- package/dist/src/test-utils/config.js +32 -0
- package/dist/src/test-utils/config.js.map +1 -0
- package/dist/src/test-utils/mockWorkspaceContext.d.ts +13 -0
- package/dist/src/test-utils/mockWorkspaceContext.js +24 -0
- package/dist/src/test-utils/mockWorkspaceContext.js.map +1 -0
- package/dist/src/test-utils/tools.d.ts +45 -0
- package/dist/src/test-utils/tools.js +105 -0
- package/dist/src/test-utils/tools.js.map +1 -0
- package/dist/src/tools/diffOptions.d.ts +9 -0
- package/dist/src/tools/diffOptions.js +38 -0
- package/dist/src/tools/diffOptions.js.map +1 -0
- package/dist/src/tools/diffOptions.test.d.ts +6 -0
- package/dist/src/tools/diffOptions.test.js +119 -0
- package/dist/src/tools/diffOptions.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +56 -0
- package/dist/src/tools/edit.js +423 -0
- package/dist/src/tools/edit.js.map +1 -0
- package/dist/src/tools/edit.test.d.ts +6 -0
- package/dist/src/tools/edit.test.js +713 -0
- package/dist/src/tools/edit.test.js.map +1 -0
- package/dist/src/tools/glob.d.ts +52 -0
- package/dist/src/tools/glob.js +236 -0
- package/dist/src/tools/glob.js.map +1 -0
- package/dist/src/tools/glob.test.d.ts +6 -0
- package/dist/src/tools/glob.test.js +375 -0
- package/dist/src/tools/glob.test.js.map +1 -0
- package/dist/src/tools/grep.d.ts +47 -0
- package/dist/src/tools/grep.js +517 -0
- package/dist/src/tools/grep.js.map +1 -0
- package/dist/src/tools/grep.test.d.ts +6 -0
- package/dist/src/tools/grep.test.js +295 -0
- package/dist/src/tools/grep.test.js.map +1 -0
- package/dist/src/tools/ls.d.ts +68 -0
- package/dist/src/tools/ls.js +227 -0
- package/dist/src/tools/ls.js.map +1 -0
- package/dist/src/tools/ls.test.d.ts +6 -0
- package/dist/src/tools/ls.test.js +389 -0
- package/dist/src/tools/ls.test.js.map +1 -0
- package/dist/src/tools/mcp-client-manager.d.ts +38 -0
- package/dist/src/tools/mcp-client-manager.js +74 -0
- package/dist/src/tools/mcp-client-manager.js.map +1 -0
- package/dist/src/tools/mcp-client-manager.test.d.ts +6 -0
- package/dist/src/tools/mcp-client-manager.test.js +39 -0
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -0
- package/dist/src/tools/mcp-client.d.ts +199 -0
- package/dist/src/tools/mcp-client.js +995 -0
- package/dist/src/tools/mcp-client.js.map +1 -0
- package/dist/src/tools/mcp-client.test.d.ts +6 -0
- package/dist/src/tools/mcp-client.test.js +454 -0
- package/dist/src/tools/mcp-client.test.js.map +1 -0
- package/dist/src/tools/mcp-tool.d.ts +23 -0
- package/dist/src/tools/mcp-tool.js +240 -0
- package/dist/src/tools/mcp-tool.js.map +1 -0
- package/dist/src/tools/mcp-tool.test.d.ts +6 -0
- package/dist/src/tools/mcp-tool.test.js +576 -0
- package/dist/src/tools/mcp-tool.test.js.map +1 -0
- package/dist/src/tools/memoryTool.d.ts +40 -0
- package/dist/src/tools/memoryTool.js +296 -0
- package/dist/src/tools/memoryTool.js.map +1 -0
- package/dist/src/tools/memoryTool.test.d.ts +6 -0
- package/dist/src/tools/memoryTool.test.js +298 -0
- package/dist/src/tools/memoryTool.test.js.map +1 -0
- package/dist/src/tools/modifiable-tool.d.ts +32 -0
- package/dist/src/tools/modifiable-tool.js +88 -0
- package/dist/src/tools/modifiable-tool.js.map +1 -0
- package/dist/src/tools/modifiable-tool.test.d.ts +6 -0
- package/dist/src/tools/modifiable-tool.test.js +193 -0
- package/dist/src/tools/modifiable-tool.test.js.map +1 -0
- package/dist/src/tools/read-file.d.ts +35 -0
- package/dist/src/tools/read-file.js +127 -0
- package/dist/src/tools/read-file.js.map +1 -0
- package/dist/src/tools/read-file.test.d.ts +6 -0
- package/dist/src/tools/read-file.test.js +311 -0
- package/dist/src/tools/read-file.test.js.map +1 -0
- package/dist/src/tools/read-many-files.d.ts +60 -0
- package/dist/src/tools/read-many-files.js +414 -0
- package/dist/src/tools/read-many-files.js.map +1 -0
- package/dist/src/tools/read-many-files.test.d.ts +6 -0
- package/dist/src/tools/read-many-files.test.js +565 -0
- package/dist/src/tools/read-many-files.test.js.map +1 -0
- package/dist/src/tools/ripGrep.d.ts +47 -0
- package/dist/src/tools/ripGrep.js +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 +22 -0
- package/dist/src/tools/shell.js +320 -0
- package/dist/src/tools/shell.js.map +1 -0
- package/dist/src/tools/shell.test.d.ts +6 -0
- package/dist/src/tools/shell.test.js +336 -0
- package/dist/src/tools/shell.test.js.map +1 -0
- package/dist/src/tools/tool-error.d.ts +43 -0
- package/dist/src/tools/tool-error.js +58 -0
- package/dist/src/tools/tool-error.js.map +1 -0
- package/dist/src/tools/tool-registry.d.ts +86 -0
- package/dist/src/tools/tool-registry.js +369 -0
- package/dist/src/tools/tool-registry.js.map +1 -0
- package/dist/src/tools/tool-registry.test.d.ts +6 -0
- package/dist/src/tools/tool-registry.test.js +332 -0
- package/dist/src/tools/tool-registry.test.js.map +1 -0
- package/dist/src/tools/tools.d.ts +274 -0
- package/dist/src/tools/tools.js +250 -0
- package/dist/src/tools/tools.js.map +1 -0
- package/dist/src/tools/tools.test.d.ts +6 -0
- package/dist/src/tools/tools.test.js +205 -0
- package/dist/src/tools/tools.test.js.map +1 -0
- package/dist/src/tools/web-fetch.d.ts +27 -0
- package/dist/src/tools/web-fetch.js +243 -0
- package/dist/src/tools/web-fetch.js.map +1 -0
- package/dist/src/tools/web-fetch.test.d.ts +6 -0
- package/dist/src/tools/web-fetch.test.js +114 -0
- package/dist/src/tools/web-fetch.test.js.map +1 -0
- package/dist/src/tools/web-search.d.ts +49 -0
- package/dist/src/tools/web-search.js +137 -0
- package/dist/src/tools/web-search.js.map +1 -0
- package/dist/src/tools/web-search.test.d.ts +6 -0
- package/dist/src/tools/web-search.test.js +207 -0
- package/dist/src/tools/web-search.test.js.map +1 -0
- package/dist/src/tools/write-file.d.ts +52 -0
- package/dist/src/tools/write-file.js +314 -0
- package/dist/src/tools/write-file.js.map +1 -0
- package/dist/src/tools/write-file.test.d.ts +6 -0
- package/dist/src/tools/write-file.test.js +531 -0
- package/dist/src/tools/write-file.test.js.map +1 -0
- package/dist/src/utils/LruCache.d.ts +13 -0
- package/dist/src/utils/LruCache.js +38 -0
- package/dist/src/utils/LruCache.js.map +1 -0
- package/dist/src/utils/bfsFileSearch.d.ts +24 -0
- package/dist/src/utils/bfsFileSearch.js +89 -0
- package/dist/src/utils/bfsFileSearch.js.map +1 -0
- package/dist/src/utils/bfsFileSearch.test.d.ts +6 -0
- package/dist/src/utils/bfsFileSearch.test.js +163 -0
- package/dist/src/utils/bfsFileSearch.test.js.map +1 -0
- package/dist/src/utils/browser.d.ts +13 -0
- package/dist/src/utils/browser.js +50 -0
- package/dist/src/utils/browser.js.map +1 -0
- package/dist/src/utils/editCorrector.d.ts +53 -0
- package/dist/src/utils/editCorrector.js +545 -0
- package/dist/src/utils/editCorrector.js.map +1 -0
- package/dist/src/utils/editCorrector.test.d.ts +6 -0
- package/dist/src/utils/editCorrector.test.js +564 -0
- package/dist/src/utils/editCorrector.test.js.map +1 -0
- package/dist/src/utils/editor.d.ts +28 -0
- package/dist/src/utils/editor.js +186 -0
- package/dist/src/utils/editor.js.map +1 -0
- package/dist/src/utils/editor.test.d.ts +6 -0
- package/dist/src/utils/editor.test.js +445 -0
- package/dist/src/utils/editor.test.js.map +1 -0
- package/dist/src/utils/environmentContext.d.ts +21 -0
- package/dist/src/utils/environmentContext.js +90 -0
- package/dist/src/utils/environmentContext.js.map +1 -0
- package/dist/src/utils/environmentContext.test.d.ts +6 -0
- package/dist/src/utils/environmentContext.test.js +140 -0
- package/dist/src/utils/environmentContext.test.js.map +1 -0
- package/dist/src/utils/errorParsing.d.ts +8 -0
- package/dist/src/utils/errorParsing.js +93 -0
- package/dist/src/utils/errorParsing.js.map +1 -0
- package/dist/src/utils/errorParsing.test.d.ts +6 -0
- package/dist/src/utils/errorParsing.test.js +172 -0
- package/dist/src/utils/errorParsing.test.js.map +1 -0
- package/dist/src/utils/errorReporting.d.ts +14 -0
- package/dist/src/utils/errorReporting.js +88 -0
- package/dist/src/utils/errorReporting.js.map +1 -0
- package/dist/src/utils/errorReporting.test.d.ts +6 -0
- package/dist/src/utils/errorReporting.test.js +130 -0
- package/dist/src/utils/errorReporting.test.js.map +1 -0
- package/dist/src/utils/errors.d.ts +33 -0
- package/dist/src/utils/errors.js +86 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/fetch.d.ts +11 -0
- package/dist/src/utils/fetch.js +51 -0
- package/dist/src/utils/fetch.js.map +1 -0
- package/dist/src/utils/fileUtils.d.ts +52 -0
- package/dist/src/utils/fileUtils.js +283 -0
- package/dist/src/utils/fileUtils.js.map +1 -0
- package/dist/src/utils/fileUtils.test.d.ts +6 -0
- package/dist/src/utils/fileUtils.test.js +364 -0
- package/dist/src/utils/fileUtils.test.js.map +1 -0
- package/dist/src/utils/filesearch/crawlCache.d.ts +25 -0
- package/dist/src/utils/filesearch/crawlCache.js +57 -0
- package/dist/src/utils/filesearch/crawlCache.js.map +1 -0
- package/dist/src/utils/filesearch/crawlCache.test.d.ts +6 -0
- package/dist/src/utils/filesearch/crawlCache.test.js +103 -0
- package/dist/src/utils/filesearch/crawlCache.test.js.map +1 -0
- package/dist/src/utils/filesearch/crawler.d.ts +15 -0
- package/dist/src/utils/filesearch/crawler.js +50 -0
- package/dist/src/utils/filesearch/crawler.js.map +1 -0
- package/dist/src/utils/filesearch/crawler.test.d.ts +6 -0
- package/dist/src/utils/filesearch/crawler.test.js +468 -0
- package/dist/src/utils/filesearch/crawler.test.js.map +1 -0
- package/dist/src/utils/filesearch/fileSearch.d.ts +38 -0
- package/dist/src/utils/filesearch/fileSearch.js +191 -0
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -0
- package/dist/src/utils/filesearch/fileSearch.test.d.ts +6 -0
- package/dist/src/utils/filesearch/fileSearch.test.js +642 -0
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -0
- package/dist/src/utils/filesearch/ignore.d.ts +42 -0
- package/dist/src/utils/filesearch/ignore.js +106 -0
- package/dist/src/utils/filesearch/ignore.js.map +1 -0
- package/dist/src/utils/filesearch/ignore.test.d.ts +6 -0
- package/dist/src/utils/filesearch/ignore.test.js +144 -0
- package/dist/src/utils/filesearch/ignore.test.js.map +1 -0
- package/dist/src/utils/filesearch/result-cache.d.ts +33 -0
- package/dist/src/utils/filesearch/result-cache.js +59 -0
- package/dist/src/utils/filesearch/result-cache.js.map +1 -0
- package/dist/src/utils/filesearch/result-cache.test.d.ts +6 -0
- package/dist/src/utils/filesearch/result-cache.test.js +46 -0
- package/dist/src/utils/filesearch/result-cache.test.js.map +1 -0
- package/dist/src/utils/flashFallback.integration.test.d.ts +6 -0
- package/dist/src/utils/flashFallback.integration.test.js +118 -0
- package/dist/src/utils/flashFallback.integration.test.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +6 -0
- package/dist/src/utils/formatters.js +16 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/generateContentResponseUtilities.d.ts +13 -0
- package/dist/src/utils/generateContentResponseUtilities.js +80 -0
- package/dist/src/utils/generateContentResponseUtilities.js.map +1 -0
- package/dist/src/utils/generateContentResponseUtilities.test.d.ts +6 -0
- package/dist/src/utils/generateContentResponseUtilities.test.js +235 -0
- package/dist/src/utils/generateContentResponseUtilities.test.js.map +1 -0
- package/dist/src/utils/getFolderStructure.d.ts +31 -0
- package/dist/src/utils/getFolderStructure.js +246 -0
- package/dist/src/utils/getFolderStructure.js.map +1 -0
- package/dist/src/utils/getFolderStructure.test.d.ts +6 -0
- package/dist/src/utils/getFolderStructure.test.js +282 -0
- package/dist/src/utils/getFolderStructure.test.js.map +1 -0
- package/dist/src/utils/getPty.d.ts +19 -0
- package/dist/src/utils/getPty.js +23 -0
- package/dist/src/utils/getPty.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.d.ts +20 -0
- package/dist/src/utils/gitIgnoreParser.js +61 -0
- package/dist/src/utils/gitIgnoreParser.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.test.d.ts +6 -0
- package/dist/src/utils/gitIgnoreParser.test.js +154 -0
- package/dist/src/utils/gitIgnoreParser.test.js.map +1 -0
- package/dist/src/utils/gitUtils.d.ts +17 -0
- package/dist/src/utils/gitUtils.js +61 -0
- package/dist/src/utils/gitUtils.js.map +1 -0
- package/dist/src/utils/ignorePatterns.d.ts +103 -0
- package/dist/src/utils/ignorePatterns.js +220 -0
- package/dist/src/utils/ignorePatterns.js.map +1 -0
- package/dist/src/utils/ignorePatterns.test.d.ts +6 -0
- package/dist/src/utils/ignorePatterns.test.js +250 -0
- package/dist/src/utils/ignorePatterns.test.js.map +1 -0
- package/dist/src/utils/installationManager.d.ts +16 -0
- package/dist/src/utils/installationManager.js +50 -0
- package/dist/src/utils/installationManager.js.map +1 -0
- package/dist/src/utils/installationManager.test.d.ts +6 -0
- package/dist/src/utils/installationManager.test.js +83 -0
- package/dist/src/utils/installationManager.test.js.map +1 -0
- package/dist/src/utils/language-detection.d.ts +6 -0
- package/dist/src/utils/language-detection.js +101 -0
- package/dist/src/utils/language-detection.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.d.ts +15 -0
- package/dist/src/utils/memoryDiscovery.js +253 -0
- package/dist/src/utils/memoryDiscovery.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.test.d.ts +6 -0
- package/dist/src/utils/memoryDiscovery.test.js +219 -0
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -0
- package/dist/src/utils/memoryImportProcessor.d.ts +42 -0
- package/dist/src/utils/memoryImportProcessor.js +296 -0
- package/dist/src/utils/memoryImportProcessor.js.map +1 -0
- package/dist/src/utils/memoryImportProcessor.test.d.ts +6 -0
- package/dist/src/utils/memoryImportProcessor.test.js +573 -0
- package/dist/src/utils/memoryImportProcessor.test.js.map +1 -0
- package/dist/src/utils/messageInspectors.d.ts +8 -0
- package/dist/src/utils/messageInspectors.js +16 -0
- package/dist/src/utils/messageInspectors.js.map +1 -0
- package/dist/src/utils/nextSpeakerChecker.d.ts +12 -0
- package/dist/src/utils/nextSpeakerChecker.js +91 -0
- package/dist/src/utils/nextSpeakerChecker.js.map +1 -0
- package/dist/src/utils/nextSpeakerChecker.test.d.ts +6 -0
- package/dist/src/utils/nextSpeakerChecker.test.js +168 -0
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -0
- package/dist/src/utils/partUtils.d.ts +35 -0
- package/dist/src/utils/partUtils.js +133 -0
- package/dist/src/utils/partUtils.js.map +1 -0
- package/dist/src/utils/partUtils.test.d.ts +6 -0
- package/dist/src/utils/partUtils.test.js +241 -0
- package/dist/src/utils/partUtils.test.js.map +1 -0
- package/dist/src/utils/pathReader.d.ts +17 -0
- package/dist/src/utils/pathReader.js +92 -0
- package/dist/src/utils/pathReader.js.map +1 -0
- package/dist/src/utils/pathReader.test.d.ts +6 -0
- package/dist/src/utils/pathReader.test.js +363 -0
- package/dist/src/utils/pathReader.test.js.map +1 -0
- package/dist/src/utils/paths.d.ts +58 -0
- package/dist/src/utils/paths.js +159 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/utils/paths.test.d.ts +6 -0
- package/dist/src/utils/paths.test.js +225 -0
- package/dist/src/utils/paths.test.js.map +1 -0
- package/dist/src/utils/quotaErrorDetection.d.ts +18 -0
- package/dist/src/utils/quotaErrorDetection.js +65 -0
- package/dist/src/utils/quotaErrorDetection.js.map +1 -0
- package/dist/src/utils/retry.d.ts +30 -0
- package/dist/src/utils/retry.js +276 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/utils/retry.test.d.ts +6 -0
- package/dist/src/utils/retry.test.js +325 -0
- package/dist/src/utils/retry.test.js.map +1 -0
- package/dist/src/utils/safeJsonStringify.d.ts +13 -0
- package/dist/src/utils/safeJsonStringify.js +25 -0
- package/dist/src/utils/safeJsonStringify.js.map +1 -0
- package/dist/src/utils/safeJsonStringify.test.d.ts +6 -0
- package/dist/src/utils/safeJsonStringify.test.js +61 -0
- package/dist/src/utils/safeJsonStringify.test.js.map +1 -0
- package/dist/src/utils/schemaValidator.d.ts +15 -0
- package/dist/src/utils/schemaValidator.js +38 -0
- package/dist/src/utils/schemaValidator.js.map +1 -0
- package/dist/src/utils/secure-browser-launcher.d.ts +23 -0
- package/dist/src/utils/secure-browser-launcher.js +165 -0
- package/dist/src/utils/secure-browser-launcher.js.map +1 -0
- package/dist/src/utils/secure-browser-launcher.test.d.ts +6 -0
- package/dist/src/utils/secure-browser-launcher.test.js +149 -0
- package/dist/src/utils/secure-browser-launcher.test.js.map +1 -0
- package/dist/src/utils/session.d.ts +6 -0
- package/dist/src/utils/session.js +8 -0
- package/dist/src/utils/session.js.map +1 -0
- package/dist/src/utils/shell-utils.d.ts +117 -0
- package/dist/src/utils/shell-utils.js +370 -0
- package/dist/src/utils/shell-utils.js.map +1 -0
- package/dist/src/utils/shell-utils.test.d.ts +6 -0
- package/dist/src/utils/shell-utils.test.js +332 -0
- package/dist/src/utils/shell-utils.test.js.map +1 -0
- package/dist/src/utils/summarizer.d.ts +25 -0
- package/dist/src/utils/summarizer.js +51 -0
- package/dist/src/utils/summarizer.js.map +1 -0
- package/dist/src/utils/summarizer.test.d.ts +6 -0
- package/dist/src/utils/summarizer.test.js +131 -0
- package/dist/src/utils/summarizer.test.js.map +1 -0
- package/dist/src/utils/systemEncoding.d.ts +40 -0
- package/dist/src/utils/systemEncoding.js +149 -0
- package/dist/src/utils/systemEncoding.js.map +1 -0
- package/dist/src/utils/systemEncoding.test.d.ts +6 -0
- package/dist/src/utils/systemEncoding.test.js +368 -0
- package/dist/src/utils/systemEncoding.test.js.map +1 -0
- package/dist/src/utils/testUtils.d.ts +29 -0
- package/dist/src/utils/testUtils.js +70 -0
- package/dist/src/utils/testUtils.js.map +1 -0
- package/dist/src/utils/textUtils.d.ts +13 -0
- package/dist/src/utils/textUtils.js +28 -0
- package/dist/src/utils/textUtils.js.map +1 -0
- package/dist/src/utils/tool-utils.d.ts +19 -0
- package/dist/src/utils/tool-utils.js +58 -0
- package/dist/src/utils/tool-utils.js.map +1 -0
- package/dist/src/utils/tool-utils.test.d.ts +6 -0
- package/dist/src/utils/tool-utils.test.js +61 -0
- package/dist/src/utils/tool-utils.test.js.map +1 -0
- package/dist/src/utils/userAccountManager.d.ts +20 -0
- package/dist/src/utils/userAccountManager.js +114 -0
- package/dist/src/utils/userAccountManager.js.map +1 -0
- package/dist/src/utils/userAccountManager.test.d.ts +6 -0
- package/dist/src/utils/userAccountManager.test.js +223 -0
- package/dist/src/utils/userAccountManager.test.js.map +1 -0
- package/dist/src/utils/workspaceContext.d.ts +66 -0
- package/dist/src/utils/workspaceContext.js +171 -0
- package/dist/src/utils/workspaceContext.js.map +1 -0
- package/dist/src/utils/workspaceContext.test.d.ts +6 -0
- package/dist/src/utils/workspaceContext.test.js +318 -0
- package/dist/src/utils/workspaceContext.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { getDirectoryContextString, getEnvironmentContext, } from '../utils/environmentContext.js';
|
|
7
|
+
import { CompressionStatus } from './turn.js';
|
|
8
|
+
import { Turn, GeminiEventType } from './turn.js';
|
|
9
|
+
import { getCoreSystemPrompt, getCompressionPrompt } from './prompts.js';
|
|
10
|
+
import { getResponseText } from '../utils/partUtils.js';
|
|
11
|
+
import { checkNextSpeaker } from '../utils/nextSpeakerChecker.js';
|
|
12
|
+
import { reportError } from '../utils/errorReporting.js';
|
|
13
|
+
import { GeminiChat } from './geminiChat.js';
|
|
14
|
+
import { retryWithBackoff } from '../utils/retry.js';
|
|
15
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
16
|
+
import { isFunctionResponse } from '../utils/messageInspectors.js';
|
|
17
|
+
import { tokenLimit } from './tokenLimits.js';
|
|
18
|
+
import { AuthType, createContentGenerator } from './contentGenerator.js';
|
|
19
|
+
import { ProxyAgent, setGlobalDispatcher } from 'undici';
|
|
20
|
+
import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
|
|
21
|
+
import { LoopDetectionService } from '../services/loopDetectionService.js';
|
|
22
|
+
import { ideContext } from '../ide/ideContext.js';
|
|
23
|
+
import { logChatCompression, logNextSpeakerCheck, logMalformedJsonResponse, } from '../telemetry/loggers.js';
|
|
24
|
+
import { makeChatCompressionEvent, MalformedJsonResponseEvent, NextSpeakerCheckEvent, } from '../telemetry/types.js';
|
|
25
|
+
function isThinkingSupported(model) {
|
|
26
|
+
if (model.startsWith('gemini-2.5'))
|
|
27
|
+
return true;
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns the index of the content after the fraction of the total characters in the history.
|
|
32
|
+
*
|
|
33
|
+
* Exported for testing purposes.
|
|
34
|
+
*/
|
|
35
|
+
export function findIndexAfterFraction(history, fraction) {
|
|
36
|
+
if (fraction <= 0 || fraction >= 1) {
|
|
37
|
+
throw new Error('Fraction must be between 0 and 1');
|
|
38
|
+
}
|
|
39
|
+
const contentLengths = history.map((content) => JSON.stringify(content).length);
|
|
40
|
+
const totalCharacters = contentLengths.reduce((sum, length) => sum + length, 0);
|
|
41
|
+
const targetCharacters = totalCharacters * fraction;
|
|
42
|
+
let charactersSoFar = 0;
|
|
43
|
+
for (let i = 0; i < contentLengths.length; i++) {
|
|
44
|
+
charactersSoFar += contentLengths[i];
|
|
45
|
+
if (charactersSoFar >= targetCharacters) {
|
|
46
|
+
return i;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return contentLengths.length;
|
|
50
|
+
}
|
|
51
|
+
const MAX_TURNS = 100;
|
|
52
|
+
/**
|
|
53
|
+
* Threshold for compression token count as a fraction of the model's token limit.
|
|
54
|
+
* If the chat history exceeds this threshold, it will be compressed.
|
|
55
|
+
*/
|
|
56
|
+
const COMPRESSION_TOKEN_THRESHOLD = 0.7;
|
|
57
|
+
/**
|
|
58
|
+
* The fraction of the latest chat history to keep. A value of 0.3
|
|
59
|
+
* means that only the last 30% of the chat history will be kept after compression.
|
|
60
|
+
*/
|
|
61
|
+
const COMPRESSION_PRESERVE_THRESHOLD = 0.3;
|
|
62
|
+
export class GeminiClient {
|
|
63
|
+
config;
|
|
64
|
+
chat;
|
|
65
|
+
contentGenerator;
|
|
66
|
+
embeddingModel;
|
|
67
|
+
generateContentConfig = {
|
|
68
|
+
temperature: 0,
|
|
69
|
+
topP: 1,
|
|
70
|
+
};
|
|
71
|
+
sessionTurnCount = 0;
|
|
72
|
+
loopDetector;
|
|
73
|
+
lastPromptId;
|
|
74
|
+
lastSentIdeContext;
|
|
75
|
+
forceFullIdeContext = true;
|
|
76
|
+
/**
|
|
77
|
+
* At any point in this conversation, was compression triggered without
|
|
78
|
+
* being forced and did it fail?
|
|
79
|
+
*/
|
|
80
|
+
hasFailedCompressionAttempt = false;
|
|
81
|
+
constructor(config) {
|
|
82
|
+
this.config = config;
|
|
83
|
+
if (config.getProxy()) {
|
|
84
|
+
setGlobalDispatcher(new ProxyAgent(config.getProxy()));
|
|
85
|
+
}
|
|
86
|
+
this.embeddingModel = config.getEmbeddingModel();
|
|
87
|
+
this.loopDetector = new LoopDetectionService(config);
|
|
88
|
+
this.lastPromptId = this.config.getSessionId();
|
|
89
|
+
}
|
|
90
|
+
async initialize(contentGeneratorConfig) {
|
|
91
|
+
this.contentGenerator = await createContentGenerator(contentGeneratorConfig, this.config, this.config.getSessionId());
|
|
92
|
+
this.chat = await this.startChat();
|
|
93
|
+
}
|
|
94
|
+
getContentGenerator() {
|
|
95
|
+
if (!this.contentGenerator) {
|
|
96
|
+
throw new Error('Content generator not initialized');
|
|
97
|
+
}
|
|
98
|
+
return this.contentGenerator;
|
|
99
|
+
}
|
|
100
|
+
getUserTier() {
|
|
101
|
+
return this.contentGenerator?.userTier;
|
|
102
|
+
}
|
|
103
|
+
async addHistory(content) {
|
|
104
|
+
this.getChat().addHistory(content);
|
|
105
|
+
}
|
|
106
|
+
getChat() {
|
|
107
|
+
if (!this.chat) {
|
|
108
|
+
throw new Error('Chat not initialized');
|
|
109
|
+
}
|
|
110
|
+
return this.chat;
|
|
111
|
+
}
|
|
112
|
+
isInitialized() {
|
|
113
|
+
return this.chat !== undefined && this.contentGenerator !== undefined;
|
|
114
|
+
}
|
|
115
|
+
getHistory() {
|
|
116
|
+
return this.getChat().getHistory();
|
|
117
|
+
}
|
|
118
|
+
setHistory(history, { stripThoughts = false } = {}) {
|
|
119
|
+
const historyToSet = stripThoughts
|
|
120
|
+
? history.map((content) => {
|
|
121
|
+
const newContent = { ...content };
|
|
122
|
+
if (newContent.parts) {
|
|
123
|
+
newContent.parts = newContent.parts.map((part) => {
|
|
124
|
+
if (part &&
|
|
125
|
+
typeof part === 'object' &&
|
|
126
|
+
'thoughtSignature' in part) {
|
|
127
|
+
const newPart = { ...part };
|
|
128
|
+
delete newPart
|
|
129
|
+
.thoughtSignature;
|
|
130
|
+
return newPart;
|
|
131
|
+
}
|
|
132
|
+
return part;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return newContent;
|
|
136
|
+
})
|
|
137
|
+
: history;
|
|
138
|
+
this.getChat().setHistory(historyToSet);
|
|
139
|
+
this.forceFullIdeContext = true;
|
|
140
|
+
}
|
|
141
|
+
async setTools() {
|
|
142
|
+
const toolRegistry = this.config.getToolRegistry();
|
|
143
|
+
const toolDeclarations = toolRegistry.getFunctionDeclarations();
|
|
144
|
+
const tools = [{ functionDeclarations: toolDeclarations }];
|
|
145
|
+
this.getChat().setTools(tools);
|
|
146
|
+
}
|
|
147
|
+
async resetChat() {
|
|
148
|
+
this.chat = await this.startChat();
|
|
149
|
+
}
|
|
150
|
+
async addDirectoryContext() {
|
|
151
|
+
if (!this.chat) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
this.getChat().addHistory({
|
|
155
|
+
role: 'user',
|
|
156
|
+
parts: [{ text: await getDirectoryContextString(this.config) }],
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async startChat(extraHistory) {
|
|
160
|
+
this.forceFullIdeContext = true;
|
|
161
|
+
this.hasFailedCompressionAttempt = false;
|
|
162
|
+
const envParts = await getEnvironmentContext(this.config);
|
|
163
|
+
const toolRegistry = this.config.getToolRegistry();
|
|
164
|
+
const toolDeclarations = toolRegistry.getFunctionDeclarations();
|
|
165
|
+
const tools = [{ functionDeclarations: toolDeclarations }];
|
|
166
|
+
const history = [
|
|
167
|
+
{
|
|
168
|
+
role: 'user',
|
|
169
|
+
parts: envParts,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
role: 'model',
|
|
173
|
+
parts: [{ text: 'Got it. Thanks for the context!' }],
|
|
174
|
+
},
|
|
175
|
+
...(extraHistory ?? []),
|
|
176
|
+
];
|
|
177
|
+
try {
|
|
178
|
+
const userMemory = this.config.getUserMemory();
|
|
179
|
+
const systemInstruction = getCoreSystemPrompt(userMemory);
|
|
180
|
+
const generateContentConfigWithThinking = isThinkingSupported(this.config.getModel())
|
|
181
|
+
? {
|
|
182
|
+
...this.generateContentConfig,
|
|
183
|
+
thinkingConfig: {
|
|
184
|
+
thinkingBudget: -1,
|
|
185
|
+
includeThoughts: true,
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
: this.generateContentConfig;
|
|
189
|
+
return new GeminiChat(this.config, this.getContentGenerator(), {
|
|
190
|
+
systemInstruction,
|
|
191
|
+
...generateContentConfigWithThinking,
|
|
192
|
+
tools,
|
|
193
|
+
}, history);
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
await reportError(error, 'Error initializing Gemini chat session.', history, 'startChat');
|
|
197
|
+
throw new Error(`Failed to initialize chat: ${getErrorMessage(error)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
getIdeContextParts(forceFullContext) {
|
|
201
|
+
const currentIdeContext = ideContext.getIdeContext();
|
|
202
|
+
if (!currentIdeContext) {
|
|
203
|
+
return { contextParts: [], newIdeContext: undefined };
|
|
204
|
+
}
|
|
205
|
+
if (forceFullContext || !this.lastSentIdeContext) {
|
|
206
|
+
// Send full context as JSON
|
|
207
|
+
const openFiles = currentIdeContext.workspaceState?.openFiles || [];
|
|
208
|
+
const activeFile = openFiles.find((f) => f.isActive);
|
|
209
|
+
const otherOpenFiles = openFiles
|
|
210
|
+
.filter((f) => !f.isActive)
|
|
211
|
+
.map((f) => f.path);
|
|
212
|
+
const contextData = {};
|
|
213
|
+
if (activeFile) {
|
|
214
|
+
contextData['activeFile'] = {
|
|
215
|
+
path: activeFile.path,
|
|
216
|
+
cursor: activeFile.cursor
|
|
217
|
+
? {
|
|
218
|
+
line: activeFile.cursor.line,
|
|
219
|
+
character: activeFile.cursor.character,
|
|
220
|
+
}
|
|
221
|
+
: undefined,
|
|
222
|
+
selectedText: activeFile.selectedText || undefined,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (otherOpenFiles.length > 0) {
|
|
226
|
+
contextData['otherOpenFiles'] = otherOpenFiles;
|
|
227
|
+
}
|
|
228
|
+
if (Object.keys(contextData).length === 0) {
|
|
229
|
+
return { contextParts: [], newIdeContext: currentIdeContext };
|
|
230
|
+
}
|
|
231
|
+
const jsonString = JSON.stringify(contextData, null, 2);
|
|
232
|
+
const contextParts = [
|
|
233
|
+
"Here is the user's editor context as a JSON object. This is for your information only.",
|
|
234
|
+
'```json',
|
|
235
|
+
jsonString,
|
|
236
|
+
'```',
|
|
237
|
+
];
|
|
238
|
+
if (this.config.getDebugMode()) {
|
|
239
|
+
console.log(contextParts.join('\n'));
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
contextParts,
|
|
243
|
+
newIdeContext: currentIdeContext,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// Calculate and send delta as JSON
|
|
248
|
+
const delta = {};
|
|
249
|
+
const changes = {};
|
|
250
|
+
const lastFiles = new Map((this.lastSentIdeContext.workspaceState?.openFiles || []).map((f) => [f.path, f]));
|
|
251
|
+
const currentFiles = new Map((currentIdeContext.workspaceState?.openFiles || []).map((f) => [
|
|
252
|
+
f.path,
|
|
253
|
+
f,
|
|
254
|
+
]));
|
|
255
|
+
const openedFiles = [];
|
|
256
|
+
for (const [path] of currentFiles.entries()) {
|
|
257
|
+
if (!lastFiles.has(path)) {
|
|
258
|
+
openedFiles.push(path);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (openedFiles.length > 0) {
|
|
262
|
+
changes['filesOpened'] = openedFiles;
|
|
263
|
+
}
|
|
264
|
+
const closedFiles = [];
|
|
265
|
+
for (const [path] of lastFiles.entries()) {
|
|
266
|
+
if (!currentFiles.has(path)) {
|
|
267
|
+
closedFiles.push(path);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (closedFiles.length > 0) {
|
|
271
|
+
changes['filesClosed'] = closedFiles;
|
|
272
|
+
}
|
|
273
|
+
const lastActiveFile = (this.lastSentIdeContext.workspaceState?.openFiles || []).find((f) => f.isActive);
|
|
274
|
+
const currentActiveFile = (currentIdeContext.workspaceState?.openFiles || []).find((f) => f.isActive);
|
|
275
|
+
if (currentActiveFile) {
|
|
276
|
+
if (!lastActiveFile || lastActiveFile.path !== currentActiveFile.path) {
|
|
277
|
+
changes['activeFileChanged'] = {
|
|
278
|
+
path: currentActiveFile.path,
|
|
279
|
+
cursor: currentActiveFile.cursor
|
|
280
|
+
? {
|
|
281
|
+
line: currentActiveFile.cursor.line,
|
|
282
|
+
character: currentActiveFile.cursor.character,
|
|
283
|
+
}
|
|
284
|
+
: undefined,
|
|
285
|
+
selectedText: currentActiveFile.selectedText || undefined,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
const lastCursor = lastActiveFile.cursor;
|
|
290
|
+
const currentCursor = currentActiveFile.cursor;
|
|
291
|
+
if (currentCursor &&
|
|
292
|
+
(!lastCursor ||
|
|
293
|
+
lastCursor.line !== currentCursor.line ||
|
|
294
|
+
lastCursor.character !== currentCursor.character)) {
|
|
295
|
+
changes['cursorMoved'] = {
|
|
296
|
+
path: currentActiveFile.path,
|
|
297
|
+
cursor: {
|
|
298
|
+
line: currentCursor.line,
|
|
299
|
+
character: currentCursor.character,
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const lastSelectedText = lastActiveFile.selectedText || '';
|
|
304
|
+
const currentSelectedText = currentActiveFile.selectedText || '';
|
|
305
|
+
if (lastSelectedText !== currentSelectedText) {
|
|
306
|
+
changes['selectionChanged'] = {
|
|
307
|
+
path: currentActiveFile.path,
|
|
308
|
+
selectedText: currentSelectedText,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else if (lastActiveFile) {
|
|
314
|
+
changes['activeFileChanged'] = {
|
|
315
|
+
path: null,
|
|
316
|
+
previousPath: lastActiveFile.path,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
if (Object.keys(changes).length === 0) {
|
|
320
|
+
return { contextParts: [], newIdeContext: currentIdeContext };
|
|
321
|
+
}
|
|
322
|
+
delta['changes'] = changes;
|
|
323
|
+
const jsonString = JSON.stringify(delta, null, 2);
|
|
324
|
+
const contextParts = [
|
|
325
|
+
"Here is a summary of changes in the user's editor context, in JSON format. This is for your information only.",
|
|
326
|
+
'```json',
|
|
327
|
+
jsonString,
|
|
328
|
+
'```',
|
|
329
|
+
];
|
|
330
|
+
if (this.config.getDebugMode()) {
|
|
331
|
+
console.log(contextParts.join('\n'));
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
contextParts,
|
|
335
|
+
newIdeContext: currentIdeContext,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
async *sendMessageStream(request, signal, prompt_id, turns = MAX_TURNS, originalModel) {
|
|
340
|
+
if (this.lastPromptId !== prompt_id) {
|
|
341
|
+
this.loopDetector.reset(prompt_id);
|
|
342
|
+
this.lastPromptId = prompt_id;
|
|
343
|
+
}
|
|
344
|
+
this.sessionTurnCount++;
|
|
345
|
+
if (this.config.getMaxSessionTurns() > 0 &&
|
|
346
|
+
this.sessionTurnCount > this.config.getMaxSessionTurns()) {
|
|
347
|
+
yield { type: GeminiEventType.MaxSessionTurns };
|
|
348
|
+
return new Turn(this.getChat(), prompt_id);
|
|
349
|
+
}
|
|
350
|
+
// Ensure turns never exceeds MAX_TURNS to prevent infinite loops
|
|
351
|
+
const boundedTurns = Math.min(turns, MAX_TURNS);
|
|
352
|
+
if (!boundedTurns) {
|
|
353
|
+
return new Turn(this.getChat(), prompt_id);
|
|
354
|
+
}
|
|
355
|
+
// Track the original model from the first call to detect model switching
|
|
356
|
+
const initialModel = originalModel || this.config.getModel();
|
|
357
|
+
const compressed = await this.tryCompressChat(prompt_id);
|
|
358
|
+
if (compressed.compressionStatus === CompressionStatus.COMPRESSED) {
|
|
359
|
+
yield { type: GeminiEventType.ChatCompressed, value: compressed };
|
|
360
|
+
}
|
|
361
|
+
// Prevent context updates from being sent while a tool call is
|
|
362
|
+
// waiting for a response. The Gemini API requires that a functionResponse
|
|
363
|
+
// part from the user immediately follows a functionCall part from the model
|
|
364
|
+
// in the conversation history . The IDE context is not discarded; it will
|
|
365
|
+
// be included in the next regular message sent to the model.
|
|
366
|
+
const history = this.getHistory();
|
|
367
|
+
const lastMessage = history.length > 0 ? history[history.length - 1] : undefined;
|
|
368
|
+
const hasPendingToolCall = !!lastMessage &&
|
|
369
|
+
lastMessage.role === 'model' &&
|
|
370
|
+
(lastMessage.parts?.some((p) => 'functionCall' in p) || false);
|
|
371
|
+
if (this.config.getIdeMode() && !hasPendingToolCall) {
|
|
372
|
+
const { contextParts, newIdeContext } = this.getIdeContextParts(this.forceFullIdeContext || history.length === 0);
|
|
373
|
+
if (contextParts.length > 0) {
|
|
374
|
+
this.getChat().addHistory({
|
|
375
|
+
role: 'user',
|
|
376
|
+
parts: [{ text: contextParts.join('\n') }],
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
this.lastSentIdeContext = newIdeContext;
|
|
380
|
+
this.forceFullIdeContext = false;
|
|
381
|
+
}
|
|
382
|
+
const turn = new Turn(this.getChat(), prompt_id);
|
|
383
|
+
const loopDetected = await this.loopDetector.turnStarted(signal);
|
|
384
|
+
if (loopDetected) {
|
|
385
|
+
yield { type: GeminiEventType.LoopDetected };
|
|
386
|
+
return turn;
|
|
387
|
+
}
|
|
388
|
+
const resultStream = turn.run(request, signal);
|
|
389
|
+
for await (const event of resultStream) {
|
|
390
|
+
if (this.loopDetector.addAndCheck(event)) {
|
|
391
|
+
yield { type: GeminiEventType.LoopDetected };
|
|
392
|
+
return turn;
|
|
393
|
+
}
|
|
394
|
+
yield event;
|
|
395
|
+
if (event.type === GeminiEventType.Error) {
|
|
396
|
+
return turn;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (!turn.pendingToolCalls.length && signal && !signal.aborted) {
|
|
400
|
+
// Check if model was switched during the call (likely due to quota error)
|
|
401
|
+
const currentModel = this.config.getModel();
|
|
402
|
+
if (currentModel !== initialModel) {
|
|
403
|
+
// Model was switched (likely due to quota error fallback)
|
|
404
|
+
// Don't continue with recursive call to prevent unwanted Flash execution
|
|
405
|
+
return turn;
|
|
406
|
+
}
|
|
407
|
+
if (this.config.getSkipNextSpeakerCheck()) {
|
|
408
|
+
return turn;
|
|
409
|
+
}
|
|
410
|
+
const nextSpeakerCheck = await checkNextSpeaker(this.getChat(), this, signal);
|
|
411
|
+
logNextSpeakerCheck(this.config, new NextSpeakerCheckEvent(prompt_id, turn.finishReason?.toString() || '', nextSpeakerCheck?.next_speaker || ''));
|
|
412
|
+
if (nextSpeakerCheck?.next_speaker === 'model') {
|
|
413
|
+
const nextRequest = [{ text: 'Please continue.' }];
|
|
414
|
+
// This recursive call's events will be yielded out, but the final
|
|
415
|
+
// turn object will be from the top-level call.
|
|
416
|
+
yield* this.sendMessageStream(nextRequest, signal, prompt_id, boundedTurns - 1, initialModel);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return turn;
|
|
420
|
+
}
|
|
421
|
+
async generateJson(contents, schema, abortSignal, model, config = {}) {
|
|
422
|
+
// Use current model from config instead of hardcoded Flash model
|
|
423
|
+
const modelToUse = model || this.config.getModel() || DEFAULT_GEMINI_FLASH_MODEL;
|
|
424
|
+
try {
|
|
425
|
+
const userMemory = this.config.getUserMemory();
|
|
426
|
+
const systemInstruction = getCoreSystemPrompt(userMemory);
|
|
427
|
+
const requestConfig = {
|
|
428
|
+
abortSignal,
|
|
429
|
+
...this.generateContentConfig,
|
|
430
|
+
...config,
|
|
431
|
+
};
|
|
432
|
+
const apiCall = () => this.getContentGenerator().generateContent({
|
|
433
|
+
model: modelToUse,
|
|
434
|
+
config: {
|
|
435
|
+
...requestConfig,
|
|
436
|
+
systemInstruction,
|
|
437
|
+
responseJsonSchema: schema,
|
|
438
|
+
responseMimeType: 'application/json',
|
|
439
|
+
},
|
|
440
|
+
contents,
|
|
441
|
+
}, this.lastPromptId);
|
|
442
|
+
const result = await retryWithBackoff(apiCall, {
|
|
443
|
+
onPersistent429: async (authType, error) => await this.handleFlashFallback(authType, error),
|
|
444
|
+
authType: this.config.getContentGeneratorConfig()?.authType,
|
|
445
|
+
});
|
|
446
|
+
let text = getResponseText(result);
|
|
447
|
+
if (!text) {
|
|
448
|
+
const error = new Error('API returned an empty response for generateJson.');
|
|
449
|
+
await reportError(error, 'Error in generateJson: API returned an empty response.', contents, 'generateJson-empty-response');
|
|
450
|
+
throw error;
|
|
451
|
+
}
|
|
452
|
+
const prefix = '```json';
|
|
453
|
+
const suffix = '```';
|
|
454
|
+
if (text.startsWith(prefix) && text.endsWith(suffix)) {
|
|
455
|
+
logMalformedJsonResponse(this.config, new MalformedJsonResponseEvent(modelToUse));
|
|
456
|
+
text = text
|
|
457
|
+
.substring(prefix.length, text.length - suffix.length)
|
|
458
|
+
.trim();
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
return JSON.parse(text);
|
|
462
|
+
}
|
|
463
|
+
catch (parseError) {
|
|
464
|
+
await reportError(parseError, 'Failed to parse JSON response from generateJson.', {
|
|
465
|
+
responseTextFailedToParse: text,
|
|
466
|
+
originalRequestContents: contents,
|
|
467
|
+
}, 'generateJson-parse');
|
|
468
|
+
throw new Error(`Failed to parse API response as JSON: ${getErrorMessage(parseError)}`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
catch (error) {
|
|
472
|
+
if (abortSignal.aborted) {
|
|
473
|
+
throw error;
|
|
474
|
+
}
|
|
475
|
+
// Avoid double reporting for the empty response case handled above
|
|
476
|
+
if (error instanceof Error &&
|
|
477
|
+
error.message === 'API returned an empty response for generateJson.') {
|
|
478
|
+
throw error;
|
|
479
|
+
}
|
|
480
|
+
await reportError(error, 'Error generating JSON content via API.', contents, 'generateJson-api');
|
|
481
|
+
throw new Error(`Failed to generate JSON content: ${getErrorMessage(error)}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
async generateContent(contents, generationConfig, abortSignal, model) {
|
|
485
|
+
const modelToUse = model ?? this.config.getModel();
|
|
486
|
+
const configToUse = {
|
|
487
|
+
...this.generateContentConfig,
|
|
488
|
+
...generationConfig,
|
|
489
|
+
};
|
|
490
|
+
try {
|
|
491
|
+
const userMemory = this.config.getUserMemory();
|
|
492
|
+
const systemInstruction = getCoreSystemPrompt(userMemory);
|
|
493
|
+
const requestConfig = {
|
|
494
|
+
abortSignal,
|
|
495
|
+
...configToUse,
|
|
496
|
+
systemInstruction,
|
|
497
|
+
};
|
|
498
|
+
const apiCall = () => this.getContentGenerator().generateContent({
|
|
499
|
+
model: modelToUse,
|
|
500
|
+
config: requestConfig,
|
|
501
|
+
contents,
|
|
502
|
+
}, this.lastPromptId);
|
|
503
|
+
const result = await retryWithBackoff(apiCall, {
|
|
504
|
+
onPersistent429: async (authType, error) => await this.handleFlashFallback(authType, error),
|
|
505
|
+
authType: this.config.getContentGeneratorConfig()?.authType,
|
|
506
|
+
});
|
|
507
|
+
return result;
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
if (abortSignal.aborted) {
|
|
511
|
+
throw error;
|
|
512
|
+
}
|
|
513
|
+
await reportError(error, `Error generating content via API with model ${modelToUse}.`, {
|
|
514
|
+
requestContents: contents,
|
|
515
|
+
requestConfig: configToUse,
|
|
516
|
+
}, 'generateContent-api');
|
|
517
|
+
throw new Error(`Failed to generate content with model ${modelToUse}: ${getErrorMessage(error)}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async generateEmbedding(texts) {
|
|
521
|
+
if (!texts || texts.length === 0) {
|
|
522
|
+
return [];
|
|
523
|
+
}
|
|
524
|
+
const embedModelParams = {
|
|
525
|
+
model: this.embeddingModel,
|
|
526
|
+
contents: texts,
|
|
527
|
+
};
|
|
528
|
+
const embedContentResponse = await this.getContentGenerator().embedContent(embedModelParams);
|
|
529
|
+
if (!embedContentResponse.embeddings ||
|
|
530
|
+
embedContentResponse.embeddings.length === 0) {
|
|
531
|
+
throw new Error('No embeddings found in API response.');
|
|
532
|
+
}
|
|
533
|
+
if (embedContentResponse.embeddings.length !== texts.length) {
|
|
534
|
+
throw new Error(`API returned a mismatched number of embeddings. Expected ${texts.length}, got ${embedContentResponse.embeddings.length}.`);
|
|
535
|
+
}
|
|
536
|
+
return embedContentResponse.embeddings.map((embedding, index) => {
|
|
537
|
+
const values = embedding.values;
|
|
538
|
+
if (!values || values.length === 0) {
|
|
539
|
+
throw new Error(`API returned an empty embedding for input text at index ${index}: "${texts[index]}"`);
|
|
540
|
+
}
|
|
541
|
+
return values;
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
async tryCompressChat(prompt_id, force = false) {
|
|
545
|
+
const curatedHistory = this.getChat().getHistory(true);
|
|
546
|
+
// Regardless of `force`, don't do anything if the history is empty.
|
|
547
|
+
if (curatedHistory.length === 0 ||
|
|
548
|
+
(this.hasFailedCompressionAttempt && !force)) {
|
|
549
|
+
return {
|
|
550
|
+
originalTokenCount: 0,
|
|
551
|
+
newTokenCount: 0,
|
|
552
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
const model = this.config.getModel();
|
|
556
|
+
const { totalTokens: originalTokenCount } = await this.getContentGenerator().countTokens({
|
|
557
|
+
model,
|
|
558
|
+
contents: curatedHistory,
|
|
559
|
+
});
|
|
560
|
+
if (originalTokenCount === undefined) {
|
|
561
|
+
console.warn(`Could not determine token count for model ${model}.`);
|
|
562
|
+
this.hasFailedCompressionAttempt = !force && true;
|
|
563
|
+
return {
|
|
564
|
+
originalTokenCount: 0,
|
|
565
|
+
newTokenCount: 0,
|
|
566
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_TOKEN_COUNT_ERROR,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
const contextPercentageThreshold = this.config.getChatCompression()?.contextPercentageThreshold;
|
|
570
|
+
// Don't compress if not forced and we are under the limit.
|
|
571
|
+
if (!force) {
|
|
572
|
+
const threshold = contextPercentageThreshold ?? COMPRESSION_TOKEN_THRESHOLD;
|
|
573
|
+
if (originalTokenCount < threshold * tokenLimit(model)) {
|
|
574
|
+
return {
|
|
575
|
+
originalTokenCount,
|
|
576
|
+
newTokenCount: originalTokenCount,
|
|
577
|
+
compressionStatus: CompressionStatus.NOOP,
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
let compressBeforeIndex = findIndexAfterFraction(curatedHistory, 1 - COMPRESSION_PRESERVE_THRESHOLD);
|
|
582
|
+
// Find the first user message after the index. This is the start of the next turn.
|
|
583
|
+
while (compressBeforeIndex < curatedHistory.length &&
|
|
584
|
+
(curatedHistory[compressBeforeIndex]?.role === 'model' ||
|
|
585
|
+
isFunctionResponse(curatedHistory[compressBeforeIndex]))) {
|
|
586
|
+
compressBeforeIndex++;
|
|
587
|
+
}
|
|
588
|
+
const historyToCompress = curatedHistory.slice(0, compressBeforeIndex);
|
|
589
|
+
const historyToKeep = curatedHistory.slice(compressBeforeIndex);
|
|
590
|
+
this.getChat().setHistory(historyToCompress);
|
|
591
|
+
const { text: summary } = await this.getChat().sendMessage({
|
|
592
|
+
message: {
|
|
593
|
+
text: 'First, reason in your scratchpad. Then, generate the <state_snapshot>.',
|
|
594
|
+
},
|
|
595
|
+
config: {
|
|
596
|
+
systemInstruction: { text: getCompressionPrompt() },
|
|
597
|
+
maxOutputTokens: originalTokenCount,
|
|
598
|
+
},
|
|
599
|
+
}, prompt_id);
|
|
600
|
+
const chat = await this.startChat([
|
|
601
|
+
{
|
|
602
|
+
role: 'user',
|
|
603
|
+
parts: [{ text: summary }],
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
role: 'model',
|
|
607
|
+
parts: [{ text: 'Got it. Thanks for the additional context!' }],
|
|
608
|
+
},
|
|
609
|
+
...historyToKeep,
|
|
610
|
+
]);
|
|
611
|
+
this.forceFullIdeContext = true;
|
|
612
|
+
const { totalTokens: newTokenCount } = await this.getContentGenerator().countTokens({
|
|
613
|
+
// model might change after calling `sendMessage`, so we get the newest value from config
|
|
614
|
+
model: this.config.getModel(),
|
|
615
|
+
contents: chat.getHistory(),
|
|
616
|
+
});
|
|
617
|
+
if (newTokenCount === undefined) {
|
|
618
|
+
console.warn('Could not determine compressed history token count.');
|
|
619
|
+
this.hasFailedCompressionAttempt = !force && true;
|
|
620
|
+
return {
|
|
621
|
+
originalTokenCount,
|
|
622
|
+
newTokenCount: originalTokenCount,
|
|
623
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_TOKEN_COUNT_ERROR,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
logChatCompression(this.config, makeChatCompressionEvent({
|
|
627
|
+
tokens_before: originalTokenCount,
|
|
628
|
+
tokens_after: newTokenCount,
|
|
629
|
+
}));
|
|
630
|
+
if (newTokenCount > originalTokenCount) {
|
|
631
|
+
this.getChat().setHistory(curatedHistory);
|
|
632
|
+
this.hasFailedCompressionAttempt = !force && true;
|
|
633
|
+
return {
|
|
634
|
+
originalTokenCount,
|
|
635
|
+
newTokenCount,
|
|
636
|
+
compressionStatus: CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
this.chat = chat; // Chat compression successful, set new state.
|
|
641
|
+
}
|
|
642
|
+
return {
|
|
643
|
+
originalTokenCount,
|
|
644
|
+
newTokenCount,
|
|
645
|
+
compressionStatus: CompressionStatus.COMPRESSED,
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Handles falling back to Flash model when persistent 429 errors occur for OAuth users.
|
|
650
|
+
* Uses a fallback handler if provided by the config; otherwise, returns null.
|
|
651
|
+
*/
|
|
652
|
+
async handleFlashFallback(authType, error) {
|
|
653
|
+
// Only handle fallback for OAuth users
|
|
654
|
+
if (authType !== AuthType.LOGIN_WITH_GOOGLE) {
|
|
655
|
+
return null;
|
|
656
|
+
}
|
|
657
|
+
const currentModel = this.config.getModel();
|
|
658
|
+
const fallbackModel = DEFAULT_GEMINI_FLASH_MODEL;
|
|
659
|
+
// Don't fallback if already using Flash model
|
|
660
|
+
if (currentModel === fallbackModel) {
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
// Check if config has a fallback handler (set by CLI package)
|
|
664
|
+
const fallbackHandler = this.config.flashFallbackHandler;
|
|
665
|
+
if (typeof fallbackHandler === 'function') {
|
|
666
|
+
try {
|
|
667
|
+
const accepted = await fallbackHandler(currentModel, fallbackModel, error);
|
|
668
|
+
if (accepted !== false && accepted !== null) {
|
|
669
|
+
this.config.setModel(fallbackModel);
|
|
670
|
+
this.config.setFallbackMode(true);
|
|
671
|
+
return fallbackModel;
|
|
672
|
+
}
|
|
673
|
+
// Check if the model was switched manually in the handler
|
|
674
|
+
if (this.config.getModel() === fallbackModel) {
|
|
675
|
+
return null; // Model was switched but don't continue with current prompt
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
catch (error) {
|
|
679
|
+
console.warn('Flash fallback handler failed:', error);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
export const TEST_ONLY = {
|
|
686
|
+
COMPRESSION_PRESERVE_THRESHOLD,
|
|
687
|
+
COMPRESSION_TOKEN_THRESHOLD,
|
|
688
|
+
};
|
|
689
|
+
//# sourceMappingURL=client.js.map
|