@vybestack/llxprt-code 0.1.20 → 0.1.22
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/README.md +31 -0
- package/dist/package.json +3 -3
- package/dist/src/commands/mcp/add.js +11 -0
- package/dist/src/commands/mcp/add.js.map +1 -1
- package/dist/src/config/auth.test.d.ts +6 -0
- package/dist/src/config/auth.test.js +57 -0
- package/dist/src/config/auth.test.js.map +1 -0
- package/dist/src/config/config.d.ts +1 -1
- package/dist/src/config/config.js +27 -14
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/keyBindings.js +3 -2
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/keyBindings.test.d.ts +6 -0
- package/dist/src/config/keyBindings.test.js +51 -0
- package/dist/src/config/keyBindings.test.js.map +1 -0
- package/dist/src/config/logging/loggingConfig.test.d.ts +6 -0
- package/dist/src/config/logging/loggingConfig.test.js +363 -0
- package/dist/src/config/logging/loggingConfig.test.js.map +1 -0
- package/dist/src/config/settingsSchema.d.ts +0 -9
- package/dist/src/config/settingsSchema.js +0 -9
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.d.ts +6 -0
- package/dist/src/config/settingsSchema.test.js +195 -0
- package/dist/src/config/settingsSchema.test.js.map +1 -0
- package/dist/src/config/trustedFolders.test.d.ts +6 -0
- package/dist/src/config/trustedFolders.test.js +156 -0
- package/dist/src/config/trustedFolders.test.js.map +1 -0
- package/dist/src/gemini.js +14 -4
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.d.ts +6 -0
- package/dist/src/gemini.test.js +199 -0
- package/dist/src/gemini.test.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/base-url-behavior.integration.test.js +492 -0
- package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -0
- package/dist/src/integration-tests/cli-args.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/cli-args.integration.test.js +398 -0
- package/dist/src/integration-tests/cli-args.integration.test.js.map +1 -0
- package/dist/src/integration-tests/compression-settings-apply.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js +436 -0
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js.map +1 -0
- package/dist/src/integration-tests/ephemeral-settings.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js +318 -0
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js.map +1 -0
- package/dist/src/integration-tests/model-params-isolation.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/model-params-isolation.integration.test.js +564 -0
- package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -0
- package/dist/src/integration-tests/modelParams.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/modelParams.integration.test.js +784 -0
- package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -0
- package/dist/src/integration-tests/profile-keyfile.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/profile-keyfile.integration.test.js +429 -0
- package/dist/src/integration-tests/profile-keyfile.integration.test.js.map +1 -0
- package/dist/src/integration-tests/profile-system.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/profile-system.integration.test.js +364 -0
- package/dist/src/integration-tests/profile-system.integration.test.js.map +1 -0
- package/dist/src/integration-tests/provider-switching.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/provider-switching.integration.test.js +207 -0
- package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -0
- package/dist/src/integration-tests/security.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/security.integration.test.js +319 -0
- package/dist/src/integration-tests/security.integration.test.js.map +1 -0
- package/dist/src/integration-tests/test-utils.test.d.ts +6 -0
- package/dist/src/integration-tests/test-utils.test.js +221 -0
- package/dist/src/integration-tests/test-utils.test.js.map +1 -0
- package/dist/src/integration-tests/todo-continuation.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/todo-continuation.integration.test.js +559 -0
- package/dist/src/integration-tests/todo-continuation.integration.test.js.map +1 -0
- package/dist/src/nonInteractiveCli.js +2 -5
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/providers/logging/LoggingProviderWrapper.test.d.ts +6 -0
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js +305 -0
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js.map +1 -0
- package/dist/src/providers/logging/git-stats.integration.test.d.ts +6 -0
- package/dist/src/providers/logging/git-stats.integration.test.js +245 -0
- package/dist/src/providers/logging/git-stats.integration.test.js.map +1 -0
- package/dist/src/providers/logging/git-stats.test.d.ts +6 -0
- package/dist/src/providers/logging/git-stats.test.js +432 -0
- package/dist/src/providers/logging/git-stats.test.js.map +1 -0
- package/dist/src/providers/logging/multi-provider-logging.integration.test.d.ts +6 -0
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js +531 -0
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -0
- package/dist/src/providers/logging/performance.test.d.ts +6 -0
- package/dist/src/providers/logging/performance.test.js +465 -0
- package/dist/src/providers/logging/performance.test.js.map +1 -0
- package/dist/src/providers/provider-gemini-switching.test.d.ts +6 -0
- package/dist/src/providers/provider-gemini-switching.test.js +129 -0
- package/dist/src/providers/provider-gemini-switching.test.js.map +1 -0
- package/dist/src/providers/provider-switching.integration.test.d.ts +6 -0
- package/dist/src/providers/provider-switching.integration.test.js +113 -0
- package/dist/src/providers/provider-switching.integration.test.js.map +1 -0
- package/dist/src/providers/providerManagerInstance.test.d.ts +6 -0
- package/dist/src/providers/providerManagerInstance.test.js +104 -0
- package/dist/src/providers/providerManagerInstance.test.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.test.d.ts +6 -0
- package/dist/src/services/BuiltinCommandLoader.test.js +118 -0
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -0
- package/dist/src/services/CommandService.test.d.ts +6 -0
- package/dist/src/services/CommandService.test.js +232 -0
- package/dist/src/services/CommandService.test.js.map +1 -0
- package/dist/src/services/FileCommandLoader.js +10 -8
- package/dist/src/services/FileCommandLoader.js.map +1 -1
- package/dist/src/services/prompt-processors/argumentProcessor.d.ts +2 -7
- package/dist/src/services/prompt-processors/argumentProcessor.js +2 -10
- package/dist/src/services/prompt-processors/argumentProcessor.js.map +1 -1
- package/dist/src/services/prompt-processors/shellProcessor.d.ts +16 -13
- package/dist/src/services/prompt-processors/shellProcessor.js +133 -40
- package/dist/src/services/prompt-processors/shellProcessor.js.map +1 -1
- package/dist/src/services/prompt-processors/types.d.ts +2 -0
- package/dist/src/services/prompt-processors/types.js +2 -0
- package/dist/src/services/prompt-processors/types.js.map +1 -1
- package/dist/src/storage/ConversationStorage.test.d.ts +6 -0
- package/dist/src/storage/ConversationStorage.test.js +379 -0
- package/dist/src/storage/ConversationStorage.test.js.map +1 -0
- package/dist/src/test-utils/customMatchers.d.ts +14 -0
- package/dist/src/test-utils/customMatchers.js +46 -0
- package/dist/src/test-utils/customMatchers.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.d.ts +18 -0
- package/dist/src/test-utils/mockCommandContext.js +86 -0
- package/dist/src/test-utils/mockCommandContext.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.test.d.ts +6 -0
- package/dist/src/test-utils/mockCommandContext.test.js +51 -0
- package/dist/src/test-utils/mockCommandContext.test.js.map +1 -0
- package/dist/src/test-utils/render.d.ts +8 -0
- package/dist/src/test-utils/render.js +10 -0
- package/dist/src/test-utils/render.js.map +1 -0
- package/dist/src/test-utils/responsive-testing.d.ts +14 -0
- package/dist/src/test-utils/responsive-testing.js +35 -0
- package/dist/src/test-utils/responsive-testing.js.map +1 -0
- package/dist/src/test-utils/responsive-testing.test.d.ts +6 -0
- package/dist/src/test-utils/responsive-testing.test.js +89 -0
- package/dist/src/test-utils/responsive-testing.test.js.map +1 -0
- package/dist/src/test-utils/testProviderConfig.d.ts +18 -0
- package/dist/src/test-utils/testProviderConfig.js +19 -0
- package/dist/src/test-utils/testProviderConfig.js.map +1 -0
- package/dist/src/ui/App.js +7 -6
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
- package/dist/src/ui/colors.js +25 -2
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +3 -0
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +8 -6
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.js +0 -1
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +3 -3
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/keyCommand.test.js +128 -0
- package/dist/src/ui/commands/keyCommand.test.js.map +1 -0
- package/dist/src/ui/commands/profileCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/profileCommand.test.js +343 -0
- package/dist/src/ui/commands/profileCommand.test.js.map +1 -0
- package/dist/src/ui/commands/setCommand.js +41 -0
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/setCommand.test.js +431 -0
- package/dist/src/ui/commands/setCommand.test.js.map +1 -0
- package/dist/src/ui/commands/setupGithubCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/setupGithubCommand.test.js +69 -0
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -0
- package/dist/src/ui/commands/toolformatCommand.test.d.ts +1 -0
- package/dist/src/ui/commands/toolformatCommand.test.js +145 -0
- package/dist/src/ui/commands/toolformatCommand.test.js.map +1 -0
- package/dist/src/ui/components/AboutBox.d.ts +1 -0
- package/dist/src/ui/components/AboutBox.js +1 -1
- package/dist/src/ui/components/AboutBox.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +1 -1
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.test.d.ts +6 -0
- package/dist/src/ui/components/AuthDialog.test.js +252 -0
- package/dist/src/ui/components/AuthDialog.test.js.map +1 -0
- package/dist/src/ui/components/ContextIndicator.ui.test.d.ts +1 -0
- package/dist/src/ui/components/ContextIndicator.ui.test.js +89 -0
- package/dist/src/ui/components/ContextIndicator.ui.test.js.map +1 -0
- package/dist/src/ui/components/ContextSummaryDisplay.js +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.semantic.test.d.ts +6 -0
- package/dist/src/ui/components/ContextUsageDisplay.semantic.test.js +75 -0
- package/dist/src/ui/components/ContextUsageDisplay.semantic.test.js.map +1 -0
- package/dist/src/ui/components/FolderTrustDialog.test.d.ts +6 -0
- package/dist/src/ui/components/FolderTrustDialog.test.js +26 -0
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -0
- package/dist/src/ui/components/Footer.d.ts +1 -0
- package/dist/src/ui/components/Footer.js +2 -2
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/Footer.responsive.test.js +262 -0
- package/dist/src/ui/components/Footer.responsive.test.js.map +1 -0
- package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.d.ts +6 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js +93 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -0
- package/dist/src/ui/components/InputPrompt.js +0 -4
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.paste.test.d.ts +6 -0
- package/dist/src/ui/components/InputPrompt.paste.test.js +263 -0
- package/dist/src/ui/components/InputPrompt.paste.test.js.map +1 -0
- package/dist/src/ui/components/LoadingIndicator.test.d.ts +6 -0
- package/dist/src/ui/components/LoadingIndicator.test.js +149 -0
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -0
- package/dist/src/ui/components/MemoryUsageDisplay.semantic.test.d.ts +6 -0
- package/dist/src/ui/components/MemoryUsageDisplay.semantic.test.js +127 -0
- package/dist/src/ui/components/MemoryUsageDisplay.semantic.test.js.map +1 -0
- package/dist/src/ui/components/ProviderDialog.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/ProviderDialog.responsive.test.js +153 -0
- package/dist/src/ui/components/ProviderDialog.responsive.test.js.map +1 -0
- package/dist/src/ui/components/ProviderModelDialog.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/ProviderModelDialog.responsive.test.js +252 -0
- package/dist/src/ui/components/ProviderModelDialog.responsive.test.js.map +1 -0
- package/dist/src/ui/components/ProviderModelDialog.test.d.ts +6 -0
- package/dist/src/ui/components/ProviderModelDialog.test.js +197 -0
- package/dist/src/ui/components/ProviderModelDialog.test.js.map +1 -0
- package/dist/src/ui/components/SettingsDialog.test.d.ts +6 -0
- package/dist/src/ui/components/SettingsDialog.test.js +555 -0
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -0
- package/dist/src/ui/components/ShellConfirmationDialog.js +2 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.test.d.ts +6 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.js +40 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -0
- package/dist/src/ui/components/TodoPanel.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/TodoPanel.responsive.test.js +221 -0
- package/dist/src/ui/components/TodoPanel.responsive.test.js.map +1 -0
- package/dist/src/ui/components/TodoPanel.semantic.test.d.ts +6 -0
- package/dist/src/ui/components/TodoPanel.semantic.test.js +137 -0
- package/dist/src/ui/components/TodoPanel.semantic.test.js.map +1 -0
- package/dist/src/ui/components/__tests__/LayoutManager.test.d.ts +6 -0
- package/dist/src/ui/components/__tests__/LayoutManager.test.js +94 -0
- package/dist/src/ui/components/__tests__/LayoutManager.test.js.map +1 -0
- package/dist/src/ui/components/messages/DiffRenderer.js +9 -3
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.d.ts +6 -0
- package/dist/src/ui/components/messages/DiffRenderer.test.js +266 -0
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -0
- package/dist/src/ui/components/messages/InfoMessage.js +2 -1
- package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +15 -5
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.responsive.test.js +173 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.responsive.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +37 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolMessage.test.js +118 -0
- package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.d.ts +6 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +154 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.js +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.d.ts +6 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js +113 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js.map +1 -0
- package/dist/src/ui/containers/SessionController.test.d.ts +6 -0
- package/dist/src/ui/containers/SessionController.test.js +440 -0
- package/dist/src/ui/containers/SessionController.test.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.d.ts +30 -0
- package/dist/src/ui/contexts/KeypressContext.js +314 -0
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.test.d.ts +6 -0
- package/dist/src/ui/contexts/KeypressContext.test.js +220 -0
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.d.ts +6 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.js +830 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -0
- package/dist/src/ui/hooks/index.d.ts +1 -0
- package/dist/src/ui/hooks/index.js +1 -0
- package/dist/src/ui/hooks/index.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.d.ts +6 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +328 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -0
- package/dist/src/ui/hooks/slashCommandProcessor.js +13 -7
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.js +3 -5
- package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.d.ts +6 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +191 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -0
- package/dist/src/ui/hooks/useEditorSettings.test.d.ts +6 -0
- package/dist/src/ui/hooks/useEditorSettings.test.js +221 -0
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.integration.test.d.ts +6 -0
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js +800 -0
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.js +12 -47
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.d.ts +6 -0
- package/dist/src/ui/hooks/useGitBranchName.test.js +170 -0
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -0
- package/dist/src/ui/hooks/useHistoryManager.test.d.ts +6 -0
- package/dist/src/ui/hooks/useHistoryManager.test.js +171 -0
- package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -0
- package/dist/src/ui/hooks/useInputHistory.test.d.ts +6 -0
- package/dist/src/ui/hooks/useInputHistory.test.js +207 -0
- package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -0
- package/dist/src/ui/hooks/useKeypress.d.ts +4 -24
- package/dist/src/ui/hooks/useKeypress.js +9 -330
- package/dist/src/ui/hooks/useKeypress.js.map +1 -1
- package/dist/src/ui/hooks/useKeypress.test.d.ts +6 -0
- package/dist/src/ui/hooks/useKeypress.test.js +176 -0
- package/dist/src/ui/hooks/useKeypress.test.js.map +1 -0
- package/dist/src/ui/hooks/usePhraseCycler.js +1 -0
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/useResponsive.test.d.ts +6 -0
- package/dist/src/ui/hooks/useResponsive.test.js +124 -0
- package/dist/src/ui/hooks/useResponsive.test.js.map +1 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.d.ts +6 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +163 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -0
- package/dist/src/ui/hooks/useShellHistory.test.d.ts +6 -0
- package/dist/src/ui/hooks/useShellHistory.test.js +162 -0
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.d.ts +6 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.js +929 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -0
- package/dist/src/ui/hooks/useStableCallback.test.d.ts +6 -0
- package/dist/src/ui/hooks/useStableCallback.test.js +57 -0
- package/dist/src/ui/hooks/useStableCallback.test.js.map +1 -0
- package/dist/src/ui/hooks/useToolScheduler.test.d.ts +6 -0
- package/dist/src/ui/hooks/useToolScheduler.test.js +841 -0
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -0
- package/dist/src/ui/keyMatchers.test.d.ts +6 -0
- package/dist/src/ui/keyMatchers.test.js +276 -0
- package/dist/src/ui/keyMatchers.test.js.map +1 -0
- package/dist/src/ui/reducers/appReducer.test.d.ts +6 -0
- package/dist/src/ui/reducers/appReducer.test.js +519 -0
- package/dist/src/ui/reducers/appReducer.test.js.map +1 -0
- package/dist/src/ui/themes/color-utils.test.d.ts +6 -0
- package/dist/src/ui/themes/color-utils.test.js +197 -0
- package/dist/src/ui/themes/color-utils.test.js.map +1 -0
- package/dist/src/ui/themes/semantic-resolver.js +16 -7
- package/dist/src/ui/themes/semantic-resolver.js.map +1 -1
- package/dist/src/ui/themes/semantic-resolver.test.d.ts +6 -0
- package/dist/src/ui/themes/semantic-resolver.test.js +246 -0
- package/dist/src/ui/themes/semantic-resolver.test.js.map +1 -0
- package/dist/src/ui/themes/semantic-tokens.d.ts +18 -33
- package/dist/src/ui/themes/semantic-tokens.js +88 -1
- package/dist/src/ui/themes/semantic-tokens.js.map +1 -1
- package/dist/src/ui/themes/semantic-tokens.test.d.ts +6 -0
- package/dist/src/ui/themes/semantic-tokens.test.js +289 -0
- package/dist/src/ui/themes/semantic-tokens.test.js.map +1 -0
- package/dist/src/ui/themes/theme-compat.d.ts +1 -1
- package/dist/src/ui/themes/theme-compat.js +7 -2
- package/dist/src/ui/themes/theme-compat.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.test.d.ts +6 -0
- package/dist/src/ui/themes/theme-manager.test.js +160 -0
- package/dist/src/ui/themes/theme-manager.test.js.map +1 -0
- package/dist/src/ui/types.d.ts +12 -1
- package/dist/src/ui/types.js +1 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.js +8 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.test.d.ts +6 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js +151 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -0
- package/dist/src/ui/utils/clipboardUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/clipboardUtils.test.js +65 -0
- package/dist/src/ui/utils/clipboardUtils.test.js.map +1 -0
- package/dist/src/ui/utils/commandUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/commandUtils.test.js +294 -0
- package/dist/src/ui/utils/commandUtils.test.js.map +1 -0
- package/dist/src/ui/utils/displayUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/displayUtils.test.js +42 -0
- package/dist/src/ui/utils/displayUtils.test.js.map +1 -0
- package/dist/src/ui/utils/formatters.test.d.ts +6 -0
- package/dist/src/ui/utils/formatters.test.js +56 -0
- package/dist/src/ui/utils/formatters.test.js.map +1 -0
- package/dist/src/ui/utils/markdownUtilities.test.d.ts +6 -0
- package/dist/src/ui/utils/markdownUtilities.test.js +42 -0
- package/dist/src/ui/utils/markdownUtilities.test.js.map +1 -0
- package/dist/src/ui/utils/platformConstants.d.ts +5 -0
- package/dist/src/ui/utils/platformConstants.js +5 -0
- package/dist/src/ui/utils/platformConstants.js.map +1 -1
- package/dist/src/ui/utils/responsive.test.d.ts +6 -0
- package/dist/src/ui/utils/responsive.test.js +107 -0
- package/dist/src/ui/utils/responsive.test.js.map +1 -0
- package/dist/src/ui/utils/secureInputHandler.test.d.ts +6 -0
- package/dist/src/ui/utils/secureInputHandler.test.js +274 -0
- package/dist/src/ui/utils/secureInputHandler.test.js.map +1 -0
- package/dist/src/ui/utils/updateCheck.test.d.ts +6 -0
- package/dist/src/ui/utils/updateCheck.test.js +202 -0
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -0
- package/dist/src/utils/ConversationContext.test.d.ts +6 -0
- package/dist/src/utils/ConversationContext.test.js +64 -0
- package/dist/src/utils/ConversationContext.test.js.map +1 -0
- package/dist/src/utils/gitUtils.test.d.ts +6 -0
- package/dist/src/utils/gitUtils.test.js +113 -0
- package/dist/src/utils/gitUtils.test.js.map +1 -0
- package/dist/src/utils/installationInfo.test.d.ts +6 -0
- package/dist/src/utils/installationInfo.test.js +242 -0
- package/dist/src/utils/installationInfo.test.js.map +1 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.test.d.ts +6 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js +463 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js.map +1 -0
- package/dist/src/utils/readStdin.js +10 -0
- package/dist/src/utils/readStdin.js.map +1 -1
- package/dist/src/utils/sandbox.js +2 -2
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/settingsUtils.test.d.ts +6 -0
- package/dist/src/utils/settingsUtils.test.js +514 -0
- package/dist/src/utils/settingsUtils.test.js.map +1 -0
- package/dist/src/utils/userStartupWarnings.js +2 -2
- package/dist/src/utils/userStartupWarnings.test.d.ts +6 -0
- package/dist/src/utils/userStartupWarnings.test.js +67 -0
- package/dist/src/utils/userStartupWarnings.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
@@ -0,0 +1,800 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Google LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
7
|
+
/**
|
8
|
+
* INTEGRATION TESTS FOR TODO CONTINUATION FUNCTIONALITY
|
9
|
+
*
|
10
|
+
* These tests are designed to verify the behavioral integration between
|
11
|
+
* useGeminiStream and the todo continuation system. They serve as both:
|
12
|
+
* 1. Specification of expected behavior per requirements REQ-001 through REQ-004
|
13
|
+
* 2. Functional tests that will pass once the integration is implemented
|
14
|
+
*
|
15
|
+
* CURRENT STATUS: These tests expect functionality that is not yet fully implemented.
|
16
|
+
* The useGeminiStream hook currently has a NotYetImplemented stub for todo continuation.
|
17
|
+
*
|
18
|
+
* IMPLEMENTATION NOTES:
|
19
|
+
* - The todo continuation logic exists in useTodoContinuation.ts
|
20
|
+
* - The integration point in useGeminiStream.ts is stubbed out
|
21
|
+
* - The GeminiClient.sendMessageStream API needs ephemeral message support
|
22
|
+
*
|
23
|
+
* These tests will be useful when:
|
24
|
+
* 1. The NotYetImplemented stub is removed from useGeminiStream
|
25
|
+
* 2. The GeminiClient API is extended to support ephemeral messages
|
26
|
+
* 3. The _handleStreamCompleted call is activated in useGeminiStream
|
27
|
+
*/
|
28
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
29
|
+
import { renderHook, act, waitFor } from '@testing-library/react';
|
30
|
+
import React from 'react';
|
31
|
+
import { useGeminiStream } from './useGeminiStream.js';
|
32
|
+
import { useReactToolScheduler, } from './useReactToolScheduler.js';
|
33
|
+
import { AuthType, GeminiEventType as ServerGeminiEventType, ApprovalMode, } from '@vybestack/llxprt-code-core';
|
34
|
+
import { StreamingState, } from '../types.js';
|
35
|
+
import { TodoContext } from '../contexts/TodoContext.js';
|
36
|
+
// --- MOCKS ---
|
37
|
+
const mockSendMessageStream = vi
|
38
|
+
.fn()
|
39
|
+
.mockReturnValue((async function* () { })());
|
40
|
+
const mockStartChat = vi.fn();
|
41
|
+
const MockedGeminiClientClass = vi.hoisted(() => vi.fn().mockImplementation(function (_config) {
|
42
|
+
this.startChat = mockStartChat;
|
43
|
+
this.sendMessageStream = mockSendMessageStream;
|
44
|
+
this.addHistory = vi.fn();
|
45
|
+
this.isInitialized = vi.fn().mockReturnValue(true);
|
46
|
+
}));
|
47
|
+
const MockedUserPromptEvent = vi.hoisted(() => vi.fn().mockImplementation(() => { }));
|
48
|
+
vi.mock('@vybestack/llxprt-code-core', async (importOriginal) => {
|
49
|
+
const actualCoreModule = (await importOriginal());
|
50
|
+
return {
|
51
|
+
...actualCoreModule,
|
52
|
+
GitService: vi.fn(),
|
53
|
+
GeminiClient: MockedGeminiClientClass,
|
54
|
+
UserPromptEvent: MockedUserPromptEvent,
|
55
|
+
parseAndFormatApiError: mockParseAndFormatApiError,
|
56
|
+
};
|
57
|
+
});
|
58
|
+
const mockUseReactToolScheduler = useReactToolScheduler;
|
59
|
+
vi.mock('./useReactToolScheduler.js', async (importOriginal) => {
|
60
|
+
const actualSchedulerModule = (await importOriginal());
|
61
|
+
return {
|
62
|
+
...(actualSchedulerModule || {}),
|
63
|
+
useReactToolScheduler: vi.fn(),
|
64
|
+
};
|
65
|
+
});
|
66
|
+
vi.mock('ink', async (importOriginal) => {
|
67
|
+
const actualInkModule = (await importOriginal());
|
68
|
+
return { ...(actualInkModule || {}), useInput: vi.fn() };
|
69
|
+
});
|
70
|
+
vi.mock('./shellCommandProcessor.js', () => ({
|
71
|
+
useShellCommandProcessor: vi.fn().mockReturnValue({
|
72
|
+
handleShellCommand: vi.fn(),
|
73
|
+
}),
|
74
|
+
}));
|
75
|
+
vi.mock('./atCommandProcessor.js', () => ({
|
76
|
+
handleAtCommand: vi
|
77
|
+
.fn()
|
78
|
+
.mockResolvedValue({ shouldProceed: true, processedQuery: 'mocked' }),
|
79
|
+
}));
|
80
|
+
vi.mock('../utils/markdownUtilities.js', () => ({
|
81
|
+
findLastSafeSplitPoint: vi.fn((s) => s.length),
|
82
|
+
}));
|
83
|
+
vi.mock('./useStateAndRef.js', () => ({
|
84
|
+
useStateAndRef: vi.fn((initial) => {
|
85
|
+
let val = initial;
|
86
|
+
const ref = { current: val };
|
87
|
+
const setVal = vi.fn((updater) => {
|
88
|
+
if (typeof updater === 'function') {
|
89
|
+
val = updater(val);
|
90
|
+
}
|
91
|
+
else {
|
92
|
+
val = updater;
|
93
|
+
}
|
94
|
+
ref.current = val;
|
95
|
+
});
|
96
|
+
return [ref, setVal];
|
97
|
+
}),
|
98
|
+
}));
|
99
|
+
vi.mock('./useLogger.js', () => ({
|
100
|
+
useLogger: vi.fn().mockReturnValue({
|
101
|
+
logMessage: vi.fn().mockResolvedValue(undefined),
|
102
|
+
}),
|
103
|
+
}));
|
104
|
+
const mockStartNewPrompt = vi.fn();
|
105
|
+
const mockAddUsage = vi.fn();
|
106
|
+
vi.mock('../contexts/SessionContext.js', () => ({
|
107
|
+
useSessionStats: vi.fn(() => ({
|
108
|
+
startNewPrompt: mockStartNewPrompt,
|
109
|
+
addUsage: mockAddUsage,
|
110
|
+
getPromptCount: vi.fn(() => 5),
|
111
|
+
})),
|
112
|
+
}));
|
113
|
+
vi.mock('./slashCommandProcessor.js', () => ({
|
114
|
+
handleSlashCommand: vi.fn().mockReturnValue(false),
|
115
|
+
}));
|
116
|
+
const mockParseAndFormatApiError = vi.hoisted(() => vi.fn());
|
117
|
+
// --- END MOCKS ---
|
118
|
+
describe('Todo Continuation Integration - useGeminiStream', () => {
|
119
|
+
/**
|
120
|
+
* @requirement CURRENT_STATE
|
121
|
+
* @scenario Integration not yet implemented
|
122
|
+
* @given Current codebase state
|
123
|
+
* @when Stream completes
|
124
|
+
* @then Integration is stubbed out with NotYetImplemented
|
125
|
+
* @note This test verifies the current state and should be updated when implementation is complete
|
126
|
+
*/
|
127
|
+
it('should currently have todo continuation integration stubbed out', async () => {
|
128
|
+
// This test verifies the current implementation state
|
129
|
+
// It should be updated/removed when the actual integration is implemented
|
130
|
+
const activeTodos = createActiveTodos();
|
131
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
132
|
+
yield {
|
133
|
+
type: ServerGeminiEventType.Content,
|
134
|
+
value: 'Response without tool calls',
|
135
|
+
};
|
136
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
137
|
+
})());
|
138
|
+
const { result } = renderTestHook([], activeTodos);
|
139
|
+
await act(async () => {
|
140
|
+
result.current.submitQuery('What should I work on?');
|
141
|
+
});
|
142
|
+
await waitFor(() => {
|
143
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
144
|
+
});
|
145
|
+
// Currently, no continuation prompt should be sent because the integration is stubbed
|
146
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
147
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('What should I work on?', expect.any(AbortSignal), expect.any(String));
|
148
|
+
});
|
149
|
+
let mockAddItem;
|
150
|
+
let mockSetShowHelp;
|
151
|
+
let mockConfig;
|
152
|
+
let mockOnDebugMessage;
|
153
|
+
let mockHandleSlashCommand;
|
154
|
+
let mockScheduleToolCalls;
|
155
|
+
let mockMarkToolsAsSubmitted;
|
156
|
+
let mockTodoContext;
|
157
|
+
beforeEach(() => {
|
158
|
+
vi.clearAllMocks();
|
159
|
+
mockAddItem = vi.fn();
|
160
|
+
mockSetShowHelp = vi.fn();
|
161
|
+
mockOnDebugMessage = vi.fn();
|
162
|
+
mockHandleSlashCommand = vi.fn().mockResolvedValue(false);
|
163
|
+
// Create mock todo context
|
164
|
+
mockTodoContext = {
|
165
|
+
todos: [],
|
166
|
+
updateTodos: vi.fn(),
|
167
|
+
refreshTodos: vi.fn(),
|
168
|
+
};
|
169
|
+
// Create mock config with ephemeral settings support
|
170
|
+
const mockGetEphemeralSettings = vi.fn(() => ({
|
171
|
+
'todo-continuation': true,
|
172
|
+
}));
|
173
|
+
const mockGetGeminiClient = vi.fn().mockImplementation(() => {
|
174
|
+
const clientInstance = new MockedGeminiClientClass(mockConfig);
|
175
|
+
return clientInstance;
|
176
|
+
});
|
177
|
+
const contentGeneratorConfig = {
|
178
|
+
model: 'test-model',
|
179
|
+
apiKey: 'test-key',
|
180
|
+
vertexai: false,
|
181
|
+
authType: AuthType.USE_GEMINI,
|
182
|
+
};
|
183
|
+
mockConfig = {
|
184
|
+
apiKey: 'test-api-key',
|
185
|
+
model: 'gemini-pro',
|
186
|
+
sandbox: false,
|
187
|
+
targetDir: '/test/dir',
|
188
|
+
debugMode: false,
|
189
|
+
question: undefined,
|
190
|
+
fullContext: false,
|
191
|
+
coreTools: [],
|
192
|
+
toolDiscoveryCommand: undefined,
|
193
|
+
toolCallCommand: undefined,
|
194
|
+
mcpServerCommand: undefined,
|
195
|
+
mcpServers: undefined,
|
196
|
+
userAgent: 'test-agent',
|
197
|
+
userMemory: '',
|
198
|
+
llxprtMdFileCount: 0,
|
199
|
+
alwaysSkipModificationConfirmation: false,
|
200
|
+
vertexai: false,
|
201
|
+
showMemoryUsage: false,
|
202
|
+
contextFileName: undefined,
|
203
|
+
getToolRegistry: vi.fn(() => Promise.resolve({ getFunctionDeclarations: vi.fn(() => []) })),
|
204
|
+
getProjectRoot: vi.fn(() => '/test/dir'),
|
205
|
+
getCheckpointingEnabled: vi.fn(() => false),
|
206
|
+
getGeminiClient: mockGetGeminiClient,
|
207
|
+
getUsageStatisticsEnabled: () => true,
|
208
|
+
getDebugMode: () => false,
|
209
|
+
addHistory: vi.fn(),
|
210
|
+
getSessionId() {
|
211
|
+
return 'test-session-id';
|
212
|
+
},
|
213
|
+
setQuotaErrorOccurred: vi.fn(),
|
214
|
+
getQuotaErrorOccurred: vi.fn(() => false),
|
215
|
+
getModel: vi.fn(() => 'gemini-2.5-pro'),
|
216
|
+
getContentGeneratorConfig: vi
|
217
|
+
.fn()
|
218
|
+
.mockReturnValue(contentGeneratorConfig),
|
219
|
+
getEphemeralSettings: mockGetEphemeralSettings,
|
220
|
+
getApprovalMode: vi.fn(() => ApprovalMode.DEFAULT),
|
221
|
+
};
|
222
|
+
// Mock return value for useReactToolScheduler
|
223
|
+
mockScheduleToolCalls = vi.fn();
|
224
|
+
mockMarkToolsAsSubmitted = vi.fn();
|
225
|
+
mockUseReactToolScheduler.mockReturnValue([
|
226
|
+
[], // Default to empty array for toolCalls
|
227
|
+
mockScheduleToolCalls,
|
228
|
+
mockMarkToolsAsSubmitted,
|
229
|
+
]);
|
230
|
+
// Reset mocks for GeminiClient instance methods
|
231
|
+
mockStartChat.mockClear().mockResolvedValue({
|
232
|
+
sendMessageStream: mockSendMessageStream,
|
233
|
+
});
|
234
|
+
mockSendMessageStream
|
235
|
+
.mockClear()
|
236
|
+
.mockReturnValue((async function* () { })());
|
237
|
+
});
|
238
|
+
const mockLoadedSettings = {
|
239
|
+
merged: { preferredEditor: 'vscode' },
|
240
|
+
user: { path: '/user/settings.json', settings: {} },
|
241
|
+
workspace: { path: '/workspace/.llxprt/settings.json', settings: {} },
|
242
|
+
errors: [],
|
243
|
+
forScope: vi.fn(),
|
244
|
+
setValue: vi.fn(),
|
245
|
+
};
|
246
|
+
const createActiveTodos = () => [
|
247
|
+
{
|
248
|
+
id: 'todo-1',
|
249
|
+
content: 'Implement user auth',
|
250
|
+
status: 'in_progress',
|
251
|
+
priority: 'high',
|
252
|
+
},
|
253
|
+
{
|
254
|
+
id: 'todo-2',
|
255
|
+
content: 'Add validation',
|
256
|
+
status: 'pending',
|
257
|
+
priority: 'medium',
|
258
|
+
},
|
259
|
+
];
|
260
|
+
const TodoContextProvider = ({ children, todos = [], }) => {
|
261
|
+
const contextValue = {
|
262
|
+
...mockTodoContext,
|
263
|
+
todos,
|
264
|
+
};
|
265
|
+
return React.createElement(TodoContext.Provider, { value: contextValue }, children);
|
266
|
+
};
|
267
|
+
const renderTestHook = (initialToolCalls = [], todos = [], ephemeralSettings = { 'todo-continuation': true }) => {
|
268
|
+
// Update mock config with provided ephemeral settings
|
269
|
+
mockConfig.getEphemeralSettings.mockReturnValue(ephemeralSettings);
|
270
|
+
let currentToolCalls = initialToolCalls;
|
271
|
+
const setToolCalls = (newToolCalls) => {
|
272
|
+
currentToolCalls = newToolCalls;
|
273
|
+
};
|
274
|
+
mockUseReactToolScheduler.mockImplementation(() => [
|
275
|
+
currentToolCalls,
|
276
|
+
mockScheduleToolCalls,
|
277
|
+
mockMarkToolsAsSubmitted,
|
278
|
+
]);
|
279
|
+
const client = mockConfig.getGeminiClient();
|
280
|
+
const { result, rerender } = renderHook((props) => {
|
281
|
+
if (props.toolCalls) {
|
282
|
+
setToolCalls(props.toolCalls);
|
283
|
+
}
|
284
|
+
return useGeminiStream(props.client, props.history, props.addItem, props.setShowHelp, props.config, props.onDebugMessage, props.handleSlashCommand, props.shellModeActive, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, () => { });
|
285
|
+
}, {
|
286
|
+
initialProps: {
|
287
|
+
client,
|
288
|
+
history: [],
|
289
|
+
addItem: mockAddItem,
|
290
|
+
setShowHelp: mockSetShowHelp,
|
291
|
+
config: mockConfig,
|
292
|
+
onDebugMessage: mockOnDebugMessage,
|
293
|
+
handleSlashCommand: mockHandleSlashCommand,
|
294
|
+
shellModeActive: false,
|
295
|
+
loadedSettings: mockLoadedSettings,
|
296
|
+
toolCalls: initialToolCalls,
|
297
|
+
},
|
298
|
+
wrapper: ({ children }) => TodoContextProvider({ children, todos }),
|
299
|
+
});
|
300
|
+
return {
|
301
|
+
result,
|
302
|
+
rerender,
|
303
|
+
mockMarkToolsAsSubmitted,
|
304
|
+
mockSendMessageStream,
|
305
|
+
client,
|
306
|
+
};
|
307
|
+
};
|
308
|
+
/**
|
309
|
+
* @requirement REQ-001.1, REQ-001.2, REQ-002.1
|
310
|
+
* @scenario Model completes with active todo and no tool calls
|
311
|
+
* @given Active todo 'Implement user auth', model completes streaming
|
312
|
+
* @when Stream completes without tool calls
|
313
|
+
* @then Continuation prompt sent with task description
|
314
|
+
* @and Prompt marked as ephemeral (not in history)
|
315
|
+
* @note SPECIFICATION TEST - will pass when integration is implemented
|
316
|
+
*/
|
317
|
+
it.skip('should send continuation prompt when stream completes with active todo and no tool calls', async () => {
|
318
|
+
const activeTodos = createActiveTodos();
|
319
|
+
// Mock stream that completes without tool calls
|
320
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
321
|
+
yield {
|
322
|
+
type: ServerGeminiEventType.Content,
|
323
|
+
value: 'I see the todos but made no tool calls',
|
324
|
+
};
|
325
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
326
|
+
})());
|
327
|
+
const { result } = renderTestHook([], activeTodos);
|
328
|
+
// Submit a query that will complete without tool calls
|
329
|
+
await act(async () => {
|
330
|
+
result.current.submitQuery('What should I work on?');
|
331
|
+
});
|
332
|
+
// Wait for the stream to complete
|
333
|
+
await waitFor(() => {
|
334
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
335
|
+
});
|
336
|
+
// Verify continuation prompt was sent
|
337
|
+
await waitFor(() => {
|
338
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('Please continue working on the following task: "Implement user auth"', { ephemeral: true });
|
339
|
+
});
|
340
|
+
// Verify the call was made twice: original query + continuation
|
341
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(2);
|
342
|
+
});
|
343
|
+
/**
|
344
|
+
* @requirement REQ-001.1
|
345
|
+
* @scenario Model completes with tool calls pending
|
346
|
+
* @given Active todo exists, model makes tool calls
|
347
|
+
* @when Stream completes with tool calls
|
348
|
+
* @then NO continuation prompt sent
|
349
|
+
* @note SPECIFICATION TEST - will pass when integration is implemented
|
350
|
+
*/
|
351
|
+
it.skip('should NOT send continuation prompt when stream completes with tool calls made', async () => {
|
352
|
+
const activeTodos = createActiveTodos();
|
353
|
+
// Mock stream that includes tool calls
|
354
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
355
|
+
yield {
|
356
|
+
type: ServerGeminiEventType.Content,
|
357
|
+
value: 'Let me help with that task',
|
358
|
+
};
|
359
|
+
yield {
|
360
|
+
type: ServerGeminiEventType.ToolCallRequest,
|
361
|
+
value: [
|
362
|
+
{
|
363
|
+
callId: 'call-1',
|
364
|
+
name: 'ReadFile',
|
365
|
+
args: { filePath: '/src/auth.ts' },
|
366
|
+
},
|
367
|
+
],
|
368
|
+
};
|
369
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
370
|
+
})());
|
371
|
+
const { result } = renderTestHook([], activeTodos);
|
372
|
+
await act(async () => {
|
373
|
+
result.current.submitQuery('Continue working on auth');
|
374
|
+
});
|
375
|
+
// Wait for the stream to complete
|
376
|
+
await waitFor(() => {
|
377
|
+
expect(result.current.streamingState).toBe(StreamingState.Responding);
|
378
|
+
});
|
379
|
+
// Give additional time for any potential continuation prompt
|
380
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
381
|
+
// Verify NO continuation prompt was sent (only original query)
|
382
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
383
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('Continue working on auth', expect.any(AbortSignal), expect.any(String));
|
384
|
+
});
|
385
|
+
/**
|
386
|
+
* @requirement REQ-001.4, REQ-004.1
|
387
|
+
* @scenario Continuation disabled via setting
|
388
|
+
* @given todo-continuation = false, active todo exists
|
389
|
+
* @when Stream completes without tool calls
|
390
|
+
* @then NO continuation prompt sent
|
391
|
+
*/
|
392
|
+
it('should NOT send continuation prompt when todo-continuation is disabled', async () => {
|
393
|
+
const activeTodos = createActiveTodos();
|
394
|
+
// Mock stream that completes without tool calls
|
395
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
396
|
+
yield {
|
397
|
+
type: ServerGeminiEventType.Content,
|
398
|
+
value: 'Response without tool calls',
|
399
|
+
};
|
400
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
401
|
+
})());
|
402
|
+
// Render with continuation disabled
|
403
|
+
const { result } = renderTestHook([], activeTodos, {
|
404
|
+
'todo-continuation': false,
|
405
|
+
});
|
406
|
+
await act(async () => {
|
407
|
+
result.current.submitQuery('What next?');
|
408
|
+
});
|
409
|
+
await waitFor(() => {
|
410
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
411
|
+
});
|
412
|
+
// Give time for any potential continuation attempt
|
413
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
414
|
+
// Verify NO continuation prompt was sent
|
415
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
416
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('What next?', expect.any(AbortSignal), expect.any(String));
|
417
|
+
});
|
418
|
+
/**
|
419
|
+
* @requirement REQ-002.3
|
420
|
+
* @scenario YOLO mode uses stronger prompt
|
421
|
+
* @given YOLO mode active, todo exists
|
422
|
+
* @when Stream completes
|
423
|
+
* @then Prompt contains 'without waiting for confirmation'
|
424
|
+
* @note SPECIFICATION TEST - will pass when integration is implemented
|
425
|
+
*/
|
426
|
+
it.skip('should use stronger continuation prompt in YOLO mode', async () => {
|
427
|
+
const activeTodos = createActiveTodos();
|
428
|
+
// Set YOLO mode
|
429
|
+
mockConfig.getApprovalMode.mockReturnValue(ApprovalMode.YOLO);
|
430
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
431
|
+
yield {
|
432
|
+
type: ServerGeminiEventType.Content,
|
433
|
+
value: 'Task analysis complete',
|
434
|
+
};
|
435
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
436
|
+
})());
|
437
|
+
const { result } = renderTestHook([], activeTodos);
|
438
|
+
await act(async () => {
|
439
|
+
result.current.submitQuery('Analyze the task');
|
440
|
+
});
|
441
|
+
await waitFor(() => {
|
442
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
443
|
+
});
|
444
|
+
// Verify YOLO continuation prompt was sent
|
445
|
+
await waitFor(() => {
|
446
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('Continue to proceed with the active task without waiting for confirmation: "Implement user auth"', { ephemeral: true });
|
447
|
+
});
|
448
|
+
});
|
449
|
+
/**
|
450
|
+
* @requirement REQ-003.4
|
451
|
+
* @scenario todo_pause available to model
|
452
|
+
* @given Active continuation scenario
|
453
|
+
* @when Model lists available tools
|
454
|
+
* @then todo_pause tool is accessible
|
455
|
+
*/
|
456
|
+
it('should make todo_pause tool available during continuation', async () => {
|
457
|
+
const activeTodos = createActiveTodos();
|
458
|
+
// Mock tool registry that includes todo_pause
|
459
|
+
const mockToolRegistry = {
|
460
|
+
getFunctionDeclarations: vi.fn(() => [
|
461
|
+
{
|
462
|
+
name: 'todo_pause',
|
463
|
+
description: 'Pause the current todo task',
|
464
|
+
parameters: {
|
465
|
+
type: 'object',
|
466
|
+
properties: {
|
467
|
+
reason: { type: 'string' },
|
468
|
+
},
|
469
|
+
required: ['reason'],
|
470
|
+
},
|
471
|
+
},
|
472
|
+
{
|
473
|
+
name: 'ReadFile',
|
474
|
+
description: 'Read a file',
|
475
|
+
parameters: { type: 'object', properties: {} },
|
476
|
+
},
|
477
|
+
]),
|
478
|
+
};
|
479
|
+
mockConfig.getToolRegistry.mockReturnValue(Promise.resolve(mockToolRegistry));
|
480
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
481
|
+
yield {
|
482
|
+
type: ServerGeminiEventType.Content,
|
483
|
+
value: 'Looking at available tools',
|
484
|
+
};
|
485
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
486
|
+
})());
|
487
|
+
const { result } = renderTestHook([], activeTodos);
|
488
|
+
await act(async () => {
|
489
|
+
result.current.submitQuery('What tools are available?');
|
490
|
+
});
|
491
|
+
// Verify tool registry includes todo_pause
|
492
|
+
const toolRegistry = await mockConfig.getToolRegistry();
|
493
|
+
const toolSchemas = toolRegistry.getFunctionDeclarations();
|
494
|
+
const todoPauseTool = toolSchemas.find((tool) => tool.name === 'todo_pause');
|
495
|
+
expect(todoPauseTool).toBeDefined();
|
496
|
+
expect(todoPauseTool.description).toContain('Pause');
|
497
|
+
});
|
498
|
+
/**
|
499
|
+
* @requirement REQ-001.2
|
500
|
+
* @scenario Only pending/in_progress todos trigger continuation
|
501
|
+
* @given Mix of todo statuses
|
502
|
+
* @when Stream completes without tool calls
|
503
|
+
* @then Only active todos considered for continuation
|
504
|
+
*/
|
505
|
+
it.skip('should only consider pending and in_progress todos for continuation', async () => {
|
506
|
+
const mixedStatusTodos = [
|
507
|
+
{
|
508
|
+
id: 'todo-1',
|
509
|
+
content: 'Completed task',
|
510
|
+
status: 'completed',
|
511
|
+
priority: 'high',
|
512
|
+
},
|
513
|
+
{
|
514
|
+
id: 'todo-2',
|
515
|
+
content: 'Active pending task',
|
516
|
+
status: 'pending',
|
517
|
+
priority: 'medium',
|
518
|
+
},
|
519
|
+
];
|
520
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
521
|
+
yield {
|
522
|
+
type: ServerGeminiEventType.Content,
|
523
|
+
value: 'Response without tool calls',
|
524
|
+
};
|
525
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
526
|
+
})());
|
527
|
+
const { result } = renderTestHook([], mixedStatusTodos);
|
528
|
+
await act(async () => {
|
529
|
+
result.current.submitQuery('Show me todos');
|
530
|
+
});
|
531
|
+
await waitFor(() => {
|
532
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
533
|
+
});
|
534
|
+
// Verify continuation prompt uses the pending task, not the completed one
|
535
|
+
await waitFor(() => {
|
536
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('Please continue working on the following task: "Active pending task"', { ephemeral: true });
|
537
|
+
});
|
538
|
+
});
|
539
|
+
/**
|
540
|
+
* @requirement REQ-001.3
|
541
|
+
* @scenario Prioritize in_progress over pending todos
|
542
|
+
* @given Both pending and in_progress todos exist
|
543
|
+
* @when Stream completes
|
544
|
+
* @then in_progress todo is selected for continuation
|
545
|
+
*/
|
546
|
+
it.skip('should prioritize in_progress todos over pending for continuation', async () => {
|
547
|
+
const prioritizedTodos = [
|
548
|
+
{
|
549
|
+
id: 'todo-1',
|
550
|
+
content: 'Pending task',
|
551
|
+
status: 'pending',
|
552
|
+
priority: 'high',
|
553
|
+
},
|
554
|
+
{
|
555
|
+
id: 'todo-2',
|
556
|
+
content: 'In progress task',
|
557
|
+
status: 'in_progress',
|
558
|
+
priority: 'low', // Lower priority but in_progress should win
|
559
|
+
},
|
560
|
+
];
|
561
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
562
|
+
yield {
|
563
|
+
type: ServerGeminiEventType.Content,
|
564
|
+
value: 'Task status check',
|
565
|
+
};
|
566
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
567
|
+
})());
|
568
|
+
const { result } = renderTestHook([], prioritizedTodos);
|
569
|
+
await act(async () => {
|
570
|
+
result.current.submitQuery('Check task status');
|
571
|
+
});
|
572
|
+
await waitFor(() => {
|
573
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
574
|
+
});
|
575
|
+
// Verify in_progress task is selected despite lower priority
|
576
|
+
await waitFor(() => {
|
577
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith('Please continue working on the following task: "In progress task"', { ephemeral: true });
|
578
|
+
});
|
579
|
+
});
|
580
|
+
/**
|
581
|
+
* @requirement REQ-001.5
|
582
|
+
* @scenario No continuation when no active todos
|
583
|
+
* @given No pending or in_progress todos
|
584
|
+
* @when Stream completes without tool calls
|
585
|
+
* @then NO continuation prompt sent
|
586
|
+
*/
|
587
|
+
it('should NOT send continuation prompt when no active todos exist', async () => {
|
588
|
+
const completedTodos = [
|
589
|
+
{
|
590
|
+
id: 'todo-1',
|
591
|
+
content: 'Done task',
|
592
|
+
status: 'completed',
|
593
|
+
priority: 'high',
|
594
|
+
},
|
595
|
+
];
|
596
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
597
|
+
yield {
|
598
|
+
type: ServerGeminiEventType.Content,
|
599
|
+
value: 'All tasks complete',
|
600
|
+
};
|
601
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
602
|
+
})());
|
603
|
+
const { result } = renderTestHook([], completedTodos);
|
604
|
+
await act(async () => {
|
605
|
+
result.current.submitQuery('How are we doing?');
|
606
|
+
});
|
607
|
+
await waitFor(() => {
|
608
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
609
|
+
});
|
610
|
+
// Give time for any potential continuation attempt
|
611
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
612
|
+
// Verify NO continuation prompt was sent
|
613
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
614
|
+
});
|
615
|
+
/**
|
616
|
+
* @requirement REQ-002.1
|
617
|
+
* @scenario Continuation prompt is ephemeral
|
618
|
+
* @given Active todo and stream completion
|
619
|
+
* @when Continuation prompt is sent
|
620
|
+
* @then Prompt is marked with ephemeral flag
|
621
|
+
*/
|
622
|
+
it.skip('should mark continuation prompts as ephemeral (not stored in history)', async () => {
|
623
|
+
const activeTodos = createActiveTodos();
|
624
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
625
|
+
yield {
|
626
|
+
type: ServerGeminiEventType.Content,
|
627
|
+
value: 'Regular response',
|
628
|
+
};
|
629
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
630
|
+
})());
|
631
|
+
const { result, client } = renderTestHook([], activeTodos);
|
632
|
+
await act(async () => {
|
633
|
+
result.current.submitQuery('Continue task');
|
634
|
+
});
|
635
|
+
await waitFor(() => {
|
636
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
637
|
+
});
|
638
|
+
// Verify ephemeral flag is set correctly
|
639
|
+
await waitFor(() => {
|
640
|
+
expect(mockSendMessageStream).toHaveBeenCalledWith(expect.stringContaining('Please continue working on the following task:'), { ephemeral: true });
|
641
|
+
});
|
642
|
+
// Verify the continuation prompt is NOT added to client history
|
643
|
+
// (Only the original user query should be in history)
|
644
|
+
expect(client.addHistory).toHaveBeenCalledTimes(1);
|
645
|
+
});
|
646
|
+
/**
|
647
|
+
* @requirement REQ-001.6
|
648
|
+
* @scenario Prevent rapid fire continuations
|
649
|
+
* @given Active todo and continuation in progress
|
650
|
+
* @when Multiple streams complete quickly
|
651
|
+
* @then Only one continuation prompt sent
|
652
|
+
*/
|
653
|
+
it.skip('should prevent multiple rapid continuation prompts', async () => {
|
654
|
+
const activeTodos = createActiveTodos();
|
655
|
+
// Mock multiple quick completions
|
656
|
+
let completionCount = 0;
|
657
|
+
mockSendMessageStream.mockImplementation(() => {
|
658
|
+
completionCount++;
|
659
|
+
return (async function* () {
|
660
|
+
yield {
|
661
|
+
type: ServerGeminiEventType.Content,
|
662
|
+
value: `Quick response ${completionCount}`,
|
663
|
+
};
|
664
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
665
|
+
})();
|
666
|
+
});
|
667
|
+
const { result } = renderTestHook([], activeTodos);
|
668
|
+
// Rapidly submit multiple queries
|
669
|
+
await act(async () => {
|
670
|
+
result.current.submitQuery('Query 1');
|
671
|
+
});
|
672
|
+
await act(async () => {
|
673
|
+
result.current.submitQuery('Query 2');
|
674
|
+
});
|
675
|
+
await waitFor(() => {
|
676
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
677
|
+
});
|
678
|
+
// Allow time for any potential extra continuation attempts
|
679
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
680
|
+
// Verify continuation was attempted only once despite multiple completions
|
681
|
+
const continuationCalls = mockSendMessageStream.mock.calls.filter((call) => call[0]?.includes('Please continue working on the following task:'));
|
682
|
+
expect(continuationCalls.length).toBeLessThanOrEqual(1);
|
683
|
+
});
|
684
|
+
/**
|
685
|
+
* ACTIVE TESTS - These test the current implementation state and architecture
|
686
|
+
*/
|
687
|
+
/**
|
688
|
+
* @requirement INTEGRATION_ARCHITECTURE
|
689
|
+
* @scenario Todo continuation hook is properly integrated
|
690
|
+
* @given useGeminiStream hook is rendered
|
691
|
+
* @when Hook is initialized
|
692
|
+
* @then useTodoContinuation hook is called with proper parameters
|
693
|
+
*/
|
694
|
+
it('should properly integrate useTodoContinuation hook', () => {
|
695
|
+
const activeTodos = createActiveTodos();
|
696
|
+
const { result } = renderTestHook([], activeTodos);
|
697
|
+
// Verify the hook renders successfully with todo context integration
|
698
|
+
expect(result.current).toBeDefined();
|
699
|
+
expect(result.current.submitQuery).toBeDefined();
|
700
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
701
|
+
// Verify the mock config was set up correctly
|
702
|
+
expect(mockConfig.getEphemeralSettings).toBeDefined();
|
703
|
+
});
|
704
|
+
/**
|
705
|
+
* @requirement REQ-004.1
|
706
|
+
* @scenario Configuration setting is properly read
|
707
|
+
* @given Various todo-continuation settings
|
708
|
+
* @when Hook is initialized
|
709
|
+
* @then getEphemeralSettings is called to check todo-continuation setting
|
710
|
+
*/
|
711
|
+
it('should read todo-continuation configuration setting', () => {
|
712
|
+
const settingsVariations = [
|
713
|
+
{ 'todo-continuation': true },
|
714
|
+
{ 'todo-continuation': false },
|
715
|
+
{ 'other-setting': 'value' }, // no todo-continuation setting
|
716
|
+
{}, // empty settings
|
717
|
+
];
|
718
|
+
settingsVariations.forEach((settings) => {
|
719
|
+
// Reset mocks for each test iteration
|
720
|
+
vi.clearAllMocks();
|
721
|
+
mockConfig.getEphemeralSettings.mockReturnValue(settings);
|
722
|
+
const { result } = renderTestHook([], [], settings);
|
723
|
+
// Verify hook integration works with all setting variations
|
724
|
+
expect(result.current).toBeDefined();
|
725
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
726
|
+
// Verify the configuration mock is properly set up
|
727
|
+
expect(mockConfig.getEphemeralSettings()).toEqual(settings);
|
728
|
+
});
|
729
|
+
});
|
730
|
+
/**
|
731
|
+
* @requirement REQ-003.4
|
732
|
+
* @scenario todo_pause tool availability
|
733
|
+
* @given Tool registry configuration
|
734
|
+
* @when Tools are requested
|
735
|
+
* @then todo_pause tool is available in the registry
|
736
|
+
*/
|
737
|
+
it('should have todo_pause tool available in tool registry', async () => {
|
738
|
+
// Set up tool registry with todo_pause tool
|
739
|
+
const mockToolRegistry = {
|
740
|
+
getFunctionDeclarations: vi.fn(() => [
|
741
|
+
{
|
742
|
+
name: 'todo_pause',
|
743
|
+
description: 'Pause the current todo task',
|
744
|
+
parameters: {
|
745
|
+
type: 'object',
|
746
|
+
properties: {
|
747
|
+
reason: { type: 'string', description: 'Reason for pausing' },
|
748
|
+
},
|
749
|
+
required: ['reason'],
|
750
|
+
},
|
751
|
+
},
|
752
|
+
{
|
753
|
+
name: 'ReadFile',
|
754
|
+
description: 'Read a file',
|
755
|
+
parameters: { type: 'object', properties: {} },
|
756
|
+
},
|
757
|
+
]),
|
758
|
+
};
|
759
|
+
mockConfig.getToolRegistry.mockReturnValue(Promise.resolve(mockToolRegistry));
|
760
|
+
const activeTodos = createActiveTodos();
|
761
|
+
renderTestHook([], activeTodos);
|
762
|
+
// Verify tool registry includes todo_pause
|
763
|
+
const toolRegistry = await mockConfig.getToolRegistry();
|
764
|
+
const toolSchemas = toolRegistry.getFunctionDeclarations();
|
765
|
+
const todoPauseTool = toolSchemas.find((tool) => tool.name === 'todo_pause');
|
766
|
+
expect(todoPauseTool).toBeDefined();
|
767
|
+
expect(todoPauseTool.description).toContain('Pause');
|
768
|
+
expect(todoPauseTool.parameters.properties.reason).toBeDefined();
|
769
|
+
expect(todoPauseTool.parameters.required).toContain('reason');
|
770
|
+
});
|
771
|
+
/**
|
772
|
+
* @requirement CURRENT_STATE
|
773
|
+
* @scenario Hook integration exists but is not activated
|
774
|
+
* @given Current implementation with NotYetImplemented stub
|
775
|
+
* @when Stream processing completes
|
776
|
+
* @then Hook integration code path exists but doesn't execute continuation logic
|
777
|
+
*/
|
778
|
+
it('should have hook integration architecture in place but not activated', async () => {
|
779
|
+
const activeTodos = createActiveTodos();
|
780
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
781
|
+
yield {
|
782
|
+
type: ServerGeminiEventType.Content,
|
783
|
+
value: 'Test response',
|
784
|
+
};
|
785
|
+
yield { type: ServerGeminiEventType.Finished, value: 'STOP' };
|
786
|
+
})());
|
787
|
+
const { result } = renderTestHook([], activeTodos);
|
788
|
+
await act(async () => {
|
789
|
+
result.current.submitQuery('Test query');
|
790
|
+
});
|
791
|
+
await waitFor(() => {
|
792
|
+
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
793
|
+
});
|
794
|
+
// The architectural integration should be there (hook is called)
|
795
|
+
// but the actual continuation logic should not execute due to NotYetImplemented stub
|
796
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
797
|
+
expect(mockSendMessageStream).not.toHaveBeenCalledWith(expect.stringContaining('Please continue working'), expect.anything());
|
798
|
+
});
|
799
|
+
});
|
800
|
+
//# sourceMappingURL=useGeminiStream.integration.test.js.map
|