fss-link 1.0.49 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +0 -0
- package/dist/package.json +2 -2
- package/dist/src/config/auth.js +8 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/database.d.ts +103 -11
- package/dist/src/config/database.js +301 -59
- package/dist/src/config/database.js.map +1 -1
- package/dist/src/config/databaseBackup.d.ts +114 -0
- package/dist/src/config/databaseBackup.js +334 -0
- package/dist/src/config/databaseBackup.js.map +1 -0
- package/dist/src/config/databaseMigrations.d.ts +63 -0
- package/dist/src/config/databaseMigrations.js +379 -0
- package/dist/src/config/databaseMigrations.js.map +1 -0
- package/dist/src/config/databasePool.d.ts +70 -0
- package/dist/src/config/databasePool.js +193 -0
- package/dist/src/config/databasePool.js.map +1 -0
- package/dist/src/config/queryOptimizer.d.ts +127 -0
- package/dist/src/config/queryOptimizer.js +309 -0
- package/dist/src/config/queryOptimizer.js.map +1 -0
- package/dist/src/utils/sandbox.js +2 -8
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +3 -7
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/commands/mcp/add.test.ts +0 -122
- package/dist/commands/mcp/add.ts +0 -222
- package/dist/commands/mcp/list.test.ts +0 -154
- package/dist/commands/mcp/list.ts +0 -139
- package/dist/commands/mcp/remove.test.ts +0 -69
- package/dist/commands/mcp/remove.ts +0 -60
- package/dist/commands/mcp.test.ts +0 -55
- package/dist/commands/mcp.ts +0 -27
- package/dist/config/apiValidation.test.ts +0 -118
- package/dist/config/auth.test.ts +0 -79
- package/dist/config/auth.ts +0 -100
- package/dist/config/config.integration.test.ts +0 -407
- package/dist/config/config.test.ts +0 -1952
- package/dist/config/config.ts +0 -690
- package/dist/config/database.test.ts +0 -96
- package/dist/config/database.ts +0 -824
- package/dist/config/extension.test.ts +0 -236
- package/dist/config/extension.ts +0 -180
- package/dist/config/keyBindings.test.ts +0 -62
- package/dist/config/keyBindings.ts +0 -184
- package/dist/config/modelManager.ts +0 -326
- package/dist/config/providerManager.ts +0 -244
- package/dist/config/providerPersistence.test.ts +0 -377
- package/dist/config/providerPersistence.ts +0 -105
- package/dist/config/sandboxConfig.ts +0 -107
- package/dist/config/settings.test.ts +0 -1424
- package/dist/config/settings.ts +0 -517
- package/dist/config/settingsSchema.test.ts +0 -252
- package/dist/config/settingsSchema.ts +0 -728
- package/dist/config/trustedFolders.test.ts +0 -208
- package/dist/config/trustedFolders.ts +0 -167
- package/dist/gemini.test.tsx +0 -252
- package/dist/gemini.tsx +0 -357
- package/dist/generated/git-commit.ts +0 -10
- package/dist/index.ts +0 -21
- package/dist/nonInteractiveCli.test.ts +0 -276
- package/dist/nonInteractiveCli.ts +0 -143
- package/dist/patches/is-in-ci.ts +0 -17
- package/dist/services/BuiltinCommandLoader.test.ts +0 -127
- package/dist/services/BuiltinCommandLoader.ts +0 -95
- package/dist/services/CommandService.test.ts +0 -352
- package/dist/services/CommandService.ts +0 -103
- package/dist/services/FileCommandLoader.test.ts +0 -1002
- package/dist/services/FileCommandLoader.ts +0 -289
- package/dist/services/McpPromptLoader.ts +0 -231
- package/dist/services/SearchEngineConfigProvider.ts +0 -100
- package/dist/services/prompt-processors/argumentProcessor.test.ts +0 -41
- package/dist/services/prompt-processors/argumentProcessor.ts +0 -23
- package/dist/services/prompt-processors/shellProcessor.test.ts +0 -709
- package/dist/services/prompt-processors/shellProcessor.ts +0 -248
- package/dist/services/prompt-processors/types.ts +0 -44
- package/dist/services/types.ts +0 -24
- package/dist/src/config/apiValidation.test.d.ts +0 -6
- package/dist/src/config/apiValidation.test.js +0 -99
- package/dist/src/config/apiValidation.test.js.map +0 -1
- package/dist/src/config/database.test.d.ts +0 -6
- package/dist/src/config/database.test.js +0 -80
- package/dist/src/config/database.test.js.map +0 -1
- package/dist/src/config/providerManager.d.ts +0 -74
- package/dist/src/config/providerManager.js +0 -203
- package/dist/src/config/providerManager.js.map +0 -1
- package/dist/src/config/providerPersistence.test.d.ts +0 -6
- package/dist/src/config/providerPersistence.test.js +0 -283
- package/dist/src/config/providerPersistence.test.js.map +0 -1
- package/dist/src/ui/components/GeminiKeyDialog.d.ts +0 -11
- package/dist/src/ui/components/GeminiKeyDialog.js +0 -156
- package/dist/src/ui/components/GeminiKeyDialog.js.map +0 -1
- package/dist/src/ui/components/OpenAIEndpointDialog.d.ts +0 -19
- package/dist/src/ui/components/OpenAIEndpointDialog.js +0 -163
- package/dist/src/ui/components/OpenAIEndpointDialog.js.map +0 -1
- package/dist/test-setup.ts +0 -12
- package/dist/test-utils/customMatchers.ts +0 -65
- package/dist/test-utils/mockCommandContext.test.ts +0 -62
- package/dist/test-utils/mockCommandContext.ts +0 -105
- package/dist/test-utils/render.tsx +0 -18
- package/dist/ui/App.test.tsx +0 -2181
- package/dist/ui/App.tsx +0 -1344
- package/dist/ui/IdeIntegrationNudge.tsx +0 -98
- package/dist/ui/__snapshots__/App.test.tsx.snap +0 -124
- package/dist/ui/colors.ts +0 -56
- package/dist/ui/commands/aboutCommand.test.ts +0 -153
- package/dist/ui/commands/aboutCommand.ts +0 -49
- package/dist/ui/commands/authCommand.test.ts +0 -36
- package/dist/ui/commands/authCommand.ts +0 -17
- package/dist/ui/commands/bugCommand.test.ts +0 -114
- package/dist/ui/commands/bugCommand.ts +0 -92
- package/dist/ui/commands/chatCommand.test.ts +0 -414
- package/dist/ui/commands/chatCommand.ts +0 -280
- package/dist/ui/commands/clearCommand.test.ts +0 -100
- package/dist/ui/commands/clearCommand.ts +0 -29
- package/dist/ui/commands/compressCommand.test.ts +0 -129
- package/dist/ui/commands/compressCommand.ts +0 -78
- package/dist/ui/commands/contextCommand.ts +0 -132
- package/dist/ui/commands/copyCommand.test.ts +0 -296
- package/dist/ui/commands/copyCommand.ts +0 -67
- package/dist/ui/commands/corgiCommand.test.ts +0 -34
- package/dist/ui/commands/corgiCommand.ts +0 -16
- package/dist/ui/commands/directoryCommand.test.tsx +0 -185
- package/dist/ui/commands/directoryCommand.tsx +0 -179
- package/dist/ui/commands/docsCommand.test.ts +0 -99
- package/dist/ui/commands/docsCommand.ts +0 -42
- package/dist/ui/commands/editorCommand.test.ts +0 -30
- package/dist/ui/commands/editorCommand.ts +0 -21
- package/dist/ui/commands/extensionsCommand.test.ts +0 -67
- package/dist/ui/commands/extensionsCommand.ts +0 -46
- package/dist/ui/commands/helpCommand.test.ts +0 -52
- package/dist/ui/commands/helpCommand.ts +0 -23
- package/dist/ui/commands/ideCommand.test.ts +0 -255
- package/dist/ui/commands/ideCommand.ts +0 -283
- package/dist/ui/commands/initCommand.test.ts +0 -127
- package/dist/ui/commands/initCommand.ts +0 -117
- package/dist/ui/commands/mcpCommand.test.ts +0 -1057
- package/dist/ui/commands/mcpCommand.ts +0 -531
- package/dist/ui/commands/memoryCommand.test.ts +0 -344
- package/dist/ui/commands/memoryCommand.ts +0 -305
- package/dist/ui/commands/privacyCommand.test.ts +0 -38
- package/dist/ui/commands/privacyCommand.ts +0 -17
- package/dist/ui/commands/quitCommand.test.ts +0 -55
- package/dist/ui/commands/quitCommand.ts +0 -36
- package/dist/ui/commands/restoreCommand.test.ts +0 -250
- package/dist/ui/commands/restoreCommand.ts +0 -157
- package/dist/ui/commands/searchEngineSetupCommand.ts +0 -18
- package/dist/ui/commands/settingsCommand.test.ts +0 -36
- package/dist/ui/commands/settingsCommand.ts +0 -17
- package/dist/ui/commands/setupGithubCommand.test.ts +0 -238
- package/dist/ui/commands/setupGithubCommand.ts +0 -212
- package/dist/ui/commands/speakCommand.ts +0 -175
- package/dist/ui/commands/statsCommand.test.ts +0 -78
- package/dist/ui/commands/statsCommand.ts +0 -70
- package/dist/ui/commands/terminalSetupCommand.test.ts +0 -85
- package/dist/ui/commands/terminalSetupCommand.ts +0 -45
- package/dist/ui/commands/themeCommand.test.ts +0 -38
- package/dist/ui/commands/themeCommand.ts +0 -17
- package/dist/ui/commands/toolsCommand.test.ts +0 -105
- package/dist/ui/commands/toolsCommand.ts +0 -71
- package/dist/ui/commands/ttsCommand.ts +0 -143
- package/dist/ui/commands/types.ts +0 -204
- package/dist/ui/commands/vimCommand.ts +0 -25
- package/dist/ui/commands/voiceCommand.ts +0 -125
- package/dist/ui/components/AboutBox.tsx +0 -133
- package/dist/ui/components/AsciiArt.ts +0 -54
- package/dist/ui/components/AuthDialog.test.tsx +0 -334
- package/dist/ui/components/AuthDialog.tsx +0 -289
- package/dist/ui/components/AuthInProgress.tsx +0 -62
- package/dist/ui/components/AutoAcceptIndicator.tsx +0 -47
- package/dist/ui/components/ConsoleSummaryDisplay.tsx +0 -35
- package/dist/ui/components/ContextSummaryDisplay.test.tsx +0 -85
- package/dist/ui/components/ContextSummaryDisplay.tsx +0 -120
- package/dist/ui/components/ContextUsageDisplay.tsx +0 -77
- package/dist/ui/components/DebugProfiler.tsx +0 -36
- package/dist/ui/components/DetailedMessagesDisplay.tsx +0 -82
- package/dist/ui/components/EditorSettingsDialog.tsx +0 -172
- package/dist/ui/components/FolderTrustDialog.test.tsx +0 -36
- package/dist/ui/components/FolderTrustDialog.tsx +0 -74
- package/dist/ui/components/Footer.test.tsx +0 -159
- package/dist/ui/components/Footer.tsx +0 -158
- package/dist/ui/components/GeminiKeyDialog.tsx +0 -252
- package/dist/ui/components/GeminiRespondingSpinner.tsx +0 -34
- package/dist/ui/components/Header.test.tsx +0 -44
- package/dist/ui/components/Header.tsx +0 -70
- package/dist/ui/components/Help.tsx +0 -174
- package/dist/ui/components/HistoryItemDisplay.test.tsx +0 -125
- package/dist/ui/components/HistoryItemDisplay.tsx +0 -98
- package/dist/ui/components/InputPrompt.test.tsx +0 -1467
- package/dist/ui/components/InputPrompt.tsx +0 -641
- package/dist/ui/components/LMStudioModelPrompt.tsx +0 -215
- package/dist/ui/components/LoadingIndicator.test.tsx +0 -296
- package/dist/ui/components/LoadingIndicator.tsx +0 -82
- package/dist/ui/components/MemoryUsageDisplay.tsx +0 -36
- package/dist/ui/components/ModelStatsDisplay.test.tsx +0 -252
- package/dist/ui/components/ModelStatsDisplay.tsx +0 -197
- package/dist/ui/components/OllamaModelPrompt.tsx +0 -206
- package/dist/ui/components/OpenAIEndpointDialog.tsx +0 -261
- package/dist/ui/components/OpenAIKeyPrompt.test.tsx +0 -64
- package/dist/ui/components/OpenAIKeyPrompt.tsx +0 -197
- package/dist/ui/components/PrepareLabel.tsx +0 -48
- package/dist/ui/components/SearchEngineConfigDialog.tsx +0 -280
- package/dist/ui/components/SessionSummaryDisplay.test.tsx +0 -75
- package/dist/ui/components/SessionSummaryDisplay.tsx +0 -18
- package/dist/ui/components/SettingsDialog.test.tsx +0 -865
- package/dist/ui/components/SettingsDialog.tsx +0 -753
- package/dist/ui/components/ShellConfirmationDialog.test.tsx +0 -53
- package/dist/ui/components/ShellConfirmationDialog.tsx +0 -103
- package/dist/ui/components/ShellModeIndicator.tsx +0 -18
- package/dist/ui/components/ShowMoreLines.tsx +0 -40
- package/dist/ui/components/StatsDisplay.test.tsx +0 -401
- package/dist/ui/components/StatsDisplay.tsx +0 -273
- package/dist/ui/components/SuggestionsDisplay.tsx +0 -102
- package/dist/ui/components/ThemeDialog.tsx +0 -310
- package/dist/ui/components/Tips.tsx +0 -45
- package/dist/ui/components/TodoDisplay.test.tsx +0 -97
- package/dist/ui/components/TodoDisplay.tsx +0 -72
- package/dist/ui/components/ToolStatsDisplay.test.tsx +0 -180
- package/dist/ui/components/ToolStatsDisplay.tsx +0 -208
- package/dist/ui/components/UpdateNotification.tsx +0 -23
- package/dist/ui/components/WelcomeBackDialog.tsx +0 -290
- package/dist/ui/components/__snapshots__/IDEContextDetailDisplay.test.tsx.snap +0 -24
- package/dist/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap +0 -121
- package/dist/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +0 -30
- package/dist/ui/components/__snapshots__/ShellConfirmationDialog.test.tsx.snap +0 -21
- package/dist/ui/components/__snapshots__/StatsDisplay.test.tsx.snap +0 -264
- package/dist/ui/components/__snapshots__/ToolStatsDisplay.test.tsx.snap +0 -91
- package/dist/ui/components/messages/CompressionMessage.tsx +0 -49
- package/dist/ui/components/messages/DiffRenderer.test.tsx +0 -365
- package/dist/ui/components/messages/DiffRenderer.tsx +0 -358
- package/dist/ui/components/messages/ErrorMessage.tsx +0 -31
- package/dist/ui/components/messages/GeminiMessage.tsx +0 -43
- package/dist/ui/components/messages/GeminiMessageContent.tsx +0 -43
- package/dist/ui/components/messages/InfoMessage.tsx +0 -32
- package/dist/ui/components/messages/ToolConfirmationMessage.test.tsx +0 -58
- package/dist/ui/components/messages/ToolConfirmationMessage.tsx +0 -297
- package/dist/ui/components/messages/ToolGroupMessage.tsx +0 -126
- package/dist/ui/components/messages/ToolMessage.test.tsx +0 -183
- package/dist/ui/components/messages/ToolMessage.tsx +0 -296
- package/dist/ui/components/messages/UserMessage.tsx +0 -43
- package/dist/ui/components/messages/UserShellMessage.tsx +0 -25
- package/dist/ui/components/shared/MaxSizedBox.test.tsx +0 -425
- package/dist/ui/components/shared/MaxSizedBox.tsx +0 -624
- package/dist/ui/components/shared/RadioButtonSelect.test.tsx +0 -181
- package/dist/ui/components/shared/RadioButtonSelect.tsx +0 -234
- package/dist/ui/components/shared/__snapshots__/RadioButtonSelect.test.tsx.snap +0 -47
- package/dist/ui/components/shared/text-buffer.test.ts +0 -1728
- package/dist/ui/components/shared/text-buffer.ts +0 -2227
- package/dist/ui/components/shared/vim-buffer-actions.test.ts +0 -1119
- package/dist/ui/components/shared/vim-buffer-actions.ts +0 -814
- package/dist/ui/constants.ts +0 -17
- package/dist/ui/contexts/KeypressContext.test.tsx +0 -391
- package/dist/ui/contexts/KeypressContext.tsx +0 -440
- package/dist/ui/contexts/OverflowContext.tsx +0 -87
- package/dist/ui/contexts/SessionContext.test.tsx +0 -132
- package/dist/ui/contexts/SessionContext.tsx +0 -143
- package/dist/ui/contexts/SettingsContext.tsx +0 -20
- package/dist/ui/contexts/StreamingContext.tsx +0 -22
- package/dist/ui/contexts/VimModeContext.tsx +0 -79
- package/dist/ui/editors/editorSettingsManager.ts +0 -66
- package/dist/ui/hooks/atCommandProcessor.test.ts +0 -1102
- package/dist/ui/hooks/atCommandProcessor.ts +0 -485
- package/dist/ui/hooks/shellCommandProcessor.test.ts +0 -481
- package/dist/ui/hooks/shellCommandProcessor.ts +0 -314
- package/dist/ui/hooks/slashCommandProcessor.test.ts +0 -1044
- package/dist/ui/hooks/slashCommandProcessor.ts +0 -595
- package/dist/ui/hooks/useAtCompletion.test.ts +0 -497
- package/dist/ui/hooks/useAtCompletion.ts +0 -244
- package/dist/ui/hooks/useAuthCommand.ts +0 -129
- package/dist/ui/hooks/useAutoAcceptIndicator.test.ts +0 -300
- package/dist/ui/hooks/useAutoAcceptIndicator.ts +0 -52
- package/dist/ui/hooks/useBracketedPaste.ts +0 -37
- package/dist/ui/hooks/useCommandCompletion.test.ts +0 -518
- package/dist/ui/hooks/useCommandCompletion.tsx +0 -238
- package/dist/ui/hooks/useCompletion.ts +0 -128
- package/dist/ui/hooks/useConsoleMessages.test.ts +0 -147
- package/dist/ui/hooks/useConsoleMessages.ts +0 -110
- package/dist/ui/hooks/useEditorSettings.test.ts +0 -283
- package/dist/ui/hooks/useEditorSettings.ts +0 -75
- package/dist/ui/hooks/useFocus.test.ts +0 -119
- package/dist/ui/hooks/useFocus.ts +0 -48
- package/dist/ui/hooks/useFolderTrust.test.ts +0 -159
- package/dist/ui/hooks/useFolderTrust.ts +0 -72
- package/dist/ui/hooks/useGeminiStream.test.tsx +0 -1998
- package/dist/ui/hooks/useGeminiStream.ts +0 -1017
- package/dist/ui/hooks/useGitBranchName.test.ts +0 -280
- package/dist/ui/hooks/useGitBranchName.ts +0 -79
- package/dist/ui/hooks/useHistoryManager.test.ts +0 -202
- package/dist/ui/hooks/useHistoryManager.ts +0 -111
- package/dist/ui/hooks/useInputHistory.test.ts +0 -261
- package/dist/ui/hooks/useInputHistory.ts +0 -111
- package/dist/ui/hooks/useKeypress.test.ts +0 -280
- package/dist/ui/hooks/useKeypress.ts +0 -39
- package/dist/ui/hooks/useKittyKeyboardProtocol.ts +0 -31
- package/dist/ui/hooks/useLoadingIndicator.test.ts +0 -139
- package/dist/ui/hooks/useLoadingIndicator.ts +0 -57
- package/dist/ui/hooks/useLogger.ts +0 -32
- package/dist/ui/hooks/useMessageQueue.test.ts +0 -226
- package/dist/ui/hooks/useMessageQueue.ts +0 -69
- package/dist/ui/hooks/usePhraseCycler.test.ts +0 -145
- package/dist/ui/hooks/usePhraseCycler.ts +0 -198
- package/dist/ui/hooks/usePrivacySettings.test.ts +0 -242
- package/dist/ui/hooks/usePrivacySettings.ts +0 -150
- package/dist/ui/hooks/useReactToolScheduler.ts +0 -309
- package/dist/ui/hooks/useRefreshMemoryCommand.ts +0 -7
- package/dist/ui/hooks/useReverseSearchCompletion.test.tsx +0 -260
- package/dist/ui/hooks/useReverseSearchCompletion.tsx +0 -95
- package/dist/ui/hooks/useSettingsCommand.ts +0 -25
- package/dist/ui/hooks/useShellHistory.test.ts +0 -219
- package/dist/ui/hooks/useShellHistory.ts +0 -133
- package/dist/ui/hooks/useShowMemoryCommand.ts +0 -75
- package/dist/ui/hooks/useSlashCompletion.test.ts +0 -434
- package/dist/ui/hooks/useSlashCompletion.ts +0 -187
- package/dist/ui/hooks/useStateAndRef.ts +0 -36
- package/dist/ui/hooks/useTerminalSize.ts +0 -32
- package/dist/ui/hooks/useThemeCommand.ts +0 -110
- package/dist/ui/hooks/useTimer.test.ts +0 -120
- package/dist/ui/hooks/useTimer.ts +0 -65
- package/dist/ui/hooks/useToolScheduler.test.ts +0 -1123
- package/dist/ui/hooks/useWelcomeBack.ts +0 -253
- package/dist/ui/hooks/vim.test.ts +0 -1691
- package/dist/ui/hooks/vim.ts +0 -784
- package/dist/ui/keyMatchers.test.ts +0 -337
- package/dist/ui/keyMatchers.ts +0 -105
- package/dist/ui/privacy/CloudFreePrivacyNotice.tsx +0 -117
- package/dist/ui/privacy/CloudPaidPrivacyNotice.tsx +0 -59
- package/dist/ui/privacy/GeminiPrivacyNotice.tsx +0 -62
- package/dist/ui/privacy/PrivacyNotice.tsx +0 -42
- package/dist/ui/semantic-colors.ts +0 -26
- package/dist/ui/themes/ansi-light.ts +0 -150
- package/dist/ui/themes/ansi.ts +0 -159
- package/dist/ui/themes/atom-one-dark.ts +0 -147
- package/dist/ui/themes/ayu-light.ts +0 -139
- package/dist/ui/themes/ayu.ts +0 -113
- package/dist/ui/themes/color-utils.test.ts +0 -221
- package/dist/ui/themes/color-utils.ts +0 -231
- package/dist/ui/themes/default-light.ts +0 -108
- package/dist/ui/themes/default.ts +0 -151
- package/dist/ui/themes/dracula.ts +0 -124
- package/dist/ui/themes/fss-code-dark.ts +0 -156
- package/dist/ui/themes/fss-dark.ts +0 -113
- package/dist/ui/themes/fss-light.ts +0 -139
- package/dist/ui/themes/github-dark.ts +0 -147
- package/dist/ui/themes/github-light.ts +0 -149
- package/dist/ui/themes/googlecode.ts +0 -146
- package/dist/ui/themes/no-color.ts +0 -125
- package/dist/ui/themes/qwen-dark.ts +0 -118
- package/dist/ui/themes/qwen-light.ts +0 -144
- package/dist/ui/themes/semantic-tokens.ts +0 -127
- package/dist/ui/themes/shades-of-purple.ts +0 -352
- package/dist/ui/themes/theme-manager.test.ts +0 -99
- package/dist/ui/themes/theme-manager.ts +0 -257
- package/dist/ui/themes/theme.test.ts +0 -97
- package/dist/ui/themes/theme.ts +0 -451
- package/dist/ui/themes/xcode.ts +0 -154
- package/dist/ui/types.ts +0 -255
- package/dist/ui/utils/CodeColorizer.tsx +0 -217
- package/dist/ui/utils/ConsolePatcher.ts +0 -71
- package/dist/ui/utils/InlineMarkdownRenderer.tsx +0 -173
- package/dist/ui/utils/MarkdownDisplay.test.tsx +0 -244
- package/dist/ui/utils/MarkdownDisplay.tsx +0 -415
- package/dist/ui/utils/TableRenderer.tsx +0 -159
- package/dist/ui/utils/__snapshots__/MarkdownDisplay.test.tsx.snap +0 -93
- package/dist/ui/utils/clipboardUtils.test.ts +0 -76
- package/dist/ui/utils/clipboardUtils.ts +0 -149
- package/dist/ui/utils/commandUtils.test.ts +0 -384
- package/dist/ui/utils/commandUtils.ts +0 -106
- package/dist/ui/utils/computeStats.test.ts +0 -292
- package/dist/ui/utils/computeStats.ts +0 -86
- package/dist/ui/utils/displayUtils.test.ts +0 -58
- package/dist/ui/utils/displayUtils.ts +0 -32
- package/dist/ui/utils/formatters.test.ts +0 -72
- package/dist/ui/utils/formatters.ts +0 -63
- package/dist/ui/utils/isNarrowWidth.ts +0 -9
- package/dist/ui/utils/kittyProtocolDetector.ts +0 -105
- package/dist/ui/utils/markdownUtilities.test.ts +0 -50
- package/dist/ui/utils/markdownUtilities.ts +0 -125
- package/dist/ui/utils/platformConstants.ts +0 -52
- package/dist/ui/utils/terminalSetup.ts +0 -342
- package/dist/ui/utils/textUtils.ts +0 -40
- package/dist/ui/utils/updateCheck.test.ts +0 -163
- package/dist/ui/utils/updateCheck.ts +0 -100
- package/dist/utils/checks.ts +0 -28
- package/dist/utils/cleanup.test.ts +0 -68
- package/dist/utils/cleanup.ts +0 -36
- package/dist/utils/dialogScopeUtils.ts +0 -64
- package/dist/utils/events.ts +0 -14
- package/dist/utils/gitUtils.test.ts +0 -149
- package/dist/utils/gitUtils.ts +0 -116
- package/dist/utils/handleAutoUpdate.test.ts +0 -272
- package/dist/utils/handleAutoUpdate.ts +0 -145
- package/dist/utils/installationInfo.test.ts +0 -315
- package/dist/utils/installationInfo.ts +0 -176
- package/dist/utils/package.ts +0 -38
- package/dist/utils/readStdin.ts +0 -51
- package/dist/utils/resolvePath.ts +0 -21
- package/dist/utils/sandbox-macos-permissive-closed.sb +0 -32
- package/dist/utils/sandbox-macos-permissive-open.sb +0 -25
- package/dist/utils/sandbox-macos-permissive-proxied.sb +0 -37
- package/dist/utils/sandbox-macos-restrictive-closed.sb +0 -93
- package/dist/utils/sandbox-macos-restrictive-open.sb +0 -96
- package/dist/utils/sandbox-macos-restrictive-proxied.sb +0 -98
- package/dist/utils/sandbox.ts +0 -962
- package/dist/utils/settingsUtils.test.ts +0 -797
- package/dist/utils/settingsUtils.ts +0 -489
- package/dist/utils/spawnWrapper.ts +0 -9
- package/dist/utils/startupWarnings.test.ts +0 -83
- package/dist/utils/startupWarnings.ts +0 -40
- package/dist/utils/updateEventEmitter.ts +0 -13
- package/dist/utils/userStartupWarnings.test.ts +0 -87
- package/dist/utils/userStartupWarnings.ts +0 -69
- package/dist/utils/version.ts +0 -12
- package/dist/validateNonInterActiveAuth.test.ts +0 -260
- package/dist/validateNonInterActiveAuth.ts +0 -51
- package/dist/vitest.config.ts +0 -37
- package/dist/zed-integration/acp.ts +0 -366
- package/dist/zed-integration/fileSystemService.ts +0 -47
- package/dist/zed-integration/schema.ts +0 -466
- package/dist/zed-integration/zedIntegration.ts +0 -944
|
@@ -1,1123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { describe, it, expect, vi, beforeEach, afterEach, Mock } from 'vitest';
|
|
9
|
-
import { renderHook, act } from '@testing-library/react';
|
|
10
|
-
import {
|
|
11
|
-
useReactToolScheduler,
|
|
12
|
-
mapToDisplay,
|
|
13
|
-
} from './useReactToolScheduler.js';
|
|
14
|
-
import { PartUnion, FunctionResponse } from '@google/genai';
|
|
15
|
-
import {
|
|
16
|
-
Config,
|
|
17
|
-
ToolCallRequestInfo,
|
|
18
|
-
ToolRegistry,
|
|
19
|
-
ToolResult,
|
|
20
|
-
ToolCallConfirmationDetails,
|
|
21
|
-
ToolConfirmationOutcome,
|
|
22
|
-
ToolCallResponseInfo,
|
|
23
|
-
ToolCall, // Import from core
|
|
24
|
-
Status as ToolCallStatusType,
|
|
25
|
-
ApprovalMode,
|
|
26
|
-
Kind,
|
|
27
|
-
BaseDeclarativeTool,
|
|
28
|
-
BaseToolInvocation,
|
|
29
|
-
ToolInvocation,
|
|
30
|
-
AnyDeclarativeTool,
|
|
31
|
-
AnyToolInvocation,
|
|
32
|
-
} from 'fss-link-core';
|
|
33
|
-
import {
|
|
34
|
-
HistoryItemWithoutId,
|
|
35
|
-
ToolCallStatus,
|
|
36
|
-
HistoryItemToolGroup,
|
|
37
|
-
} from '../types.js';
|
|
38
|
-
|
|
39
|
-
// Mocks
|
|
40
|
-
vi.mock('fss-link-core', async () => {
|
|
41
|
-
const actual = await vi.importActual('fss-link-core');
|
|
42
|
-
return {
|
|
43
|
-
...actual,
|
|
44
|
-
ToolRegistry: vi.fn(),
|
|
45
|
-
Config: vi.fn(),
|
|
46
|
-
};
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const mockToolRegistry = {
|
|
50
|
-
getTool: vi.fn(),
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const mockConfig = {
|
|
54
|
-
getToolRegistry: vi.fn(() => mockToolRegistry as unknown as ToolRegistry),
|
|
55
|
-
getApprovalMode: vi.fn(() => ApprovalMode.DEFAULT),
|
|
56
|
-
getUsageStatisticsEnabled: () => true,
|
|
57
|
-
getDebugMode: () => false,
|
|
58
|
-
getSessionId: () => 'test-session-id',
|
|
59
|
-
getContentGeneratorConfig: () => ({
|
|
60
|
-
model: 'test-model',
|
|
61
|
-
authType: 'oauth-personal',
|
|
62
|
-
}),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
class MockToolInvocation extends BaseToolInvocation<object, ToolResult> {
|
|
66
|
-
constructor(
|
|
67
|
-
private readonly tool: MockTool,
|
|
68
|
-
params: object,
|
|
69
|
-
) {
|
|
70
|
-
super(params);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
getDescription(): string {
|
|
74
|
-
return JSON.stringify(this.params);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
override shouldConfirmExecute(
|
|
78
|
-
abortSignal: AbortSignal,
|
|
79
|
-
): Promise<ToolCallConfirmationDetails | false> {
|
|
80
|
-
return this.tool.shouldConfirmExecute(this.params, abortSignal);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
execute(
|
|
84
|
-
signal: AbortSignal,
|
|
85
|
-
updateOutput?: (output: string) => void,
|
|
86
|
-
terminalColumns?: number,
|
|
87
|
-
terminalRows?: number,
|
|
88
|
-
): Promise<ToolResult> {
|
|
89
|
-
return this.tool.execute(
|
|
90
|
-
this.params,
|
|
91
|
-
signal,
|
|
92
|
-
updateOutput,
|
|
93
|
-
terminalColumns,
|
|
94
|
-
terminalRows,
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
class MockTool extends BaseDeclarativeTool<object, ToolResult> {
|
|
100
|
-
constructor(
|
|
101
|
-
name: string,
|
|
102
|
-
displayName: string,
|
|
103
|
-
canUpdateOutput = false,
|
|
104
|
-
shouldConfirm = false,
|
|
105
|
-
isOutputMarkdown = false,
|
|
106
|
-
) {
|
|
107
|
-
super(
|
|
108
|
-
name,
|
|
109
|
-
displayName,
|
|
110
|
-
'A mock tool for testing',
|
|
111
|
-
Kind.Other,
|
|
112
|
-
{},
|
|
113
|
-
isOutputMarkdown,
|
|
114
|
-
canUpdateOutput,
|
|
115
|
-
);
|
|
116
|
-
if (shouldConfirm) {
|
|
117
|
-
this.shouldConfirmExecute.mockImplementation(
|
|
118
|
-
async (): Promise<ToolCallConfirmationDetails | false> => ({
|
|
119
|
-
type: 'edit',
|
|
120
|
-
title: 'Mock Tool Requires Confirmation',
|
|
121
|
-
onConfirm: mockOnUserConfirmForToolConfirmation,
|
|
122
|
-
filePath: 'mock',
|
|
123
|
-
fileName: 'mockToolRequiresConfirmation.ts',
|
|
124
|
-
fileDiff: 'Mock tool requires confirmation',
|
|
125
|
-
originalContent: 'Original content',
|
|
126
|
-
newContent: 'New content',
|
|
127
|
-
}),
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
execute = vi.fn();
|
|
133
|
-
shouldConfirmExecute = vi.fn();
|
|
134
|
-
|
|
135
|
-
protected createInvocation(
|
|
136
|
-
params: object,
|
|
137
|
-
): ToolInvocation<object, ToolResult> {
|
|
138
|
-
return new MockToolInvocation(this, params);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const mockTool = new MockTool('mockTool', 'Mock Tool');
|
|
143
|
-
const mockToolWithLiveOutput = new MockTool(
|
|
144
|
-
'mockToolWithLiveOutput',
|
|
145
|
-
'Mock Tool With Live Output',
|
|
146
|
-
true,
|
|
147
|
-
);
|
|
148
|
-
let mockOnUserConfirmForToolConfirmation: Mock;
|
|
149
|
-
const mockToolRequiresConfirmation = new MockTool(
|
|
150
|
-
'mockToolRequiresConfirmation',
|
|
151
|
-
'Mock Tool Requires Confirmation',
|
|
152
|
-
false,
|
|
153
|
-
true,
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
describe('useReactToolScheduler in YOLO Mode', () => {
|
|
157
|
-
let onComplete: Mock;
|
|
158
|
-
let setPendingHistoryItem: Mock;
|
|
159
|
-
|
|
160
|
-
beforeEach(() => {
|
|
161
|
-
onComplete = vi.fn();
|
|
162
|
-
setPendingHistoryItem = vi.fn();
|
|
163
|
-
mockToolRegistry.getTool.mockClear();
|
|
164
|
-
(mockToolRequiresConfirmation.execute as Mock).mockClear();
|
|
165
|
-
(mockToolRequiresConfirmation.shouldConfirmExecute as Mock).mockClear();
|
|
166
|
-
|
|
167
|
-
// IMPORTANT: Enable YOLO mode for this test suite
|
|
168
|
-
(mockConfig.getApprovalMode as Mock).mockReturnValue(ApprovalMode.YOLO);
|
|
169
|
-
|
|
170
|
-
vi.useFakeTimers();
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
afterEach(() => {
|
|
174
|
-
vi.clearAllTimers();
|
|
175
|
-
vi.useRealTimers();
|
|
176
|
-
// IMPORTANT: Disable YOLO mode after this test suite
|
|
177
|
-
(mockConfig.getApprovalMode as Mock).mockReturnValue(ApprovalMode.DEFAULT);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const renderSchedulerInYoloMode = () =>
|
|
181
|
-
renderHook(() =>
|
|
182
|
-
useReactToolScheduler(
|
|
183
|
-
onComplete,
|
|
184
|
-
mockConfig as unknown as Config,
|
|
185
|
-
setPendingHistoryItem,
|
|
186
|
-
() => undefined,
|
|
187
|
-
() => {},
|
|
188
|
-
),
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
it('should skip confirmation and execute tool directly when yoloMode is true', async () => {
|
|
192
|
-
mockToolRegistry.getTool.mockReturnValue(mockToolRequiresConfirmation);
|
|
193
|
-
const expectedOutput = 'YOLO Confirmed output';
|
|
194
|
-
(mockToolRequiresConfirmation.execute as Mock).mockResolvedValue({
|
|
195
|
-
llmContent: expectedOutput,
|
|
196
|
-
returnDisplay: 'YOLO Formatted tool output',
|
|
197
|
-
summary: 'YOLO summary',
|
|
198
|
-
} as ToolResult);
|
|
199
|
-
|
|
200
|
-
const { result } = renderSchedulerInYoloMode();
|
|
201
|
-
const schedule = result.current[1];
|
|
202
|
-
const request: ToolCallRequestInfo = {
|
|
203
|
-
callId: 'yoloCall',
|
|
204
|
-
name: 'mockToolRequiresConfirmation',
|
|
205
|
-
args: { data: 'any data' },
|
|
206
|
-
} as any;
|
|
207
|
-
|
|
208
|
-
act(() => {
|
|
209
|
-
schedule(request, new AbortController().signal);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
await act(async () => {
|
|
213
|
-
await vi.runAllTimersAsync(); // Process validation
|
|
214
|
-
});
|
|
215
|
-
await act(async () => {
|
|
216
|
-
await vi.runAllTimersAsync(); // Process scheduling
|
|
217
|
-
});
|
|
218
|
-
await act(async () => {
|
|
219
|
-
await vi.runAllTimersAsync(); // Process execution
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// Check that shouldConfirmExecute was NOT called
|
|
223
|
-
expect(
|
|
224
|
-
mockToolRequiresConfirmation.shouldConfirmExecute,
|
|
225
|
-
).not.toHaveBeenCalled();
|
|
226
|
-
|
|
227
|
-
// Check that execute WAS called
|
|
228
|
-
expect(mockToolRequiresConfirmation.execute).toHaveBeenCalledWith(
|
|
229
|
-
request.args,
|
|
230
|
-
expect.any(AbortSignal),
|
|
231
|
-
undefined,
|
|
232
|
-
undefined,
|
|
233
|
-
undefined,
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
// Check that onComplete was called with success
|
|
237
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
238
|
-
expect.objectContaining({
|
|
239
|
-
status: 'success',
|
|
240
|
-
request,
|
|
241
|
-
response: expect.objectContaining({
|
|
242
|
-
resultDisplay: 'YOLO Formatted tool output',
|
|
243
|
-
responseParts: {
|
|
244
|
-
functionResponse: {
|
|
245
|
-
id: 'yoloCall',
|
|
246
|
-
name: 'mockToolRequiresConfirmation',
|
|
247
|
-
response: { output: expectedOutput },
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
}),
|
|
251
|
-
}),
|
|
252
|
-
]);
|
|
253
|
-
|
|
254
|
-
// Ensure no confirmation UI was triggered (setPendingHistoryItem should not have been called with confirmation details)
|
|
255
|
-
const setPendingHistoryItemCalls = setPendingHistoryItem.mock.calls;
|
|
256
|
-
const confirmationCall = setPendingHistoryItemCalls.find((call) => {
|
|
257
|
-
const item = typeof call[0] === 'function' ? call[0]({}) : call[0];
|
|
258
|
-
return item?.tools?.[0]?.confirmationDetails;
|
|
259
|
-
});
|
|
260
|
-
expect(confirmationCall).toBeUndefined();
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
describe('useReactToolScheduler', () => {
|
|
265
|
-
// TODO(ntaylormullen): The following tests are skipped due to difficulties in
|
|
266
|
-
// reliably testing the asynchronous state updates and interactions with timers.
|
|
267
|
-
// These tests involve complex sequences of events, including confirmations,
|
|
268
|
-
// live output updates, and cancellations, which are challenging to assert
|
|
269
|
-
// correctly with the current testing setup. Further investigation is needed
|
|
270
|
-
// to find a robust way to test these scenarios.
|
|
271
|
-
let onComplete: Mock;
|
|
272
|
-
let setPendingHistoryItem: Mock;
|
|
273
|
-
let capturedOnConfirmForTest:
|
|
274
|
-
| ((outcome: ToolConfirmationOutcome) => void | Promise<void>)
|
|
275
|
-
| undefined;
|
|
276
|
-
|
|
277
|
-
beforeEach(() => {
|
|
278
|
-
onComplete = vi.fn();
|
|
279
|
-
capturedOnConfirmForTest = undefined;
|
|
280
|
-
setPendingHistoryItem = vi.fn((updaterOrValue) => {
|
|
281
|
-
let pendingItem: HistoryItemWithoutId | null = null;
|
|
282
|
-
if (typeof updaterOrValue === 'function') {
|
|
283
|
-
// Loosen the type for prevState to allow for more flexible updates in tests
|
|
284
|
-
const prevState: Partial<HistoryItemToolGroup> = {
|
|
285
|
-
type: 'tool_group', // Still default to tool_group for most cases
|
|
286
|
-
tools: [],
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
pendingItem = updaterOrValue(prevState as any); // Allow any for more flexibility
|
|
290
|
-
} else {
|
|
291
|
-
pendingItem = updaterOrValue;
|
|
292
|
-
}
|
|
293
|
-
// Capture onConfirm if it exists, regardless of the exact type of pendingItem
|
|
294
|
-
// This is a common pattern in these tests.
|
|
295
|
-
if (
|
|
296
|
-
(pendingItem as HistoryItemToolGroup)?.tools?.[0]?.confirmationDetails
|
|
297
|
-
?.onConfirm
|
|
298
|
-
) {
|
|
299
|
-
capturedOnConfirmForTest = (pendingItem as HistoryItemToolGroup)
|
|
300
|
-
.tools[0].confirmationDetails?.onConfirm;
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
mockToolRegistry.getTool.mockClear();
|
|
305
|
-
(mockTool.execute as Mock).mockClear();
|
|
306
|
-
(mockTool.shouldConfirmExecute as Mock).mockClear();
|
|
307
|
-
(mockToolWithLiveOutput.execute as Mock).mockClear();
|
|
308
|
-
(mockToolWithLiveOutput.shouldConfirmExecute as Mock).mockClear();
|
|
309
|
-
(mockToolRequiresConfirmation.execute as Mock).mockClear();
|
|
310
|
-
(mockToolRequiresConfirmation.shouldConfirmExecute as Mock).mockClear();
|
|
311
|
-
|
|
312
|
-
mockOnUserConfirmForToolConfirmation = vi.fn();
|
|
313
|
-
(
|
|
314
|
-
mockToolRequiresConfirmation.shouldConfirmExecute as Mock
|
|
315
|
-
).mockImplementation(
|
|
316
|
-
async (): Promise<ToolCallConfirmationDetails | null> =>
|
|
317
|
-
({
|
|
318
|
-
onConfirm: mockOnUserConfirmForToolConfirmation,
|
|
319
|
-
fileName: 'mockToolRequiresConfirmation.ts',
|
|
320
|
-
fileDiff: 'Mock tool requires confirmation',
|
|
321
|
-
type: 'edit',
|
|
322
|
-
title: 'Mock Tool Requires Confirmation',
|
|
323
|
-
}) as any,
|
|
324
|
-
);
|
|
325
|
-
|
|
326
|
-
vi.useFakeTimers();
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
afterEach(() => {
|
|
330
|
-
vi.clearAllTimers();
|
|
331
|
-
vi.useRealTimers();
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
const renderScheduler = () =>
|
|
335
|
-
renderHook(() =>
|
|
336
|
-
useReactToolScheduler(
|
|
337
|
-
onComplete,
|
|
338
|
-
mockConfig as unknown as Config,
|
|
339
|
-
setPendingHistoryItem,
|
|
340
|
-
() => undefined,
|
|
341
|
-
() => {},
|
|
342
|
-
),
|
|
343
|
-
);
|
|
344
|
-
|
|
345
|
-
it('initial state should be empty', () => {
|
|
346
|
-
const { result } = renderScheduler();
|
|
347
|
-
expect(result.current[0]).toEqual([]);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
it('should schedule and execute a tool call successfully', async () => {
|
|
351
|
-
mockToolRegistry.getTool.mockReturnValue(mockTool);
|
|
352
|
-
(mockTool.execute as Mock).mockResolvedValue({
|
|
353
|
-
llmContent: 'Tool output',
|
|
354
|
-
returnDisplay: 'Formatted tool output',
|
|
355
|
-
summary: 'Formatted summary',
|
|
356
|
-
} as ToolResult);
|
|
357
|
-
(mockTool.shouldConfirmExecute as Mock).mockResolvedValue(null);
|
|
358
|
-
|
|
359
|
-
const { result } = renderScheduler();
|
|
360
|
-
const schedule = result.current[1];
|
|
361
|
-
const request: ToolCallRequestInfo = {
|
|
362
|
-
callId: 'call1',
|
|
363
|
-
name: 'mockTool',
|
|
364
|
-
args: { param: 'value' },
|
|
365
|
-
} as any;
|
|
366
|
-
|
|
367
|
-
act(() => {
|
|
368
|
-
schedule(request, new AbortController().signal);
|
|
369
|
-
});
|
|
370
|
-
await act(async () => {
|
|
371
|
-
await vi.runAllTimersAsync();
|
|
372
|
-
});
|
|
373
|
-
await act(async () => {
|
|
374
|
-
await vi.runAllTimersAsync();
|
|
375
|
-
});
|
|
376
|
-
await act(async () => {
|
|
377
|
-
await vi.runAllTimersAsync();
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
expect(mockTool.execute).toHaveBeenCalledWith(
|
|
381
|
-
request.args,
|
|
382
|
-
expect.any(AbortSignal),
|
|
383
|
-
undefined,
|
|
384
|
-
undefined,
|
|
385
|
-
undefined,
|
|
386
|
-
);
|
|
387
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
388
|
-
expect.objectContaining({
|
|
389
|
-
status: 'success',
|
|
390
|
-
request,
|
|
391
|
-
response: expect.objectContaining({
|
|
392
|
-
resultDisplay: 'Formatted tool output',
|
|
393
|
-
responseParts: {
|
|
394
|
-
functionResponse: {
|
|
395
|
-
id: 'call1',
|
|
396
|
-
name: 'mockTool',
|
|
397
|
-
response: { output: 'Tool output' },
|
|
398
|
-
},
|
|
399
|
-
},
|
|
400
|
-
}),
|
|
401
|
-
}),
|
|
402
|
-
]);
|
|
403
|
-
expect(result.current[0]).toEqual([]);
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
it('should handle tool not found', async () => {
|
|
407
|
-
mockToolRegistry.getTool.mockReturnValue(undefined);
|
|
408
|
-
const { result } = renderScheduler();
|
|
409
|
-
const schedule = result.current[1];
|
|
410
|
-
const request: ToolCallRequestInfo = {
|
|
411
|
-
callId: 'call1',
|
|
412
|
-
name: 'nonexistentTool',
|
|
413
|
-
args: {},
|
|
414
|
-
} as any;
|
|
415
|
-
|
|
416
|
-
act(() => {
|
|
417
|
-
schedule(request, new AbortController().signal);
|
|
418
|
-
});
|
|
419
|
-
await act(async () => {
|
|
420
|
-
await vi.runAllTimersAsync();
|
|
421
|
-
});
|
|
422
|
-
await act(async () => {
|
|
423
|
-
await vi.runAllTimersAsync();
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
427
|
-
expect.objectContaining({
|
|
428
|
-
status: 'error',
|
|
429
|
-
request,
|
|
430
|
-
response: expect.objectContaining({
|
|
431
|
-
error: expect.objectContaining({
|
|
432
|
-
message: 'Tool "nonexistentTool" not found in registry.',
|
|
433
|
-
}),
|
|
434
|
-
}),
|
|
435
|
-
}),
|
|
436
|
-
]);
|
|
437
|
-
expect(result.current[0]).toEqual([]);
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
it('should handle error during shouldConfirmExecute', async () => {
|
|
441
|
-
mockToolRegistry.getTool.mockReturnValue(mockTool);
|
|
442
|
-
const confirmError = new Error('Confirmation check failed');
|
|
443
|
-
(mockTool.shouldConfirmExecute as Mock).mockRejectedValue(confirmError);
|
|
444
|
-
|
|
445
|
-
const { result } = renderScheduler();
|
|
446
|
-
const schedule = result.current[1];
|
|
447
|
-
const request: ToolCallRequestInfo = {
|
|
448
|
-
callId: 'call1',
|
|
449
|
-
name: 'mockTool',
|
|
450
|
-
args: {},
|
|
451
|
-
} as any;
|
|
452
|
-
|
|
453
|
-
act(() => {
|
|
454
|
-
schedule(request, new AbortController().signal);
|
|
455
|
-
});
|
|
456
|
-
await act(async () => {
|
|
457
|
-
await vi.runAllTimersAsync();
|
|
458
|
-
});
|
|
459
|
-
await act(async () => {
|
|
460
|
-
await vi.runAllTimersAsync();
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
464
|
-
expect.objectContaining({
|
|
465
|
-
status: 'error',
|
|
466
|
-
request,
|
|
467
|
-
response: expect.objectContaining({
|
|
468
|
-
error: confirmError,
|
|
469
|
-
}),
|
|
470
|
-
}),
|
|
471
|
-
]);
|
|
472
|
-
expect(result.current[0]).toEqual([]);
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
it('should handle error during execute', async () => {
|
|
476
|
-
mockToolRegistry.getTool.mockReturnValue(mockTool);
|
|
477
|
-
(mockTool.shouldConfirmExecute as Mock).mockResolvedValue(null);
|
|
478
|
-
const execError = new Error('Execution failed');
|
|
479
|
-
(mockTool.execute as Mock).mockRejectedValue(execError);
|
|
480
|
-
|
|
481
|
-
const { result } = renderScheduler();
|
|
482
|
-
const schedule = result.current[1];
|
|
483
|
-
const request: ToolCallRequestInfo = {
|
|
484
|
-
callId: 'call1',
|
|
485
|
-
name: 'mockTool',
|
|
486
|
-
args: {},
|
|
487
|
-
} as any;
|
|
488
|
-
|
|
489
|
-
act(() => {
|
|
490
|
-
schedule(request, new AbortController().signal);
|
|
491
|
-
});
|
|
492
|
-
await act(async () => {
|
|
493
|
-
await vi.runAllTimersAsync();
|
|
494
|
-
});
|
|
495
|
-
await act(async () => {
|
|
496
|
-
await vi.runAllTimersAsync();
|
|
497
|
-
});
|
|
498
|
-
await act(async () => {
|
|
499
|
-
await vi.runAllTimersAsync();
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
503
|
-
expect.objectContaining({
|
|
504
|
-
status: 'error',
|
|
505
|
-
request,
|
|
506
|
-
response: expect.objectContaining({
|
|
507
|
-
error: execError,
|
|
508
|
-
}),
|
|
509
|
-
}),
|
|
510
|
-
]);
|
|
511
|
-
expect(result.current[0]).toEqual([]);
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
it.skip('should handle tool requiring confirmation - approved', async () => {
|
|
515
|
-
mockToolRegistry.getTool.mockReturnValue(mockToolRequiresConfirmation);
|
|
516
|
-
const expectedOutput = 'Confirmed output';
|
|
517
|
-
(mockToolRequiresConfirmation.execute as Mock).mockResolvedValue({
|
|
518
|
-
llmContent: expectedOutput,
|
|
519
|
-
returnDisplay: 'Confirmed display',
|
|
520
|
-
summary: 'Confirmed summary',
|
|
521
|
-
} as ToolResult);
|
|
522
|
-
|
|
523
|
-
const { result } = renderScheduler();
|
|
524
|
-
const schedule = result.current[1];
|
|
525
|
-
const request: ToolCallRequestInfo = {
|
|
526
|
-
callId: 'callConfirm',
|
|
527
|
-
name: 'mockToolRequiresConfirmation',
|
|
528
|
-
args: { data: 'sensitive' },
|
|
529
|
-
} as any;
|
|
530
|
-
|
|
531
|
-
act(() => {
|
|
532
|
-
schedule(request, new AbortController().signal);
|
|
533
|
-
});
|
|
534
|
-
await act(async () => {
|
|
535
|
-
await vi.runAllTimersAsync();
|
|
536
|
-
});
|
|
537
|
-
|
|
538
|
-
expect(setPendingHistoryItem).toHaveBeenCalled();
|
|
539
|
-
expect(capturedOnConfirmForTest).toBeDefined();
|
|
540
|
-
|
|
541
|
-
await act(async () => {
|
|
542
|
-
await capturedOnConfirmForTest?.(ToolConfirmationOutcome.ProceedOnce);
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
await act(async () => {
|
|
546
|
-
await vi.runAllTimersAsync();
|
|
547
|
-
});
|
|
548
|
-
await act(async () => {
|
|
549
|
-
await vi.runAllTimersAsync();
|
|
550
|
-
});
|
|
551
|
-
await act(async () => {
|
|
552
|
-
await vi.runAllTimersAsync();
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
expect(mockOnUserConfirmForToolConfirmation).toHaveBeenCalledWith(
|
|
556
|
-
ToolConfirmationOutcome.ProceedOnce,
|
|
557
|
-
);
|
|
558
|
-
expect(mockToolRequiresConfirmation.execute).toHaveBeenCalled();
|
|
559
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
560
|
-
expect.objectContaining({
|
|
561
|
-
status: 'success',
|
|
562
|
-
request,
|
|
563
|
-
response: expect.objectContaining({
|
|
564
|
-
resultDisplay: 'Confirmed display',
|
|
565
|
-
responseParts: expect.arrayContaining([
|
|
566
|
-
expect.objectContaining({
|
|
567
|
-
functionResponse: expect.objectContaining({
|
|
568
|
-
response: { output: expectedOutput },
|
|
569
|
-
}),
|
|
570
|
-
}),
|
|
571
|
-
]),
|
|
572
|
-
}),
|
|
573
|
-
}),
|
|
574
|
-
]);
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
it.skip('should handle tool requiring confirmation - cancelled by user', async () => {
|
|
578
|
-
mockToolRegistry.getTool.mockReturnValue(mockToolRequiresConfirmation);
|
|
579
|
-
const { result } = renderScheduler();
|
|
580
|
-
const schedule = result.current[1];
|
|
581
|
-
const request: ToolCallRequestInfo = {
|
|
582
|
-
callId: 'callConfirmCancel',
|
|
583
|
-
name: 'mockToolRequiresConfirmation',
|
|
584
|
-
args: {},
|
|
585
|
-
} as any;
|
|
586
|
-
|
|
587
|
-
act(() => {
|
|
588
|
-
schedule(request, new AbortController().signal);
|
|
589
|
-
});
|
|
590
|
-
await act(async () => {
|
|
591
|
-
await vi.runAllTimersAsync();
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
expect(setPendingHistoryItem).toHaveBeenCalled();
|
|
595
|
-
expect(capturedOnConfirmForTest).toBeDefined();
|
|
596
|
-
|
|
597
|
-
await act(async () => {
|
|
598
|
-
await capturedOnConfirmForTest?.(ToolConfirmationOutcome.Cancel);
|
|
599
|
-
});
|
|
600
|
-
await act(async () => {
|
|
601
|
-
await vi.runAllTimersAsync();
|
|
602
|
-
});
|
|
603
|
-
await act(async () => {
|
|
604
|
-
await vi.runAllTimersAsync();
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
expect(mockOnUserConfirmForToolConfirmation).toHaveBeenCalledWith(
|
|
608
|
-
ToolConfirmationOutcome.Cancel,
|
|
609
|
-
);
|
|
610
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
611
|
-
expect.objectContaining({
|
|
612
|
-
status: 'cancelled',
|
|
613
|
-
request,
|
|
614
|
-
response: expect.objectContaining({
|
|
615
|
-
responseParts: expect.arrayContaining([
|
|
616
|
-
expect.objectContaining({
|
|
617
|
-
functionResponse: expect.objectContaining({
|
|
618
|
-
response: expect.objectContaining({
|
|
619
|
-
error: `User did not allow tool call ${request.name}. Reason: User cancelled.`,
|
|
620
|
-
}),
|
|
621
|
-
}),
|
|
622
|
-
}),
|
|
623
|
-
]),
|
|
624
|
-
}),
|
|
625
|
-
}),
|
|
626
|
-
]);
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
it.skip('should handle live output updates', async () => {
|
|
630
|
-
mockToolRegistry.getTool.mockReturnValue(mockToolWithLiveOutput);
|
|
631
|
-
let liveUpdateFn: ((output: string) => void) | undefined;
|
|
632
|
-
let resolveExecutePromise: (value: ToolResult) => void;
|
|
633
|
-
const executePromise = new Promise<ToolResult>((resolve) => {
|
|
634
|
-
resolveExecutePromise = resolve;
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
(mockToolWithLiveOutput.execute as Mock).mockImplementation(
|
|
638
|
-
async (
|
|
639
|
-
_args: Record<string, unknown>,
|
|
640
|
-
_signal: AbortSignal,
|
|
641
|
-
updateFn: ((output: string) => void) | undefined,
|
|
642
|
-
) => {
|
|
643
|
-
liveUpdateFn = updateFn;
|
|
644
|
-
return executePromise;
|
|
645
|
-
},
|
|
646
|
-
);
|
|
647
|
-
(mockToolWithLiveOutput.shouldConfirmExecute as Mock).mockResolvedValue(
|
|
648
|
-
null,
|
|
649
|
-
);
|
|
650
|
-
|
|
651
|
-
const { result } = renderScheduler();
|
|
652
|
-
const schedule = result.current[1];
|
|
653
|
-
const request: ToolCallRequestInfo = {
|
|
654
|
-
callId: 'liveCall',
|
|
655
|
-
name: 'mockToolWithLiveOutput',
|
|
656
|
-
args: {},
|
|
657
|
-
} as any;
|
|
658
|
-
|
|
659
|
-
act(() => {
|
|
660
|
-
schedule(request, new AbortController().signal);
|
|
661
|
-
});
|
|
662
|
-
await act(async () => {
|
|
663
|
-
await vi.runAllTimersAsync();
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
expect(liveUpdateFn).toBeDefined();
|
|
667
|
-
expect(setPendingHistoryItem).toHaveBeenCalled();
|
|
668
|
-
|
|
669
|
-
await act(async () => {
|
|
670
|
-
liveUpdateFn?.('Live output 1');
|
|
671
|
-
});
|
|
672
|
-
await act(async () => {
|
|
673
|
-
await vi.runAllTimersAsync();
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
await act(async () => {
|
|
677
|
-
liveUpdateFn?.('Live output 2');
|
|
678
|
-
});
|
|
679
|
-
await act(async () => {
|
|
680
|
-
await vi.runAllTimersAsync();
|
|
681
|
-
});
|
|
682
|
-
|
|
683
|
-
act(() => {
|
|
684
|
-
resolveExecutePromise({
|
|
685
|
-
llmContent: 'Final output',
|
|
686
|
-
returnDisplay: 'Final display',
|
|
687
|
-
summary: 'Final summary',
|
|
688
|
-
} as ToolResult);
|
|
689
|
-
});
|
|
690
|
-
await act(async () => {
|
|
691
|
-
await vi.runAllTimersAsync();
|
|
692
|
-
});
|
|
693
|
-
await act(async () => {
|
|
694
|
-
await vi.runAllTimersAsync();
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
698
|
-
expect.objectContaining({
|
|
699
|
-
status: 'success',
|
|
700
|
-
request,
|
|
701
|
-
response: expect.objectContaining({
|
|
702
|
-
resultDisplay: 'Final display',
|
|
703
|
-
responseParts: expect.arrayContaining([
|
|
704
|
-
expect.objectContaining({
|
|
705
|
-
functionResponse: expect.objectContaining({
|
|
706
|
-
response: { output: 'Final output' },
|
|
707
|
-
}),
|
|
708
|
-
}),
|
|
709
|
-
]),
|
|
710
|
-
}),
|
|
711
|
-
}),
|
|
712
|
-
]);
|
|
713
|
-
expect(result.current[0]).toEqual([]);
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
it('should schedule and execute multiple tool calls', async () => {
|
|
717
|
-
const tool1 = new MockTool('tool1', 'Tool 1');
|
|
718
|
-
tool1.execute.mockResolvedValue({
|
|
719
|
-
llmContent: 'Output 1',
|
|
720
|
-
returnDisplay: 'Display 1',
|
|
721
|
-
summary: 'Summary 1',
|
|
722
|
-
} as ToolResult);
|
|
723
|
-
tool1.shouldConfirmExecute.mockResolvedValue(null);
|
|
724
|
-
|
|
725
|
-
const tool2 = new MockTool('tool2', 'Tool 2');
|
|
726
|
-
tool2.execute.mockResolvedValue({
|
|
727
|
-
llmContent: 'Output 2',
|
|
728
|
-
returnDisplay: 'Display 2',
|
|
729
|
-
summary: 'Summary 2',
|
|
730
|
-
} as ToolResult);
|
|
731
|
-
tool2.shouldConfirmExecute.mockResolvedValue(null);
|
|
732
|
-
|
|
733
|
-
mockToolRegistry.getTool.mockImplementation((name) => {
|
|
734
|
-
if (name === 'tool1') return tool1;
|
|
735
|
-
if (name === 'tool2') return tool2;
|
|
736
|
-
return undefined;
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
const { result } = renderScheduler();
|
|
740
|
-
const schedule = result.current[1];
|
|
741
|
-
const requests: ToolCallRequestInfo[] = [
|
|
742
|
-
{ callId: 'multi1', name: 'tool1', args: { p: 1 } } as any,
|
|
743
|
-
{ callId: 'multi2', name: 'tool2', args: { p: 2 } } as any,
|
|
744
|
-
];
|
|
745
|
-
|
|
746
|
-
act(() => {
|
|
747
|
-
schedule(requests, new AbortController().signal);
|
|
748
|
-
});
|
|
749
|
-
await act(async () => {
|
|
750
|
-
await vi.runAllTimersAsync();
|
|
751
|
-
});
|
|
752
|
-
await act(async () => {
|
|
753
|
-
await vi.runAllTimersAsync();
|
|
754
|
-
});
|
|
755
|
-
await act(async () => {
|
|
756
|
-
await vi.runAllTimersAsync();
|
|
757
|
-
});
|
|
758
|
-
await act(async () => {
|
|
759
|
-
await vi.runAllTimersAsync();
|
|
760
|
-
});
|
|
761
|
-
|
|
762
|
-
expect(onComplete).toHaveBeenCalledTimes(1);
|
|
763
|
-
const completedCalls = onComplete.mock.calls[0][0] as ToolCall[];
|
|
764
|
-
expect(completedCalls.length).toBe(2);
|
|
765
|
-
|
|
766
|
-
const call1Result = completedCalls.find(
|
|
767
|
-
(c) => c.request.callId === 'multi1',
|
|
768
|
-
);
|
|
769
|
-
const call2Result = completedCalls.find(
|
|
770
|
-
(c) => c.request.callId === 'multi2',
|
|
771
|
-
);
|
|
772
|
-
|
|
773
|
-
expect(call1Result).toMatchObject({
|
|
774
|
-
status: 'success',
|
|
775
|
-
request: requests[0],
|
|
776
|
-
response: expect.objectContaining({
|
|
777
|
-
resultDisplay: 'Display 1',
|
|
778
|
-
responseParts: {
|
|
779
|
-
functionResponse: {
|
|
780
|
-
id: 'multi1',
|
|
781
|
-
name: 'tool1',
|
|
782
|
-
response: { output: 'Output 1' },
|
|
783
|
-
},
|
|
784
|
-
},
|
|
785
|
-
}),
|
|
786
|
-
});
|
|
787
|
-
expect(call2Result).toMatchObject({
|
|
788
|
-
status: 'success',
|
|
789
|
-
request: requests[1],
|
|
790
|
-
response: expect.objectContaining({
|
|
791
|
-
resultDisplay: 'Display 2',
|
|
792
|
-
responseParts: {
|
|
793
|
-
functionResponse: {
|
|
794
|
-
id: 'multi2',
|
|
795
|
-
name: 'tool2',
|
|
796
|
-
response: { output: 'Output 2' },
|
|
797
|
-
},
|
|
798
|
-
},
|
|
799
|
-
}),
|
|
800
|
-
});
|
|
801
|
-
expect(result.current[0]).toEqual([]);
|
|
802
|
-
});
|
|
803
|
-
|
|
804
|
-
it.skip('should throw error if scheduling while already running', async () => {
|
|
805
|
-
mockToolRegistry.getTool.mockReturnValue(mockTool);
|
|
806
|
-
const longExecutePromise = new Promise<ToolResult>((resolve) =>
|
|
807
|
-
setTimeout(
|
|
808
|
-
() =>
|
|
809
|
-
resolve({
|
|
810
|
-
llmContent: 'done',
|
|
811
|
-
returnDisplay: 'done display',
|
|
812
|
-
summary: 'done summary',
|
|
813
|
-
}),
|
|
814
|
-
50,
|
|
815
|
-
),
|
|
816
|
-
);
|
|
817
|
-
(mockTool.execute as Mock).mockReturnValue(longExecutePromise);
|
|
818
|
-
(mockTool.shouldConfirmExecute as Mock).mockResolvedValue(null);
|
|
819
|
-
|
|
820
|
-
const { result } = renderScheduler();
|
|
821
|
-
const schedule = result.current[1];
|
|
822
|
-
const request1: ToolCallRequestInfo = {
|
|
823
|
-
callId: 'run1',
|
|
824
|
-
name: 'mockTool',
|
|
825
|
-
args: {},
|
|
826
|
-
} as any;
|
|
827
|
-
const request2: ToolCallRequestInfo = {
|
|
828
|
-
callId: 'run2',
|
|
829
|
-
name: 'mockTool',
|
|
830
|
-
args: {},
|
|
831
|
-
} as any;
|
|
832
|
-
|
|
833
|
-
act(() => {
|
|
834
|
-
schedule(request1, new AbortController().signal);
|
|
835
|
-
});
|
|
836
|
-
await act(async () => {
|
|
837
|
-
await vi.runAllTimersAsync();
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
expect(() => schedule(request2, new AbortController().signal)).toThrow(
|
|
841
|
-
'Cannot schedule tool calls while other tool calls are running',
|
|
842
|
-
);
|
|
843
|
-
|
|
844
|
-
await act(async () => {
|
|
845
|
-
await vi.advanceTimersByTimeAsync(50);
|
|
846
|
-
await vi.runAllTimersAsync();
|
|
847
|
-
await act(async () => {
|
|
848
|
-
await vi.runAllTimersAsync();
|
|
849
|
-
});
|
|
850
|
-
});
|
|
851
|
-
expect(onComplete).toHaveBeenCalledWith([
|
|
852
|
-
expect.objectContaining({
|
|
853
|
-
status: 'success',
|
|
854
|
-
request: request1,
|
|
855
|
-
response: expect.objectContaining({ resultDisplay: 'done display' }),
|
|
856
|
-
}),
|
|
857
|
-
]);
|
|
858
|
-
expect(result.current[0]).toEqual([]);
|
|
859
|
-
});
|
|
860
|
-
});
|
|
861
|
-
|
|
862
|
-
describe('mapToDisplay', () => {
|
|
863
|
-
const baseRequest: ToolCallRequestInfo = {
|
|
864
|
-
callId: 'testCallId',
|
|
865
|
-
name: 'testTool',
|
|
866
|
-
args: { foo: 'bar' },
|
|
867
|
-
} as any;
|
|
868
|
-
|
|
869
|
-
const baseTool = new MockTool('testTool', 'Test Tool Display');
|
|
870
|
-
|
|
871
|
-
const baseResponse: ToolCallResponseInfo = {
|
|
872
|
-
callId: 'testCallId',
|
|
873
|
-
responseParts: [
|
|
874
|
-
{
|
|
875
|
-
functionResponse: {
|
|
876
|
-
name: 'testTool',
|
|
877
|
-
id: 'testCallId',
|
|
878
|
-
response: { output: 'Test output' },
|
|
879
|
-
} as FunctionResponse,
|
|
880
|
-
} as PartUnion,
|
|
881
|
-
],
|
|
882
|
-
resultDisplay: 'Test display output',
|
|
883
|
-
error: undefined,
|
|
884
|
-
} as any;
|
|
885
|
-
|
|
886
|
-
// Define a more specific type for extraProps for these tests
|
|
887
|
-
// This helps ensure that tool and confirmationDetails are only accessed when they are expected to exist.
|
|
888
|
-
type MapToDisplayExtraProps =
|
|
889
|
-
| {
|
|
890
|
-
tool?: AnyDeclarativeTool;
|
|
891
|
-
invocation?: AnyToolInvocation;
|
|
892
|
-
liveOutput?: string;
|
|
893
|
-
response?: ToolCallResponseInfo;
|
|
894
|
-
confirmationDetails?: ToolCallConfirmationDetails;
|
|
895
|
-
}
|
|
896
|
-
| {
|
|
897
|
-
tool: AnyDeclarativeTool;
|
|
898
|
-
invocation?: AnyToolInvocation;
|
|
899
|
-
response?: ToolCallResponseInfo;
|
|
900
|
-
confirmationDetails?: ToolCallConfirmationDetails;
|
|
901
|
-
}
|
|
902
|
-
| {
|
|
903
|
-
response: ToolCallResponseInfo;
|
|
904
|
-
tool?: undefined;
|
|
905
|
-
confirmationDetails?: ToolCallConfirmationDetails;
|
|
906
|
-
}
|
|
907
|
-
| {
|
|
908
|
-
confirmationDetails: ToolCallConfirmationDetails;
|
|
909
|
-
tool?: AnyDeclarativeTool;
|
|
910
|
-
invocation?: AnyToolInvocation;
|
|
911
|
-
response?: ToolCallResponseInfo;
|
|
912
|
-
};
|
|
913
|
-
|
|
914
|
-
const baseInvocation = baseTool.build(baseRequest.args);
|
|
915
|
-
const testCases: Array<{
|
|
916
|
-
name: string;
|
|
917
|
-
status: ToolCallStatusType;
|
|
918
|
-
extraProps?: MapToDisplayExtraProps;
|
|
919
|
-
expectedStatus: ToolCallStatus;
|
|
920
|
-
expectedResultDisplay?: string;
|
|
921
|
-
expectedName?: string;
|
|
922
|
-
expectedDescription?: string;
|
|
923
|
-
}> = [
|
|
924
|
-
{
|
|
925
|
-
name: 'validating',
|
|
926
|
-
status: 'validating',
|
|
927
|
-
extraProps: { tool: baseTool, invocation: baseInvocation },
|
|
928
|
-
expectedStatus: ToolCallStatus.Executing,
|
|
929
|
-
expectedName: baseTool.displayName,
|
|
930
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
931
|
-
},
|
|
932
|
-
{
|
|
933
|
-
name: 'awaiting_approval',
|
|
934
|
-
status: 'awaiting_approval',
|
|
935
|
-
extraProps: {
|
|
936
|
-
tool: baseTool,
|
|
937
|
-
invocation: baseInvocation,
|
|
938
|
-
confirmationDetails: {
|
|
939
|
-
onConfirm: vi.fn(),
|
|
940
|
-
type: 'edit',
|
|
941
|
-
title: 'Test Tool Display',
|
|
942
|
-
serverName: 'testTool',
|
|
943
|
-
toolName: 'testTool',
|
|
944
|
-
toolDisplayName: 'Test Tool Display',
|
|
945
|
-
filePath: 'mock',
|
|
946
|
-
fileName: 'test.ts',
|
|
947
|
-
fileDiff: 'Test diff',
|
|
948
|
-
originalContent: 'Original content',
|
|
949
|
-
newContent: 'New content',
|
|
950
|
-
} as ToolCallConfirmationDetails,
|
|
951
|
-
},
|
|
952
|
-
expectedStatus: ToolCallStatus.Confirming,
|
|
953
|
-
expectedName: baseTool.displayName,
|
|
954
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
955
|
-
},
|
|
956
|
-
{
|
|
957
|
-
name: 'scheduled',
|
|
958
|
-
status: 'scheduled',
|
|
959
|
-
extraProps: { tool: baseTool, invocation: baseInvocation },
|
|
960
|
-
expectedStatus: ToolCallStatus.Pending,
|
|
961
|
-
expectedName: baseTool.displayName,
|
|
962
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
963
|
-
},
|
|
964
|
-
{
|
|
965
|
-
name: 'executing no live output',
|
|
966
|
-
status: 'executing',
|
|
967
|
-
extraProps: { tool: baseTool, invocation: baseInvocation },
|
|
968
|
-
expectedStatus: ToolCallStatus.Executing,
|
|
969
|
-
expectedName: baseTool.displayName,
|
|
970
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
971
|
-
},
|
|
972
|
-
{
|
|
973
|
-
name: 'executing with live output',
|
|
974
|
-
status: 'executing',
|
|
975
|
-
extraProps: {
|
|
976
|
-
tool: baseTool,
|
|
977
|
-
invocation: baseInvocation,
|
|
978
|
-
liveOutput: 'Live test output',
|
|
979
|
-
},
|
|
980
|
-
expectedStatus: ToolCallStatus.Executing,
|
|
981
|
-
expectedResultDisplay: 'Live test output',
|
|
982
|
-
expectedName: baseTool.displayName,
|
|
983
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
984
|
-
},
|
|
985
|
-
{
|
|
986
|
-
name: 'success',
|
|
987
|
-
status: 'success',
|
|
988
|
-
extraProps: {
|
|
989
|
-
tool: baseTool,
|
|
990
|
-
invocation: baseInvocation,
|
|
991
|
-
response: baseResponse,
|
|
992
|
-
},
|
|
993
|
-
expectedStatus: ToolCallStatus.Success,
|
|
994
|
-
expectedResultDisplay: baseResponse.resultDisplay as any,
|
|
995
|
-
expectedName: baseTool.displayName,
|
|
996
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
997
|
-
},
|
|
998
|
-
{
|
|
999
|
-
name: 'error tool not found',
|
|
1000
|
-
status: 'error',
|
|
1001
|
-
extraProps: {
|
|
1002
|
-
response: {
|
|
1003
|
-
...baseResponse,
|
|
1004
|
-
error: new Error('Test error tool not found'),
|
|
1005
|
-
resultDisplay: 'Error display tool not found',
|
|
1006
|
-
},
|
|
1007
|
-
},
|
|
1008
|
-
expectedStatus: ToolCallStatus.Error,
|
|
1009
|
-
expectedResultDisplay: 'Error display tool not found',
|
|
1010
|
-
expectedName: baseRequest.name,
|
|
1011
|
-
expectedDescription: JSON.stringify(baseRequest.args),
|
|
1012
|
-
},
|
|
1013
|
-
{
|
|
1014
|
-
name: 'error tool execution failed',
|
|
1015
|
-
status: 'error',
|
|
1016
|
-
extraProps: {
|
|
1017
|
-
tool: baseTool,
|
|
1018
|
-
response: {
|
|
1019
|
-
...baseResponse,
|
|
1020
|
-
error: new Error('Tool execution failed'),
|
|
1021
|
-
resultDisplay: 'Execution failed display',
|
|
1022
|
-
},
|
|
1023
|
-
},
|
|
1024
|
-
expectedStatus: ToolCallStatus.Error,
|
|
1025
|
-
expectedResultDisplay: 'Execution failed display',
|
|
1026
|
-
expectedName: baseTool.displayName, // Changed from baseTool.name
|
|
1027
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
name: 'cancelled',
|
|
1031
|
-
status: 'cancelled',
|
|
1032
|
-
extraProps: {
|
|
1033
|
-
tool: baseTool,
|
|
1034
|
-
invocation: baseInvocation,
|
|
1035
|
-
response: {
|
|
1036
|
-
...baseResponse,
|
|
1037
|
-
resultDisplay: 'Cancelled display',
|
|
1038
|
-
},
|
|
1039
|
-
},
|
|
1040
|
-
expectedStatus: ToolCallStatus.Canceled,
|
|
1041
|
-
expectedResultDisplay: 'Cancelled display',
|
|
1042
|
-
expectedName: baseTool.displayName,
|
|
1043
|
-
expectedDescription: baseInvocation.getDescription(),
|
|
1044
|
-
},
|
|
1045
|
-
];
|
|
1046
|
-
|
|
1047
|
-
testCases.forEach(
|
|
1048
|
-
({
|
|
1049
|
-
name: testName,
|
|
1050
|
-
status,
|
|
1051
|
-
extraProps,
|
|
1052
|
-
expectedStatus,
|
|
1053
|
-
expectedResultDisplay,
|
|
1054
|
-
expectedName,
|
|
1055
|
-
expectedDescription,
|
|
1056
|
-
}) => {
|
|
1057
|
-
it(`should map ToolCall with status '${status}' (${testName}) correctly`, () => {
|
|
1058
|
-
const toolCall: ToolCall = {
|
|
1059
|
-
request: baseRequest,
|
|
1060
|
-
status,
|
|
1061
|
-
...(extraProps || {}),
|
|
1062
|
-
} as ToolCall;
|
|
1063
|
-
|
|
1064
|
-
const display = mapToDisplay(toolCall);
|
|
1065
|
-
expect(display.type).toBe('tool_group');
|
|
1066
|
-
expect(display.tools.length).toBe(1);
|
|
1067
|
-
const toolDisplay = display.tools[0];
|
|
1068
|
-
|
|
1069
|
-
expect(toolDisplay.callId).toBe(baseRequest.callId);
|
|
1070
|
-
expect(toolDisplay.status).toBe(expectedStatus);
|
|
1071
|
-
expect(toolDisplay.resultDisplay).toBe(expectedResultDisplay);
|
|
1072
|
-
|
|
1073
|
-
expect(toolDisplay.name).toBe(expectedName);
|
|
1074
|
-
expect(toolDisplay.description).toBe(expectedDescription);
|
|
1075
|
-
|
|
1076
|
-
expect(toolDisplay.renderOutputAsMarkdown).toBe(
|
|
1077
|
-
extraProps?.tool?.isOutputMarkdown ?? false,
|
|
1078
|
-
);
|
|
1079
|
-
if (status === 'awaiting_approval') {
|
|
1080
|
-
expect(toolDisplay.confirmationDetails).toBe(
|
|
1081
|
-
extraProps!.confirmationDetails,
|
|
1082
|
-
);
|
|
1083
|
-
} else {
|
|
1084
|
-
expect(toolDisplay.confirmationDetails).toBeUndefined();
|
|
1085
|
-
}
|
|
1086
|
-
});
|
|
1087
|
-
},
|
|
1088
|
-
);
|
|
1089
|
-
|
|
1090
|
-
it('should map an array of ToolCalls correctly', () => {
|
|
1091
|
-
const toolCall1: ToolCall = {
|
|
1092
|
-
request: { ...baseRequest, callId: 'call1' },
|
|
1093
|
-
status: 'success',
|
|
1094
|
-
tool: baseTool,
|
|
1095
|
-
invocation: baseTool.build(baseRequest.args),
|
|
1096
|
-
response: { ...baseResponse, callId: 'call1' },
|
|
1097
|
-
} as ToolCall;
|
|
1098
|
-
const toolForCall2 = new MockTool(
|
|
1099
|
-
baseTool.name,
|
|
1100
|
-
baseTool.displayName,
|
|
1101
|
-
false,
|
|
1102
|
-
false,
|
|
1103
|
-
true,
|
|
1104
|
-
);
|
|
1105
|
-
const toolCall2: ToolCall = {
|
|
1106
|
-
request: { ...baseRequest, callId: 'call2' },
|
|
1107
|
-
status: 'executing',
|
|
1108
|
-
tool: toolForCall2,
|
|
1109
|
-
invocation: toolForCall2.build(baseRequest.args),
|
|
1110
|
-
liveOutput: 'markdown output',
|
|
1111
|
-
} as ToolCall;
|
|
1112
|
-
|
|
1113
|
-
const display = mapToDisplay([toolCall1, toolCall2]);
|
|
1114
|
-
expect(display.tools.length).toBe(2);
|
|
1115
|
-
expect(display.tools[0].callId).toBe('call1');
|
|
1116
|
-
expect(display.tools[0].status).toBe(ToolCallStatus.Success);
|
|
1117
|
-
expect(display.tools[0].renderOutputAsMarkdown).toBe(false);
|
|
1118
|
-
expect(display.tools[1].callId).toBe('call2');
|
|
1119
|
-
expect(display.tools[1].status).toBe(ToolCallStatus.Executing);
|
|
1120
|
-
expect(display.tools[1].resultDisplay).toBe('markdown output');
|
|
1121
|
-
expect(display.tools[1].renderOutputAsMarkdown).toBe(true);
|
|
1122
|
-
});
|
|
1123
|
-
});
|