@machina.ai/cell-cli-core 1.10.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 +13 -5
- package/dist/src/agents/codebase-investigator.js +2 -5
- package/dist/src/agents/codebase-investigator.js.map +1 -1
- package/dist/src/agents/executor.d.ts +19 -0
- package/dist/src/agents/executor.js +234 -46
- package/dist/src/agents/executor.js.map +1 -1
- package/dist/src/agents/executor.test.js +371 -40
- package/dist/src/agents/executor.test.js.map +1 -1
- package/dist/src/agents/registry.js +4 -3
- package/dist/src/agents/registry.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/converter.d.ts +1 -0
- package/dist/src/code_assist/converter.js +1 -0
- package/dist/src/code_assist/converter.js.map +1 -1
- package/dist/src/code_assist/converter.test.js +19 -0
- package/dist/src/code_assist/converter.test.js.map +1 -1
- package/dist/src/code_assist/experiments/client_metadata.d.ts +12 -0
- package/dist/src/code_assist/experiments/client_metadata.js +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 +64 -51
- 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.js +19 -0
- package/dist/src/commands/extensions.test.js.map +1 -0
- package/dist/src/config/config.d.ts +81 -32
- package/dist/src/config/config.js +193 -66
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +115 -36
- 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/confirmation-bus/message-bus.d.ts +2 -1
- package/dist/src/confirmation-bus/message-bus.js +7 -1
- package/dist/src/confirmation-bus/message-bus.js.map +1 -1
- package/dist/src/confirmation-bus/types.d.ts +12 -2
- package/dist/src/confirmation-bus/types.js +1 -0
- package/dist/src/confirmation-bus/types.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 +31 -170
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +107 -429
- 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 +8 -2
- package/dist/src/core/coreToolScheduler.js +337 -172
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +363 -12
- 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 +7 -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 +21 -19
- 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/nonInteractiveToolExecutor.test.js +3 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +115 -72
- 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/core/turn.d.ts +2 -0
- package/dist/src/core/turn.js +3 -1
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +48 -0
- package/dist/src/core/turn.test.js.map +1 -1
- 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/ide/ide-client.js +2 -1
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.js +18 -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 +140 -55
- 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 +28 -8
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/oauth-utils.test.js +45 -2
- 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/output/stream-json-formatter.d.ts +32 -0
- package/dist/src/output/stream-json-formatter.js +52 -0
- package/dist/src/output/stream-json-formatter.js.map +1 -0
- package/dist/src/output/stream-json-formatter.test.d.ts +6 -0
- package/dist/src/output/stream-json-formatter.test.js +479 -0
- package/dist/src/output/stream-json-formatter.test.js.map +1 -0
- package/dist/src/output/types.d.ts +63 -1
- package/dist/src/output/types.js +11 -0
- package/dist/src/output/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/prompts/prompt-registry.js +2 -1
- package/dist/src/prompts/prompt-registry.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js +3 -2
- package/dist/src/routing/strategies/classifierStrategy.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 +27 -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 +50 -23
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +82 -15
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/activity-monitor.d.ts +116 -0
- package/dist/src/telemetry/activity-monitor.js +209 -0
- package/dist/src/telemetry/activity-monitor.js.map +1 -0
- package/dist/src/telemetry/activity-monitor.test.d.ts +6 -0
- package/dist/src/telemetry/activity-monitor.test.js +248 -0
- package/dist/src/telemetry/activity-monitor.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +5 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +135 -57
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +43 -75
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +7 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +13 -1
- 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 +4 -2
- package/dist/src/telemetry/index.js +5 -3
- 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 +215 -56
- 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/sdk.js +3 -2
- package/dist/src/telemetry/sdk.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 +79 -34
- package/dist/src/telemetry/types.js +191 -61
- 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 +24 -19
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +78 -2
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +3 -2
- package/dist/src/tools/glob.js +15 -19
- 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.d.ts +3 -2
- package/dist/src/tools/grep.js +22 -16
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.d.ts +3 -2
- package/dist/src/tools/ls.js +15 -20
- 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 -11
- package/dist/src/tools/mcp-client-manager.js +209 -31
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +132 -25
- 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 +85 -104
- 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 +5 -2
- package/dist/src/tools/mcp-tool.js +16 -8
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +6 -4
- package/dist/src/tools/memoryTool.js +13 -10
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/message-bus-integration.test.js +14 -1
- package/dist/src/tools/message-bus-integration.test.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.d.ts +4 -3
- package/dist/src/tools/read-file.js +16 -11
- 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.d.ts +4 -3
- package/dist/src/tools/read-many-files.js +19 -37
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +0 -1
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +3 -2
- package/dist/src/tools/ripGrep.js +47 -17
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +106 -60
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +7 -5
- package/dist/src/tools/shell.js +39 -68
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +69 -9
- 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 +30 -18
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/smart-edit.test.js +62 -2
- package/dist/src/tools/smart-edit.test.js.map +1 -1
- package/dist/src/tools/tool-names.d.ts +8 -0
- package/dist/src/tools/tool-names.js +8 -5
- package/dist/src/tools/tool-names.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +6 -19
- package/dist/src/tools/tool-registry.js +14 -49
- 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 +22 -8
- package/dist/src/tools/tools.js +65 -36
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +4 -3
- package/dist/src/tools/web-fetch.js +37 -25
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +262 -1
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +4 -3
- package/dist/src/tools/web-search.js +8 -6
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +3 -2
- package/dist/src/tools/write-file.js +8 -8
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +1 -2
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +4 -8
- package/dist/src/tools/write-todos.js +15 -6
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/tools/write-todos.test.js +2 -2
- package/dist/src/tools/write-todos.test.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.js +3 -2
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/channel.d.ts +19 -0
- package/dist/src/utils/channel.js +49 -0
- package/dist/src/utils/channel.js.map +1 -0
- package/dist/src/utils/channel.test.d.ts +6 -0
- package/dist/src/utils/channel.test.js +170 -0
- package/dist/src/utils/channel.test.js.map +1 -0
- package/dist/src/utils/debugLogger.d.ts +25 -0
- package/dist/src/utils/debugLogger.js +33 -0
- package/dist/src/utils/debugLogger.js.map +1 -0
- package/dist/src/utils/debugLogger.test.d.ts +6 -0
- package/dist/src/utils/debugLogger.test.js +67 -0
- package/dist/src/utils/debugLogger.test.js.map +1 -0
- package/dist/src/utils/delay.d.ts +16 -0
- package/dist/src/utils/delay.js +43 -0
- package/dist/src/utils/delay.js.map +1 -0
- package/dist/src/utils/delay.test.d.ts +6 -0
- package/dist/src/utils/delay.test.js +88 -0
- package/dist/src/utils/delay.test.js.map +1 -0
- package/dist/src/utils/editCorrector.js +5 -9
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +3 -5
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.js +33 -38
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/environmentContext.d.ts +2 -1
- package/dist/src/utils/environmentContext.js +18 -33
- package/dist/src/utils/environmentContext.js.map +1 -1
- package/dist/src/utils/environmentContext.test.js +0 -34
- package/dist/src/utils/environmentContext.test.js.map +1 -1
- package/dist/src/utils/errorParsing.d.ts +1 -1
- package/dist/src/utils/errorParsing.js +5 -33
- package/dist/src/utils/errorParsing.js.map +1 -1
- package/dist/src/utils/errorParsing.test.js +0 -88
- package/dist/src/utils/errorParsing.test.js.map +1 -1
- package/dist/src/utils/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.d.ts +1 -0
- package/dist/src/utils/fetch.js +4 -0
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +4 -0
- package/dist/src/utils/fileUtils.js +34 -2
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +12 -1
- package/dist/src/utils/fileUtils.test.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 +9 -17
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.d.ts +4 -1
- package/dist/src/utils/gitIgnoreParser.js +28 -10
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +58 -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 +29 -4
- 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 -1
- package/dist/src/utils/memoryDiscovery.js +150 -11
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +157 -19
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +3 -2
- package/dist/src/utils/memoryImportProcessor.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.js +2 -1
- package/dist/src/utils/nextSpeakerChecker.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.d.ts +1 -0
- package/dist/src/utils/retry.js +57 -158
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +48 -109
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/safeJsonStringify.d.ts +4 -4
- package/dist/src/utils/safeJsonStringify.js +31 -7
- package/dist/src/utils/safeJsonStringify.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +14 -2
- package/dist/src/utils/shell-utils.js +381 -136
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +242 -60
- 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/systemEncoding.js +5 -4
- package/dist/src/utils/systemEncoding.js.map +1 -1
- package/dist/src/utils/tool-utils.d.ts +2 -2
- package/dist/src/utils/tool-utils.js +14 -5
- package/dist/src/utils/tool-utils.js.map +1 -1
- package/dist/src/utils/userAccountManager.js +5 -4
- package/dist/src/utils/userAccountManager.js.map +1 -1
- package/dist/src/utils/workspaceContext.js +3 -2
- 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 +13 -5
- package/dist/src/core/subagent.d.ts +0 -236
- package/dist/src/core/subagent.js +0 -482
- package/dist/src/core/subagent.js.map +0 -1
- package/dist/src/core/subagent.test.js +0 -556
- package/dist/src/core/subagent.test.js.map +0 -1
- /package/dist/src/{core/subagent.test.d.ts → commands/extensions.test.d.ts} +0 -0
|
@@ -16,6 +16,7 @@ export interface RetryOptions {
|
|
|
16
16
|
onPersistent429?: (authType?: string, error?: unknown) => Promise<string | boolean | null>;
|
|
17
17
|
authType?: string;
|
|
18
18
|
retryFetchErrors?: boolean;
|
|
19
|
+
signal?: AbortSignal;
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
22
|
* Retries a function with exponential backoff and jitter.
|
package/dist/src/utils/retry.js
CHANGED
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ApiError } from '@google/genai';
|
|
7
7
|
import { AuthType } from '../core/contentGenerator.js';
|
|
8
|
-
import {
|
|
8
|
+
import { classifyGoogleError, RetryableQuotaError, TerminalQuotaError, } from './googleQuotaErrors.js';
|
|
9
|
+
import { delay, createAbortError } from './delay.js';
|
|
10
|
+
import { debugLogger } from './debugLogger.js';
|
|
9
11
|
const FETCH_FAILED_MESSAGE = 'exception TypeError: fetch failed sending request';
|
|
10
12
|
const DEFAULT_RETRY_OPTIONS = {
|
|
11
|
-
maxAttempts:
|
|
13
|
+
maxAttempts: 3,
|
|
12
14
|
initialDelayMs: 5000,
|
|
13
15
|
maxDelayMs: 30000, // 30 seconds
|
|
14
16
|
shouldRetryOnError: defaultShouldRetry,
|
|
@@ -40,14 +42,6 @@ function defaultShouldRetry(error, retryFetchErrors) {
|
|
|
40
42
|
}
|
|
41
43
|
return false;
|
|
42
44
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Delays execution for a specified number of milliseconds.
|
|
45
|
-
* @param ms The number of milliseconds to delay.
|
|
46
|
-
* @returns A promise that resolves after the delay.
|
|
47
|
-
*/
|
|
48
|
-
function delay(ms) {
|
|
49
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
50
|
-
}
|
|
51
45
|
/**
|
|
52
46
|
* Retries a function with exponential backoff and jitter.
|
|
53
47
|
* @param fn The asynchronous function to retry.
|
|
@@ -56,20 +50,25 @@ function delay(ms) {
|
|
|
56
50
|
* @throws The last error encountered if all attempts fail.
|
|
57
51
|
*/
|
|
58
52
|
export async function retryWithBackoff(fn, options) {
|
|
53
|
+
if (options?.signal?.aborted) {
|
|
54
|
+
throw createAbortError();
|
|
55
|
+
}
|
|
59
56
|
if (options?.maxAttempts !== undefined && options.maxAttempts <= 0) {
|
|
60
57
|
throw new Error('maxAttempts must be a positive number.');
|
|
61
58
|
}
|
|
62
59
|
const cleanOptions = options
|
|
63
60
|
? Object.fromEntries(Object.entries(options).filter(([_, v]) => v != null))
|
|
64
61
|
: {};
|
|
65
|
-
const { maxAttempts, initialDelayMs, maxDelayMs, onPersistent429, authType, shouldRetryOnError, shouldRetryOnContent, retryFetchErrors, } = {
|
|
62
|
+
const { maxAttempts, initialDelayMs, maxDelayMs, onPersistent429, authType, shouldRetryOnError, shouldRetryOnContent, retryFetchErrors, signal, } = {
|
|
66
63
|
...DEFAULT_RETRY_OPTIONS,
|
|
67
64
|
...cleanOptions,
|
|
68
65
|
};
|
|
69
66
|
let attempt = 0;
|
|
70
67
|
let currentDelay = initialDelayMs;
|
|
71
|
-
let consecutive429Count = 0;
|
|
72
68
|
while (attempt < maxAttempts) {
|
|
69
|
+
if (signal?.aborted) {
|
|
70
|
+
throw createAbortError();
|
|
71
|
+
}
|
|
73
72
|
attempt++;
|
|
74
73
|
try {
|
|
75
74
|
const result = await fn();
|
|
@@ -77,122 +76,68 @@ export async function retryWithBackoff(fn, options) {
|
|
|
77
76
|
shouldRetryOnContent(result)) {
|
|
78
77
|
const jitter = currentDelay * 0.3 * (Math.random() * 2 - 1);
|
|
79
78
|
const delayWithJitter = Math.max(0, currentDelay + jitter);
|
|
80
|
-
await delay(delayWithJitter);
|
|
79
|
+
await delay(delayWithJitter, signal);
|
|
81
80
|
currentDelay = Math.min(maxDelayMs, currentDelay * 2);
|
|
82
81
|
continue;
|
|
83
82
|
}
|
|
84
83
|
return result;
|
|
85
84
|
}
|
|
86
85
|
catch (error) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (errorStatus === 429 &&
|
|
90
|
-
authType === AuthType.LOGIN_WITH_GOOGLE &&
|
|
91
|
-
isProQuotaExceededError(error) &&
|
|
92
|
-
onPersistent429) {
|
|
93
|
-
try {
|
|
94
|
-
const fallbackModel = await onPersistent429(authType, error);
|
|
95
|
-
if (fallbackModel !== false && fallbackModel !== null) {
|
|
96
|
-
// Reset attempt counter and try with new model
|
|
97
|
-
attempt = 0;
|
|
98
|
-
consecutive429Count = 0;
|
|
99
|
-
currentDelay = initialDelayMs;
|
|
100
|
-
// With the model updated, we continue to the next attempt
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
// Fallback handler returned null/false, meaning don't continue - stop retry process
|
|
105
|
-
throw error;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch (fallbackError) {
|
|
109
|
-
// If fallback fails, continue with original error
|
|
110
|
-
console.warn('Fallback to Flash model failed:', fallbackError);
|
|
111
|
-
}
|
|
86
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
87
|
+
throw error;
|
|
112
88
|
}
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
authType === AuthType.LOGIN_WITH_GOOGLE
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
attempt = 0;
|
|
124
|
-
consecutive429Count = 0;
|
|
125
|
-
currentDelay = initialDelayMs;
|
|
126
|
-
// With the model updated, we continue to the next attempt
|
|
127
|
-
continue;
|
|
89
|
+
const classifiedError = classifyGoogleError(error);
|
|
90
|
+
if (classifiedError instanceof TerminalQuotaError) {
|
|
91
|
+
if (onPersistent429 && authType === AuthType.LOGIN_WITH_GOOGLE) {
|
|
92
|
+
try {
|
|
93
|
+
const fallbackModel = await onPersistent429(authType, classifiedError);
|
|
94
|
+
if (fallbackModel) {
|
|
95
|
+
attempt = 0; // Reset attempts and retry with the new model.
|
|
96
|
+
currentDelay = initialDelayMs;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
128
99
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
throw error;
|
|
100
|
+
catch (fallbackError) {
|
|
101
|
+
debugLogger.warn('Fallback to Flash model failed:', fallbackError);
|
|
132
102
|
}
|
|
133
103
|
}
|
|
134
|
-
|
|
135
|
-
// If fallback fails, continue with original error
|
|
136
|
-
console.warn('Fallback to Flash model failed:', fallbackError);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// Track consecutive 429 errors
|
|
140
|
-
if (errorStatus === 429) {
|
|
141
|
-
consecutive429Count++;
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
consecutive429Count = 0;
|
|
104
|
+
throw classifiedError; // Throw if no fallback or fallback failed.
|
|
145
105
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
106
|
+
if (classifiedError instanceof RetryableQuotaError) {
|
|
107
|
+
if (attempt >= maxAttempts) {
|
|
108
|
+
if (onPersistent429 && authType === AuthType.LOGIN_WITH_GOOGLE) {
|
|
109
|
+
try {
|
|
110
|
+
const fallbackModel = await onPersistent429(authType, classifiedError);
|
|
111
|
+
if (fallbackModel) {
|
|
112
|
+
attempt = 0; // Reset attempts and retry with the new model.
|
|
113
|
+
currentDelay = initialDelayMs;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (fallbackError) {
|
|
118
|
+
console.warn('Model fallback failed:', fallbackError);
|
|
119
|
+
}
|
|
159
120
|
}
|
|
160
|
-
|
|
161
|
-
// Fallback handler returned null/false, meaning don't continue - stop retry process
|
|
162
|
-
throw error;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
catch (fallbackError) {
|
|
166
|
-
// If fallback fails, continue with original error
|
|
167
|
-
console.warn('Fallback to Flash model failed:', fallbackError);
|
|
121
|
+
throw classifiedError;
|
|
168
122
|
}
|
|
123
|
+
console.warn(`Attempt ${attempt} failed: ${classifiedError.message}. Retrying after ${classifiedError.retryDelayMs}ms...`);
|
|
124
|
+
await delay(classifiedError.retryDelayMs, signal);
|
|
125
|
+
continue;
|
|
169
126
|
}
|
|
170
|
-
//
|
|
127
|
+
// Generic retry logic for other errors
|
|
171
128
|
if (attempt >= maxAttempts ||
|
|
172
129
|
!shouldRetryOnError(error, retryFetchErrors)) {
|
|
173
130
|
throw error;
|
|
174
131
|
}
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
// Fall back to exponential backoff with jitter
|
|
185
|
-
logRetryAttempt(attempt, error, errorStatus);
|
|
186
|
-
// Add jitter: +/- 30% of currentDelay
|
|
187
|
-
const jitter = currentDelay * 0.3 * (Math.random() * 2 - 1);
|
|
188
|
-
const delayWithJitter = Math.max(0, currentDelay + jitter);
|
|
189
|
-
await delay(delayWithJitter);
|
|
190
|
-
currentDelay = Math.min(maxDelayMs, currentDelay * 2);
|
|
191
|
-
}
|
|
132
|
+
const errorStatus = getErrorStatus(error);
|
|
133
|
+
logRetryAttempt(attempt, error, errorStatus);
|
|
134
|
+
// Exponential backoff with jitter for non-quota errors
|
|
135
|
+
const jitter = currentDelay * 0.3 * (Math.random() * 2 - 1);
|
|
136
|
+
const delayWithJitter = Math.max(0, currentDelay + jitter);
|
|
137
|
+
await delay(delayWithJitter, signal);
|
|
138
|
+
currentDelay = Math.min(maxDelayMs, currentDelay * 2);
|
|
192
139
|
}
|
|
193
140
|
}
|
|
194
|
-
// This line should theoretically be unreachable due to the throw in the catch block.
|
|
195
|
-
// Added for type safety and to satisfy the compiler that a promise is always returned.
|
|
196
141
|
throw new Error('Retry attempts exhausted');
|
|
197
142
|
}
|
|
198
143
|
/**
|
|
@@ -217,52 +162,6 @@ export function getErrorStatus(error) {
|
|
|
217
162
|
}
|
|
218
163
|
return undefined;
|
|
219
164
|
}
|
|
220
|
-
/**
|
|
221
|
-
* Extracts the Retry-After delay from an error object's headers.
|
|
222
|
-
* @param error The error object.
|
|
223
|
-
* @returns The delay in milliseconds, or 0 if not found or invalid.
|
|
224
|
-
*/
|
|
225
|
-
function getRetryAfterDelayMs(error) {
|
|
226
|
-
if (typeof error === 'object' && error !== null) {
|
|
227
|
-
// Check for error.response.headers (common in axios errors)
|
|
228
|
-
if ('response' in error &&
|
|
229
|
-
typeof error.response === 'object' &&
|
|
230
|
-
error.response !== null) {
|
|
231
|
-
const response = error.response;
|
|
232
|
-
if ('headers' in response &&
|
|
233
|
-
typeof response.headers === 'object' &&
|
|
234
|
-
response.headers !== null) {
|
|
235
|
-
const headers = response.headers;
|
|
236
|
-
const retryAfterHeader = headers['retry-after'];
|
|
237
|
-
if (typeof retryAfterHeader === 'string') {
|
|
238
|
-
const retryAfterSeconds = parseInt(retryAfterHeader, 10);
|
|
239
|
-
if (!isNaN(retryAfterSeconds)) {
|
|
240
|
-
return retryAfterSeconds * 1000;
|
|
241
|
-
}
|
|
242
|
-
// It might be an HTTP date
|
|
243
|
-
const retryAfterDate = new Date(retryAfterHeader);
|
|
244
|
-
if (!isNaN(retryAfterDate.getTime())) {
|
|
245
|
-
return Math.max(0, retryAfterDate.getTime() - Date.now());
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return 0;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Determines the delay duration based on the error, prioritizing Retry-After header.
|
|
255
|
-
* @param error The error object.
|
|
256
|
-
* @returns An object containing the delay duration in milliseconds and the error status.
|
|
257
|
-
*/
|
|
258
|
-
function getDelayDurationAndStatus(error) {
|
|
259
|
-
const errorStatus = getErrorStatus(error);
|
|
260
|
-
let delayDurationMs = 0;
|
|
261
|
-
if (errorStatus === 429) {
|
|
262
|
-
delayDurationMs = getRetryAfterDelayMs(error);
|
|
263
|
-
}
|
|
264
|
-
return { delayDurationMs, errorStatus };
|
|
265
|
-
}
|
|
266
165
|
/**
|
|
267
166
|
* Logs a message for a retry attempt when using exponential backoff.
|
|
268
167
|
* @param attempt The current attempt number.
|
|
@@ -275,7 +174,7 @@ function logRetryAttempt(attempt, error, errorStatus) {
|
|
|
275
174
|
message = `Attempt ${attempt} failed with status ${errorStatus}. Retrying with backoff...`;
|
|
276
175
|
}
|
|
277
176
|
if (errorStatus === 429) {
|
|
278
|
-
|
|
177
|
+
debugLogger.warn(message, error);
|
|
279
178
|
}
|
|
280
179
|
else if (errorStatus && errorStatus >= 500 && errorStatus < 600) {
|
|
281
180
|
console.error(message, error);
|
|
@@ -283,17 +182,17 @@ function logRetryAttempt(attempt, error, errorStatus) {
|
|
|
283
182
|
else if (error instanceof Error) {
|
|
284
183
|
// Fallback for errors that might not have a status but have a message
|
|
285
184
|
if (error.message.includes('429')) {
|
|
286
|
-
|
|
185
|
+
debugLogger.warn(`Attempt ${attempt} failed with 429 error (no Retry-After header). Retrying with backoff...`, error);
|
|
287
186
|
}
|
|
288
187
|
else if (error.message.match(/5\d{2}/)) {
|
|
289
188
|
console.error(`Attempt ${attempt} failed with 5xx error. Retrying with backoff...`, error);
|
|
290
189
|
}
|
|
291
190
|
else {
|
|
292
|
-
|
|
191
|
+
debugLogger.warn(message, error); // Default to warn for other errors
|
|
293
192
|
}
|
|
294
193
|
}
|
|
295
194
|
else {
|
|
296
|
-
|
|
195
|
+
debugLogger.warn(message, error); // Default to warn if error type is unknown
|
|
297
196
|
}
|
|
298
197
|
}
|
|
299
198
|
//# sourceMappingURL=retry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
7
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
8
8
|
import { ApiError } from '@google/genai';
|
|
9
|
+
import { AuthType } from '../core/contentGenerator.js';
|
|
9
10
|
import { retryWithBackoff } from './retry.js';
|
|
10
11
|
import { setSimulate429 } from './testUtils.js';
|
|
12
|
+
import { debugLogger } from './debugLogger.js';
|
|
13
|
+
import { TerminalQuotaError, RetryableQuotaError, } from './googleQuotaErrors.js';
|
|
11
14
|
// Helper to create a mock function that fails a certain number of times
|
|
12
15
|
const createFailingFunction = (failures, successValue = 'success') => {
|
|
13
16
|
let attempts = 0;
|
|
@@ -35,7 +38,7 @@ describe('retryWithBackoff', () => {
|
|
|
35
38
|
// Disable 429 simulation for tests
|
|
36
39
|
setSimulate429(false);
|
|
37
40
|
// Suppress unhandled promise rejection warnings for tests that expect errors
|
|
38
|
-
|
|
41
|
+
debugLogger.warn = vi.fn();
|
|
39
42
|
});
|
|
40
43
|
afterEach(() => {
|
|
41
44
|
vi.restoreAllMocks();
|
|
@@ -79,21 +82,21 @@ describe('retryWithBackoff', () => {
|
|
|
79
82
|
const promise = retryWithBackoff(mockFn);
|
|
80
83
|
// Expect it to fail with the error from the 5th attempt.
|
|
81
84
|
await Promise.all([
|
|
82
|
-
expect(promise).rejects.toThrow('Simulated error attempt
|
|
85
|
+
expect(promise).rejects.toThrow('Simulated error attempt 3'),
|
|
83
86
|
vi.runAllTimersAsync(),
|
|
84
87
|
]);
|
|
85
|
-
expect(mockFn).toHaveBeenCalledTimes(
|
|
88
|
+
expect(mockFn).toHaveBeenCalledTimes(3);
|
|
86
89
|
});
|
|
87
|
-
it('should default to
|
|
88
|
-
// This function will fail more than
|
|
90
|
+
it('should default to 3 maxAttempts if options.maxAttempts is undefined', async () => {
|
|
91
|
+
// This function will fail more than 3 times to ensure all retries are used.
|
|
89
92
|
const mockFn = createFailingFunction(10);
|
|
90
93
|
const promise = retryWithBackoff(mockFn, { maxAttempts: undefined });
|
|
91
94
|
// Expect it to fail with the error from the 5th attempt.
|
|
92
95
|
await Promise.all([
|
|
93
|
-
expect(promise).rejects.toThrow('Simulated error attempt
|
|
96
|
+
expect(promise).rejects.toThrow('Simulated error attempt 3'),
|
|
94
97
|
vi.runAllTimersAsync(),
|
|
95
98
|
]);
|
|
96
|
-
expect(mockFn).toHaveBeenCalledTimes(
|
|
99
|
+
expect(mockFn).toHaveBeenCalledTimes(3);
|
|
97
100
|
});
|
|
98
101
|
it('should not retry if shouldRetry returns false', async () => {
|
|
99
102
|
const mockFn = vi.fn(async () => {
|
|
@@ -259,140 +262,76 @@ describe('retryWithBackoff', () => {
|
|
|
259
262
|
});
|
|
260
263
|
});
|
|
261
264
|
describe('Flash model fallback for OAuth users', () => {
|
|
262
|
-
it('should trigger fallback for OAuth personal users
|
|
265
|
+
it('should trigger fallback for OAuth personal users on TerminalQuotaError', async () => {
|
|
263
266
|
const fallbackCallback = vi.fn().mockResolvedValue('gemini-2.5-flash');
|
|
264
267
|
let fallbackOccurred = false;
|
|
265
268
|
const mockFn = vi.fn().mockImplementation(async () => {
|
|
266
269
|
if (!fallbackOccurred) {
|
|
267
|
-
|
|
268
|
-
error.status = 429;
|
|
269
|
-
throw error;
|
|
270
|
+
throw new TerminalQuotaError('Daily limit reached', {});
|
|
270
271
|
}
|
|
271
272
|
return 'success';
|
|
272
273
|
});
|
|
273
274
|
const promise = retryWithBackoff(mockFn, {
|
|
274
275
|
maxAttempts: 3,
|
|
275
276
|
initialDelayMs: 100,
|
|
276
|
-
onPersistent429: async (authType) => {
|
|
277
|
+
onPersistent429: async (authType, error) => {
|
|
277
278
|
fallbackOccurred = true;
|
|
278
|
-
return await fallbackCallback(authType);
|
|
279
|
+
return await fallbackCallback(authType, error);
|
|
279
280
|
},
|
|
280
281
|
authType: 'oauth-personal',
|
|
281
282
|
});
|
|
282
|
-
// Advance all timers to complete retries
|
|
283
283
|
await vi.runAllTimersAsync();
|
|
284
|
-
// Should succeed after fallback
|
|
285
284
|
await expect(promise).resolves.toBe('success');
|
|
286
|
-
|
|
287
|
-
expect(
|
|
288
|
-
// Should retry again after fallback
|
|
289
|
-
expect(mockFn).toHaveBeenCalledTimes(3); // 2 initial attempts + 1 after fallback
|
|
285
|
+
expect(fallbackCallback).toHaveBeenCalledWith('oauth-personal', expect.any(TerminalQuotaError));
|
|
286
|
+
expect(mockFn).toHaveBeenCalledTimes(2);
|
|
290
287
|
});
|
|
291
|
-
it('should
|
|
292
|
-
const
|
|
293
|
-
const mockFn = vi.fn(async () => {
|
|
294
|
-
|
|
295
|
-
error.status = 429;
|
|
296
|
-
throw error;
|
|
288
|
+
it('should use retryDelayMs from RetryableQuotaError', async () => {
|
|
289
|
+
const setTimeoutSpy = vi.spyOn(global, 'setTimeout');
|
|
290
|
+
const mockFn = vi.fn().mockImplementation(async () => {
|
|
291
|
+
throw new RetryableQuotaError('Per-minute limit', {}, 12.345);
|
|
297
292
|
});
|
|
298
293
|
const promise = retryWithBackoff(mockFn, {
|
|
299
|
-
maxAttempts:
|
|
294
|
+
maxAttempts: 2,
|
|
300
295
|
initialDelayMs: 100,
|
|
301
|
-
onPersistent429: fallbackCallback,
|
|
302
|
-
authType: 'gemini-api-key',
|
|
303
296
|
});
|
|
304
|
-
//
|
|
305
|
-
|
|
297
|
+
// Attach the rejection expectation *before* running timers
|
|
298
|
+
// eslint-disable-next-line vitest/valid-expect
|
|
299
|
+
const assertionPromise = expect(promise).rejects.toThrow();
|
|
306
300
|
await vi.runAllTimersAsync();
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
expect(result).toBeInstanceOf(Error);
|
|
310
|
-
expect(result.message).toBe('Rate limit exceeded');
|
|
311
|
-
// Callback should not be called for API key users
|
|
312
|
-
expect(fallbackCallback).not.toHaveBeenCalled();
|
|
301
|
+
await assertionPromise;
|
|
302
|
+
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 12345);
|
|
313
303
|
});
|
|
314
|
-
it('should
|
|
315
|
-
|
|
316
|
-
const fallbackCallback = vi.fn().mockImplementation(async () => {
|
|
317
|
-
fallbackCalled = true;
|
|
318
|
-
return 'gemini-2.5-flash';
|
|
319
|
-
});
|
|
304
|
+
it.each([[AuthType.USE_GEMINI], [AuthType.USE_VERTEX_AI], [undefined]])('should not trigger fallback for non-Google auth users (authType: %s) on TerminalQuotaError', async (authType) => {
|
|
305
|
+
const fallbackCallback = vi.fn();
|
|
320
306
|
const mockFn = vi.fn().mockImplementation(async () => {
|
|
321
|
-
|
|
322
|
-
const error = new Error('Rate limit exceeded');
|
|
323
|
-
error.status = 429;
|
|
324
|
-
throw error;
|
|
325
|
-
}
|
|
326
|
-
return 'success';
|
|
307
|
+
throw new TerminalQuotaError('Daily limit reached', {});
|
|
327
308
|
});
|
|
328
309
|
const promise = retryWithBackoff(mockFn, {
|
|
329
310
|
maxAttempts: 3,
|
|
330
|
-
initialDelayMs: 100,
|
|
331
311
|
onPersistent429: fallbackCallback,
|
|
332
|
-
authType
|
|
312
|
+
authType,
|
|
333
313
|
});
|
|
334
|
-
await
|
|
335
|
-
|
|
336
|
-
expect(
|
|
314
|
+
await expect(promise).rejects.toThrow('Daily limit reached');
|
|
315
|
+
expect(fallbackCallback).not.toHaveBeenCalled();
|
|
316
|
+
expect(mockFn).toHaveBeenCalledTimes(1);
|
|
337
317
|
});
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const promise = retryWithBackoff(mockFn, {
|
|
346
|
-
maxAttempts: 3,
|
|
347
|
-
initialDelayMs: 100,
|
|
348
|
-
onPersistent429: fallbackCallback,
|
|
349
|
-
authType: 'oauth-personal',
|
|
350
|
-
});
|
|
351
|
-
// Handle the promise properly to avoid unhandled rejections
|
|
352
|
-
const resultPromise = promise.catch((error) => error);
|
|
353
|
-
await vi.runAllTimersAsync();
|
|
354
|
-
const result = await resultPromise;
|
|
355
|
-
// Should fail with original error when fallback is rejected
|
|
356
|
-
expect(result).toBeInstanceOf(Error);
|
|
357
|
-
expect(result.message).toBe('Rate limit exceeded');
|
|
358
|
-
expect(fallbackCallback).toHaveBeenCalledWith('oauth-personal', expect.any(Error));
|
|
318
|
+
});
|
|
319
|
+
it('should abort the retry loop when the signal is aborted', async () => {
|
|
320
|
+
const abortController = new AbortController();
|
|
321
|
+
const mockFn = vi.fn().mockImplementation(async () => {
|
|
322
|
+
const error = new Error('Server error');
|
|
323
|
+
error.status = 500;
|
|
324
|
+
throw error;
|
|
359
325
|
});
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const mockFn = vi.fn().mockImplementation(async () => {
|
|
365
|
-
attempts++;
|
|
366
|
-
if (fallbackOccurred) {
|
|
367
|
-
return 'success';
|
|
368
|
-
}
|
|
369
|
-
if (attempts === 1) {
|
|
370
|
-
// First attempt: 500 error (resets consecutive count)
|
|
371
|
-
const error = new Error('Server error');
|
|
372
|
-
error.status = 500;
|
|
373
|
-
throw error;
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
// Remaining attempts: 429 errors
|
|
377
|
-
const error = new Error('Rate limit exceeded');
|
|
378
|
-
error.status = 429;
|
|
379
|
-
throw error;
|
|
380
|
-
}
|
|
381
|
-
});
|
|
382
|
-
const promise = retryWithBackoff(mockFn, {
|
|
383
|
-
maxAttempts: 5,
|
|
384
|
-
initialDelayMs: 100,
|
|
385
|
-
onPersistent429: async (authType) => {
|
|
386
|
-
fallbackOccurred = true;
|
|
387
|
-
return await fallbackCallback(authType);
|
|
388
|
-
},
|
|
389
|
-
authType: 'oauth-personal',
|
|
390
|
-
});
|
|
391
|
-
await vi.runAllTimersAsync();
|
|
392
|
-
await expect(promise).resolves.toBe('success');
|
|
393
|
-
// Should trigger fallback after 2 consecutive 429s (attempts 2-3)
|
|
394
|
-
expect(fallbackCallback).toHaveBeenCalledWith('oauth-personal');
|
|
326
|
+
const promise = retryWithBackoff(mockFn, {
|
|
327
|
+
maxAttempts: 5,
|
|
328
|
+
initialDelayMs: 100,
|
|
329
|
+
signal: abortController.signal,
|
|
395
330
|
});
|
|
331
|
+
await vi.advanceTimersByTimeAsync(50);
|
|
332
|
+
abortController.abort();
|
|
333
|
+
await expect(promise).rejects.toThrow(expect.objectContaining({ name: 'AbortError' }));
|
|
334
|
+
expect(mockFn).toHaveBeenCalledTimes(1);
|
|
396
335
|
});
|
|
397
336
|
});
|
|
398
337
|
//# sourceMappingURL=retry.test.js.map
|