@machina.ai/cell-cli 1.41.1-rc2 → 1.45.1-rc2
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 +17 -17
- package/dist/index.js.map +1 -1
- package/dist/package.json +4 -4
- package/dist/src/acp/README.md +81 -0
- package/dist/src/acp/{commandHandler.d.ts → acpCommandHandler.d.ts} +1 -1
- package/dist/src/acp/{commandHandler.js → acpCommandHandler.js} +2 -2
- package/dist/src/acp/acpCommandHandler.js.map +1 -0
- package/dist/src/acp/{commandHandler.test.js → acpCommandHandler.test.js} +4 -5
- package/dist/src/acp/acpCommandHandler.test.js.map +1 -0
- package/dist/src/acp/acpErrors.d.ts +1 -1
- package/dist/src/acp/acpErrors.js +1 -1
- package/dist/src/acp/acpErrors.test.d.ts +1 -1
- package/dist/src/acp/acpErrors.test.js +1 -1
- package/dist/src/acp/{fileSystemService.d.ts → acpFileSystemService.d.ts} +1 -1
- package/dist/src/acp/{fileSystemService.js → acpFileSystemService.js} +7 -4
- package/dist/src/acp/acpFileSystemService.js.map +1 -0
- package/dist/src/acp/{fileSystemService.test.js → acpFileSystemService.test.js} +3 -3
- package/dist/src/acp/acpFileSystemService.test.js.map +1 -0
- package/dist/src/acp/acpResume.test.d.ts +1 -1
- package/dist/src/acp/acpResume.test.js +12 -7
- package/dist/src/acp/acpResume.test.js.map +1 -1
- package/dist/src/acp/acpRpcDispatcher.d.ts +28 -0
- package/dist/src/acp/acpRpcDispatcher.js +177 -0
- package/dist/src/acp/acpRpcDispatcher.js.map +1 -0
- package/dist/src/acp/acpRpcDispatcher.test.d.ts +6 -0
- package/dist/src/acp/acpRpcDispatcher.test.js +238 -0
- package/dist/src/acp/acpRpcDispatcher.test.js.map +1 -0
- package/dist/src/acp/acpSession.d.ts +36 -0
- package/dist/src/acp/{acpClient.js → acpSession.js} +333 -781
- package/dist/src/acp/acpSession.js.map +1 -0
- package/dist/src/acp/acpSession.test.d.ts +6 -0
- package/dist/src/acp/acpSession.test.js +739 -0
- package/dist/src/acp/acpSession.test.js.map +1 -0
- package/dist/src/acp/acpSessionManager.d.ts +30 -0
- package/dist/src/acp/acpSessionManager.js +206 -0
- package/dist/src/acp/acpSessionManager.js.map +1 -0
- package/dist/src/acp/acpSessionManager.test.d.ts +6 -0
- package/dist/src/acp/acpSessionManager.test.js +283 -0
- package/dist/src/acp/acpSessionManager.test.js.map +1 -0
- package/dist/src/acp/acpStdioTransport.d.ts +9 -0
- package/dist/src/acp/acpStdioTransport.js +23 -0
- package/dist/src/acp/acpStdioTransport.js.map +1 -0
- package/dist/src/acp/acpUtils.d.ts +56 -0
- package/dist/src/acp/acpUtils.js +288 -0
- package/dist/src/acp/acpUtils.js.map +1 -0
- package/dist/src/acp/commands/commandRegistry.d.ts +1 -1
- package/dist/src/acp/commands/commandRegistry.js +1 -1
- package/dist/src/acp/commands/extensions.d.ts +1 -1
- package/dist/src/acp/commands/extensions.js +1 -1
- package/dist/src/acp/commands/extensions.test.d.ts +6 -0
- package/dist/src/acp/commands/extensions.test.js +70 -0
- package/dist/src/acp/commands/extensions.test.js.map +1 -0
- package/dist/src/acp/commands/init.d.ts +1 -1
- package/dist/src/acp/commands/init.js +1 -1
- package/dist/src/acp/commands/memory.d.ts +3 -8
- package/dist/src/acp/commands/memory.js +18 -47
- package/dist/src/acp/commands/memory.js.map +1 -1
- package/dist/src/acp/commands/restore.d.ts +1 -1
- package/dist/src/acp/commands/restore.js +1 -1
- package/dist/src/acp/commands/restore.test.js +7 -13
- package/dist/src/acp/commands/restore.test.js.map +1 -1
- package/dist/src/acp/commands/types.d.ts +1 -1
- package/dist/src/acp/commands/types.js +1 -1
- package/dist/src/commands/extensions/configure.test.js +6 -2
- package/dist/src/commands/extensions/configure.test.js.map +1 -1
- package/dist/src/commands/extensions/utils.d.ts +1 -1
- package/dist/src/commands/extensions/utils.js +1 -2
- package/dist/src/commands/extensions/utils.js.map +1 -1
- package/dist/src/commands/mcp/list.js +19 -5
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/commands/mcp/list.test.js +285 -100
- package/dist/src/commands/mcp/list.test.js.map +1 -1
- package/dist/src/config/auth.d.ts +1 -1
- package/dist/src/config/auth.js +4 -3
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/auth.test.js +11 -4
- package/dist/src/config/auth.test.js.map +1 -1
- package/dist/src/config/config.d.ts +4 -0
- package/dist/src/config/config.js +65 -47
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +25 -106
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extension-manager-agents.test.js +2 -0
- package/dist/src/config/extension-manager-agents.test.js.map +1 -1
- package/dist/src/config/extension-manager-hydration.test.js +2 -0
- package/dist/src/config/extension-manager-hydration.test.js.map +1 -1
- package/dist/src/config/extension-manager-scope.test.js +4 -2
- package/dist/src/config/extension-manager-scope.test.js.map +1 -1
- package/dist/src/config/extension-manager-themes.spec.js +2 -0
- package/dist/src/config/extension-manager-themes.spec.js.map +1 -1
- package/dist/src/config/extension-manager.d.ts +2 -2
- package/dist/src/config/extension-manager.js +2 -1
- package/dist/src/config/extension-manager.js.map +1 -1
- package/dist/src/config/extensionRegistryClient.js +0 -1
- package/dist/src/config/extensionRegistryClient.js.map +1 -1
- package/dist/src/config/extensions/consent.d.ts +1 -1
- package/dist/src/config/extensions/consent.js +5 -4
- package/dist/src/config/extensions/consent.js.map +1 -1
- package/dist/src/config/extensions/consent.test.js +22 -0
- package/dist/src/config/extensions/consent.test.js.map +1 -1
- package/dist/src/config/extensions/extensionEnablement.js +4 -2
- package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
- package/dist/src/config/extensions/extensionSettings.d.ts +3 -3
- package/dist/src/config/extensions/extensionSettings.js +7 -3
- package/dist/src/config/extensions/extensionSettings.js.map +1 -1
- package/dist/src/config/extensions/variables.js +1 -3
- package/dist/src/config/extensions/variables.js.map +1 -1
- package/dist/src/config/footerItems.d.ts +4 -0
- package/dist/src/config/footerItems.js +6 -0
- package/dist/src/config/footerItems.js.map +1 -1
- package/dist/src/config/footerItems.test.js +1 -0
- package/dist/src/config/footerItems.test.js.map +1 -1
- package/dist/src/config/mcp/mcpServerEnablement.js +1 -1
- package/dist/src/config/mcp/mcpServerEnablement.js.map +1 -1
- package/dist/src/config/mutual-exclusivity.test.js +33 -0
- package/dist/src/config/mutual-exclusivity.test.js.map +1 -0
- package/dist/src/config/settings-env-isolation.test.d.ts +6 -0
- package/dist/src/config/settings-env-isolation.test.js +188 -0
- package/dist/src/config/settings-env-isolation.test.js.map +1 -0
- package/dist/src/config/settings.d.ts +15 -1
- package/dist/src/config/settings.js +85 -10
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settings.test.js +167 -0
- package/dist/src/config/settings.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +56 -25
- package/dist/src/config/settingsSchema.js +66 -27
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +8 -0
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/config/skipExtensions.test.d.ts +6 -0
- package/dist/src/config/skipExtensions.test.js +49 -0
- package/dist/src/config/skipExtensions.test.js.map +1 -0
- package/dist/src/config/workspace-policy-cli.test.js +0 -5
- package/dist/src/config/workspace-policy-cli.test.js.map +1 -1
- package/dist/src/gemini.d.ts +2 -2
- package/dist/src/gemini.js +108 -30
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +147 -16
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/gemini_cleanup.test.js +1 -1
- package/dist/src/gemini_cleanup.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/interactiveCli.js +1 -1
- package/dist/src/interactiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.d.ts +7 -0
- package/dist/src/nonInteractiveCli.js +56 -6
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +253 -18
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/nonInteractiveCliAgentSession.d.ts +7 -0
- package/dist/src/nonInteractiveCliAgentSession.js +22 -3
- package/dist/src/nonInteractiveCliAgentSession.js.map +1 -1
- package/dist/src/nonInteractiveCliAgentSession.test.js +200 -20
- package/dist/src/nonInteractiveCliAgentSession.test.js.map +1 -1
- package/dist/src/output-redirection.test.d.ts +6 -0
- package/dist/src/output-redirection.test.js +77 -0
- package/dist/src/output-redirection.test.js.map +1 -0
- package/dist/src/patches/http-proxy-agent.d.ts +6 -0
- package/dist/src/patches/http-proxy-agent.js +8 -0
- package/dist/src/patches/http-proxy-agent.js.map +1 -0
- package/dist/src/patches/https-proxy-agent.d.ts +6 -0
- package/dist/src/patches/https-proxy-agent.js +8 -0
- package/dist/src/patches/https-proxy-agent.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.js +5 -1
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.js +6 -1
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
- package/dist/src/services/FileCommandLoader.d.ts +21 -0
- package/dist/src/services/FileCommandLoader.js +58 -6
- package/dist/src/services/FileCommandLoader.js.map +1 -1
- package/dist/src/services/FileCommandLoader.test.js +27 -1
- package/dist/src/services/FileCommandLoader.test.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +6 -1
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/test-utils/mockConfig.js +0 -3
- package/dist/src/test-utils/mockConfig.js.map +1 -1
- package/dist/src/test-utils/render.js +1 -0
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/test-utils/settings.d.ts +1 -0
- package/dist/src/test-utils/settings.js.map +1 -1
- package/dist/src/ui/AppContainer.js +60 -73
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +101 -1
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.js +6 -3
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js +33 -10
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/LoginRestartDialog.d.ts +13 -0
- package/dist/src/ui/auth/{LoginWithGoogleRestartDialog.js → LoginRestartDialog.js} +7 -6
- package/dist/src/ui/auth/LoginRestartDialog.js.map +1 -0
- package/dist/src/ui/auth/LoginRestartDialog.test.d.ts +6 -0
- package/dist/src/ui/auth/{LoginWithGoogleRestartDialog.test.js → LoginRestartDialog.test.js} +13 -8
- package/dist/src/ui/auth/LoginRestartDialog.test.js.map +1 -0
- package/dist/src/ui/auth/useAuth.d.ts +1 -1
- package/dist/src/ui/auth/useAuth.js +2 -2
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/auth/useAuth.test.js +10 -10
- package/dist/src/ui/auth/useAuth.test.js.map +1 -1
- package/dist/src/ui/commands/agentsCommand.js +19 -2
- package/dist/src/ui/commands/agentsCommand.js.map +1 -1
- package/dist/src/ui/commands/agentsCommand.test.js +34 -3
- package/dist/src/ui/commands/agentsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/bugCommand.js +36 -0
- package/dist/src/ui/commands/bugCommand.js.map +1 -1
- package/dist/src/ui/commands/bugCommand.test.js +106 -1
- package/dist/src/ui/commands/bugCommand.test.js.map +1 -1
- package/dist/src/ui/commands/bugMemoryCommand.d.ts +7 -0
- package/dist/src/ui/commands/bugMemoryCommand.js +62 -0
- package/dist/src/ui/commands/bugMemoryCommand.js.map +1 -0
- package/dist/src/ui/commands/bugMemoryCommand.test.js +100 -0
- package/dist/src/ui/commands/bugMemoryCommand.test.js.map +1 -0
- package/dist/src/ui/commands/commandsCommand.js +52 -4
- package/dist/src/ui/commands/commandsCommand.js.map +1 -1
- package/dist/src/ui/commands/commandsCommand.test.js +75 -2
- package/dist/src/ui/commands/commandsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/compressCommand.js +28 -26
- package/dist/src/ui/commands/compressCommand.js.map +1 -1
- package/dist/src/ui/commands/compressCommand.test.js +5 -0
- package/dist/src/ui/commands/compressCommand.test.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +2 -2
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.test.js +1 -0
- package/dist/src/ui/commands/directoryCommand.test.js.map +1 -1
- package/dist/src/ui/commands/exportSessionCommand.d.ts +7 -0
- package/dist/src/ui/commands/exportSessionCommand.js +74 -0
- package/dist/src/ui/commands/exportSessionCommand.js.map +1 -0
- package/dist/src/ui/commands/exportSessionCommand.test.js +100 -0
- package/dist/src/ui/commands/exportSessionCommand.test.js.map +1 -0
- package/dist/src/ui/commands/extensionsCommand.js +1 -0
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.test.js +4 -0
- package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.d.ts +2 -1
- package/dist/src/ui/commands/memoryCommand.js +110 -117
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.test.js +18 -71
- package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
- package/dist/src/ui/commands/quitCommand.js +3 -1
- package/dist/src/ui/commands/quitCommand.js.map +1 -1
- package/dist/src/ui/commands/quitCommand.test.js +46 -1
- package/dist/src/ui/commands/quitCommand.test.js.map +1 -1
- package/dist/src/ui/commands/rewindCommand.js.map +1 -1
- package/dist/src/ui/commands/skillsCommand.js +1 -1
- package/dist/src/ui/commands/skillsCommand.js.map +1 -1
- package/dist/src/ui/commands/skillsCommand.test.js +19 -0
- package/dist/src/ui/commands/skillsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +3 -1
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/AsciiArt.d.ts +6 -6
- package/dist/src/ui/components/AsciiArt.js +6 -6
- package/dist/src/ui/components/AskUserDialog.js +3 -1
- package/dist/src/ui/components/AskUserDialog.js.map +1 -1
- package/dist/src/ui/components/AskUserDialog.test.js +43 -0
- package/dist/src/ui/components/AskUserDialog.test.js.map +1 -1
- package/dist/src/ui/components/Composer.js +1 -1
- package/dist/src/ui/components/Composer.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +4 -0
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/EditorSettingsDialog.js +3 -6
- package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
- package/dist/src/ui/components/Footer.js +6 -0
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/FooterConfigDialog.js +1 -0
- package/dist/src/ui/components/FooterConfigDialog.js.map +1 -1
- package/dist/src/ui/components/FooterConfigDialog.test.js +1 -1
- package/dist/src/ui/components/FooterConfigDialog.test.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +3 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.js +15 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
- package/dist/src/ui/components/{SkillInboxDialog.d.ts → InboxDialog.d.ts} +3 -2
- package/dist/src/ui/components/InboxDialog.js +756 -0
- package/dist/src/ui/components/InboxDialog.js.map +1 -0
- package/dist/src/ui/components/InboxDialog.test.d.ts +6 -0
- package/dist/src/ui/components/InboxDialog.test.js +824 -0
- package/dist/src/ui/components/InboxDialog.test.js.map +1 -0
- package/dist/src/ui/components/InputPrompt.d.ts +3 -0
- package/dist/src/ui/components/InputPrompt.js +35 -17
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.test.js +95 -46
- package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
- package/dist/src/ui/components/ListeningIndicator.d.ts +10 -0
- package/dist/src/ui/components/ListeningIndicator.js +30 -0
- package/dist/src/ui/components/ListeningIndicator.js.map +1 -0
- package/dist/src/ui/components/MainContent.test.js +23 -3
- package/dist/src/ui/components/MainContent.test.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.js +32 -37
- package/dist/src/ui/components/ModelDialog.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.test.js +30 -27
- package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.js +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js +41 -0
- package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SessionBrowser.js +7 -0
- package/dist/src/ui/components/SessionBrowser.js.map +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.js +9 -4
- package/dist/src/ui/components/SessionSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js +12 -23
- package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.js +37 -17
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +83 -1
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.js +2 -2
- package/dist/src/ui/components/StatsDisplay.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js +24 -0
- package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.constants.d.ts +26 -0
- package/dist/src/ui/components/ThemeDialog.constants.js +27 -0
- package/dist/src/ui/components/ThemeDialog.constants.js.map +1 -0
- package/dist/src/ui/components/ThemeDialog.js +5 -15
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/ToolConfirmationQueue.test.js +1 -1
- package/dist/src/ui/components/ToolConfirmationQueue.test.js.map +1 -1
- package/dist/src/ui/components/VoiceModelDialog.js +7 -2
- package/dist/src/ui/components/VoiceModelDialog.js.map +1 -1
- package/dist/src/ui/components/VoiceModelDialog.test.d.ts +6 -0
- package/dist/src/ui/components/VoiceModelDialog.test.js +68 -0
- package/dist/src/ui/components/VoiceModelDialog.test.js.map +1 -0
- package/dist/src/ui/components/messages/ExportSessionMessage.d.ts +11 -0
- package/dist/src/ui/components/messages/ExportSessionMessage.js +15 -0
- package/dist/src/ui/components/messages/ExportSessionMessage.js.map +1 -0
- package/dist/src/ui/components/messages/ExportSessionMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ExportSessionMessage.test.js +31 -0
- package/dist/src/ui/components/messages/ExportSessionMessage.test.js.map +1 -0
- package/dist/src/ui/components/messages/ShellToolMessage.js +6 -2
- package/dist/src/ui/components/messages/ShellToolMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ShellToolMessage.test.js +33 -0
- package/dist/src/ui/components/messages/ShellToolMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/SubagentGroupDisplay.js +13 -13
- package/dist/src/ui/components/messages/SubagentGroupDisplay.js.map +1 -1
- package/dist/src/ui/components/messages/SubagentGroupDisplay.test.js +5 -5
- package/dist/src/ui/components/messages/SubagentGroupDisplay.test.js.map +1 -1
- package/dist/src/ui/components/messages/SubagentHistoryMessage.test.js +4 -3
- package/dist/src/ui/components/messages/SubagentHistoryMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/SubagentProgressDisplay.d.ts +1 -1
- package/dist/src/ui/components/messages/SubagentProgressDisplay.js +7 -6
- package/dist/src/ui/components/messages/SubagentProgressDisplay.js.map +1 -1
- package/dist/src/ui/components/messages/SubagentProgressDisplay.test.js +10 -9
- package/dist/src/ui/components/messages/SubagentProgressDisplay.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +3 -9
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +60 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupDisplay.d.ts +13 -0
- package/dist/src/ui/components/messages/ToolGroupDisplay.js +78 -0
- package/dist/src/ui/components/messages/ToolGroupDisplay.js.map +1 -0
- package/dist/src/ui/components/messages/ToolGroupDisplay.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolGroupDisplay.test.js +210 -0
- package/dist/src/ui/components/messages/ToolGroupDisplay.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.js +4 -2
- package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +28 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.js +3 -3
- package/dist/src/ui/components/messages/ToolGroupMessageRegression.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolMessage.js +6 -2
- package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolShared.d.ts +1 -0
- package/dist/src/ui/components/messages/ToolShared.js +5 -3
- package/dist/src/ui/components/messages/ToolShared.js.map +1 -1
- package/dist/src/ui/components/messages/ToolShared.test.js +18 -1
- package/dist/src/ui/components/messages/ToolShared.test.js.map +1 -1
- package/dist/src/ui/components/shared/BaseSettingsDialog.d.ts +6 -1
- package/dist/src/ui/components/shared/BaseSettingsDialog.js +8 -8
- package/dist/src/ui/components/shared/BaseSettingsDialog.js.map +1 -1
- package/dist/src/ui/components/shared/performance.test.js +9 -0
- package/dist/src/ui/components/shared/performance.test.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.js +22 -5
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +211 -0
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/constants/tips.js +0 -1
- package/dist/src/ui/constants/tips.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +1 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +78 -69
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +128 -18
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +13 -0
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.test.js +85 -0
- package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/useAgentStream.d.ts +2 -2
- package/dist/src/ui/hooks/useAgentStream.js +63 -30
- package/dist/src/ui/hooks/useAgentStream.js.map +1 -1
- package/dist/src/ui/hooks/useAgentStream.test.js +1 -1
- package/dist/src/ui/hooks/useAgentStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.js +0 -2
- package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -2
- package/dist/src/ui/hooks/useGeminiStream.js +48 -29
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +44 -82
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.js +29 -16
- package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.js +102 -51
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
- package/dist/src/ui/hooks/useIncludeDirsTrust.js +2 -2
- package/dist/src/ui/hooks/useIncludeDirsTrust.js.map +1 -1
- package/dist/src/ui/hooks/useIncludeDirsTrust.test.js +2 -0
- package/dist/src/ui/hooks/useIncludeDirsTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.d.ts +2 -1
- package/dist/src/ui/hooks/useMessageQueue.js +3 -1
- package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.test.js +38 -0
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
- package/dist/src/ui/hooks/useSessionBrowser.d.ts +3 -3
- package/dist/src/ui/hooks/useSessionBrowser.js.map +1 -1
- package/dist/src/ui/hooks/useSessionBrowser.test.js +44 -38
- package/dist/src/ui/hooks/useSessionBrowser.test.js.map +1 -1
- package/dist/src/ui/hooks/useSessionResume.d.ts +3 -3
- package/dist/src/ui/hooks/useSessionResume.js.map +1 -1
- package/dist/src/ui/hooks/useSessionResume.test.js +6 -4
- package/dist/src/ui/hooks/useSessionResume.test.js.map +1 -1
- package/dist/src/ui/hooks/useSuspend.d.ts +1 -3
- package/dist/src/ui/hooks/useSuspend.js +3 -17
- package/dist/src/ui/hooks/useSuspend.js.map +1 -1
- package/dist/src/ui/hooks/useSuspend.test.js +0 -14
- package/dist/src/ui/hooks/useSuspend.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +6 -6
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/hooks/useVoiceMode.js +25 -19
- package/dist/src/ui/hooks/useVoiceMode.js.map +1 -1
- package/dist/src/ui/hooks/vim-passthrough.test.js +10 -0
- package/dist/src/ui/hooks/vim-passthrough.test.js.map +1 -1
- package/dist/src/ui/hooks/vim.js +8 -0
- package/dist/src/ui/hooks/vim.js.map +1 -1
- package/dist/src/ui/hooks/vim.test.js +61 -0
- package/dist/src/ui/hooks/vim.test.js.map +1 -1
- package/dist/src/ui/key/keyBindings.d.ts +2 -0
- package/dist/src/ui/key/keyBindings.js +26 -9
- package/dist/src/ui/key/keyBindings.js.map +1 -1
- package/dist/src/ui/key/keyBindings.test.js +24 -0
- package/dist/src/ui/key/keyBindings.test.js.map +1 -1
- package/dist/src/ui/key/keyMatchers.test.js +26 -5
- package/dist/src/ui/key/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.js +0 -2
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/types.d.ts +23 -2
- package/dist/src/ui/types.js +3 -2
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/TableRenderer.js +6 -6
- package/dist/src/ui/utils/TableRenderer.js.map +1 -1
- package/dist/src/ui/utils/TableRenderer.test.js +10 -0
- package/dist/src/ui/utils/TableRenderer.test.js.map +1 -1
- package/dist/src/ui/utils/directoryUtils.test.js +0 -5
- package/dist/src/ui/utils/directoryUtils.test.js.map +1 -1
- package/dist/src/ui/utils/editorUtils.d.ts +2 -1
- package/dist/src/ui/utils/editorUtils.js +75 -28
- package/dist/src/ui/utils/editorUtils.js.map +1 -1
- package/dist/src/ui/utils/latexToUnicode.d.ts +21 -0
- package/dist/src/ui/utils/latexToUnicode.js +538 -0
- package/dist/src/ui/utils/latexToUnicode.js.map +1 -0
- package/dist/src/ui/utils/latexToUnicode.test.d.ts +6 -0
- package/dist/src/ui/utils/latexToUnicode.test.js +222 -0
- package/dist/src/ui/utils/latexToUnicode.test.js.map +1 -0
- package/dist/src/ui/utils/markdownParsingUtils.d.ts +1 -5
- package/dist/src/ui/utils/markdownParsingUtils.js +36 -1
- package/dist/src/ui/utils/markdownParsingUtils.js.map +1 -1
- package/dist/src/ui/utils/markdownParsingUtils.test.js +35 -0
- package/dist/src/ui/utils/markdownParsingUtils.test.js.map +1 -1
- package/dist/src/ui/utils/memorySnapshot.d.ts +19 -0
- package/dist/src/ui/utils/memorySnapshot.js +28 -0
- package/dist/src/ui/utils/memorySnapshot.js.map +1 -0
- package/dist/src/ui/utils/memorySnapshot.test.d.ts +6 -0
- package/dist/src/ui/utils/memorySnapshot.test.js +62 -0
- package/dist/src/ui/utils/memorySnapshot.test.js.map +1 -0
- package/dist/src/ui/utils/updateCheck.js +11 -2
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.js +73 -0
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
- package/dist/src/utils/commands.d.ts +1 -1
- package/dist/src/utils/commands.js +1 -1
- package/dist/src/utils/commands.test.js +14 -14
- package/dist/src/utils/commands.test.js.map +1 -1
- package/dist/src/utils/envVarResolver.js +10 -7
- package/dist/src/utils/envVarResolver.js.map +1 -1
- package/dist/src/utils/gitUtils.js +1 -2
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.d.ts +1 -1
- package/dist/src/utils/handleAutoUpdate.js +15 -3
- package/dist/src/utils/handleAutoUpdate.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.test.js +45 -16
- package/dist/src/utils/handleAutoUpdate.test.js.map +1 -1
- package/dist/src/utils/installationInfo.d.ts +1 -0
- package/dist/src/utils/installationInfo.js +16 -1
- package/dist/src/utils/installationInfo.js.map +1 -1
- package/dist/src/utils/installationInfo.test.js +16 -0
- package/dist/src/utils/installationInfo.test.js.map +1 -1
- package/dist/src/utils/jsonoutput.js +0 -2
- package/dist/src/utils/jsonoutput.js.map +1 -1
- package/dist/src/utils/processUtils.d.ts +28 -0
- package/dist/src/utils/processUtils.js +71 -0
- package/dist/src/utils/processUtils.js.map +1 -1
- package/dist/src/utils/processUtils.test.js +122 -1
- package/dist/src/utils/processUtils.test.js.map +1 -1
- package/dist/src/utils/readStdin.js +22 -4
- package/dist/src/utils/readStdin.js.map +1 -1
- package/dist/src/utils/readStdin.test.js +32 -0
- package/dist/src/utils/readStdin.test.js.map +1 -1
- package/dist/src/utils/relaunch.js +6 -13
- package/dist/src/utils/relaunch.js.map +1 -1
- package/dist/src/utils/relaunch.test.js +82 -86
- package/dist/src/utils/relaunch.test.js.map +1 -1
- package/dist/src/utils/sandbox.js +34 -24
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/sandbox.test.js +108 -9
- package/dist/src/utils/sandbox.test.js.map +1 -1
- package/dist/src/utils/sandboxUtils.js +12 -7
- package/dist/src/utils/sandboxUtils.js.map +1 -1
- package/dist/src/utils/sandboxUtils.test.js +68 -0
- package/dist/src/utils/sandboxUtils.test.js.map +1 -1
- package/dist/src/utils/sessionCleanup.js +49 -14
- package/dist/src/utils/sessionCleanup.js.map +1 -1
- package/dist/src/utils/sessionCleanup.test.js +63 -0
- package/dist/src/utils/sessionCleanup.test.js.map +1 -1
- package/dist/src/utils/sessionUtils.js +22 -7
- package/dist/src/utils/sessionUtils.js.map +1 -1
- package/dist/src/utils/sessionUtils.test.js +99 -0
- package/dist/src/utils/sessionUtils.test.js.map +1 -1
- package/dist/src/utils/sessions.js +2 -4
- package/dist/src/utils/sessions.js.map +1 -1
- package/dist/src/utils/sessions.test.js +9 -12
- package/dist/src/utils/sessions.test.js.map +1 -1
- package/dist/src/utils/userStartupWarnings.js +4 -3
- package/dist/src/utils/userStartupWarnings.js.map +1 -1
- package/dist/src/utils/userStartupWarnings.test.js +40 -3
- package/dist/src/utils/userStartupWarnings.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +1 -1
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/src/acp/acpClient.d.ts +0 -56
- package/dist/src/acp/acpClient.js.map +0 -1
- package/dist/src/acp/acpClient.test.js +0 -1816
- package/dist/src/acp/acpClient.test.js.map +0 -1
- package/dist/src/acp/commandHandler.js.map +0 -1
- package/dist/src/acp/commandHandler.test.js.map +0 -1
- package/dist/src/acp/fileSystemService.js.map +0 -1
- package/dist/src/acp/fileSystemService.test.js.map +0 -1
- package/dist/src/ui/auth/LoginWithGoogleRestartDialog.d.ts +0 -12
- package/dist/src/ui/auth/LoginWithGoogleRestartDialog.js.map +0 -1
- package/dist/src/ui/auth/LoginWithGoogleRestartDialog.test.js.map +0 -1
- package/dist/src/ui/components/SkillInboxDialog.js +0 -420
- package/dist/src/ui/components/SkillInboxDialog.js.map +0 -1
- package/dist/src/ui/components/SkillInboxDialog.test.js +0 -467
- package/dist/src/ui/components/SkillInboxDialog.test.js.map +0 -1
- /package/dist/src/acp/{commandHandler.test.d.ts → acpCommandHandler.test.d.ts} +0 -0
- /package/dist/src/{ui/components/SkillInboxDialog.test.d.ts → acp/acpFileSystemService.test.d.ts} +0 -0
- /package/dist/src/{acp/acpClient.test.d.ts → config/mutual-exclusivity.test.d.ts} +0 -0
- /package/dist/src/{acp/fileSystemService.test.d.ts → ui/commands/bugMemoryCommand.test.d.ts} +0 -0
- /package/dist/src/ui/{auth/LoginWithGoogleRestartDialog.test.d.ts → commands/exportSessionCommand.test.d.ts} +0 -0
|
@@ -1,359 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { CoreToolCallStatus,
|
|
6
|
+
import { CoreToolCallStatus, coreEvents, CoreEvent, logToolCall, convertToFunctionResponse, ToolConfirmationOutcome, getErrorStatus, DiscoveredMCPTool, ToolCallEvent, debugLogger, ReadManyFilesTool, partListUnionToString, updatePolicy, getErrorMessage, isTextPart, GeminiEventType, isWithinRoot, processSingleFileContent, isNodeError, REFERENCE_CONTENT_START, InvalidStreamError, MessageBusType, PolicyDecision, resolveAtCommandPath, } from '@google/gemini-cli-core';
|
|
7
7
|
import * as acp from '@agentclientprotocol/sdk';
|
|
8
|
-
import { AcpFileSystemService } from './fileSystemService.js';
|
|
9
|
-
import { getAcpErrorMessage } from './acpErrors.js';
|
|
10
|
-
import { Readable, Writable } from 'node:stream';
|
|
11
|
-
function hasMeta(obj) {
|
|
12
|
-
return typeof obj === 'object' && obj !== null && '_meta' in obj;
|
|
13
|
-
}
|
|
14
|
-
import { SettingScope, loadSettings, } from '../config/settings.js';
|
|
15
|
-
import { createPolicyUpdater } from '../config/policy.js';
|
|
16
8
|
import * as fs from 'node:fs/promises';
|
|
17
9
|
import * as path from 'node:path';
|
|
18
|
-
import { z } from 'zod';
|
|
19
10
|
import { randomUUID } from 'node:crypto';
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
z.object({ outcome: z.literal('cancelled') }),
|
|
28
|
-
z.object({
|
|
29
|
-
outcome: z.literal('selected'),
|
|
30
|
-
optionId: z.string(),
|
|
31
|
-
}),
|
|
32
|
-
]),
|
|
11
|
+
import { CommandHandler } from './acpCommandHandler.js';
|
|
12
|
+
import { toToolCallContent, toPermissionOptions, toAcpToolKind, buildAvailableModes, RequestPermissionResponseSchema, } from './acpUtils.js';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { getAcpErrorMessage } from './acpErrors.js';
|
|
15
|
+
const StructuredErrorSchema = z.object({
|
|
16
|
+
status: z.number().optional(),
|
|
17
|
+
message: z.string().optional(),
|
|
33
18
|
});
|
|
34
|
-
export async function runAcpClient(config, settings, argv) {
|
|
35
|
-
// ... (skip unchanged lines) ...
|
|
36
|
-
const { stdout: workingStdout } = createWorkingStdio();
|
|
37
|
-
const stdout = Writable.toWeb(workingStdout);
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
39
|
-
const stdin = Readable.toWeb(process.stdin);
|
|
40
|
-
const stream = acp.ndJsonStream(stdout, stdin);
|
|
41
|
-
const connection = new acp.AgentSideConnection((connection) => new GeminiAgent(config, settings, argv, connection), stream);
|
|
42
|
-
// SIGTERM/SIGINT handlers (in sdk.ts) don't fire when stdin closes.
|
|
43
|
-
// We must explicitly await the connection close to flush telemetry.
|
|
44
|
-
// Use finally() to ensure cleanup runs even on stream errors.
|
|
45
|
-
await connection.closed.finally(runExitCleanup);
|
|
46
|
-
}
|
|
47
|
-
export class GeminiAgent {
|
|
48
|
-
context;
|
|
49
|
-
settings;
|
|
50
|
-
argv;
|
|
51
|
-
connection;
|
|
52
|
-
static callIdCounter = 0;
|
|
53
|
-
static generateCallId(name) {
|
|
54
|
-
return `${name}-${Date.now()}-${++GeminiAgent.callIdCounter}`;
|
|
55
|
-
}
|
|
56
|
-
sessions = new Map();
|
|
57
|
-
clientCapabilities;
|
|
58
|
-
apiKey;
|
|
59
|
-
baseUrl;
|
|
60
|
-
customHeaders;
|
|
61
|
-
constructor(context, settings, argv, connection) {
|
|
62
|
-
this.context = context;
|
|
63
|
-
this.settings = settings;
|
|
64
|
-
this.argv = argv;
|
|
65
|
-
this.connection = connection;
|
|
66
|
-
}
|
|
67
|
-
async initialize(args) {
|
|
68
|
-
this.clientCapabilities = args.clientCapabilities;
|
|
69
|
-
const authMethods = [
|
|
70
|
-
{
|
|
71
|
-
id: AuthType.KEYCLOAK,
|
|
72
|
-
name: 'Cell SSO',
|
|
73
|
-
description: "Log in via your organization's single sign-on (Keycloak)",
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
id: AuthType.LOGIN_WITH_GOOGLE,
|
|
77
|
-
name: 'Log in with Google',
|
|
78
|
-
description: 'Log in with your Google account',
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
id: AuthType.USE_GEMINI,
|
|
82
|
-
name: 'Gemini API key',
|
|
83
|
-
description: 'Use an API key with Gemini Developer API',
|
|
84
|
-
_meta: {
|
|
85
|
-
'api-key': {
|
|
86
|
-
provider: 'google',
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
id: AuthType.USE_VERTEX_AI,
|
|
92
|
-
name: 'Vertex AI',
|
|
93
|
-
description: 'Use an API key with Vertex AI GenAI API',
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: AuthType.GATEWAY,
|
|
97
|
-
name: 'AI API Gateway',
|
|
98
|
-
description: 'Use a custom AI API Gateway',
|
|
99
|
-
_meta: {
|
|
100
|
-
gateway: {
|
|
101
|
-
protocol: 'google',
|
|
102
|
-
restartRequired: 'false',
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
];
|
|
107
|
-
await this.context.config.initialize();
|
|
108
|
-
const version = await getVersion();
|
|
109
|
-
return {
|
|
110
|
-
protocolVersion: acp.PROTOCOL_VERSION,
|
|
111
|
-
authMethods,
|
|
112
|
-
agentInfo: {
|
|
113
|
-
name: 'gemini-cli',
|
|
114
|
-
title: 'Cell CLI',
|
|
115
|
-
version,
|
|
116
|
-
},
|
|
117
|
-
agentCapabilities: {
|
|
118
|
-
loadSession: true,
|
|
119
|
-
promptCapabilities: {
|
|
120
|
-
image: true,
|
|
121
|
-
audio: true,
|
|
122
|
-
embeddedContext: true,
|
|
123
|
-
},
|
|
124
|
-
mcpCapabilities: {
|
|
125
|
-
http: true,
|
|
126
|
-
sse: true,
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
async authenticate(req) {
|
|
132
|
-
const { methodId } = req;
|
|
133
|
-
const method = z.nativeEnum(AuthType).parse(methodId);
|
|
134
|
-
const selectedAuthType = this.settings.merged.security.auth.selectedType;
|
|
135
|
-
// Only clear credentials when switching to a different auth method
|
|
136
|
-
if (selectedAuthType && selectedAuthType !== method) {
|
|
137
|
-
await clearCachedCredentialFile();
|
|
138
|
-
}
|
|
139
|
-
// Check for api-key in _meta
|
|
140
|
-
const meta = hasMeta(req) ? req._meta : undefined;
|
|
141
|
-
const apiKey = typeof meta?.['api-key'] === 'string' ? meta['api-key'] : undefined;
|
|
142
|
-
// Refresh auth with the requested method
|
|
143
|
-
// This will reuse existing credentials if they're valid,
|
|
144
|
-
// or perform new authentication if needed
|
|
145
|
-
try {
|
|
146
|
-
if (apiKey) {
|
|
147
|
-
this.apiKey = apiKey;
|
|
148
|
-
}
|
|
149
|
-
// Extract gateway details if present
|
|
150
|
-
const gatewaySchema = z.object({
|
|
151
|
-
baseUrl: z.string().optional(),
|
|
152
|
-
headers: z.record(z.string()).optional(),
|
|
153
|
-
});
|
|
154
|
-
let baseUrl;
|
|
155
|
-
let headers;
|
|
156
|
-
if (meta?.['gateway']) {
|
|
157
|
-
const result = gatewaySchema.safeParse(meta['gateway']);
|
|
158
|
-
if (result.success) {
|
|
159
|
-
baseUrl = result.data.baseUrl;
|
|
160
|
-
headers = result.data.headers;
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
throw new acp.RequestError(-32602, `Malformed gateway payload: ${result.error.message}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
this.baseUrl = baseUrl;
|
|
167
|
-
this.customHeaders = headers;
|
|
168
|
-
await this.context.config.refreshAuth(method, (msg) => {
|
|
169
|
-
process.stderr.write(`${msg}\n`);
|
|
170
|
-
}, apiKey ?? this.apiKey, baseUrl, headers);
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
throw new acp.RequestError(-32000, getAcpErrorMessage(e));
|
|
174
|
-
}
|
|
175
|
-
this.settings.setValue(SettingScope.User, 'security.auth.selectedType', method);
|
|
176
|
-
}
|
|
177
|
-
async newSession({ cwd, mcpServers, }) {
|
|
178
|
-
const sessionId = randomUUID();
|
|
179
|
-
const loadedSettings = loadSettings(cwd);
|
|
180
|
-
const config = await this.newSessionConfig(sessionId, cwd, mcpServers, loadedSettings);
|
|
181
|
-
const authType = loadedSettings.merged.security.auth.selectedType || AuthType.USE_GEMINI;
|
|
182
|
-
let isAuthenticated = false;
|
|
183
|
-
let authErrorMessage = '';
|
|
184
|
-
try {
|
|
185
|
-
await config.refreshAuth(authType, undefined, this.apiKey, this.baseUrl, this.customHeaders);
|
|
186
|
-
isAuthenticated = true;
|
|
187
|
-
// Extra validation for Gemini API key
|
|
188
|
-
const contentGeneratorConfig = config.getContentGeneratorConfig();
|
|
189
|
-
if (authType === AuthType.USE_GEMINI &&
|
|
190
|
-
(!contentGeneratorConfig || !contentGeneratorConfig.apiKey)) {
|
|
191
|
-
isAuthenticated = false;
|
|
192
|
-
authErrorMessage = 'Gemini API key is missing or not configured.';
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
catch (e) {
|
|
196
|
-
isAuthenticated = false;
|
|
197
|
-
authErrorMessage = getAcpErrorMessage(e);
|
|
198
|
-
debugLogger.error(`Authentication failed: ${e instanceof Error ? e.stack : e}`);
|
|
199
|
-
}
|
|
200
|
-
if (!isAuthenticated) {
|
|
201
|
-
throw new acp.RequestError(-32000, authErrorMessage || 'Authentication required.');
|
|
202
|
-
}
|
|
203
|
-
if (this.clientCapabilities?.fs) {
|
|
204
|
-
const acpFileSystemService = new AcpFileSystemService(this.connection, sessionId, this.clientCapabilities.fs, config.getFileSystemService(), cwd);
|
|
205
|
-
config.setFileSystemService(acpFileSystemService);
|
|
206
|
-
}
|
|
207
|
-
await config.initialize();
|
|
208
|
-
startupProfiler.flush(config);
|
|
209
|
-
startAutoMemoryIfEnabled(config);
|
|
210
|
-
const geminiClient = config.getGeminiClient();
|
|
211
|
-
const chat = await geminiClient.startChat();
|
|
212
|
-
const session = new Session(sessionId, chat, config, this.connection, this.settings);
|
|
213
|
-
this.sessions.set(sessionId, session);
|
|
214
|
-
setTimeout(() => {
|
|
215
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
216
|
-
session.sendAvailableCommands();
|
|
217
|
-
}, 0);
|
|
218
|
-
const { availableModels, currentModelId } = buildAvailableModels(config, loadedSettings);
|
|
219
|
-
const response = {
|
|
220
|
-
sessionId,
|
|
221
|
-
modes: {
|
|
222
|
-
availableModes: buildAvailableModes(config.isPlanEnabled()),
|
|
223
|
-
currentModeId: config.getApprovalMode(),
|
|
224
|
-
},
|
|
225
|
-
models: {
|
|
226
|
-
availableModels,
|
|
227
|
-
currentModelId,
|
|
228
|
-
},
|
|
229
|
-
};
|
|
230
|
-
return response;
|
|
231
|
-
}
|
|
232
|
-
async loadSession({ sessionId, cwd, mcpServers, }) {
|
|
233
|
-
const config = await this.initializeSessionConfig(sessionId, cwd, mcpServers);
|
|
234
|
-
const sessionSelector = new SessionSelector(config.storage);
|
|
235
|
-
const { sessionData, sessionPath } = await sessionSelector.resolveSession(sessionId);
|
|
236
|
-
const clientHistory = convertSessionToClientHistory(sessionData.messages);
|
|
237
|
-
const geminiClient = config.getGeminiClient();
|
|
238
|
-
await geminiClient.initialize();
|
|
239
|
-
await geminiClient.resumeChat(clientHistory, {
|
|
240
|
-
conversation: sessionData,
|
|
241
|
-
filePath: sessionPath,
|
|
242
|
-
});
|
|
243
|
-
const session = new Session(sessionId, geminiClient.getChat(), config, this.connection, this.settings);
|
|
244
|
-
this.sessions.set(sessionId, session);
|
|
245
|
-
// Stream history back to client
|
|
246
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
247
|
-
session.streamHistory(sessionData.messages);
|
|
248
|
-
setTimeout(() => {
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
250
|
-
session.sendAvailableCommands();
|
|
251
|
-
}, 0);
|
|
252
|
-
const { availableModels, currentModelId } = buildAvailableModels(config, this.settings);
|
|
253
|
-
const response = {
|
|
254
|
-
modes: {
|
|
255
|
-
availableModes: buildAvailableModes(config.isPlanEnabled()),
|
|
256
|
-
currentModeId: config.getApprovalMode(),
|
|
257
|
-
},
|
|
258
|
-
models: {
|
|
259
|
-
availableModels,
|
|
260
|
-
currentModelId,
|
|
261
|
-
},
|
|
262
|
-
};
|
|
263
|
-
return response;
|
|
264
|
-
}
|
|
265
|
-
async initializeSessionConfig(sessionId, cwd, mcpServers) {
|
|
266
|
-
const selectedAuthType = this.settings.merged.security.auth.selectedType;
|
|
267
|
-
if (!selectedAuthType) {
|
|
268
|
-
throw acp.RequestError.authRequired();
|
|
269
|
-
}
|
|
270
|
-
// 1. Create config WITHOUT initializing it (no MCP servers started yet)
|
|
271
|
-
const config = await this.newSessionConfig(sessionId, cwd, mcpServers);
|
|
272
|
-
// 2. Authenticate BEFORE initializing configuration or starting MCP servers.
|
|
273
|
-
// This satisfies the security requirement to verify the user before executing
|
|
274
|
-
// potentially unsafe server definitions.
|
|
275
|
-
try {
|
|
276
|
-
await config.refreshAuth(selectedAuthType, undefined, this.apiKey, this.baseUrl, this.customHeaders);
|
|
277
|
-
}
|
|
278
|
-
catch (e) {
|
|
279
|
-
debugLogger.error(`Authentication failed: ${e}`);
|
|
280
|
-
throw acp.RequestError.authRequired();
|
|
281
|
-
}
|
|
282
|
-
// 3. Set the ACP FileSystemService (if supported) before config initialization
|
|
283
|
-
if (this.clientCapabilities?.fs) {
|
|
284
|
-
const acpFileSystemService = new AcpFileSystemService(this.connection, sessionId, this.clientCapabilities.fs, config.getFileSystemService(), cwd);
|
|
285
|
-
config.setFileSystemService(acpFileSystemService);
|
|
286
|
-
}
|
|
287
|
-
// 4. Now that we are authenticated, it is safe to initialize the config
|
|
288
|
-
// which starts the MCP servers and other heavy resources.
|
|
289
|
-
await config.initialize();
|
|
290
|
-
startupProfiler.flush(config);
|
|
291
|
-
startAutoMemoryIfEnabled(config);
|
|
292
|
-
return config;
|
|
293
|
-
}
|
|
294
|
-
async newSessionConfig(sessionId, cwd, mcpServers, loadedSettings) {
|
|
295
|
-
const currentSettings = loadedSettings || this.settings;
|
|
296
|
-
const mergedMcpServers = { ...currentSettings.merged.mcpServers };
|
|
297
|
-
for (const server of mcpServers) {
|
|
298
|
-
if ('type' in server &&
|
|
299
|
-
(server.type === 'sse' || server.type === 'http')) {
|
|
300
|
-
// HTTP or SSE MCP server
|
|
301
|
-
const headers = Object.fromEntries(server.headers.map(({ name, value }) => [name, value]));
|
|
302
|
-
mergedMcpServers[server.name] = new MCPServerConfig(undefined, // command
|
|
303
|
-
undefined, // args
|
|
304
|
-
undefined, // env
|
|
305
|
-
undefined, // cwd
|
|
306
|
-
server.type === 'sse', // isSse
|
|
307
|
-
server.type === 'sse' ? server.url : undefined, // url (sse)
|
|
308
|
-
server.type === 'http' ? server.url : undefined, // httpUrl
|
|
309
|
-
headers);
|
|
310
|
-
}
|
|
311
|
-
else if ('command' in server) {
|
|
312
|
-
// Stdio MCP server
|
|
313
|
-
const env = {};
|
|
314
|
-
for (const { name: envName, value } of server.env) {
|
|
315
|
-
env[envName] = value;
|
|
316
|
-
}
|
|
317
|
-
mergedMcpServers[server.name] = new MCPServerConfig(server.command, server.args, env, cwd);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
const settings = {
|
|
321
|
-
...currentSettings.merged,
|
|
322
|
-
mcpServers: mergedMcpServers,
|
|
323
|
-
};
|
|
324
|
-
const config = await loadCliConfig(settings, sessionId, this.argv, { cwd });
|
|
325
|
-
createPolicyUpdater(config.getPolicyEngine(), config.messageBus, config.storage);
|
|
326
|
-
return config;
|
|
327
|
-
}
|
|
328
|
-
async cancel(params) {
|
|
329
|
-
const session = this.sessions.get(params.sessionId);
|
|
330
|
-
if (!session) {
|
|
331
|
-
throw new Error(`Session not found: ${params.sessionId}`);
|
|
332
|
-
}
|
|
333
|
-
await session.cancelPendingPrompt();
|
|
334
|
-
}
|
|
335
|
-
async prompt(params) {
|
|
336
|
-
const session = this.sessions.get(params.sessionId);
|
|
337
|
-
if (!session) {
|
|
338
|
-
throw new Error(`Session not found: ${params.sessionId}`);
|
|
339
|
-
}
|
|
340
|
-
return session.prompt(params);
|
|
341
|
-
}
|
|
342
|
-
async setSessionMode(params) {
|
|
343
|
-
const session = this.sessions.get(params.sessionId);
|
|
344
|
-
if (!session) {
|
|
345
|
-
throw new Error(`Session not found: ${params.sessionId}`);
|
|
346
|
-
}
|
|
347
|
-
return session.setMode(params.modeId);
|
|
348
|
-
}
|
|
349
|
-
async unstable_setSessionModel(params) {
|
|
350
|
-
const session = this.sessions.get(params.sessionId);
|
|
351
|
-
if (!session) {
|
|
352
|
-
throw new Error(`Session not found: ${params.sessionId}`);
|
|
353
|
-
}
|
|
354
|
-
return session.setModel(params.modelId);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
19
|
export class Session {
|
|
358
20
|
id;
|
|
359
21
|
chat;
|
|
@@ -362,12 +24,97 @@ export class Session {
|
|
|
362
24
|
settings;
|
|
363
25
|
pendingPrompt = null;
|
|
364
26
|
commandHandler = new CommandHandler();
|
|
27
|
+
callIdCounter = 0;
|
|
28
|
+
disposeController = new AbortController();
|
|
29
|
+
generateCallId(name) {
|
|
30
|
+
return `${name}-${Date.now()}-${++this.callIdCounter}`;
|
|
31
|
+
}
|
|
365
32
|
constructor(id, chat, context, connection, settings) {
|
|
366
33
|
this.id = id;
|
|
367
34
|
this.chat = chat;
|
|
368
35
|
this.context = context;
|
|
369
36
|
this.connection = connection;
|
|
370
37
|
this.settings = settings;
|
|
38
|
+
coreEvents.on(CoreEvent.ApprovalModeChanged, this.handleApprovalModeChanged);
|
|
39
|
+
// Subscribe to tool confirmation requests to handle policy checks (e.g. auto-allowing safe shell commands)
|
|
40
|
+
this.context.config
|
|
41
|
+
.getMessageBus()
|
|
42
|
+
?.subscribe(MessageBusType.TOOL_CONFIRMATION_REQUEST, this.handleToolConfirmationRequest, { signal: this.disposeController.signal });
|
|
43
|
+
}
|
|
44
|
+
handleToolConfirmationRequest = async (request) => {
|
|
45
|
+
try {
|
|
46
|
+
const policyEngine = this.context.config.getPolicyEngine?.();
|
|
47
|
+
const messageBus = this.context.config.getMessageBus();
|
|
48
|
+
if (!messageBus) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!policyEngine) {
|
|
52
|
+
debugLogger.warn('Policy engine missing. Denying tool confirmation request.');
|
|
53
|
+
await messageBus.publish({
|
|
54
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
55
|
+
correlationId: request.correlationId,
|
|
56
|
+
confirmed: false,
|
|
57
|
+
requiresUserConfirmation: false,
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const toolName = request.toolCall.name?.trim();
|
|
62
|
+
if (!toolName) {
|
|
63
|
+
debugLogger.warn('Tool confirmation request missing tool name. Denying.');
|
|
64
|
+
await messageBus.publish({
|
|
65
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
66
|
+
correlationId: request.correlationId,
|
|
67
|
+
confirmed: false,
|
|
68
|
+
requiresUserConfirmation: false,
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const tool = this.context.toolRegistry.getTool(toolName);
|
|
73
|
+
if (!tool) {
|
|
74
|
+
debugLogger.warn(`Tool confirmation request for unknown tool: ${toolName}. Denying.`);
|
|
75
|
+
await messageBus.publish({
|
|
76
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
77
|
+
correlationId: request.correlationId,
|
|
78
|
+
confirmed: false,
|
|
79
|
+
requiresUserConfirmation: false,
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const serverName = tool instanceof DiscoveredMCPTool ? tool.serverName : undefined;
|
|
84
|
+
const toolAnnotations = tool.toolAnnotations;
|
|
85
|
+
const result = await policyEngine.check(request.toolCall, serverName, toolAnnotations, request.subagent);
|
|
86
|
+
await messageBus.publish({
|
|
87
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
88
|
+
correlationId: request.correlationId,
|
|
89
|
+
confirmed: result.decision === PolicyDecision.ALLOW,
|
|
90
|
+
requiresUserConfirmation: result.decision === PolicyDecision.ASK_USER,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
debugLogger.error('Error handling tool confirmation request:', error);
|
|
95
|
+
// Fail closed on exception
|
|
96
|
+
await this.context.config.getMessageBus()?.publish({
|
|
97
|
+
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
|
|
98
|
+
correlationId: request.correlationId,
|
|
99
|
+
confirmed: false,
|
|
100
|
+
requiresUserConfirmation: false,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
handleApprovalModeChanged = (payload) => {
|
|
105
|
+
if (payload.sessionId === this.id) {
|
|
106
|
+
void this.sendUpdate({
|
|
107
|
+
sessionUpdate: 'agent_message_chunk',
|
|
108
|
+
content: {
|
|
109
|
+
type: 'text',
|
|
110
|
+
text: `[MODE_UPDATE] ${payload.mode}`,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
dispose() {
|
|
116
|
+
coreEvents.off(CoreEvent.ApprovalModeChanged, this.handleApprovalModeChanged);
|
|
117
|
+
this.disposeController.abort();
|
|
371
118
|
}
|
|
372
119
|
async cancelPendingPrompt() {
|
|
373
120
|
if (!this.pendingPrompt) {
|
|
@@ -474,19 +221,15 @@ export class Session {
|
|
|
474
221
|
this.pendingPrompt = pendingSend;
|
|
475
222
|
await this.context.config.waitForMcpInit();
|
|
476
223
|
const promptId = Math.random().toString(16).slice(2);
|
|
477
|
-
const chat = this.chat;
|
|
478
224
|
const parts = await this.#resolvePrompt(params.prompt, pendingSend.signal);
|
|
479
225
|
// Command interception
|
|
480
226
|
let commandText = '';
|
|
481
227
|
for (const part of parts) {
|
|
482
228
|
if (typeof part === 'object' && part !== null) {
|
|
483
|
-
if (
|
|
229
|
+
if (isTextPart(part)) {
|
|
484
230
|
// It is a text part
|
|
485
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-type-assertion
|
|
486
231
|
const text = part.text;
|
|
487
|
-
|
|
488
|
-
commandText += text;
|
|
489
|
-
}
|
|
232
|
+
commandText += text;
|
|
490
233
|
}
|
|
491
234
|
else {
|
|
492
235
|
// Non-text part (image, embedded resource)
|
|
@@ -517,78 +260,97 @@ export class Session {
|
|
|
517
260
|
let totalInputTokens = 0;
|
|
518
261
|
let totalOutputTokens = 0;
|
|
519
262
|
const modelUsageMap = new Map();
|
|
520
|
-
let
|
|
521
|
-
|
|
263
|
+
let currentParts = parts;
|
|
264
|
+
let turnCount = 0;
|
|
265
|
+
const maxTurns = this.context.config.getMaxSessionTurns();
|
|
266
|
+
while (true) {
|
|
267
|
+
turnCount++;
|
|
268
|
+
if (maxTurns >= 0 && turnCount > maxTurns) {
|
|
269
|
+
return {
|
|
270
|
+
stopReason: 'max_turn_requests',
|
|
271
|
+
_meta: {
|
|
272
|
+
quota: {
|
|
273
|
+
token_count: {
|
|
274
|
+
input_tokens: totalInputTokens,
|
|
275
|
+
output_tokens: totalOutputTokens,
|
|
276
|
+
},
|
|
277
|
+
model_usage: Array.from(modelUsageMap.entries()).map(([modelName, counts]) => ({
|
|
278
|
+
model: modelName,
|
|
279
|
+
token_count: {
|
|
280
|
+
input_tokens: counts.input,
|
|
281
|
+
output_tokens: counts.output,
|
|
282
|
+
},
|
|
283
|
+
})),
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
}
|
|
522
288
|
if (pendingSend.signal.aborted) {
|
|
523
|
-
|
|
524
|
-
return { stopReason: CoreToolCallStatus.Cancelled };
|
|
289
|
+
return { stopReason: 'cancelled' };
|
|
525
290
|
}
|
|
526
|
-
const
|
|
291
|
+
const toolCallRequests = [];
|
|
292
|
+
let stopReason = 'end_turn';
|
|
293
|
+
let turnModelId = this.context.config.getModel();
|
|
294
|
+
let turnInputTokens = 0;
|
|
295
|
+
let turnOutputTokens = 0;
|
|
527
296
|
try {
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
request: nextMessage?.parts ?? [],
|
|
531
|
-
signal: pendingSend.signal,
|
|
532
|
-
requestedModel: this.context.config.getModel(),
|
|
533
|
-
};
|
|
534
|
-
const router = this.context.config.getModelRouterService();
|
|
535
|
-
const { model } = await router.route(routingContext);
|
|
536
|
-
const responseStream = await chat.sendMessageStream({ model }, nextMessage?.parts ?? [], promptId, pendingSend.signal, LlmRole.MAIN);
|
|
537
|
-
nextMessage = null;
|
|
538
|
-
let turnInputTokens = 0;
|
|
539
|
-
let turnOutputTokens = 0;
|
|
540
|
-
let turnModelId = model;
|
|
541
|
-
for await (const resp of responseStream) {
|
|
297
|
+
const responseStream = this.context.geminiClient.sendMessageStream(currentParts, pendingSend.signal, promptId);
|
|
298
|
+
for await (const event of responseStream) {
|
|
542
299
|
if (pendingSend.signal.aborted) {
|
|
543
|
-
return { stopReason:
|
|
544
|
-
}
|
|
545
|
-
if (resp.type === StreamEventType.CHUNK && resp.value.usageMetadata) {
|
|
546
|
-
turnInputTokens =
|
|
547
|
-
resp.value.usageMetadata.promptTokenCount ?? turnInputTokens;
|
|
548
|
-
turnOutputTokens =
|
|
549
|
-
resp.value.usageMetadata.candidatesTokenCount ?? turnOutputTokens;
|
|
550
|
-
if (resp.value.modelVersion) {
|
|
551
|
-
turnModelId = resp.value.modelVersion;
|
|
552
|
-
}
|
|
300
|
+
return { stopReason: 'cancelled' };
|
|
553
301
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
resp.value.candidates.length > 0) {
|
|
557
|
-
const candidate = resp.value.candidates[0];
|
|
558
|
-
for (const part of candidate.content?.parts ?? []) {
|
|
559
|
-
if (!part.text) {
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
302
|
+
switch (event.type) {
|
|
303
|
+
case GeminiEventType.Content: {
|
|
562
304
|
const content = {
|
|
563
305
|
type: 'text',
|
|
564
|
-
text:
|
|
306
|
+
text: event.value,
|
|
565
307
|
};
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
sessionUpdate: part.thought
|
|
569
|
-
? 'agent_thought_chunk'
|
|
570
|
-
: 'agent_message_chunk',
|
|
308
|
+
await this.sendUpdate({
|
|
309
|
+
sessionUpdate: 'agent_message_chunk',
|
|
571
310
|
content,
|
|
572
311
|
});
|
|
312
|
+
break;
|
|
573
313
|
}
|
|
314
|
+
case GeminiEventType.Thought: {
|
|
315
|
+
const thoughtText = `**${event.value.subject}**\n${event.value.description}`;
|
|
316
|
+
await this.sendUpdate({
|
|
317
|
+
sessionUpdate: 'agent_thought_chunk',
|
|
318
|
+
content: { type: 'text', text: thoughtText },
|
|
319
|
+
});
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case GeminiEventType.ToolCallRequest:
|
|
323
|
+
toolCallRequests.push(event.value);
|
|
324
|
+
break;
|
|
325
|
+
case GeminiEventType.Finished: {
|
|
326
|
+
const usage = event.value.usageMetadata;
|
|
327
|
+
if (usage) {
|
|
328
|
+
turnInputTokens = usage.promptTokenCount ?? turnInputTokens;
|
|
329
|
+
turnOutputTokens =
|
|
330
|
+
usage.candidatesTokenCount ?? turnOutputTokens;
|
|
331
|
+
}
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
case GeminiEventType.ModelInfo:
|
|
335
|
+
turnModelId = event.value;
|
|
336
|
+
break;
|
|
337
|
+
case GeminiEventType.MaxSessionTurns:
|
|
338
|
+
stopReason = 'max_turn_requests';
|
|
339
|
+
break;
|
|
340
|
+
case GeminiEventType.LoopDetected:
|
|
341
|
+
stopReason = 'max_turn_requests';
|
|
342
|
+
break;
|
|
343
|
+
case GeminiEventType.ContextWindowWillOverflow:
|
|
344
|
+
stopReason = 'max_tokens';
|
|
345
|
+
break;
|
|
346
|
+
case GeminiEventType.Error: {
|
|
347
|
+
const parseResult = StructuredErrorSchema.safeParse(event.value.error);
|
|
348
|
+
const errData = parseResult.success ? parseResult.data : {};
|
|
349
|
+
throw new acp.RequestError(errData.status ?? 500, errData.message ?? 'Unknown stream execution error.');
|
|
350
|
+
}
|
|
351
|
+
default:
|
|
352
|
+
break;
|
|
574
353
|
}
|
|
575
|
-
if (resp.type === StreamEventType.CHUNK && resp.value.functionCalls) {
|
|
576
|
-
functionCalls.push(...resp.value.functionCalls);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
totalInputTokens += turnInputTokens;
|
|
580
|
-
totalOutputTokens += turnOutputTokens;
|
|
581
|
-
if (turnInputTokens > 0 || turnOutputTokens > 0) {
|
|
582
|
-
const existing = modelUsageMap.get(turnModelId) ?? {
|
|
583
|
-
input: 0,
|
|
584
|
-
output: 0,
|
|
585
|
-
};
|
|
586
|
-
existing.input += turnInputTokens;
|
|
587
|
-
existing.output += turnOutputTokens;
|
|
588
|
-
modelUsageMap.set(turnModelId, existing);
|
|
589
|
-
}
|
|
590
|
-
if (pendingSend.signal.aborted) {
|
|
591
|
-
return { stopReason: CoreToolCallStatus.Cancelled };
|
|
592
354
|
}
|
|
593
355
|
}
|
|
594
356
|
catch (error) {
|
|
@@ -597,7 +359,10 @@ export class Session {
|
|
|
597
359
|
}
|
|
598
360
|
if (pendingSend.signal.aborted ||
|
|
599
361
|
(error instanceof Error && error.name === 'AbortError')) {
|
|
600
|
-
return { stopReason:
|
|
362
|
+
return { stopReason: 'cancelled' };
|
|
363
|
+
}
|
|
364
|
+
if (error instanceof acp.RequestError) {
|
|
365
|
+
throw error;
|
|
601
366
|
}
|
|
602
367
|
if (error instanceof InvalidStreamError ||
|
|
603
368
|
(error &&
|
|
@@ -630,14 +395,51 @@ export class Session {
|
|
|
630
395
|
}
|
|
631
396
|
throw new acp.RequestError(getErrorStatus(error) || 500, getAcpErrorMessage(error));
|
|
632
397
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
398
|
+
totalInputTokens += turnInputTokens;
|
|
399
|
+
totalOutputTokens += turnOutputTokens;
|
|
400
|
+
if (turnInputTokens > 0 || turnOutputTokens > 0) {
|
|
401
|
+
const existing = modelUsageMap.get(turnModelId) ?? {
|
|
402
|
+
input: 0,
|
|
403
|
+
output: 0,
|
|
404
|
+
};
|
|
405
|
+
existing.input += turnInputTokens;
|
|
406
|
+
existing.output += turnOutputTokens;
|
|
407
|
+
modelUsageMap.set(turnModelId, existing);
|
|
408
|
+
}
|
|
409
|
+
if (stopReason !== 'end_turn') {
|
|
410
|
+
return {
|
|
411
|
+
stopReason,
|
|
412
|
+
_meta: {
|
|
413
|
+
quota: {
|
|
414
|
+
token_count: {
|
|
415
|
+
input_tokens: totalInputTokens,
|
|
416
|
+
output_tokens: totalOutputTokens,
|
|
417
|
+
},
|
|
418
|
+
model_usage: Array.from(modelUsageMap.entries()).map(([modelName, counts]) => ({
|
|
419
|
+
model: modelName,
|
|
420
|
+
token_count: {
|
|
421
|
+
input_tokens: counts.input,
|
|
422
|
+
output_tokens: counts.output,
|
|
423
|
+
},
|
|
424
|
+
})),
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
if (toolCallRequests.length === 0) {
|
|
430
|
+
break;
|
|
640
431
|
}
|
|
432
|
+
const toolResponseParts = [];
|
|
433
|
+
for (const tReq of toolCallRequests) {
|
|
434
|
+
const fc = {
|
|
435
|
+
id: tReq.callId,
|
|
436
|
+
name: tReq.name,
|
|
437
|
+
args: tReq.args,
|
|
438
|
+
};
|
|
439
|
+
const response = await this.runTool(pendingSend.signal, promptId, fc);
|
|
440
|
+
toolResponseParts.push(...response);
|
|
441
|
+
}
|
|
442
|
+
currentParts = toolResponseParts;
|
|
641
443
|
}
|
|
642
444
|
const modelUsageArray = Array.from(modelUsageMap.entries()).map(([modelName, counts]) => ({
|
|
643
445
|
model: modelName,
|
|
@@ -684,7 +486,7 @@ export class Session {
|
|
|
684
486
|
await this.connection.sessionUpdate(params);
|
|
685
487
|
}
|
|
686
488
|
async runTool(abortSignal, promptId, fc) {
|
|
687
|
-
const callId = fc.id ??
|
|
489
|
+
const callId = fc.id ?? this.generateCallId(fc.name || 'unknown');
|
|
688
490
|
const args = fc.args ?? {};
|
|
689
491
|
const startTime = Date.now();
|
|
690
492
|
const errorResponse = (error) => {
|
|
@@ -718,12 +520,6 @@ export class Session {
|
|
|
718
520
|
const explanation = typeof invocation.getExplanation === 'function'
|
|
719
521
|
? invocation.getExplanation()
|
|
720
522
|
: '';
|
|
721
|
-
if (explanation) {
|
|
722
|
-
await this.sendUpdate({
|
|
723
|
-
sessionUpdate: 'agent_thought_chunk',
|
|
724
|
-
content: { type: 'text', text: explanation },
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
523
|
const confirmationDetails = await invocation.shouldConfirmExecute(abortSignal);
|
|
728
524
|
if (confirmationDetails) {
|
|
729
525
|
const content = [];
|
|
@@ -742,6 +538,12 @@ export class Session {
|
|
|
742
538
|
},
|
|
743
539
|
});
|
|
744
540
|
}
|
|
541
|
+
if (content.length === 0 && explanation) {
|
|
542
|
+
content.push({
|
|
543
|
+
type: 'content',
|
|
544
|
+
content: { type: 'text', text: explanation },
|
|
545
|
+
});
|
|
546
|
+
}
|
|
745
547
|
const params = {
|
|
746
548
|
sessionId: this.id,
|
|
747
549
|
options: toPermissionOptions(confirmationDetails, this.context.config, this.settings.merged.security.enablePermanentToolApproval),
|
|
@@ -781,6 +583,12 @@ export class Session {
|
|
|
781
583
|
}
|
|
782
584
|
else {
|
|
783
585
|
const content = [];
|
|
586
|
+
if (explanation) {
|
|
587
|
+
content.push({
|
|
588
|
+
type: 'content',
|
|
589
|
+
content: { type: 'text', text: explanation },
|
|
590
|
+
});
|
|
591
|
+
}
|
|
784
592
|
await this.sendUpdate({
|
|
785
593
|
sessionUpdate: 'tool_call',
|
|
786
594
|
toolCallId: callId,
|
|
@@ -942,80 +750,101 @@ export class Session {
|
|
|
942
750
|
let currentPathSpec = pathName;
|
|
943
751
|
let resolvedSuccessfully = false;
|
|
944
752
|
let readDirectly = false;
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
753
|
+
const result = await resolveAtCommandPath(pathName, this.context.config, (msg) => this.debug(msg));
|
|
754
|
+
let validationError = null;
|
|
755
|
+
let absolutePath;
|
|
756
|
+
let resolved;
|
|
757
|
+
if (result.status === 'resolved') {
|
|
758
|
+
resolved = result.resolved;
|
|
759
|
+
absolutePath = resolved.absolutePath;
|
|
760
|
+
}
|
|
761
|
+
else if (result.status === 'unauthorized') {
|
|
762
|
+
absolutePath = result.absolutePath;
|
|
763
|
+
validationError = result.error;
|
|
764
|
+
}
|
|
765
|
+
else if (result.status === 'invalid') {
|
|
766
|
+
// Already logged in resolveAtCommandPath
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
// Result is not_found.
|
|
771
|
+
// We still check if it's an unauthorized absolute path that we can ask permission for,
|
|
772
|
+
// specifically for paths that are completely outside the root and not even in any workspace directory.
|
|
773
|
+
// For relative paths not found anywhere, we resolve relative to targetDir for permission check.
|
|
774
|
+
absolutePath = path.resolve(this.context.config.getTargetDir(), pathName);
|
|
775
|
+
}
|
|
776
|
+
if (!resolved &&
|
|
777
|
+
validationError &&
|
|
778
|
+
!isWithinRoot(absolutePath, this.context.config.getTargetDir())) {
|
|
779
|
+
try {
|
|
780
|
+
const stats = await fs.stat(absolutePath);
|
|
781
|
+
if (stats.isFile()) {
|
|
782
|
+
const syntheticCallId = `resolve-prompt-${pathName}-${randomUUID()}`;
|
|
783
|
+
const params = {
|
|
784
|
+
sessionId: this.id,
|
|
785
|
+
options: [
|
|
786
|
+
{
|
|
787
|
+
optionId: ToolConfirmationOutcome.ProceedOnce,
|
|
788
|
+
name: 'Allow once',
|
|
789
|
+
kind: 'allow_once',
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
optionId: ToolConfirmationOutcome.Cancel,
|
|
793
|
+
name: 'Deny',
|
|
794
|
+
kind: 'reject_once',
|
|
795
|
+
},
|
|
796
|
+
],
|
|
797
|
+
toolCall: {
|
|
798
|
+
toolCallId: syntheticCallId,
|
|
799
|
+
status: 'pending',
|
|
800
|
+
title: `Allow access to absolute path: ${pathName}`,
|
|
801
|
+
content: [
|
|
963
802
|
{
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
803
|
+
type: 'content',
|
|
804
|
+
content: {
|
|
805
|
+
type: 'text',
|
|
806
|
+
text: `The Agent needs access to read an attached file outside your workspace: ${pathName}`,
|
|
807
|
+
},
|
|
967
808
|
},
|
|
968
809
|
],
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
status: 'pending',
|
|
972
|
-
title: `Allow access to absolute path: ${pathName}`,
|
|
973
|
-
content: [
|
|
974
|
-
{
|
|
975
|
-
type: 'content',
|
|
976
|
-
content: {
|
|
977
|
-
type: 'text',
|
|
978
|
-
text: `The Agent needs access to read an attached file outside your workspace: ${pathName}`,
|
|
979
|
-
},
|
|
980
|
-
},
|
|
981
|
-
],
|
|
982
|
-
locations: [],
|
|
983
|
-
kind: 'read',
|
|
984
|
-
},
|
|
985
|
-
};
|
|
986
|
-
const output = RequestPermissionResponseSchema.parse(await this.connection.requestPermission(params));
|
|
987
|
-
const outcome = output.outcome.outcome === 'cancelled'
|
|
988
|
-
? ToolConfirmationOutcome.Cancel
|
|
989
|
-
: z
|
|
990
|
-
.nativeEnum(ToolConfirmationOutcome)
|
|
991
|
-
.parse(output.outcome.optionId);
|
|
992
|
-
if (outcome === ToolConfirmationOutcome.ProceedOnce) {
|
|
993
|
-
this.context.config
|
|
994
|
-
.getWorkspaceContext()
|
|
995
|
-
.addReadOnlyPath(absolutePath);
|
|
996
|
-
validationError = null;
|
|
997
|
-
}
|
|
998
|
-
else {
|
|
999
|
-
this.debug(`Direct read authorization denied for absolute path ${pathName}`);
|
|
1000
|
-
directContents.push({
|
|
1001
|
-
spec: pathName,
|
|
1002
|
-
content: `[Warning: Access to absolute path \`${pathName}\` denied by user.]`,
|
|
1003
|
-
});
|
|
1004
|
-
continue;
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
catch (error) {
|
|
1009
|
-
this.debug(`Failed to request permission for absolute attachment ${pathName}: ${getErrorMessage(error)}`);
|
|
1010
|
-
await this.sendUpdate({
|
|
1011
|
-
sessionUpdate: 'agent_thought_chunk',
|
|
1012
|
-
content: {
|
|
1013
|
-
type: 'text',
|
|
1014
|
-
text: `Warning: Failed to display permission dialog for \`${absolutePath}\`. Error: ${getErrorMessage(error)}`,
|
|
810
|
+
locations: [],
|
|
811
|
+
kind: 'read',
|
|
1015
812
|
},
|
|
1016
|
-
}
|
|
813
|
+
};
|
|
814
|
+
const output = RequestPermissionResponseSchema.parse(await this.connection.requestPermission(params));
|
|
815
|
+
const outcome = output.outcome.outcome === 'cancelled'
|
|
816
|
+
? ToolConfirmationOutcome.Cancel
|
|
817
|
+
: z
|
|
818
|
+
.nativeEnum(ToolConfirmationOutcome)
|
|
819
|
+
.parse(output.outcome.optionId);
|
|
820
|
+
if (outcome === ToolConfirmationOutcome.ProceedOnce) {
|
|
821
|
+
this.context.config
|
|
822
|
+
.getWorkspaceContext()
|
|
823
|
+
.addReadOnlyPath(absolutePath);
|
|
824
|
+
validationError = null;
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
this.debug(`Direct read authorization denied for absolute path ${pathName}`);
|
|
828
|
+
directContents.push({
|
|
829
|
+
spec: pathName,
|
|
830
|
+
content: `[Warning: Access to absolute path \`${pathName}\` denied by user.]`,
|
|
831
|
+
});
|
|
832
|
+
continue;
|
|
833
|
+
}
|
|
1017
834
|
}
|
|
1018
835
|
}
|
|
836
|
+
catch (error) {
|
|
837
|
+
this.debug(`Failed to request permission for absolute attachment ${pathName}: ${getErrorMessage(error)}`);
|
|
838
|
+
await this.sendUpdate({
|
|
839
|
+
sessionUpdate: 'agent_thought_chunk',
|
|
840
|
+
content: {
|
|
841
|
+
type: 'text',
|
|
842
|
+
text: `Warning: Failed to display permission dialog for \`${absolutePath}\`. Error: ${getErrorMessage(error)}`,
|
|
843
|
+
},
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
try {
|
|
1019
848
|
if (!validationError) {
|
|
1020
849
|
// If it's an absolute path that is authorized (e.g. added via readOnlyPaths),
|
|
1021
850
|
// read it directly to avoid ReadManyFilesTool absolute path resolution issues.
|
|
@@ -1023,7 +852,9 @@ export class Session {
|
|
|
1023
852
|
!isWithinRoot(absolutePath, this.context.config.getTargetDir())) &&
|
|
1024
853
|
!readDirectly) {
|
|
1025
854
|
try {
|
|
1026
|
-
const stats =
|
|
855
|
+
const stats = resolved
|
|
856
|
+
? resolved.stats
|
|
857
|
+
: await fs.stat(absolutePath);
|
|
1027
858
|
if (stats.isFile()) {
|
|
1028
859
|
const fileReadResult = await processSingleFileContent(absolutePath, this.context.config.getTargetDir(), this.context.config.getFileSystemService());
|
|
1029
860
|
if (!fileReadResult.error) {
|
|
@@ -1073,7 +904,9 @@ export class Session {
|
|
|
1073
904
|
}
|
|
1074
905
|
}
|
|
1075
906
|
if (!readDirectly) {
|
|
1076
|
-
const stats =
|
|
907
|
+
const stats = resolved
|
|
908
|
+
? resolved.stats
|
|
909
|
+
: await fs.stat(absolutePath);
|
|
1077
910
|
if (stats.isDirectory()) {
|
|
1078
911
|
currentPathSpec = pathName.endsWith('/')
|
|
1079
912
|
? `${pathName}**`
|
|
@@ -1202,7 +1035,7 @@ export class Session {
|
|
|
1202
1035
|
const toolArgs = {
|
|
1203
1036
|
include: pathSpecsToRead,
|
|
1204
1037
|
};
|
|
1205
|
-
const callId =
|
|
1038
|
+
const callId = this.generateCallId(readManyFilesTool.name);
|
|
1206
1039
|
try {
|
|
1207
1040
|
const invocation = readManyFilesTool.build(toolArgs);
|
|
1208
1041
|
await this.sendUpdate({
|
|
@@ -1332,285 +1165,4 @@ export class Session {
|
|
|
1332
1165
|
}
|
|
1333
1166
|
}
|
|
1334
1167
|
}
|
|
1335
|
-
|
|
1336
|
-
if (toolResult.error?.message) {
|
|
1337
|
-
throw new Error(toolResult.error.message);
|
|
1338
|
-
}
|
|
1339
|
-
if (toolResult.returnDisplay) {
|
|
1340
|
-
if (typeof toolResult.returnDisplay === 'string') {
|
|
1341
|
-
return {
|
|
1342
|
-
type: 'content',
|
|
1343
|
-
content: { type: 'text', text: toolResult.returnDisplay },
|
|
1344
|
-
};
|
|
1345
|
-
}
|
|
1346
|
-
else {
|
|
1347
|
-
if ('fileName' in toolResult.returnDisplay) {
|
|
1348
|
-
return {
|
|
1349
|
-
type: 'diff',
|
|
1350
|
-
path: toolResult.returnDisplay.filePath ??
|
|
1351
|
-
toolResult.returnDisplay.fileName,
|
|
1352
|
-
oldText: toolResult.returnDisplay.originalContent,
|
|
1353
|
-
newText: toolResult.returnDisplay.newContent,
|
|
1354
|
-
_meta: {
|
|
1355
|
-
kind: !toolResult.returnDisplay.originalContent
|
|
1356
|
-
? 'add'
|
|
1357
|
-
: toolResult.returnDisplay.newContent === ''
|
|
1358
|
-
? 'delete'
|
|
1359
|
-
: 'modify',
|
|
1360
|
-
},
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
return null;
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
else {
|
|
1367
|
-
return null;
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
const basicPermissionOptions = [
|
|
1371
|
-
{
|
|
1372
|
-
optionId: ToolConfirmationOutcome.ProceedOnce,
|
|
1373
|
-
name: 'Allow',
|
|
1374
|
-
kind: 'allow_once',
|
|
1375
|
-
},
|
|
1376
|
-
{
|
|
1377
|
-
optionId: ToolConfirmationOutcome.Cancel,
|
|
1378
|
-
name: 'Reject',
|
|
1379
|
-
kind: 'reject_once',
|
|
1380
|
-
},
|
|
1381
|
-
];
|
|
1382
|
-
function toPermissionOptions(confirmation, config, enablePermanentToolApproval = false) {
|
|
1383
|
-
const disableAlwaysAllow = config.getDisableAlwaysAllow();
|
|
1384
|
-
const options = [];
|
|
1385
|
-
if (!disableAlwaysAllow) {
|
|
1386
|
-
switch (confirmation.type) {
|
|
1387
|
-
case 'edit':
|
|
1388
|
-
options.push({
|
|
1389
|
-
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
1390
|
-
name: 'Allow for this session',
|
|
1391
|
-
kind: 'allow_always',
|
|
1392
|
-
});
|
|
1393
|
-
if (enablePermanentToolApproval) {
|
|
1394
|
-
options.push({
|
|
1395
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
1396
|
-
name: 'Allow for this file in all future sessions',
|
|
1397
|
-
kind: 'allow_always',
|
|
1398
|
-
});
|
|
1399
|
-
}
|
|
1400
|
-
break;
|
|
1401
|
-
case 'exec':
|
|
1402
|
-
options.push({
|
|
1403
|
-
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
1404
|
-
name: 'Allow for this session',
|
|
1405
|
-
kind: 'allow_always',
|
|
1406
|
-
});
|
|
1407
|
-
if (enablePermanentToolApproval) {
|
|
1408
|
-
options.push({
|
|
1409
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
1410
|
-
name: 'Allow this command for all future sessions',
|
|
1411
|
-
kind: 'allow_always',
|
|
1412
|
-
});
|
|
1413
|
-
}
|
|
1414
|
-
break;
|
|
1415
|
-
case 'mcp':
|
|
1416
|
-
options.push({
|
|
1417
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysServer,
|
|
1418
|
-
name: 'Allow all server tools for this session',
|
|
1419
|
-
kind: 'allow_always',
|
|
1420
|
-
}, {
|
|
1421
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysTool,
|
|
1422
|
-
name: 'Allow tool for this session',
|
|
1423
|
-
kind: 'allow_always',
|
|
1424
|
-
});
|
|
1425
|
-
if (enablePermanentToolApproval) {
|
|
1426
|
-
options.push({
|
|
1427
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
1428
|
-
name: 'Allow tool for all future sessions',
|
|
1429
|
-
kind: 'allow_always',
|
|
1430
|
-
});
|
|
1431
|
-
}
|
|
1432
|
-
break;
|
|
1433
|
-
case 'info':
|
|
1434
|
-
options.push({
|
|
1435
|
-
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
1436
|
-
name: 'Allow for this session',
|
|
1437
|
-
kind: 'allow_always',
|
|
1438
|
-
});
|
|
1439
|
-
if (enablePermanentToolApproval) {
|
|
1440
|
-
options.push({
|
|
1441
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
1442
|
-
name: 'Allow for all future sessions',
|
|
1443
|
-
kind: 'allow_always',
|
|
1444
|
-
});
|
|
1445
|
-
}
|
|
1446
|
-
break;
|
|
1447
|
-
case 'ask_user':
|
|
1448
|
-
case 'exit_plan_mode':
|
|
1449
|
-
// askuser and exit_plan_mode don't need "always allow" options
|
|
1450
|
-
break;
|
|
1451
|
-
default:
|
|
1452
|
-
// No "always allow" options for other types
|
|
1453
|
-
break;
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
options.push(...basicPermissionOptions);
|
|
1457
|
-
// Exhaustive check
|
|
1458
|
-
switch (confirmation.type) {
|
|
1459
|
-
case 'edit':
|
|
1460
|
-
case 'exec':
|
|
1461
|
-
case 'mcp':
|
|
1462
|
-
case 'info':
|
|
1463
|
-
case 'ask_user':
|
|
1464
|
-
case 'exit_plan_mode':
|
|
1465
|
-
case 'sandbox_expansion':
|
|
1466
|
-
break;
|
|
1467
|
-
default: {
|
|
1468
|
-
const unreachable = confirmation;
|
|
1469
|
-
throw new Error(`Unexpected: ${unreachable}`);
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
return options;
|
|
1473
|
-
}
|
|
1474
|
-
/**
|
|
1475
|
-
* Maps our internal tool kind to the ACP ToolKind.
|
|
1476
|
-
* Fallback to 'other' for kinds that are not supported by the ACP protocol.
|
|
1477
|
-
*/
|
|
1478
|
-
function toAcpToolKind(kind) {
|
|
1479
|
-
switch (kind) {
|
|
1480
|
-
case Kind.Read:
|
|
1481
|
-
case Kind.Edit:
|
|
1482
|
-
case Kind.Execute:
|
|
1483
|
-
case Kind.Search:
|
|
1484
|
-
case Kind.Delete:
|
|
1485
|
-
case Kind.Move:
|
|
1486
|
-
case Kind.Think:
|
|
1487
|
-
case Kind.Fetch:
|
|
1488
|
-
case Kind.SwitchMode:
|
|
1489
|
-
case Kind.Other:
|
|
1490
|
-
return kind;
|
|
1491
|
-
case Kind.Agent:
|
|
1492
|
-
return 'think';
|
|
1493
|
-
case Kind.Plan:
|
|
1494
|
-
case Kind.Communicate:
|
|
1495
|
-
default:
|
|
1496
|
-
return 'other';
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
function buildAvailableModes(isPlanEnabled) {
|
|
1500
|
-
const modes = [
|
|
1501
|
-
{
|
|
1502
|
-
id: ApprovalMode.DEFAULT,
|
|
1503
|
-
name: 'Default',
|
|
1504
|
-
description: 'Prompts for approval',
|
|
1505
|
-
},
|
|
1506
|
-
{
|
|
1507
|
-
id: ApprovalMode.AUTO_EDIT,
|
|
1508
|
-
name: 'Auto Edit',
|
|
1509
|
-
description: 'Auto-approves edit tools',
|
|
1510
|
-
},
|
|
1511
|
-
{
|
|
1512
|
-
id: ApprovalMode.YOLO,
|
|
1513
|
-
name: 'YOLO',
|
|
1514
|
-
description: 'Auto-approves all tools',
|
|
1515
|
-
},
|
|
1516
|
-
];
|
|
1517
|
-
if (isPlanEnabled) {
|
|
1518
|
-
modes.push({
|
|
1519
|
-
id: ApprovalMode.PLAN,
|
|
1520
|
-
name: 'Plan',
|
|
1521
|
-
description: 'Read-only mode',
|
|
1522
|
-
});
|
|
1523
|
-
}
|
|
1524
|
-
return modes;
|
|
1525
|
-
}
|
|
1526
|
-
function buildAvailableModels(config, settings) {
|
|
1527
|
-
const preferredModel = config.getModel() || DEFAULT_GEMINI_MODEL_AUTO;
|
|
1528
|
-
const shouldShowPreviewModels = config.getHasAccessToPreviewModel();
|
|
1529
|
-
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
|
|
1530
|
-
const useGemini31FlashLite = config.getGemini31FlashLiteLaunchedSync?.() ?? false;
|
|
1531
|
-
const selectedAuthType = settings.merged.security.auth.selectedType;
|
|
1532
|
-
const useCustomToolModel = useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
|
|
1533
|
-
// --- DYNAMIC PATH ---
|
|
1534
|
-
if (config.getExperimentalDynamicModelConfiguration?.() === true &&
|
|
1535
|
-
config.getModelConfigService) {
|
|
1536
|
-
const options = config.getModelConfigService().getAvailableModelOptions({
|
|
1537
|
-
useGemini3_1: useGemini31,
|
|
1538
|
-
useGemini3_1FlashLite: useGemini31FlashLite,
|
|
1539
|
-
useCustomTools: useCustomToolModel,
|
|
1540
|
-
hasAccessToPreview: shouldShowPreviewModels,
|
|
1541
|
-
});
|
|
1542
|
-
return {
|
|
1543
|
-
availableModels: options,
|
|
1544
|
-
currentModelId: preferredModel,
|
|
1545
|
-
};
|
|
1546
|
-
}
|
|
1547
|
-
// --- LEGACY PATH ---
|
|
1548
|
-
const mainOptions = [
|
|
1549
|
-
{
|
|
1550
|
-
value: DEFAULT_GEMINI_MODEL_AUTO,
|
|
1551
|
-
title: getDisplayString(DEFAULT_GEMINI_MODEL_AUTO),
|
|
1552
|
-
description: 'Let Cell CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash',
|
|
1553
|
-
},
|
|
1554
|
-
];
|
|
1555
|
-
if (shouldShowPreviewModels) {
|
|
1556
|
-
mainOptions.unshift({
|
|
1557
|
-
value: PREVIEW_GEMINI_MODEL_AUTO,
|
|
1558
|
-
title: getDisplayString(PREVIEW_GEMINI_MODEL_AUTO),
|
|
1559
|
-
description: useGemini31
|
|
1560
|
-
? 'Let Cell CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash'
|
|
1561
|
-
: 'Let Cell CLI decide the best model for the task: gemini-3-pro, gemini-3-flash',
|
|
1562
|
-
});
|
|
1563
|
-
}
|
|
1564
|
-
const manualOptions = [
|
|
1565
|
-
{
|
|
1566
|
-
value: DEFAULT_GEMINI_MODEL,
|
|
1567
|
-
title: getDisplayString(DEFAULT_GEMINI_MODEL),
|
|
1568
|
-
},
|
|
1569
|
-
{
|
|
1570
|
-
value: DEFAULT_GEMINI_FLASH_MODEL,
|
|
1571
|
-
title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL),
|
|
1572
|
-
},
|
|
1573
|
-
{
|
|
1574
|
-
value: DEFAULT_GEMINI_FLASH_LITE_MODEL,
|
|
1575
|
-
title: getDisplayString(DEFAULT_GEMINI_FLASH_LITE_MODEL),
|
|
1576
|
-
},
|
|
1577
|
-
];
|
|
1578
|
-
if (shouldShowPreviewModels) {
|
|
1579
|
-
const previewProModel = useGemini31
|
|
1580
|
-
? PREVIEW_GEMINI_3_1_MODEL
|
|
1581
|
-
: PREVIEW_GEMINI_MODEL;
|
|
1582
|
-
const previewProValue = useCustomToolModel
|
|
1583
|
-
? PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL
|
|
1584
|
-
: previewProModel;
|
|
1585
|
-
const previewOptions = [
|
|
1586
|
-
{
|
|
1587
|
-
value: previewProValue,
|
|
1588
|
-
title: getDisplayString(previewProModel),
|
|
1589
|
-
},
|
|
1590
|
-
{
|
|
1591
|
-
value: PREVIEW_GEMINI_FLASH_MODEL,
|
|
1592
|
-
title: getDisplayString(PREVIEW_GEMINI_FLASH_MODEL),
|
|
1593
|
-
},
|
|
1594
|
-
];
|
|
1595
|
-
if (useGemini31FlashLite) {
|
|
1596
|
-
previewOptions.push({
|
|
1597
|
-
value: PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
|
|
1598
|
-
title: getDisplayString(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL),
|
|
1599
|
-
});
|
|
1600
|
-
}
|
|
1601
|
-
manualOptions.unshift(...previewOptions);
|
|
1602
|
-
}
|
|
1603
|
-
const scaleOptions = (options) => options.map((o) => ({
|
|
1604
|
-
modelId: o.value,
|
|
1605
|
-
name: o.title,
|
|
1606
|
-
description: o.description,
|
|
1607
|
-
}));
|
|
1608
|
-
return {
|
|
1609
|
-
availableModels: [
|
|
1610
|
-
...scaleOptions(mainOptions),
|
|
1611
|
-
...scaleOptions(manualOptions),
|
|
1612
|
-
],
|
|
1613
|
-
currentModelId: preferredModel,
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
//# sourceMappingURL=acpClient.js.map
|
|
1168
|
+
//# sourceMappingURL=acpSession.js.map
|