@google/gemini-cli-core 0.0.3-preview.4 → 0.0.3
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 +2 -2
- package/README.md +12 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/src/code_assist/codeAssist.d.ts +2 -0
- package/dist/src/code_assist/codeAssist.js +12 -0
- package/dist/src/code_assist/codeAssist.js.map +1 -1
- package/dist/src/code_assist/converter.d.ts +3 -1
- package/dist/src/code_assist/converter.js +2 -1
- package/dist/src/code_assist/converter.js.map +1 -1
- package/dist/src/code_assist/converter.test.js +10 -0
- package/dist/src/code_assist/converter.test.js.map +1 -1
- package/dist/src/code_assist/oauth-credential-storage.d.ts +25 -0
- package/dist/src/code_assist/oauth-credential-storage.js +109 -0
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -0
- package/dist/src/code_assist/oauth-credential-storage.test.js +136 -0
- package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -0
- package/dist/src/code_assist/oauth2.js +92 -29
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +729 -339
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +1 -1
- package/dist/src/code_assist/server.js +24 -1
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +25 -0
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +17 -2
- package/dist/src/config/config.d.ts +72 -12
- package/dist/src/config/config.js +196 -64
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +305 -178
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +16 -0
- package/dist/src/config/models.js +29 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.d.ts +6 -0
- package/dist/src/config/models.test.js +55 -0
- package/dist/src/config/models.test.js.map +1 -0
- package/dist/src/config/storage.d.ts +2 -0
- package/dist/src/config/storage.js +6 -1
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/config/storage.test.js +4 -0
- package/dist/src/config/storage.test.js.map +1 -1
- package/dist/src/confirmation-bus/index.d.ts +7 -0
- package/dist/src/confirmation-bus/index.js +8 -0
- package/dist/src/confirmation-bus/index.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.d.ts +17 -0
- package/dist/src/confirmation-bus/message-bus.js +81 -0
- package/dist/src/confirmation-bus/message-bus.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.test.d.ts +6 -0
- package/dist/src/confirmation-bus/message-bus.test.js +164 -0
- package/dist/src/confirmation-bus/message-bus.test.js.map +1 -0
- package/dist/src/confirmation-bus/types.d.ts +38 -0
- package/dist/src/confirmation-bus/types.js +15 -0
- package/dist/src/confirmation-bus/types.js.map +1 -0
- package/dist/src/core/baseLlmClient.d.ts +46 -0
- package/dist/src/core/baseLlmClient.js +112 -0
- package/dist/src/core/baseLlmClient.js.map +1 -0
- package/dist/src/core/baseLlmClient.test.d.ts +6 -0
- package/dist/src/core/baseLlmClient.test.js +253 -0
- package/dist/src/core/baseLlmClient.test.js.map +1 -0
- package/dist/src/core/client.d.ts +16 -21
- package/dist/src/core/client.js +145 -232
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +393 -492
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +2 -3
- package/dist/src/core/contentGenerator.js +0 -4
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +1 -3
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +8 -3
- package/dist/src/core/coreToolScheduler.js +106 -5
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +233 -5
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +38 -32
- package/dist/src/core/geminiChat.js +209 -219
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +674 -386
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.js +13 -16
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +59 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.d.ts +5 -0
- package/dist/src/core/prompts.js +63 -42
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +130 -1
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/subagent.js +7 -10
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/core/subagent.test.js +32 -22
- package/dist/src/core/subagent.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +21 -5
- package/dist/src/core/turn.js +45 -11
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +340 -100
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/fallback/handler.d.ts +7 -0
- package/dist/src/fallback/handler.js +51 -0
- package/dist/src/fallback/handler.js.map +1 -0
- package/dist/src/fallback/handler.test.d.ts +6 -0
- package/dist/src/fallback/handler.test.js +130 -0
- package/dist/src/fallback/handler.test.js.map +1 -0
- package/dist/src/fallback/types.d.ts +14 -0
- package/dist/src/fallback/types.js +7 -0
- package/dist/src/fallback/types.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/ide/constants.d.ts +3 -0
- package/dist/src/ide/constants.js +3 -0
- package/dist/src/ide/constants.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +42 -14
- package/dist/src/ide/detect-ide.js +22 -68
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +11 -51
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +60 -18
- package/dist/src/ide/ide-client.js +275 -53
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.js +239 -6
- package/dist/src/ide/ide-client.test.js.map +1 -1
- package/dist/src/ide/ide-installer.d.ts +2 -2
- package/dist/src/ide/ide-installer.js +15 -11
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +30 -12
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +35 -365
- package/dist/src/ide/ideContext.js +60 -106
- package/dist/src/ide/ideContext.js.map +1 -1
- package/dist/src/ide/ideContext.test.js +152 -24
- package/dist/src/ide/ideContext.test.js.map +1 -1
- package/dist/src/ide/process-utils.d.ts +0 -1
- package/dist/src/ide/process-utils.js +43 -25
- package/dist/src/ide/process-utils.js.map +1 -1
- package/dist/src/ide/process-utils.test.js +90 -4
- package/dist/src/ide/process-utils.test.js.map +1 -1
- package/dist/src/ide/types.d.ts +486 -0
- package/dist/src/ide/types.js +138 -0
- package/dist/src/ide/types.js.map +1 -0
- package/dist/src/index.d.ts +10 -2
- package/dist/src/index.js +11 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/oauth-provider.d.ts +15 -12
- package/dist/src/mcp/oauth-provider.js +63 -56
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +74 -35
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.d.ts +14 -10
- package/dist/src/mcp/oauth-token-storage.js +52 -20
- package/dist/src/mcp/oauth-token-storage.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.test.js +255 -162
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.d.ts +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.js +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.js.map +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.test.js +1 -1
- package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.d.ts +24 -0
- package/dist/src/mcp/token-storage/file-token-storage.js +144 -0
- package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/file-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/file-token-storage.test.js +235 -0
- package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.d.ts +23 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.js +78 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +193 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/index.d.ts +11 -0
- package/dist/src/mcp/token-storage/index.js +12 -0
- package/dist/src/mcp/token-storage/index.js.map +1 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +31 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.js +190 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js +254 -0
- package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -0
- package/dist/src/mcp/token-storage/types.d.ts +4 -0
- package/dist/src/mcp/token-storage/types.js +5 -1
- package/dist/src/mcp/token-storage/types.js.map +1 -1
- package/dist/src/output/json-formatter.d.ts +11 -0
- package/dist/src/output/json-formatter.js +30 -0
- package/dist/src/output/json-formatter.js.map +1 -0
- package/dist/src/output/json-formatter.test.d.ts +6 -0
- package/dist/src/output/json-formatter.test.js +266 -0
- package/dist/src/output/json-formatter.test.js.map +1 -0
- package/dist/src/output/types.d.ts +20 -0
- package/dist/src/output/types.js +11 -0
- package/dist/src/output/types.js.map +1 -0
- package/dist/src/policy/index.d.ts +7 -0
- package/dist/src/policy/index.js +8 -0
- package/dist/src/policy/index.js.map +1 -0
- package/dist/src/policy/policy-engine.d.ts +30 -0
- package/dist/src/policy/policy-engine.js +92 -0
- package/dist/src/policy/policy-engine.js.map +1 -0
- package/dist/src/policy/policy-engine.test.d.ts +6 -0
- package/dist/src/policy/policy-engine.test.js +515 -0
- package/dist/src/policy/policy-engine.test.js.map +1 -0
- package/dist/src/policy/stable-stringify.d.ts +58 -0
- package/dist/src/policy/stable-stringify.js +122 -0
- package/dist/src/policy/stable-stringify.js.map +1 -0
- package/dist/src/policy/types.d.ts +47 -0
- package/dist/src/policy/types.js +12 -0
- package/dist/src/policy/types.js.map +1 -0
- package/dist/src/routing/modelRouterService.d.ts +23 -0
- package/dist/src/routing/modelRouterService.js +70 -0
- package/dist/src/routing/modelRouterService.js.map +1 -0
- package/dist/src/routing/modelRouterService.test.d.ts +6 -0
- package/dist/src/routing/modelRouterService.test.js +98 -0
- package/dist/src/routing/modelRouterService.test.js.map +1 -0
- package/dist/src/routing/routingStrategy.d.ts +62 -0
- package/dist/src/routing/routingStrategy.js +7 -0
- package/dist/src/routing/routingStrategy.js.map +1 -0
- package/dist/src/routing/strategies/classifierStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/classifierStrategy.js +173 -0
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -0
- package/dist/src/routing/strategies/classifierStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js +192 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/compositeStrategy.d.ts +26 -0
- package/dist/src/routing/strategies/compositeStrategy.js +67 -0
- package/dist/src/routing/strategies/compositeStrategy.js.map +1 -0
- package/dist/src/routing/strategies/compositeStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/compositeStrategy.test.js +123 -0
- package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/defaultStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/defaultStrategy.js +20 -0
- package/dist/src/routing/strategies/defaultStrategy.js.map +1 -0
- package/dist/src/routing/strategies/defaultStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/defaultStrategy.test.js +26 -0
- package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/fallbackStrategy.d.ts +12 -0
- package/dist/src/routing/strategies/fallbackStrategy.js +25 -0
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js +55 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/overrideStrategy.d.ts +15 -0
- package/dist/src/routing/strategies/overrideStrategy.js +28 -0
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -0
- package/dist/src/routing/strategies/overrideStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js +42 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -0
- package/dist/src/services/chatRecordingService.d.ts +7 -13
- package/dist/src/services/chatRecordingService.js +28 -19
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +62 -20
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.d.ts +10 -0
- package/dist/src/services/fileDiscoveryService.js +31 -17
- package/dist/src/services/fileDiscoveryService.js.map +1 -1
- package/dist/src/services/gitService.js +9 -12
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +10 -20
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +5 -0
- package/dist/src/services/loopDetectionService.js +36 -20
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +41 -12
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.d.ts +34 -2
- package/dist/src/services/shellExecutionService.js +192 -43
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +184 -55
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/activity-detector.d.ts +41 -0
- package/dist/src/telemetry/activity-detector.js +61 -0
- package/dist/src/telemetry/activity-detector.js.map +1 -0
- package/dist/src/telemetry/activity-detector.test.d.ts +6 -0
- package/dist/src/telemetry/activity-detector.test.js +136 -0
- package/dist/src/telemetry/activity-detector.test.js.map +1 -0
- package/dist/src/telemetry/activity-types.d.ts +19 -0
- package/dist/src/telemetry/activity-types.js +21 -0
- package/dist/src/telemetry/activity-types.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +16 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +143 -24
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +101 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +19 -2
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +48 -2
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/constants.d.ts +8 -0
- package/dist/src/telemetry/constants.js +8 -0
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/gcp-exporters.d.ts +34 -0
- package/dist/src/telemetry/gcp-exporters.js +117 -0
- package/dist/src/telemetry/gcp-exporters.js.map +1 -0
- package/dist/src/telemetry/gcp-exporters.test.d.ts +6 -0
- package/dist/src/telemetry/gcp-exporters.test.js +318 -0
- package/dist/src/telemetry/gcp-exporters.test.js.map +1 -0
- package/dist/src/telemetry/high-water-mark-tracker.d.ts +43 -0
- package/dist/src/telemetry/high-water-mark-tracker.js +88 -0
- package/dist/src/telemetry/high-water-mark-tracker.js.map +1 -0
- package/dist/src/telemetry/high-water-mark-tracker.test.d.ts +6 -0
- package/dist/src/telemetry/high-water-mark-tracker.test.js +152 -0
- package/dist/src/telemetry/high-water-mark-tracker.test.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +7 -2
- package/dist/src/telemetry/index.js +7 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +8 -1
- package/dist/src/telemetry/loggers.js +140 -8
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +268 -39
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +4 -3
- package/dist/src/telemetry/metrics.js +33 -10
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +47 -25
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/rate-limiter.d.ts +48 -0
- package/dist/src/telemetry/rate-limiter.js +100 -0
- package/dist/src/telemetry/rate-limiter.js.map +1 -0
- package/dist/src/telemetry/rate-limiter.test.d.ts +6 -0
- package/dist/src/telemetry/rate-limiter.test.js +207 -0
- package/dist/src/telemetry/rate-limiter.test.js.map +1 -0
- package/dist/src/telemetry/sdk.js +16 -1
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/sdk.test.js +95 -0
- package/dist/src/telemetry/sdk.test.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +70 -6
- package/dist/src/telemetry/types.js +112 -8
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +1 -1
- package/dist/src/telemetry/uiTelemetry.js +6 -7
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +15 -15
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/test-utils/index.d.ts +6 -0
- package/dist/src/test-utils/index.js +7 -0
- package/dist/src/test-utils/index.js.map +1 -0
- package/dist/src/test-utils/mock-tool.d.ts +41 -0
- package/dist/src/test-utils/mock-tool.js +51 -0
- package/dist/src/test-utils/mock-tool.js.map +1 -0
- package/dist/src/tools/diffOptions.js +21 -13
- package/dist/src/tools/diffOptions.js.map +1 -1
- package/dist/src/tools/diffOptions.test.js +58 -22
- package/dist/src/tools/diffOptions.test.js.map +1 -1
- package/dist/src/tools/edit.d.ts +2 -2
- package/dist/src/tools/edit.js +35 -44
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +124 -13
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +5 -1
- package/dist/src/tools/glob.js +24 -17
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +51 -0
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/ls.js +19 -32
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +140 -280
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +5 -3
- package/dist/src/tools/mcp-client-manager.js +13 -4
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +20 -1
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +5 -5
- package/dist/src/tools/mcp-client.js +40 -35
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +3 -3
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +3 -2
- package/dist/src/tools/mcp-tool.js +9 -9
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +28 -7
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.js +5 -33
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/read-file.js +8 -3
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +29 -0
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +1 -1
- package/dist/src/tools/read-many-files.js +18 -50
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +4 -4
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +8 -0
- package/dist/src/tools/ripGrep.js +26 -1
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +107 -5
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +12 -2
- package/dist/src/tools/shell.js +20 -24
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +35 -70
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +72 -0
- package/dist/src/tools/smart-edit.js +594 -0
- package/dist/src/tools/smart-edit.js.map +1 -0
- package/dist/src/tools/smart-edit.test.d.ts +6 -0
- package/dist/src/tools/smart-edit.test.js +419 -0
- package/dist/src/tools/smart-edit.test.js.map +1 -0
- package/dist/src/tools/tool-registry.d.ts +2 -1
- package/dist/src/tools/tool-registry.js +6 -5
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tools.d.ts +14 -7
- package/dist/src/tools/tools.js +9 -2
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.js +4 -3
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +1 -1
- package/dist/src/tools/web-search.js +3 -1
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/write-file.js +14 -19
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +99 -19
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.js +11 -5
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/editCorrector.d.ts +7 -6
- package/dist/src/utils/editCorrector.js +61 -18
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +30 -79
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.js +31 -44
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +61 -75
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/errorParsing.js +2 -2
- package/dist/src/utils/errorParsing.js.map +1 -1
- package/dist/src/utils/errorParsing.test.js +7 -7
- package/dist/src/utils/errorParsing.test.js.map +1 -1
- package/dist/src/utils/errors.d.ts +6 -0
- package/dist/src/utils/errors.js +10 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +20 -3
- package/dist/src/utils/fileUtils.js +154 -32
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +347 -29
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/flashFallback.test.d.ts +6 -0
- package/dist/src/utils/{flashFallback.integration.test.js → flashFallback.test.js} +31 -27
- package/dist/src/utils/flashFallback.test.js.map +1 -0
- package/dist/src/utils/geminiIgnoreParser.d.ts +18 -0
- package/dist/src/utils/geminiIgnoreParser.js +61 -0
- package/dist/src/utils/geminiIgnoreParser.js.map +1 -0
- package/dist/src/utils/geminiIgnoreParser.test.d.ts +6 -0
- package/dist/src/utils/geminiIgnoreParser.test.js +50 -0
- package/dist/src/utils/geminiIgnoreParser.test.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.d.ts +3 -7
- package/dist/src/utils/gitIgnoreParser.js +125 -34
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +66 -35
- package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
- package/dist/src/utils/llm-edit-fixer.d.ts +26 -0
- package/dist/src/utils/llm-edit-fixer.js +121 -0
- package/dist/src/utils/llm-edit-fixer.js.map +1 -0
- package/dist/src/utils/llm-edit-fixer.test.d.ts +6 -0
- package/dist/src/utils/llm-edit-fixer.test.js +105 -0
- package/dist/src/utils/llm-edit-fixer.test.js.map +1 -0
- package/dist/src/utils/memoryDiscovery.d.ts +5 -4
- package/dist/src/utils/memoryDiscovery.js +10 -9
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +50 -25
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.d.ts +2 -2
- package/dist/src/utils/nextSpeakerChecker.js +8 -2
- package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.test.js +75 -64
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
- package/dist/src/utils/promptIdContext.d.ts +7 -0
- package/dist/src/utils/promptIdContext.js +8 -0
- package/dist/src/utils/promptIdContext.js.map +1 -0
- package/dist/src/utils/shell-utils.d.ts +5 -0
- package/dist/src/utils/shell-utils.js +23 -0
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/terminalSerializer.d.ts +28 -0
- package/dist/src/utils/terminalSerializer.js +432 -0
- package/dist/src/utils/terminalSerializer.js.map +1 -0
- package/dist/src/utils/terminalSerializer.test.d.ts +6 -0
- package/dist/src/utils/terminalSerializer.test.js +176 -0
- package/dist/src/utils/terminalSerializer.test.js.map +1 -0
- package/dist/src/utils/textUtils.d.ts +5 -0
- package/dist/src/utils/textUtils.js +14 -0
- package/dist/src/utils/textUtils.js.map +1 -1
- package/dist/src/utils/textUtils.test.d.ts +6 -0
- package/dist/src/utils/textUtils.test.js +59 -0
- package/dist/src/utils/textUtils.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -3
- package/dist/google-gemini-cli-core-0.3.0-preview.3.tgz +0 -0
- package/dist/src/utils/flashFallback.integration.test.js.map +0 -1
- /package/dist/src/{utils/flashFallback.integration.test.d.ts → code_assist/oauth-credential-storage.test.d.ts} +0 -0
|
@@ -3,10 +3,24 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
7
|
-
import type { ContentGenerator } from './contentGenerator.js';
|
|
6
|
+
import { GenerateContentResponse, type Content, type GenerateContentConfig, type SendMessageParameters, type Part, type Tool } from '@google/genai';
|
|
8
7
|
import type { Config } from '../config/config.js';
|
|
9
8
|
import type { StructuredError } from './turn.js';
|
|
9
|
+
import { ChatRecordingService } from '../services/chatRecordingService.js';
|
|
10
|
+
export declare enum StreamEventType {
|
|
11
|
+
/** A regular content chunk from the API. */
|
|
12
|
+
CHUNK = "chunk",
|
|
13
|
+
/** A signal that a retry is about to happen. The UI should discard any partial
|
|
14
|
+
* content from the attempt that just failed. */
|
|
15
|
+
RETRY = "retry"
|
|
16
|
+
}
|
|
17
|
+
export type StreamEvent = {
|
|
18
|
+
type: StreamEventType.CHUNK;
|
|
19
|
+
value: GenerateContentResponse;
|
|
20
|
+
} | {
|
|
21
|
+
type: StreamEventType.RETRY;
|
|
22
|
+
};
|
|
23
|
+
export declare function isValidNonThoughtTextPart(part: Part): boolean;
|
|
10
24
|
/**
|
|
11
25
|
* Custom error to signal that a stream completed without valid content,
|
|
12
26
|
* which should trigger a retry.
|
|
@@ -23,38 +37,12 @@ export declare class EmptyStreamError extends Error {
|
|
|
23
37
|
*/
|
|
24
38
|
export declare class GeminiChat {
|
|
25
39
|
private readonly config;
|
|
26
|
-
private readonly contentGenerator;
|
|
27
40
|
private readonly generationConfig;
|
|
28
41
|
private history;
|
|
29
42
|
private sendPromise;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* Handles falling back to Flash model when persistent 429 errors occur for OAuth users.
|
|
33
|
-
* Uses a fallback handler if provided by the config; otherwise, returns null.
|
|
34
|
-
*/
|
|
35
|
-
private handleFlashFallback;
|
|
43
|
+
private readonly chatRecordingService;
|
|
44
|
+
constructor(config: Config, generationConfig?: GenerateContentConfig, history?: Content[]);
|
|
36
45
|
setSystemInstruction(sysInstr: string): void;
|
|
37
|
-
/**
|
|
38
|
-
* Sends a message to the model and returns the response.
|
|
39
|
-
*
|
|
40
|
-
* @remarks
|
|
41
|
-
* This method will wait for the previous message to be processed before
|
|
42
|
-
* sending the next message.
|
|
43
|
-
*
|
|
44
|
-
* @see {@link Chat#sendMessageStream} for streaming method.
|
|
45
|
-
* @param params - parameters for sending messages within a chat session.
|
|
46
|
-
* @returns The model's response.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* const chat = ai.chats.create({model: 'gemini-2.0-flash'});
|
|
51
|
-
* const response = await chat.sendMessage({
|
|
52
|
-
* message: 'Why is the sky blue?'
|
|
53
|
-
* });
|
|
54
|
-
* console.log(response.text);
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
sendMessage(params: SendMessageParameters, prompt_id: string): Promise<GenerateContentResponse>;
|
|
58
46
|
/**
|
|
59
47
|
* Sends a message to the model and returns the response in chunks.
|
|
60
48
|
*
|
|
@@ -77,7 +65,7 @@ export declare class GeminiChat {
|
|
|
77
65
|
* }
|
|
78
66
|
* ```
|
|
79
67
|
*/
|
|
80
|
-
sendMessageStream(params: SendMessageParameters, prompt_id: string): Promise<AsyncGenerator<
|
|
68
|
+
sendMessageStream(model: string, params: SendMessageParameters, prompt_id: string): Promise<AsyncGenerator<StreamEvent>>;
|
|
81
69
|
private makeApiCallAndProcessStream;
|
|
82
70
|
/**
|
|
83
71
|
* Returns the chat history.
|
|
@@ -112,10 +100,28 @@ export declare class GeminiChat {
|
|
|
112
100
|
*/
|
|
113
101
|
addHistory(content: Content): void;
|
|
114
102
|
setHistory(history: Content[]): void;
|
|
103
|
+
stripThoughtsFromHistory(): void;
|
|
115
104
|
setTools(tools: Tool[]): void;
|
|
116
105
|
maybeIncludeSchemaDepthContext(error: StructuredError): Promise<void>;
|
|
117
106
|
private processStreamResponse;
|
|
118
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Gets the chat recording service instance.
|
|
109
|
+
*/
|
|
110
|
+
getChatRecordingService(): ChatRecordingService;
|
|
111
|
+
/**
|
|
112
|
+
* Extracts and records thought from thought content.
|
|
113
|
+
*/
|
|
114
|
+
private recordThoughtFromContent;
|
|
115
|
+
/**
|
|
116
|
+
* Truncates the chunkStream right before the second function call to a
|
|
117
|
+
* function that mutates state. This may involve trimming parts from a chunk
|
|
118
|
+
* as well as omtting some chunks altogether.
|
|
119
|
+
*
|
|
120
|
+
* We do this because it improves tool call quality if the model gets
|
|
121
|
+
* feedback from one mutating function call before it makes the next one.
|
|
122
|
+
*/
|
|
123
|
+
private stopBeforeSecondMutator;
|
|
124
|
+
private isMutatorFunctionCall;
|
|
119
125
|
}
|
|
120
126
|
/** Visible for Testing */
|
|
121
127
|
export declare function isSchemaDepthError(errorMessage: string): boolean;
|
|
@@ -3,13 +3,29 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
// DISCLAIMER: This is a copied version of https://github.com/googleapis/js-genai/blob/main/src/chats.ts with the intention of working around a key bug
|
|
7
|
+
// where function responses are not treated as "valid" responses: https://b.corp.google.com/issues/420354090
|
|
8
|
+
import { GenerateContentResponse, FinishReason, } from '@google/genai';
|
|
9
|
+
import { toParts } from '../code_assist/converter.js';
|
|
6
10
|
import { createUserContent } from '@google/genai';
|
|
7
11
|
import { retryWithBackoff } from '../utils/retry.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { hasCycleInSchema } from '../tools/tools.js';
|
|
12
|
+
import { DEFAULT_GEMINI_FLASH_MODEL, getEffectiveModel, } from '../config/models.js';
|
|
13
|
+
import { hasCycleInSchema, MUTATOR_KINDS } from '../tools/tools.js';
|
|
11
14
|
import { logContentRetry, logContentRetryFailure, logInvalidChunk, } from '../telemetry/loggers.js';
|
|
15
|
+
import { ChatRecordingService } from '../services/chatRecordingService.js';
|
|
12
16
|
import { ContentRetryEvent, ContentRetryFailureEvent, InvalidChunkEvent, } from '../telemetry/types.js';
|
|
17
|
+
import { handleFallback } from '../fallback/handler.js';
|
|
18
|
+
import { isFunctionResponse } from '../utils/messageInspectors.js';
|
|
19
|
+
import { partListUnionToString } from './geminiRequest.js';
|
|
20
|
+
import { uiTelemetryService } from '../telemetry/uiTelemetry.js';
|
|
21
|
+
export var StreamEventType;
|
|
22
|
+
(function (StreamEventType) {
|
|
23
|
+
/** A regular content chunk from the API. */
|
|
24
|
+
StreamEventType["CHUNK"] = "chunk";
|
|
25
|
+
/** A signal that a retry is about to happen. The UI should discard any partial
|
|
26
|
+
* content from the attempt that just failed. */
|
|
27
|
+
StreamEventType["RETRY"] = "retry";
|
|
28
|
+
})(StreamEventType || (StreamEventType = {}));
|
|
13
29
|
const INVALID_CONTENT_RETRY_OPTIONS = {
|
|
14
30
|
maxAttempts: 3, // 1 initial call + 2 retries
|
|
15
31
|
initialDelayMs: 500,
|
|
@@ -27,6 +43,16 @@ function isValidResponse(response) {
|
|
|
27
43
|
}
|
|
28
44
|
return isValidContent(content);
|
|
29
45
|
}
|
|
46
|
+
export function isValidNonThoughtTextPart(part) {
|
|
47
|
+
return (typeof part.text === 'string' &&
|
|
48
|
+
!part.thought &&
|
|
49
|
+
// Technically, the model should never generate parts that have text and
|
|
50
|
+
// any of these but we don't trust them so check anyways.
|
|
51
|
+
!part.functionCall &&
|
|
52
|
+
!part.functionResponse &&
|
|
53
|
+
!part.inlineData &&
|
|
54
|
+
!part.fileData);
|
|
55
|
+
}
|
|
30
56
|
function isValidContent(content) {
|
|
31
57
|
if (content.parts === undefined || content.parts.length === 0) {
|
|
32
58
|
return false;
|
|
@@ -110,141 +136,23 @@ export class EmptyStreamError extends Error {
|
|
|
110
136
|
*/
|
|
111
137
|
export class GeminiChat {
|
|
112
138
|
config;
|
|
113
|
-
contentGenerator;
|
|
114
139
|
generationConfig;
|
|
115
140
|
history;
|
|
116
141
|
// A promise to represent the current state of the message being sent to the
|
|
117
142
|
// model.
|
|
118
143
|
sendPromise = Promise.resolve();
|
|
119
|
-
|
|
144
|
+
chatRecordingService;
|
|
145
|
+
constructor(config, generationConfig = {}, history = []) {
|
|
120
146
|
this.config = config;
|
|
121
|
-
this.contentGenerator = contentGenerator;
|
|
122
147
|
this.generationConfig = generationConfig;
|
|
123
148
|
this.history = history;
|
|
124
149
|
validateHistory(history);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
* Handles falling back to Flash model when persistent 429 errors occur for OAuth users.
|
|
128
|
-
* Uses a fallback handler if provided by the config; otherwise, returns null.
|
|
129
|
-
*/
|
|
130
|
-
async handleFlashFallback(authType, error) {
|
|
131
|
-
// Only handle fallback for OAuth users
|
|
132
|
-
if (authType !== AuthType.LOGIN_WITH_GOOGLE) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
const currentModel = this.config.getModel();
|
|
136
|
-
const fallbackModel = DEFAULT_GEMINI_FLASH_MODEL;
|
|
137
|
-
// Don't fallback if already using Flash model
|
|
138
|
-
if (currentModel === fallbackModel) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
// Check if config has a fallback handler (set by CLI package)
|
|
142
|
-
const fallbackHandler = this.config.flashFallbackHandler;
|
|
143
|
-
if (typeof fallbackHandler === 'function') {
|
|
144
|
-
try {
|
|
145
|
-
const accepted = await fallbackHandler(currentModel, fallbackModel, error);
|
|
146
|
-
if (accepted !== false && accepted !== null) {
|
|
147
|
-
this.config.setModel(fallbackModel);
|
|
148
|
-
this.config.setFallbackMode(true);
|
|
149
|
-
return fallbackModel;
|
|
150
|
-
}
|
|
151
|
-
// Check if the model was switched manually in the handler
|
|
152
|
-
if (this.config.getModel() === fallbackModel) {
|
|
153
|
-
return null; // Model was switched but don't continue with current prompt
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
catch (error) {
|
|
157
|
-
console.warn('Flash fallback handler failed:', error);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return null;
|
|
150
|
+
this.chatRecordingService = new ChatRecordingService(config);
|
|
151
|
+
this.chatRecordingService.initialize();
|
|
161
152
|
}
|
|
162
153
|
setSystemInstruction(sysInstr) {
|
|
163
154
|
this.generationConfig.systemInstruction = sysInstr;
|
|
164
155
|
}
|
|
165
|
-
/**
|
|
166
|
-
* Sends a message to the model and returns the response.
|
|
167
|
-
*
|
|
168
|
-
* @remarks
|
|
169
|
-
* This method will wait for the previous message to be processed before
|
|
170
|
-
* sending the next message.
|
|
171
|
-
*
|
|
172
|
-
* @see {@link Chat#sendMessageStream} for streaming method.
|
|
173
|
-
* @param params - parameters for sending messages within a chat session.
|
|
174
|
-
* @returns The model's response.
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* ```ts
|
|
178
|
-
* const chat = ai.chats.create({model: 'gemini-2.0-flash'});
|
|
179
|
-
* const response = await chat.sendMessage({
|
|
180
|
-
* message: 'Why is the sky blue?'
|
|
181
|
-
* });
|
|
182
|
-
* console.log(response.text);
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
async sendMessage(params, prompt_id) {
|
|
186
|
-
await this.sendPromise;
|
|
187
|
-
const userContent = createUserContent(params.message);
|
|
188
|
-
const requestContents = this.getHistory(true).concat(userContent);
|
|
189
|
-
let response;
|
|
190
|
-
try {
|
|
191
|
-
const apiCall = () => {
|
|
192
|
-
const modelToUse = this.config.getModel() || DEFAULT_GEMINI_FLASH_MODEL;
|
|
193
|
-
// Prevent Flash model calls immediately after quota error
|
|
194
|
-
if (this.config.getQuotaErrorOccurred() &&
|
|
195
|
-
modelToUse === DEFAULT_GEMINI_FLASH_MODEL) {
|
|
196
|
-
throw new Error('Please submit a new query to continue with the Flash model.');
|
|
197
|
-
}
|
|
198
|
-
return this.contentGenerator.generateContent({
|
|
199
|
-
model: modelToUse,
|
|
200
|
-
contents: requestContents,
|
|
201
|
-
config: { ...this.generationConfig, ...params.config },
|
|
202
|
-
}, prompt_id);
|
|
203
|
-
};
|
|
204
|
-
response = await retryWithBackoff(apiCall, {
|
|
205
|
-
shouldRetry: (error) => {
|
|
206
|
-
// Check for known error messages and codes.
|
|
207
|
-
if (error instanceof Error && error.message) {
|
|
208
|
-
if (isSchemaDepthError(error.message))
|
|
209
|
-
return false;
|
|
210
|
-
if (error.message.includes('429'))
|
|
211
|
-
return true;
|
|
212
|
-
if (error.message.match(/5\d{2}/))
|
|
213
|
-
return true;
|
|
214
|
-
}
|
|
215
|
-
return false; // Don't retry other errors by default
|
|
216
|
-
},
|
|
217
|
-
onPersistent429: async (authType, error) => await this.handleFlashFallback(authType, error),
|
|
218
|
-
authType: this.config.getContentGeneratorConfig()?.authType,
|
|
219
|
-
});
|
|
220
|
-
this.sendPromise = (async () => {
|
|
221
|
-
const outputContent = response.candidates?.[0]?.content;
|
|
222
|
-
const modelOutput = outputContent ? [outputContent] : [];
|
|
223
|
-
// Because the AFC input contains the entire curated chat history in
|
|
224
|
-
// addition to the new user input, we need to truncate the AFC history
|
|
225
|
-
// to deduplicate the existing chat history.
|
|
226
|
-
const fullAutomaticFunctionCallingHistory = response.automaticFunctionCallingHistory;
|
|
227
|
-
const index = this.getHistory(true).length;
|
|
228
|
-
let automaticFunctionCallingHistory = [];
|
|
229
|
-
if (fullAutomaticFunctionCallingHistory != null) {
|
|
230
|
-
automaticFunctionCallingHistory =
|
|
231
|
-
fullAutomaticFunctionCallingHistory.slice(index) ?? [];
|
|
232
|
-
}
|
|
233
|
-
this.recordHistory(userContent, modelOutput, automaticFunctionCallingHistory);
|
|
234
|
-
})();
|
|
235
|
-
await this.sendPromise.catch((error) => {
|
|
236
|
-
// Resets sendPromise to avoid subsequent calls failing
|
|
237
|
-
this.sendPromise = Promise.resolve();
|
|
238
|
-
// Re-throw the error so the caller knows something went wrong.
|
|
239
|
-
throw error;
|
|
240
|
-
});
|
|
241
|
-
return response;
|
|
242
|
-
}
|
|
243
|
-
catch (error) {
|
|
244
|
-
this.sendPromise = Promise.resolve();
|
|
245
|
-
throw error;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
156
|
/**
|
|
249
157
|
* Sends a message to the model and returns the response in chunks.
|
|
250
158
|
*
|
|
@@ -267,7 +175,7 @@ export class GeminiChat {
|
|
|
267
175
|
* }
|
|
268
176
|
* ```
|
|
269
177
|
*/
|
|
270
|
-
async sendMessageStream(params, prompt_id) {
|
|
178
|
+
async sendMessageStream(model, params, prompt_id) {
|
|
271
179
|
await this.sendPromise;
|
|
272
180
|
let streamDoneResolver;
|
|
273
181
|
const streamDonePromise = new Promise((resolve) => {
|
|
@@ -275,6 +183,19 @@ export class GeminiChat {
|
|
|
275
183
|
});
|
|
276
184
|
this.sendPromise = streamDonePromise;
|
|
277
185
|
const userContent = createUserContent(params.message);
|
|
186
|
+
// Record user input - capture complete message with all parts (text, files, images, etc.)
|
|
187
|
+
// but skip recording function responses (tool call results) as they should be stored in tool call records
|
|
188
|
+
if (!isFunctionResponse(userContent)) {
|
|
189
|
+
const userMessage = Array.isArray(params.message)
|
|
190
|
+
? params.message
|
|
191
|
+
: [params.message];
|
|
192
|
+
const userMessageContent = partListUnionToString(toParts(userMessage));
|
|
193
|
+
this.chatRecordingService.recordMessage({
|
|
194
|
+
model,
|
|
195
|
+
type: 'user',
|
|
196
|
+
content: userMessageContent,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
278
199
|
// Add user content to history ONCE before any attempts.
|
|
279
200
|
this.history.push(userContent);
|
|
280
201
|
const requestContents = this.getHistory(true);
|
|
@@ -285,9 +206,12 @@ export class GeminiChat {
|
|
|
285
206
|
let lastError = new Error('Request failed after all retries.');
|
|
286
207
|
for (let attempt = 0; attempt < INVALID_CONTENT_RETRY_OPTIONS.maxAttempts; attempt++) {
|
|
287
208
|
try {
|
|
288
|
-
|
|
209
|
+
if (attempt > 0) {
|
|
210
|
+
yield { type: StreamEventType.RETRY };
|
|
211
|
+
}
|
|
212
|
+
const stream = await self.makeApiCallAndProcessStream(model, requestContents, params, prompt_id);
|
|
289
213
|
for await (const chunk of stream) {
|
|
290
|
-
yield chunk;
|
|
214
|
+
yield { type: StreamEventType.CHUNK, value: chunk };
|
|
291
215
|
}
|
|
292
216
|
lastError = null;
|
|
293
217
|
break;
|
|
@@ -323,19 +247,20 @@ export class GeminiChat {
|
|
|
323
247
|
}
|
|
324
248
|
})();
|
|
325
249
|
}
|
|
326
|
-
async makeApiCallAndProcessStream(requestContents, params, prompt_id
|
|
250
|
+
async makeApiCallAndProcessStream(model, requestContents, params, prompt_id) {
|
|
327
251
|
const apiCall = () => {
|
|
328
|
-
const modelToUse = this.config.
|
|
252
|
+
const modelToUse = getEffectiveModel(this.config.isInFallbackMode(), model);
|
|
329
253
|
if (this.config.getQuotaErrorOccurred() &&
|
|
330
254
|
modelToUse === DEFAULT_GEMINI_FLASH_MODEL) {
|
|
331
255
|
throw new Error('Please submit a new query to continue with the Flash model.');
|
|
332
256
|
}
|
|
333
|
-
return this.
|
|
257
|
+
return this.config.getContentGenerator().generateContentStream({
|
|
334
258
|
model: modelToUse,
|
|
335
259
|
contents: requestContents,
|
|
336
260
|
config: { ...this.generationConfig, ...params.config },
|
|
337
261
|
}, prompt_id);
|
|
338
262
|
};
|
|
263
|
+
const onPersistent429Callback = async (authType, error) => await handleFallback(this.config, model, authType, error);
|
|
339
264
|
const streamResponse = await retryWithBackoff(apiCall, {
|
|
340
265
|
shouldRetry: (error) => {
|
|
341
266
|
if (error instanceof Error && error.message) {
|
|
@@ -348,10 +273,10 @@ export class GeminiChat {
|
|
|
348
273
|
}
|
|
349
274
|
return false;
|
|
350
275
|
},
|
|
351
|
-
onPersistent429:
|
|
276
|
+
onPersistent429: onPersistent429Callback,
|
|
352
277
|
authType: this.config.getContentGeneratorConfig()?.authType,
|
|
353
278
|
});
|
|
354
|
-
return this.processStreamResponse(
|
|
279
|
+
return this.processStreamResponse(model, streamResponse);
|
|
355
280
|
}
|
|
356
281
|
/**
|
|
357
282
|
* Returns the chat history.
|
|
@@ -399,6 +324,22 @@ export class GeminiChat {
|
|
|
399
324
|
setHistory(history) {
|
|
400
325
|
this.history = history;
|
|
401
326
|
}
|
|
327
|
+
stripThoughtsFromHistory() {
|
|
328
|
+
this.history = this.history.map((content) => {
|
|
329
|
+
const newContent = { ...content };
|
|
330
|
+
if (newContent.parts) {
|
|
331
|
+
newContent.parts = newContent.parts.map((part) => {
|
|
332
|
+
if (part && typeof part === 'object' && 'thoughtSignature' in part) {
|
|
333
|
+
const newPart = { ...part };
|
|
334
|
+
delete newPart.thoughtSignature;
|
|
335
|
+
return newPart;
|
|
336
|
+
}
|
|
337
|
+
return part;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return newContent;
|
|
341
|
+
});
|
|
342
|
+
}
|
|
402
343
|
setTools(tools) {
|
|
403
344
|
this.generationConfig.tools = tools;
|
|
404
345
|
}
|
|
@@ -424,117 +365,166 @@ export class GeminiChat {
|
|
|
424
365
|
}
|
|
425
366
|
}
|
|
426
367
|
}
|
|
427
|
-
async *processStreamResponse(
|
|
368
|
+
async *processStreamResponse(model, streamResponse) {
|
|
428
369
|
const modelResponseParts = [];
|
|
429
|
-
let isStreamInvalid = false;
|
|
430
370
|
let hasReceivedAnyChunk = false;
|
|
431
|
-
|
|
371
|
+
let hasReceivedValidChunk = false;
|
|
372
|
+
let hasToolCall = false;
|
|
373
|
+
let lastChunk = null;
|
|
374
|
+
let lastChunkIsInvalid = false;
|
|
375
|
+
for await (const chunk of this.stopBeforeSecondMutator(streamResponse)) {
|
|
432
376
|
hasReceivedAnyChunk = true;
|
|
377
|
+
lastChunk = chunk;
|
|
433
378
|
if (isValidResponse(chunk)) {
|
|
379
|
+
hasReceivedValidChunk = true;
|
|
380
|
+
lastChunkIsInvalid = false;
|
|
434
381
|
const content = chunk.candidates?.[0]?.content;
|
|
435
382
|
if (content?.parts) {
|
|
436
|
-
|
|
383
|
+
if (content.parts.some((part) => part.thought)) {
|
|
384
|
+
// Record thoughts
|
|
385
|
+
this.recordThoughtFromContent(content);
|
|
386
|
+
}
|
|
387
|
+
if (content.parts.some((part) => part.functionCall)) {
|
|
388
|
+
hasToolCall = true;
|
|
389
|
+
}
|
|
390
|
+
modelResponseParts.push(...content.parts.filter((part) => !part.thought));
|
|
437
391
|
}
|
|
438
392
|
}
|
|
439
393
|
else {
|
|
440
394
|
logInvalidChunk(this.config, new InvalidChunkEvent('Invalid chunk received from stream.'));
|
|
441
|
-
|
|
395
|
+
lastChunkIsInvalid = true;
|
|
442
396
|
}
|
|
443
|
-
|
|
397
|
+
// Record token usage if this chunk has usageMetadata
|
|
398
|
+
if (chunk.usageMetadata) {
|
|
399
|
+
this.chatRecordingService.recordMessageTokens(chunk.usageMetadata);
|
|
400
|
+
if (chunk.usageMetadata.promptTokenCount !== undefined) {
|
|
401
|
+
uiTelemetryService.setLastPromptTokenCount(chunk.usageMetadata.promptTokenCount);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
yield chunk; // Yield every chunk to the UI immediately.
|
|
444
405
|
}
|
|
445
|
-
if (
|
|
446
|
-
throw new EmptyStreamError('Model stream
|
|
406
|
+
if (!hasReceivedAnyChunk) {
|
|
407
|
+
throw new EmptyStreamError('Model stream completed without any chunks.');
|
|
447
408
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
//
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
this.history.push(...extractCuratedHistory(automaticFunctionCallingHistory));
|
|
409
|
+
const hasFinishReason = lastChunk?.candidates?.some((candidate) => candidate.finishReason);
|
|
410
|
+
// Stream validation logic: A stream is considered successful if:
|
|
411
|
+
// 1. There's a tool call (tool calls can end without explicit finish reasons), OR
|
|
412
|
+
// 2. There's a finish reason AND the last chunk is valid (or we haven't received any valid chunks)
|
|
413
|
+
//
|
|
414
|
+
// We throw an error only when there's no tool call AND:
|
|
415
|
+
// - No finish reason, OR
|
|
416
|
+
// - Last chunk is invalid after receiving valid content
|
|
417
|
+
if (!hasToolCall &&
|
|
418
|
+
(!hasFinishReason || (lastChunkIsInvalid && !hasReceivedValidChunk))) {
|
|
419
|
+
throw new EmptyStreamError('Model stream ended with an invalid chunk or missing finish reason.');
|
|
460
420
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
421
|
+
// Record model response text from the collected parts
|
|
422
|
+
if (modelResponseParts.length > 0) {
|
|
423
|
+
const responseText = modelResponseParts
|
|
424
|
+
.filter((part) => part.text)
|
|
425
|
+
.map((part) => part.text)
|
|
426
|
+
.join('');
|
|
427
|
+
if (responseText.trim()) {
|
|
428
|
+
this.chatRecordingService.recordMessage({
|
|
429
|
+
model,
|
|
430
|
+
type: 'gemini',
|
|
431
|
+
content: responseText,
|
|
432
|
+
});
|
|
474
433
|
}
|
|
475
434
|
}
|
|
476
|
-
//
|
|
477
|
-
const
|
|
478
|
-
for (const
|
|
479
|
-
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
// B. Filter out 'thought' parts.
|
|
485
|
-
const visibleParts = content.parts.filter((part) => !part.thought);
|
|
486
|
-
const newTurn = { ...content, parts: visibleParts };
|
|
487
|
-
const lastTurnInFinal = finalModelTurns[finalModelTurns.length - 1];
|
|
488
|
-
// Consolidate this new turn with the PREVIOUS turn if they are adjacent model turns.
|
|
489
|
-
if (lastTurnInFinal &&
|
|
490
|
-
lastTurnInFinal.role === 'model' &&
|
|
491
|
-
newTurn.role === 'model' &&
|
|
492
|
-
lastTurnInFinal.parts && // SAFETY CHECK: Ensure the destination has a parts array.
|
|
493
|
-
newTurn.parts) {
|
|
494
|
-
lastTurnInFinal.parts.push(...newTurn.parts);
|
|
435
|
+
// String thoughts and consolidate text parts.
|
|
436
|
+
const consolidatedParts = [];
|
|
437
|
+
for (const part of modelResponseParts) {
|
|
438
|
+
const lastPart = consolidatedParts[consolidatedParts.length - 1];
|
|
439
|
+
if (lastPart?.text &&
|
|
440
|
+
isValidNonThoughtTextPart(lastPart) &&
|
|
441
|
+
isValidNonThoughtTextPart(part)) {
|
|
442
|
+
lastPart.text += part.text;
|
|
495
443
|
}
|
|
496
444
|
else {
|
|
497
|
-
|
|
445
|
+
consolidatedParts.push(part);
|
|
498
446
|
}
|
|
499
447
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
448
|
+
this.history.push({ role: 'model', parts: consolidatedParts });
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Gets the chat recording service instance.
|
|
452
|
+
*/
|
|
453
|
+
getChatRecordingService() {
|
|
454
|
+
return this.chatRecordingService;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Extracts and records thought from thought content.
|
|
458
|
+
*/
|
|
459
|
+
recordThoughtFromContent(content) {
|
|
460
|
+
if (!content.parts || content.parts.length === 0) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const thoughtPart = content.parts[0];
|
|
464
|
+
if (thoughtPart.text) {
|
|
465
|
+
// Extract subject and description using the same logic as turn.ts
|
|
466
|
+
const rawText = thoughtPart.text;
|
|
467
|
+
const subjectStringMatches = rawText.match(/\*\*(.*?)\*\*/s);
|
|
468
|
+
const subject = subjectStringMatches
|
|
469
|
+
? subjectStringMatches[1].trim()
|
|
470
|
+
: '';
|
|
471
|
+
const description = rawText.replace(/\*\*(.*?)\*\*/s, '').trim();
|
|
472
|
+
this.chatRecordingService.recordThought({
|
|
473
|
+
subject,
|
|
474
|
+
description,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Truncates the chunkStream right before the second function call to a
|
|
480
|
+
* function that mutates state. This may involve trimming parts from a chunk
|
|
481
|
+
* as well as omtting some chunks altogether.
|
|
482
|
+
*
|
|
483
|
+
* We do this because it improves tool call quality if the model gets
|
|
484
|
+
* feedback from one mutating function call before it makes the next one.
|
|
485
|
+
*/
|
|
486
|
+
async *stopBeforeSecondMutator(chunkStream) {
|
|
487
|
+
let foundMutatorFunctionCall = false;
|
|
488
|
+
for await (const chunk of chunkStream) {
|
|
489
|
+
const candidate = chunk.candidates?.[0];
|
|
490
|
+
const content = candidate?.content;
|
|
491
|
+
if (!candidate || !content?.parts) {
|
|
492
|
+
yield chunk;
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
const truncatedParts = [];
|
|
496
|
+
for (const part of content.parts) {
|
|
497
|
+
if (this.isMutatorFunctionCall(part)) {
|
|
498
|
+
if (foundMutatorFunctionCall) {
|
|
499
|
+
// This is the second mutator call.
|
|
500
|
+
// Truncate and return immedaitely.
|
|
501
|
+
const newChunk = new GenerateContentResponse();
|
|
502
|
+
newChunk.candidates = [
|
|
503
|
+
{
|
|
504
|
+
...candidate,
|
|
505
|
+
content: {
|
|
506
|
+
...content,
|
|
507
|
+
parts: truncatedParts,
|
|
508
|
+
},
|
|
509
|
+
finishReason: FinishReason.STOP,
|
|
510
|
+
},
|
|
511
|
+
];
|
|
512
|
+
yield newChunk;
|
|
513
|
+
return;
|
|
528
514
|
}
|
|
529
|
-
|
|
515
|
+
foundMutatorFunctionCall = true;
|
|
530
516
|
}
|
|
517
|
+
truncatedParts.push(part);
|
|
531
518
|
}
|
|
532
|
-
|
|
519
|
+
yield chunk;
|
|
533
520
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
521
|
+
}
|
|
522
|
+
isMutatorFunctionCall(part) {
|
|
523
|
+
if (!part?.functionCall?.name) {
|
|
524
|
+
return false;
|
|
537
525
|
}
|
|
526
|
+
const tool = this.config.getToolRegistry().getTool(part.functionCall.name);
|
|
527
|
+
return !!tool && MUTATOR_KINDS.includes(tool.kind);
|
|
538
528
|
}
|
|
539
529
|
}
|
|
540
530
|
/** Visible for Testing */
|