@google/gemini-cli-core 0.0.3-preview.4 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +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
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
7
|
+
import { MessageBus } from './message-bus.js';
|
|
8
|
+
import { PolicyEngine } from '../policy/policy-engine.js';
|
|
9
|
+
import { PolicyDecision } from '../policy/types.js';
|
|
10
|
+
import { MessageBusType, } from './types.js';
|
|
11
|
+
describe('MessageBus', () => {
|
|
12
|
+
let messageBus;
|
|
13
|
+
let policyEngine;
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
policyEngine = new PolicyEngine();
|
|
16
|
+
messageBus = new MessageBus(policyEngine);
|
|
17
|
+
});
|
|
18
|
+
describe('publish', () => {
|
|
19
|
+
it('should emit error for invalid message', () => {
|
|
20
|
+
const errorHandler = vi.fn();
|
|
21
|
+
messageBus.on('error', errorHandler);
|
|
22
|
+
// @ts-expect-error - Testing invalid message
|
|
23
|
+
messageBus.publish({ invalid: 'message' });
|
|
24
|
+
expect(errorHandler).toHaveBeenCalledWith(expect.objectContaining({
|
|
25
|
+
message: expect.stringContaining('Invalid message structure'),
|
|
26
|
+
}));
|
|
27
|
+
});
|
|
28
|
+
it('should validate tool confirmation requests have correlationId', () => {
|
|
29
|
+
const errorHandler = vi.fn();
|
|
30
|
+
messageBus.on('error', errorHandler);
|
|
31
|
+
// @ts-expect-error - Testing missing correlationId
|
|
32
|
+
messageBus.publish({
|
|
33
|
+
type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
|
|
34
|
+
toolCall: { name: 'test' },
|
|
35
|
+
});
|
|
36
|
+
expect(errorHandler).toHaveBeenCalled();
|
|
37
|
+
});
|
|
38
|
+
it('should emit confirmation response when policy allows', () => {
|
|
39
|
+
vi.spyOn(policyEngine, 'check').mockReturnValue(PolicyDecision.ALLOW);
|
|
40
|
+
const responseHandler = vi.fn();
|
|
41
|
+
messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_RESPONSE, responseHandler);
|
|
42
|
+
const request = {
|
|
43
|
+
type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
|
|
44
|
+
toolCall: { name: 'test-tool', args: {} },
|
|
45
|
+
correlationId: '123',
|
|
46
|
+
};
|
|
47
|
+
messageBus.publish(request);
|
|
48
|
+
const expectedResponse = {
|
|
49
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
50
|
+
correlationId: '123',
|
|
51
|
+
confirmed: true,
|
|
52
|
+
};
|
|
53
|
+
expect(responseHandler).toHaveBeenCalledWith(expectedResponse);
|
|
54
|
+
});
|
|
55
|
+
it('should emit rejection and response when policy denies', () => {
|
|
56
|
+
vi.spyOn(policyEngine, 'check').mockReturnValue(PolicyDecision.DENY);
|
|
57
|
+
const responseHandler = vi.fn();
|
|
58
|
+
const rejectionHandler = vi.fn();
|
|
59
|
+
messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_RESPONSE, responseHandler);
|
|
60
|
+
messageBus.subscribe(MessageBusType.TOOL_POLICY_REJECTION, rejectionHandler);
|
|
61
|
+
const request = {
|
|
62
|
+
type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
|
|
63
|
+
toolCall: { name: 'test-tool', args: {} },
|
|
64
|
+
correlationId: '123',
|
|
65
|
+
};
|
|
66
|
+
messageBus.publish(request);
|
|
67
|
+
const expectedRejection = {
|
|
68
|
+
type: MessageBusType.TOOL_POLICY_REJECTION,
|
|
69
|
+
toolCall: { name: 'test-tool', args: {} },
|
|
70
|
+
};
|
|
71
|
+
expect(rejectionHandler).toHaveBeenCalledWith(expectedRejection);
|
|
72
|
+
const expectedResponse = {
|
|
73
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
74
|
+
correlationId: '123',
|
|
75
|
+
confirmed: false,
|
|
76
|
+
};
|
|
77
|
+
expect(responseHandler).toHaveBeenCalledWith(expectedResponse);
|
|
78
|
+
});
|
|
79
|
+
it('should pass through to UI when policy says ASK_USER', () => {
|
|
80
|
+
vi.spyOn(policyEngine, 'check').mockReturnValue(PolicyDecision.ASK_USER);
|
|
81
|
+
const requestHandler = vi.fn();
|
|
82
|
+
messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_REQUEST, requestHandler);
|
|
83
|
+
const request = {
|
|
84
|
+
type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
|
|
85
|
+
toolCall: { name: 'test-tool', args: {} },
|
|
86
|
+
correlationId: '123',
|
|
87
|
+
};
|
|
88
|
+
messageBus.publish(request);
|
|
89
|
+
expect(requestHandler).toHaveBeenCalledWith(request);
|
|
90
|
+
});
|
|
91
|
+
it('should emit other message types directly', () => {
|
|
92
|
+
const successHandler = vi.fn();
|
|
93
|
+
messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, successHandler);
|
|
94
|
+
const message = {
|
|
95
|
+
type: MessageBusType.TOOL_EXECUTION_SUCCESS,
|
|
96
|
+
toolCall: { name: 'test-tool' },
|
|
97
|
+
result: 'success',
|
|
98
|
+
};
|
|
99
|
+
messageBus.publish(message);
|
|
100
|
+
expect(successHandler).toHaveBeenCalledWith(message);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe('subscribe/unsubscribe', () => {
|
|
104
|
+
it('should allow subscribing to specific message types', () => {
|
|
105
|
+
const handler = vi.fn();
|
|
106
|
+
messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler);
|
|
107
|
+
const message = {
|
|
108
|
+
type: MessageBusType.TOOL_EXECUTION_SUCCESS,
|
|
109
|
+
toolCall: { name: 'test' },
|
|
110
|
+
result: 'test',
|
|
111
|
+
};
|
|
112
|
+
messageBus.publish(message);
|
|
113
|
+
expect(handler).toHaveBeenCalledWith(message);
|
|
114
|
+
});
|
|
115
|
+
it('should allow unsubscribing from message types', () => {
|
|
116
|
+
const handler = vi.fn();
|
|
117
|
+
messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler);
|
|
118
|
+
messageBus.unsubscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler);
|
|
119
|
+
const message = {
|
|
120
|
+
type: MessageBusType.TOOL_EXECUTION_SUCCESS,
|
|
121
|
+
toolCall: { name: 'test' },
|
|
122
|
+
result: 'test',
|
|
123
|
+
};
|
|
124
|
+
messageBus.publish(message);
|
|
125
|
+
expect(handler).not.toHaveBeenCalled();
|
|
126
|
+
});
|
|
127
|
+
it('should support multiple subscribers for the same message type', () => {
|
|
128
|
+
const handler1 = vi.fn();
|
|
129
|
+
const handler2 = vi.fn();
|
|
130
|
+
messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler1);
|
|
131
|
+
messageBus.subscribe(MessageBusType.TOOL_EXECUTION_SUCCESS, handler2);
|
|
132
|
+
const message = {
|
|
133
|
+
type: MessageBusType.TOOL_EXECUTION_SUCCESS,
|
|
134
|
+
toolCall: { name: 'test' },
|
|
135
|
+
result: 'test',
|
|
136
|
+
};
|
|
137
|
+
messageBus.publish(message);
|
|
138
|
+
expect(handler1).toHaveBeenCalledWith(message);
|
|
139
|
+
expect(handler2).toHaveBeenCalledWith(message);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
describe('error handling', () => {
|
|
143
|
+
it('should not crash on errors during message processing', () => {
|
|
144
|
+
const errorHandler = vi.fn();
|
|
145
|
+
messageBus.on('error', errorHandler);
|
|
146
|
+
// Mock policyEngine to throw an error
|
|
147
|
+
vi.spyOn(policyEngine, 'check').mockImplementation(() => {
|
|
148
|
+
throw new Error('Policy check failed');
|
|
149
|
+
});
|
|
150
|
+
const request = {
|
|
151
|
+
type: MessageBusType.TOOL_CONFIRMATION_REQUEST,
|
|
152
|
+
toolCall: { name: 'test-tool' },
|
|
153
|
+
correlationId: '123',
|
|
154
|
+
};
|
|
155
|
+
// Should not throw
|
|
156
|
+
expect(() => messageBus.publish(request)).not.toThrow();
|
|
157
|
+
// Should emit error
|
|
158
|
+
expect(errorHandler).toHaveBeenCalledWith(expect.objectContaining({
|
|
159
|
+
message: 'Policy check failed',
|
|
160
|
+
}));
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
//# sourceMappingURL=message-bus.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-bus.test.js","sourceRoot":"","sources":["../../../src/confirmation-bus/message-bus.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { type FunctionCall } from '@google/genai';
|
|
7
|
+
export declare enum MessageBusType {
|
|
8
|
+
TOOL_CONFIRMATION_REQUEST = "tool-confirmation-request",
|
|
9
|
+
TOOL_CONFIRMATION_RESPONSE = "tool-confirmation-response",
|
|
10
|
+
TOOL_POLICY_REJECTION = "tool-policy-rejection",
|
|
11
|
+
TOOL_EXECUTION_SUCCESS = "tool-execution-success",
|
|
12
|
+
TOOL_EXECUTION_FAILURE = "tool-execution-failure"
|
|
13
|
+
}
|
|
14
|
+
export interface ToolConfirmationRequest {
|
|
15
|
+
type: MessageBusType.TOOL_CONFIRMATION_REQUEST;
|
|
16
|
+
toolCall: FunctionCall;
|
|
17
|
+
correlationId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ToolConfirmationResponse {
|
|
20
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE;
|
|
21
|
+
correlationId: string;
|
|
22
|
+
confirmed: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface ToolPolicyRejection {
|
|
25
|
+
type: MessageBusType.TOOL_POLICY_REJECTION;
|
|
26
|
+
toolCall: FunctionCall;
|
|
27
|
+
}
|
|
28
|
+
export interface ToolExecutionSuccess<T = unknown> {
|
|
29
|
+
type: MessageBusType.TOOL_EXECUTION_SUCCESS;
|
|
30
|
+
toolCall: FunctionCall;
|
|
31
|
+
result: T;
|
|
32
|
+
}
|
|
33
|
+
export interface ToolExecutionFailure<E = Error> {
|
|
34
|
+
type: MessageBusType.TOOL_EXECUTION_FAILURE;
|
|
35
|
+
toolCall: FunctionCall;
|
|
36
|
+
error: E;
|
|
37
|
+
}
|
|
38
|
+
export type Message = ToolConfirmationRequest | ToolConfirmationResponse | ToolPolicyRejection | ToolExecutionSuccess | ToolExecutionFailure;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import {} from '@google/genai';
|
|
7
|
+
export var MessageBusType;
|
|
8
|
+
(function (MessageBusType) {
|
|
9
|
+
MessageBusType["TOOL_CONFIRMATION_REQUEST"] = "tool-confirmation-request";
|
|
10
|
+
MessageBusType["TOOL_CONFIRMATION_RESPONSE"] = "tool-confirmation-response";
|
|
11
|
+
MessageBusType["TOOL_POLICY_REJECTION"] = "tool-policy-rejection";
|
|
12
|
+
MessageBusType["TOOL_EXECUTION_SUCCESS"] = "tool-execution-success";
|
|
13
|
+
MessageBusType["TOOL_EXECUTION_FAILURE"] = "tool-execution-failure";
|
|
14
|
+
})(MessageBusType || (MessageBusType = {}));
|
|
15
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/confirmation-bus/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAqB,MAAM,eAAe,CAAC;AAElD,MAAM,CAAN,IAAY,cAMX;AAND,WAAY,cAAc;IACxB,yEAAuD,CAAA;IACvD,2EAAyD,CAAA;IACzD,iEAA+C,CAAA;IAC/C,mEAAiD,CAAA;IACjD,mEAAiD,CAAA;AACnD,CAAC,EANW,cAAc,KAAd,cAAc,QAMzB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Content, GenerateContentConfig, Part } from '@google/genai';
|
|
7
|
+
import type { Config } from '../config/config.js';
|
|
8
|
+
import type { ContentGenerator } from './contentGenerator.js';
|
|
9
|
+
/**
|
|
10
|
+
* Options for the generateJson utility function.
|
|
11
|
+
*/
|
|
12
|
+
export interface GenerateJsonOptions {
|
|
13
|
+
/** The input prompt or history. */
|
|
14
|
+
contents: Content[];
|
|
15
|
+
/** The required JSON schema for the output. */
|
|
16
|
+
schema: Record<string, unknown>;
|
|
17
|
+
/** The specific model to use for this task. */
|
|
18
|
+
model: string;
|
|
19
|
+
/**
|
|
20
|
+
* Task-specific system instructions.
|
|
21
|
+
* If omitted, no system instruction is sent.
|
|
22
|
+
*/
|
|
23
|
+
systemInstruction?: string | Part | Part[] | Content;
|
|
24
|
+
/**
|
|
25
|
+
* Overrides for generation configuration (e.g., temperature).
|
|
26
|
+
*/
|
|
27
|
+
config?: Omit<GenerateContentConfig, 'systemInstruction' | 'responseJsonSchema' | 'responseMimeType' | 'tools' | 'abortSignal'>;
|
|
28
|
+
/** Signal for cancellation. */
|
|
29
|
+
abortSignal: AbortSignal;
|
|
30
|
+
/**
|
|
31
|
+
* A unique ID for the prompt, used for logging/telemetry correlation.
|
|
32
|
+
*/
|
|
33
|
+
promptId: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A client dedicated to stateless, utility-focused LLM calls.
|
|
37
|
+
*/
|
|
38
|
+
export declare class BaseLlmClient {
|
|
39
|
+
private readonly contentGenerator;
|
|
40
|
+
private readonly config;
|
|
41
|
+
private readonly defaultUtilityConfig;
|
|
42
|
+
constructor(contentGenerator: ContentGenerator, config: Config);
|
|
43
|
+
generateJson(options: GenerateJsonOptions): Promise<Record<string, unknown>>;
|
|
44
|
+
generateEmbedding(texts: string[]): Promise<number[][]>;
|
|
45
|
+
private cleanJsonResponse;
|
|
46
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { getResponseText } from '../utils/partUtils.js';
|
|
7
|
+
import { reportError } from '../utils/errorReporting.js';
|
|
8
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
9
|
+
import { logMalformedJsonResponse } from '../telemetry/loggers.js';
|
|
10
|
+
import { MalformedJsonResponseEvent } from '../telemetry/types.js';
|
|
11
|
+
import { retryWithBackoff } from '../utils/retry.js';
|
|
12
|
+
/**
|
|
13
|
+
* A client dedicated to stateless, utility-focused LLM calls.
|
|
14
|
+
*/
|
|
15
|
+
export class BaseLlmClient {
|
|
16
|
+
contentGenerator;
|
|
17
|
+
config;
|
|
18
|
+
// Default configuration for utility tasks
|
|
19
|
+
defaultUtilityConfig = {
|
|
20
|
+
temperature: 0,
|
|
21
|
+
topP: 1,
|
|
22
|
+
};
|
|
23
|
+
constructor(contentGenerator, config) {
|
|
24
|
+
this.contentGenerator = contentGenerator;
|
|
25
|
+
this.config = config;
|
|
26
|
+
}
|
|
27
|
+
async generateJson(options) {
|
|
28
|
+
const { contents, schema, model, abortSignal, systemInstruction, promptId, } = options;
|
|
29
|
+
const requestConfig = {
|
|
30
|
+
abortSignal,
|
|
31
|
+
...this.defaultUtilityConfig,
|
|
32
|
+
...options.config,
|
|
33
|
+
...(systemInstruction && { systemInstruction }),
|
|
34
|
+
responseJsonSchema: schema,
|
|
35
|
+
responseMimeType: 'application/json',
|
|
36
|
+
};
|
|
37
|
+
try {
|
|
38
|
+
const apiCall = () => this.contentGenerator.generateContent({
|
|
39
|
+
model,
|
|
40
|
+
config: requestConfig,
|
|
41
|
+
contents,
|
|
42
|
+
}, promptId);
|
|
43
|
+
const result = await retryWithBackoff(apiCall);
|
|
44
|
+
let text = getResponseText(result)?.trim();
|
|
45
|
+
if (!text) {
|
|
46
|
+
const error = new Error('API returned an empty response for generateJson.');
|
|
47
|
+
await reportError(error, 'Error in generateJson: API returned an empty response.', contents, 'generateJson-empty-response');
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
text = this.cleanJsonResponse(text, model);
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(text);
|
|
53
|
+
}
|
|
54
|
+
catch (parseError) {
|
|
55
|
+
const error = new Error(`Failed to parse API response as JSON: ${getErrorMessage(parseError)}`);
|
|
56
|
+
await reportError(parseError, 'Failed to parse JSON response from generateJson.', {
|
|
57
|
+
responseTextFailedToParse: text,
|
|
58
|
+
originalRequestContents: contents,
|
|
59
|
+
}, 'generateJson-parse');
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (abortSignal.aborted) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
if (error instanceof Error &&
|
|
68
|
+
(error.message === 'API returned an empty response for generateJson.' ||
|
|
69
|
+
error.message.startsWith('Failed to parse API response as JSON:'))) {
|
|
70
|
+
// We perform this check so that we don't report these again.
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
await reportError(error, 'Error generating JSON content via API.', contents, 'generateJson-api');
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`Failed to generate JSON content: ${getErrorMessage(error)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async generateEmbedding(texts) {
|
|
79
|
+
if (!texts || texts.length === 0) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const embedModelParams = {
|
|
83
|
+
model: this.config.getEmbeddingModel(),
|
|
84
|
+
contents: texts,
|
|
85
|
+
};
|
|
86
|
+
const embedContentResponse = await this.contentGenerator.embedContent(embedModelParams);
|
|
87
|
+
if (!embedContentResponse.embeddings ||
|
|
88
|
+
embedContentResponse.embeddings.length === 0) {
|
|
89
|
+
throw new Error('No embeddings found in API response.');
|
|
90
|
+
}
|
|
91
|
+
if (embedContentResponse.embeddings.length !== texts.length) {
|
|
92
|
+
throw new Error(`API returned a mismatched number of embeddings. Expected ${texts.length}, got ${embedContentResponse.embeddings.length}.`);
|
|
93
|
+
}
|
|
94
|
+
return embedContentResponse.embeddings.map((embedding, index) => {
|
|
95
|
+
const values = embedding.values;
|
|
96
|
+
if (!values || values.length === 0) {
|
|
97
|
+
throw new Error(`API returned an empty embedding for input text at index ${index}: "${texts[index]}"`);
|
|
98
|
+
}
|
|
99
|
+
return values;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
cleanJsonResponse(text, model) {
|
|
103
|
+
const prefix = '```json';
|
|
104
|
+
const suffix = '```';
|
|
105
|
+
if (text.startsWith(prefix) && text.endsWith(suffix)) {
|
|
106
|
+
logMalformedJsonResponse(this.config, new MalformedJsonResponseEvent(model));
|
|
107
|
+
return text.substring(prefix.length, text.length - suffix.length).trim();
|
|
108
|
+
}
|
|
109
|
+
return text;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=baseLlmClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseLlmClient.js","sourceRoot":"","sources":["../../../src/core/baseLlmClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
7
|
+
import { BaseLlmClient } from './baseLlmClient.js';
|
|
8
|
+
import { AuthType } from './contentGenerator.js';
|
|
9
|
+
import { reportError } from '../utils/errorReporting.js';
|
|
10
|
+
import { logMalformedJsonResponse } from '../telemetry/loggers.js';
|
|
11
|
+
import { retryWithBackoff } from '../utils/retry.js';
|
|
12
|
+
import { MalformedJsonResponseEvent } from '../telemetry/types.js';
|
|
13
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
14
|
+
vi.mock('../utils/errorReporting.js');
|
|
15
|
+
vi.mock('../telemetry/loggers.js');
|
|
16
|
+
vi.mock('../utils/errors.js', async (importOriginal) => {
|
|
17
|
+
const actual = await importOriginal();
|
|
18
|
+
return {
|
|
19
|
+
...actual,
|
|
20
|
+
getErrorMessage: vi.fn((e) => (e instanceof Error ? e.message : String(e))),
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
vi.mock('../utils/retry.js', () => ({
|
|
24
|
+
retryWithBackoff: vi.fn(async (fn) => await fn()),
|
|
25
|
+
}));
|
|
26
|
+
const mockGenerateContent = vi.fn();
|
|
27
|
+
const mockEmbedContent = vi.fn();
|
|
28
|
+
const mockContentGenerator = {
|
|
29
|
+
generateContent: mockGenerateContent,
|
|
30
|
+
embedContent: mockEmbedContent,
|
|
31
|
+
};
|
|
32
|
+
const mockConfig = {
|
|
33
|
+
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
|
34
|
+
getContentGeneratorConfig: vi
|
|
35
|
+
.fn()
|
|
36
|
+
.mockReturnValue({ authType: AuthType.USE_GEMINI }),
|
|
37
|
+
getEmbeddingModel: vi.fn().mockReturnValue('test-embedding-model'),
|
|
38
|
+
};
|
|
39
|
+
// Helper to create a mock GenerateContentResponse
|
|
40
|
+
const createMockResponse = (text) => ({
|
|
41
|
+
candidates: [{ content: { role: 'model', parts: [{ text }] }, index: 0 }],
|
|
42
|
+
});
|
|
43
|
+
describe('BaseLlmClient', () => {
|
|
44
|
+
let client;
|
|
45
|
+
let abortController;
|
|
46
|
+
let defaultOptions;
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
vi.clearAllMocks();
|
|
49
|
+
// Reset the mocked implementation for getErrorMessage for accurate error message assertions
|
|
50
|
+
vi.mocked(getErrorMessage).mockImplementation((e) => e instanceof Error ? e.message : String(e));
|
|
51
|
+
client = new BaseLlmClient(mockContentGenerator, mockConfig);
|
|
52
|
+
abortController = new AbortController();
|
|
53
|
+
defaultOptions = {
|
|
54
|
+
contents: [{ role: 'user', parts: [{ text: 'Give me a color.' }] }],
|
|
55
|
+
schema: { type: 'object', properties: { color: { type: 'string' } } },
|
|
56
|
+
model: 'test-model',
|
|
57
|
+
abortSignal: abortController.signal,
|
|
58
|
+
promptId: 'test-prompt-id',
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
afterEach(() => {
|
|
62
|
+
abortController.abort();
|
|
63
|
+
});
|
|
64
|
+
describe('generateJson - Success Scenarios', () => {
|
|
65
|
+
it('should call generateContent with correct parameters, defaults, and utilize retry mechanism', async () => {
|
|
66
|
+
const mockResponse = createMockResponse('{"color": "blue"}');
|
|
67
|
+
mockGenerateContent.mockResolvedValue(mockResponse);
|
|
68
|
+
const result = await client.generateJson(defaultOptions);
|
|
69
|
+
expect(result).toEqual({ color: 'blue' });
|
|
70
|
+
// Ensure the retry mechanism was engaged
|
|
71
|
+
expect(retryWithBackoff).toHaveBeenCalledTimes(1);
|
|
72
|
+
// Validate the parameters passed to the underlying generator
|
|
73
|
+
expect(mockGenerateContent).toHaveBeenCalledTimes(1);
|
|
74
|
+
expect(mockGenerateContent).toHaveBeenCalledWith({
|
|
75
|
+
model: 'test-model',
|
|
76
|
+
contents: defaultOptions.contents,
|
|
77
|
+
config: {
|
|
78
|
+
abortSignal: defaultOptions.abortSignal,
|
|
79
|
+
temperature: 0,
|
|
80
|
+
topP: 1,
|
|
81
|
+
responseJsonSchema: defaultOptions.schema,
|
|
82
|
+
responseMimeType: 'application/json',
|
|
83
|
+
// Crucial: systemInstruction should NOT be in the config object if not provided
|
|
84
|
+
},
|
|
85
|
+
}, 'test-prompt-id');
|
|
86
|
+
});
|
|
87
|
+
it('should respect configuration overrides', async () => {
|
|
88
|
+
const mockResponse = createMockResponse('{"color": "red"}');
|
|
89
|
+
mockGenerateContent.mockResolvedValue(mockResponse);
|
|
90
|
+
const options = {
|
|
91
|
+
...defaultOptions,
|
|
92
|
+
config: { temperature: 0.8, topK: 10 },
|
|
93
|
+
};
|
|
94
|
+
await client.generateJson(options);
|
|
95
|
+
expect(mockGenerateContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
96
|
+
config: expect.objectContaining({
|
|
97
|
+
temperature: 0.8,
|
|
98
|
+
topP: 1, // Default should remain if not overridden
|
|
99
|
+
topK: 10,
|
|
100
|
+
}),
|
|
101
|
+
}), expect.any(String));
|
|
102
|
+
});
|
|
103
|
+
it('should include system instructions when provided', async () => {
|
|
104
|
+
const mockResponse = createMockResponse('{"color": "green"}');
|
|
105
|
+
mockGenerateContent.mockResolvedValue(mockResponse);
|
|
106
|
+
const systemInstruction = 'You are a helpful assistant.';
|
|
107
|
+
const options = {
|
|
108
|
+
...defaultOptions,
|
|
109
|
+
systemInstruction,
|
|
110
|
+
};
|
|
111
|
+
await client.generateJson(options);
|
|
112
|
+
expect(mockGenerateContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
113
|
+
config: expect.objectContaining({
|
|
114
|
+
systemInstruction,
|
|
115
|
+
}),
|
|
116
|
+
}), expect.any(String));
|
|
117
|
+
});
|
|
118
|
+
it('should use the provided promptId', async () => {
|
|
119
|
+
const mockResponse = createMockResponse('{"color": "yellow"}');
|
|
120
|
+
mockGenerateContent.mockResolvedValue(mockResponse);
|
|
121
|
+
const customPromptId = 'custom-id-123';
|
|
122
|
+
const options = {
|
|
123
|
+
...defaultOptions,
|
|
124
|
+
promptId: customPromptId,
|
|
125
|
+
};
|
|
126
|
+
await client.generateJson(options);
|
|
127
|
+
expect(mockGenerateContent).toHaveBeenCalledWith(expect.any(Object), customPromptId);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('generateJson - Response Cleaning', () => {
|
|
131
|
+
it('should clean JSON wrapped in markdown backticks and log telemetry', async () => {
|
|
132
|
+
const malformedResponse = '```json\n{"color": "purple"}\n```';
|
|
133
|
+
mockGenerateContent.mockResolvedValue(createMockResponse(malformedResponse));
|
|
134
|
+
const result = await client.generateJson(defaultOptions);
|
|
135
|
+
expect(result).toEqual({ color: 'purple' });
|
|
136
|
+
expect(logMalformedJsonResponse).toHaveBeenCalledTimes(1);
|
|
137
|
+
expect(logMalformedJsonResponse).toHaveBeenCalledWith(mockConfig, expect.any(MalformedJsonResponseEvent));
|
|
138
|
+
// Validate the telemetry event content
|
|
139
|
+
const event = vi.mocked(logMalformedJsonResponse).mock
|
|
140
|
+
.calls[0][1];
|
|
141
|
+
expect(event.model).toBe('test-model');
|
|
142
|
+
});
|
|
143
|
+
it('should handle extra whitespace correctly without logging malformed telemetry', async () => {
|
|
144
|
+
const responseWithWhitespace = ' \n {"color": "orange"} \n';
|
|
145
|
+
mockGenerateContent.mockResolvedValue(createMockResponse(responseWithWhitespace));
|
|
146
|
+
const result = await client.generateJson(defaultOptions);
|
|
147
|
+
expect(result).toEqual({ color: 'orange' });
|
|
148
|
+
expect(logMalformedJsonResponse).not.toHaveBeenCalled();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe('generateJson - Error Handling', () => {
|
|
152
|
+
it('should throw and report error for empty response', async () => {
|
|
153
|
+
mockGenerateContent.mockResolvedValue(createMockResponse(''));
|
|
154
|
+
// The final error message includes the prefix added by the client's outer catch block.
|
|
155
|
+
await expect(client.generateJson(defaultOptions)).rejects.toThrow('Failed to generate JSON content: API returned an empty response for generateJson.');
|
|
156
|
+
// Verify error reporting details
|
|
157
|
+
expect(reportError).toHaveBeenCalledTimes(1);
|
|
158
|
+
expect(reportError).toHaveBeenCalledWith(expect.any(Error), 'Error in generateJson: API returned an empty response.', defaultOptions.contents, 'generateJson-empty-response');
|
|
159
|
+
});
|
|
160
|
+
it('should throw and report error for invalid JSON syntax', async () => {
|
|
161
|
+
const invalidJson = '{"color": "blue"'; // missing closing brace
|
|
162
|
+
mockGenerateContent.mockResolvedValue(createMockResponse(invalidJson));
|
|
163
|
+
await expect(client.generateJson(defaultOptions)).rejects.toThrow(/^Failed to generate JSON content: Failed to parse API response as JSON:/);
|
|
164
|
+
expect(reportError).toHaveBeenCalledTimes(1);
|
|
165
|
+
expect(reportError).toHaveBeenCalledWith(expect.any(Error), 'Failed to parse JSON response from generateJson.', expect.objectContaining({ responseTextFailedToParse: invalidJson }), 'generateJson-parse');
|
|
166
|
+
});
|
|
167
|
+
it('should throw and report generic API errors', async () => {
|
|
168
|
+
const apiError = new Error('Service Unavailable (503)');
|
|
169
|
+
// Simulate the generator failing
|
|
170
|
+
mockGenerateContent.mockRejectedValue(apiError);
|
|
171
|
+
await expect(client.generateJson(defaultOptions)).rejects.toThrow('Failed to generate JSON content: Service Unavailable (503)');
|
|
172
|
+
// Verify generic error reporting
|
|
173
|
+
expect(reportError).toHaveBeenCalledTimes(1);
|
|
174
|
+
expect(reportError).toHaveBeenCalledWith(apiError, 'Error generating JSON content via API.', defaultOptions.contents, 'generateJson-api');
|
|
175
|
+
});
|
|
176
|
+
it('should throw immediately without reporting if aborted', async () => {
|
|
177
|
+
const abortError = new DOMException('Aborted', 'AbortError');
|
|
178
|
+
// Simulate abortion happening during the API call
|
|
179
|
+
mockGenerateContent.mockImplementation(() => {
|
|
180
|
+
abortController.abort(); // Ensure the signal is aborted when the service checks
|
|
181
|
+
throw abortError;
|
|
182
|
+
});
|
|
183
|
+
const options = {
|
|
184
|
+
...defaultOptions,
|
|
185
|
+
abortSignal: abortController.signal,
|
|
186
|
+
};
|
|
187
|
+
await expect(client.generateJson(options)).rejects.toThrow(abortError);
|
|
188
|
+
// Crucially, it should not report a cancellation as an application error
|
|
189
|
+
expect(reportError).not.toHaveBeenCalled();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe('generateEmbedding', () => {
|
|
193
|
+
const texts = ['hello world', 'goodbye world'];
|
|
194
|
+
const testEmbeddingModel = 'test-embedding-model';
|
|
195
|
+
it('should call embedContent with correct parameters and return embeddings', async () => {
|
|
196
|
+
const mockEmbeddings = [
|
|
197
|
+
[0.1, 0.2, 0.3],
|
|
198
|
+
[0.4, 0.5, 0.6],
|
|
199
|
+
];
|
|
200
|
+
mockEmbedContent.mockResolvedValue({
|
|
201
|
+
embeddings: [
|
|
202
|
+
{ values: mockEmbeddings[0] },
|
|
203
|
+
{ values: mockEmbeddings[1] },
|
|
204
|
+
],
|
|
205
|
+
});
|
|
206
|
+
const result = await client.generateEmbedding(texts);
|
|
207
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(1);
|
|
208
|
+
expect(mockEmbedContent).toHaveBeenCalledWith({
|
|
209
|
+
model: testEmbeddingModel,
|
|
210
|
+
contents: texts,
|
|
211
|
+
});
|
|
212
|
+
expect(result).toEqual(mockEmbeddings);
|
|
213
|
+
});
|
|
214
|
+
it('should return an empty array if an empty array is passed', async () => {
|
|
215
|
+
const result = await client.generateEmbedding([]);
|
|
216
|
+
expect(result).toEqual([]);
|
|
217
|
+
expect(mockEmbedContent).not.toHaveBeenCalled();
|
|
218
|
+
});
|
|
219
|
+
it('should throw an error if API response has no embeddings array', async () => {
|
|
220
|
+
mockEmbedContent.mockResolvedValue({});
|
|
221
|
+
await expect(client.generateEmbedding(texts)).rejects.toThrow('No embeddings found in API response.');
|
|
222
|
+
});
|
|
223
|
+
it('should throw an error if API response has an empty embeddings array', async () => {
|
|
224
|
+
mockEmbedContent.mockResolvedValue({
|
|
225
|
+
embeddings: [],
|
|
226
|
+
});
|
|
227
|
+
await expect(client.generateEmbedding(texts)).rejects.toThrow('No embeddings found in API response.');
|
|
228
|
+
});
|
|
229
|
+
it('should throw an error if API returns a mismatched number of embeddings', async () => {
|
|
230
|
+
mockEmbedContent.mockResolvedValue({
|
|
231
|
+
embeddings: [{ values: [1, 2, 3] }], // Only one for two texts
|
|
232
|
+
});
|
|
233
|
+
await expect(client.generateEmbedding(texts)).rejects.toThrow('API returned a mismatched number of embeddings. Expected 2, got 1.');
|
|
234
|
+
});
|
|
235
|
+
it('should throw an error if any embedding has nullish values', async () => {
|
|
236
|
+
mockEmbedContent.mockResolvedValue({
|
|
237
|
+
embeddings: [{ values: [1, 2, 3] }, { values: undefined }], // Second one is bad
|
|
238
|
+
});
|
|
239
|
+
await expect(client.generateEmbedding(texts)).rejects.toThrow('API returned an empty embedding for input text at index 1: "goodbye world"');
|
|
240
|
+
});
|
|
241
|
+
it('should throw an error if any embedding has an empty values array', async () => {
|
|
242
|
+
mockEmbedContent.mockResolvedValue({
|
|
243
|
+
embeddings: [{ values: [] }, { values: [1, 2, 3] }], // First one is bad
|
|
244
|
+
});
|
|
245
|
+
await expect(client.generateEmbedding(texts)).rejects.toThrow('API returned an empty embedding for input text at index 0: "hello world"');
|
|
246
|
+
});
|
|
247
|
+
it('should propagate errors from the API call', async () => {
|
|
248
|
+
mockEmbedContent.mockRejectedValue(new Error('API Failure'));
|
|
249
|
+
await expect(client.generateEmbedding(texts)).rejects.toThrow('API Failure');
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
//# sourceMappingURL=baseLlmClient.test.js.map
|