@within-7/minto 0.3.9 → 0.4.0
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/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +461 -657
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/ctx_viz.js +1 -1
- package/dist/commands/effort.js +87 -0
- package/dist/commands/effort.js.map +7 -0
- package/dist/commands/export.js +684 -94
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/ide.js +18 -0
- package/dist/commands/ide.js.map +7 -0
- package/dist/commands/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +425 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/memory.js +168 -0
- package/dist/commands/memory.js.map +7 -0
- package/dist/commands/model.js +457 -65
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/outputStyle.js +64 -0
- package/dist/commands/outputStyle.js.map +7 -0
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +891 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +146 -174
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands/vim.js +22 -0
- package/dist/commands/vim.js.map +7 -0
- package/dist/commands.js +12 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +590 -565
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +26 -11
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/PulseLabel.js +44 -0
- package/dist/components/PulseLabel.js.map +7 -0
- package/dist/components/RequestStatusIndicator.js +1 -1
- package/dist/components/RequestStatusIndicator.js.map +1 -1
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/Spinner.js +12 -42
- package/dist/components/Spinner.js.map +3 -3
- package/dist/components/StartupStatus.js +57 -0
- package/dist/components/StartupStatus.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
- package/dist/components/TabbedListView/TabBar.js +13 -8
- package/dist/components/TabbedListView/TabBar.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +123 -48
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TodoPanel.js +1 -1
- package/dist/components/TodoPanel.js.map +1 -1
- package/dist/components/ToolUseLoader.js +5 -0
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TrustDialog.js +0 -2
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +1 -1
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js +1 -1
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +6 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/modelCapabilities.js +103 -18
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/product.js +2 -0
- package/dist/constants/product.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +30 -0
- package/dist/constants/prompts/agentPrompt.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +27 -0
- package/dist/constants/prompts/codeConventions.js.map +7 -0
- package/dist/constants/prompts/doingTasks.js +15 -0
- package/dist/constants/prompts/doingTasks.js.map +7 -0
- package/dist/constants/prompts/envInfo.js +17 -0
- package/dist/constants/prompts/envInfo.js.map +7 -0
- package/dist/constants/prompts/executingWithCare.js +17 -0
- package/dist/constants/prompts/executingWithCare.js.map +7 -0
- package/dist/constants/prompts/identity.js +10 -0
- package/dist/constants/prompts/identity.js.map +7 -0
- package/dist/constants/prompts/index.js +78 -0
- package/dist/constants/prompts/index.js.map +7 -0
- package/dist/constants/prompts/taskManagement.js +60 -0
- package/dist/constants/prompts/taskManagement.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +62 -0
- package/dist/constants/prompts/toneAndStyle.js.map +7 -0
- package/dist/constants/prompts/toolUsagePolicy.js +38 -0
- package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
- package/dist/constants/prompts.js +5 -176
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/providerRegistry.js +235 -0
- package/dist/constants/providerRegistry.js.map +7 -0
- package/dist/constants/providers.js +35 -0
- package/dist/constants/providers.js.map +7 -0
- package/dist/context/PermissionContext.js +0 -1
- package/dist/context/PermissionContext.js.map +2 -2
- package/dist/context.js +87 -31
- package/dist/context.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +11 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +21 -3
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +2 -2
- package/dist/core/tokenStatsManager.js +22 -4
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +81 -68
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +1 -1
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +2 -1
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useBackgroundShells.js +29 -0
- package/dist/hooks/useBackgroundShells.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +1 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +64 -0
- package/dist/hooks/useDeferredLoading.js.map +7 -0
- package/dist/hooks/useHookStatus.js +1 -1
- package/dist/hooks/useHookStatus.js.map +2 -2
- package/dist/hooks/useSessionTracking.js +55 -0
- package/dist/hooks/useSessionTracking.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +21 -0
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useTextInput.js +1 -0
- package/dist/hooks/useTextInput.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +3 -2
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/locales/en.js +299 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +300 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js +41 -17
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +94 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +27 -19
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +83 -74
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +6 -0
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/agentTeams/index.js +35 -0
- package/dist/services/agentTeams/index.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +114 -0
- package/dist/services/agentTeams/mailbox.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +149 -0
- package/dist/services/agentTeams/teamManager.js.map +7 -0
- package/dist/services/agentTeams/teamTaskStore.js +114 -0
- package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
- package/dist/services/agentTeams/teammateSpawner.js +80 -0
- package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
- package/dist/services/checkpointManager.js +16 -3
- package/dist/services/checkpointManager.js.map +2 -2
- package/dist/services/claude.js +19 -1728
- package/dist/services/claude.js.map +3 -3
- package/dist/services/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/gpt5ConnectionTest.js +4 -2
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +411 -127
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +807 -0
- package/dist/services/llm/anthropicProvider.js.map +7 -0
- package/dist/services/llm/dispatch.js +218 -0
- package/dist/services/llm/dispatch.js.map +7 -0
- package/dist/services/llm/index.js +44 -0
- package/dist/services/llm/index.js.map +7 -0
- package/dist/services/llm/mintoContext.js +69 -0
- package/dist/services/llm/mintoContext.js.map +7 -0
- package/dist/services/llm/openaiProvider.js +622 -0
- package/dist/services/llm/openaiProvider.js.map +7 -0
- package/dist/services/llm/types.js +157 -0
- package/dist/services/llm/types.js.map +7 -0
- package/dist/services/mcpClient.js +183 -33
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/notifier.js +14 -0
- package/dist/services/notifier.js.map +2 -2
- package/dist/services/oauth.js +4 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +66 -56
- package/dist/services/openai.js.map +3 -3
- package/dist/services/outputStyles.js +102 -21
- package/dist/services/outputStyles.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +20 -9
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/sentry.js +1 -1
- package/dist/services/sentry.js.map +2 -2
- package/dist/services/sessionMemory.js +16 -3
- package/dist/services/sessionMemory.js.map +2 -2
- package/dist/services/systemReminder.js +367 -9
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +19 -0
- package/dist/services/taskStore.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
- package/dist/tools/BashTool/BashTool.js +28 -0
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +8 -1
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +14 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +10 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/LspTool/LspTool.js +11 -2
- package/dist/tools/LspTool/LspTool.js.map +2 -2
- package/dist/tools/MCPTool/MCPTool.js.map +1 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
- package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
- package/dist/tools/TaskTool/TaskTool.js +84 -11
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +12 -6
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
- package/dist/tools/WebSearchTool/searchProviders.js +2 -1
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools/lsTool/lsTool.js.map +2 -2
- package/dist/tools/lsTool/prompt.js.map +1 -1
- package/dist/tools.js +14 -3
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +21 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/agentTeams.js +1 -0
- package/dist/types/agentTeams.js.map +7 -0
- package/dist/types/hooks.js +8 -2
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +3 -5
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +91 -15
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js.map +2 -2
- package/dist/utils/animationManager.js +1 -1
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +1 -1
- package/dist/utils/async.js +5 -1
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/autoCompactCore.js +60 -0
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +27 -151
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +227 -0
- package/dist/utils/configSchema.js.map +7 -0
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js +4 -3
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +34 -0
- package/dist/utils/envConfig.js.map +3 -3
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/gpt5.js +146 -0
- package/dist/utils/gpt5.js.map +7 -0
- package/dist/utils/hookManager.js +374 -140
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/markdown.js +47 -0
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +68 -29
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +249 -57
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +77 -12
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/streamingState.js +52 -0
- package/dist/utils/streamingState.js.map +7 -0
- package/dist/utils/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +162 -16
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +0 -6
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskTool/TaskTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TextBlock } from '@anthropic-ai/sdk/resources/index.mjs'\nimport chalk from 'chalk'\nimport { last, memoize } from 'lodash-es'\nimport { EOL } from 'os'\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text } from 'ink'\nimport { z } from 'zod'\nimport { Tool, ValidationResult } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { getAgentPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { AssistantMessage, Message as MessageType, query } from '@query'\nimport { formatDuration, formatNumber } from '@utils/format'\nimport {\n getMessagesPath,\n getNextAvailableLogSidechainNumber,\n overwriteLog,\n logError,\n} from '@utils/log'\nimport { applyMarkdown } from '@utils/markdown'\nimport {\n createAssistantMessage,\n createUserMessage,\n getLastAssistantMessageId,\n INTERRUPT_MESSAGE,\n normalizeMessages,\n} from '@utils/messages'\nimport { getModelManager } from '@utils/model'\nimport { getMaxThinkingTokens } from '@utils/thinking'\nimport { getTheme } from '@utils/theme'\nimport { generateAgentId } from '@utils/agentStorage'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { getTaskTools, getPrompt } from './prompt'\nimport { TOOL_NAME } from './constants'\nimport {\n getActiveAgents,\n getAgentByType,\n getAvailableAgentTypes,\n} from '@utils/agentLoader'\nimport {\n createAgentTranscript,\n getAgentTranscript,\n getResumableTranscript,\n appendMessageToTranscript,\n updateAgentTranscript,\n completeAgentTranscript,\n failAgentTranscript,\n interruptAgentTranscript,\n canResumeTranscript,\n registerToolUseAgent,\n type AgentTranscript,\n} from '@utils/agentTranscripts'\n// Background agent imports removed - run_in_background feature deprecated\nimport { UserFriendlyError, formatErrorForUser } from '@utils/userFriendlyError'\nimport {\n pushAgentContext,\n popAgentContext,\n cleanupAgentStreamingState,\n} from '@components/Spinner'\nimport {\n validateAgentPermission,\n MODE_CONFIGS,\n type PermissionMode,\n} from '@minto-types/PermissionMode'\nimport {\n executeAgentHooks,\n createHookContext,\n} from '@utils/agentHookExecutor'\nimport {\n loadAgentMemory,\n saveAgentMemory,\n formatMemoryForPrompt,\n} from '@utils/agentMemory'\nimport { getSkill, loadSkillContent } from '@utils/skillLoader'\nimport { substituteVariables } from '@utils/stringSubstitution'\n\nconst inputSchema = z.object({\n description: z\n .string()\n .describe('A short (3-5 word) description of the task'),\n prompt: z.string().describe('The task for the agent to perform'),\n model_name: z\n .string()\n .optional()\n .describe(\n 'Optional: Specific model name to use for this task. If not provided, uses the default task model pointer.',\n ),\n model: z\n .enum(['sonnet', 'opus', 'haiku'])\n .optional()\n .describe(\n 'Optional model hint for this agent. Maps to configured model pointers: sonnet\u2192main, opus\u2192reasoning, haiku\u2192quick. If not specified, uses the task model pointer. Prefer haiku for quick, straightforward tasks.',\n ),\n subagent_type: z\n .string()\n .optional()\n .describe(\n 'The specialized agent type to use. MUST be an exact name from the available agents list in the tool description. Defaults to \"general-purpose\" if not specified.',\n ),\n resume: z\n .string()\n .optional()\n .describe(\n 'Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript.',\n ),\n max_turns: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Maximum number of agentic turns (API round-trips) before stopping. Used internally for warmup.',\n ),\n // run_in_background parameter removed - concurrent execution is automatic\n})\n\nexport const TaskTool = {\n async prompt({ safeMode }) {\n return await getPrompt(safeMode)\n },\n name: TOOL_NAME,\n async description() {\n // Dynamically load available agent types from plugins\n const availableTypes = await getAvailableAgentTypes()\n const typesList = availableTypes.join(', ')\n return `Launch a specialized agent to handle tasks autonomously. You MUST use an exact agent type name from this list: ${typesList}. Default to \"general-purpose\" if unsure.`\n },\n inputSchema,\n\n async *call(\n {\n description,\n prompt,\n model_name,\n model,\n subagent_type,\n resume,\n max_turns,\n },\n {\n abortController,\n options: { safeMode = false, forkNumber, messageLogName, verbose },\n readFileTimestamps,\n toolUseId,\n },\n ): AsyncGenerator<\n | { type: 'result'; data: TextBlock[]; resultForAssistant?: string }\n | {\n type: 'progress'\n content: any\n normalizedMessages?: any[]\n tools?: any[]\n },\n void,\n unknown\n > {\n const startTime = Date.now()\n\n // Default to general-purpose if no subagent_type specified\n const agentType = subagent_type || 'general-purpose'\n\n // Handle resume: check if we're resuming from a previous transcript\n let resumedTranscript: AgentTranscript | null = null\n let agentId: string\n\n if (resume) {\n resumedTranscript = getResumableTranscript(resume)\n if (!resumedTranscript) {\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Cannot resume agent '${resume}': transcript not found or not resumable (status must be 'running' or 'interrupted')`,\n },\n ] as TextBlock[],\n resultForAssistant: `Cannot resume agent '${resume}': transcript not found or not resumable`,\n }\n return\n }\n agentId = resume\n debugLogger.info('TASK_AGENT_RESUMING', {\n agentId,\n agentType: resumedTranscript.agentType,\n messageCount: resumedTranscript.messages.length,\n previousStatus: resumedTranscript.status,\n })\n } else {\n agentId = generateAgentId()\n }\n\n // Register toolUseId -> agentId mapping for UI association\n if (toolUseId) {\n registerToolUseAgent(toolUseId, agentId)\n }\n\n // \uD83D\uDD27 CRITICAL FIX: Track whether we've yielded a result to prevent UI stuck state\n let hasYieldedResult = false\n\n // Apply subagent configuration\n let effectivePrompt = prompt\n let effectiveModel = model_name || 'task'\n let toolFilter = null\n let disallowedToolFilter: string[] | null = null // Claude Code spec: disallowedTools denylist\n let temperature = undefined\n let agentMaxThinkingTokens: number | undefined = undefined\n let effectivePermissionMode: PermissionMode = 'default'\n let loadedAgentConfig: Awaited<ReturnType<typeof getAgentByType>> = null\n\n // Load agent configuration dynamically\n if (agentType) {\n const agentConfig = await getAgentByType(agentType)\n\n if (!agentConfig) {\n // If agent type not found, return helpful message instead of throwing\n const availableTypes = await getAvailableAgentTypes()\n const helpMessage = `Agent type '${agentType}' not found.\\n\\nAvailable agents:\\n${availableTypes.map(t => ` \u2022 ${t}`).join('\\n')}\\n\\nUse /agents command to manage agent configurations.`\n\n yield {\n type: 'result',\n data: [{ type: 'text', text: helpMessage }] as TextBlock[],\n resultForAssistant: helpMessage,\n }\n hasYieldedResult = true\n return\n }\n\n // Store config for later use (hooks, memory, etc.)\n loadedAgentConfig = agentConfig\n\n // Apply system prompt if configured\n if (agentConfig.systemPrompt) {\n effectivePrompt = `${agentConfig.systemPrompt}\\n\\n${prompt}`\n }\n\n // Apply model if not overridden by model_name parameter\n if (!model_name && agentConfig.model_name) {\n // Support inherit: keep pointer-based default\n if (agentConfig.model_name !== 'inherit') {\n effectiveModel = agentConfig.model_name as string\n }\n }\n\n // Store tool filter for later application\n toolFilter = agentConfig.tools\n\n // Store disallowed tools filter for later application (Claude Code spec compliance)\n if (agentConfig.disallowedTools?.length) {\n disallowedToolFilter = agentConfig.disallowedTools\n }\n\n // Apply maxThinkingTokens if configured (Claude Code spec)\n if (agentConfig.maxThinkingTokens) {\n agentMaxThinkingTokens = agentConfig.maxThinkingTokens\n }\n\n // Validate and apply permission mode (Claude Code spec)\n // Agent permission cannot exceed session permission level\n if (agentConfig.permissionMode) {\n const sessionMode: PermissionMode = safeMode ? 'plan' : 'default'\n effectivePermissionMode = validateAgentPermission(\n agentConfig.permissionMode,\n sessionMode,\n )\n }\n\n // Load agent memory if configured (Claude Code spec)\n if (agentConfig.memory) {\n try {\n const memoryContent = await loadAgentMemory(\n agentConfig.agentType,\n agentConfig.memory,\n )\n if (memoryContent) {\n // Inject memory into system prompt\n effectivePrompt =\n formatMemoryForPrompt(memoryContent, agentConfig.agentType) +\n '\\n' +\n effectivePrompt\n }\n } catch (error) {\n debugLogger.warn('TASK_AGENT_MEMORY_LOAD_FAILED', {\n agentId,\n agentType,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n // Preload skills if configured (Claude Code spec)\n if (agentConfig.skills?.length) {\n for (const skillName of agentConfig.skills) {\n try {\n const skill = getSkill(skillName)\n if (skill) {\n const skillContent = await loadSkillContent(skill)\n // Apply string substitution for skill content\n const substitutedContent = await substituteVariables(\n skillContent,\n '', // No arguments for preloaded skills\n { sessionId: agentId, cwd: process.cwd() },\n )\n effectivePrompt += `\\n\\n<preloaded-skill name=\"${skillName}\">\\n${substitutedContent}\\n</preloaded-skill>`\n }\n } catch (error) {\n debugLogger.warn('TASK_AGENT_SKILL_PRELOAD_FAILED', {\n agentId,\n skillName,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n }\n\n // Execute onStart hooks if configured (Claude Code spec)\n if (agentConfig.hooks?.onStart?.length) {\n try {\n const hookContext = createHookContext({\n sessionId: agentId,\n agentId,\n agentType,\n })\n const hookResult = await executeAgentHooks(\n 'onStart',\n agentConfig,\n hookContext,\n )\n if (!hookResult.continue) {\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Agent ${agentType} blocked by onStart hook: ${hookResult.reason || 'Hook requested stop'}`,\n },\n ] as TextBlock[],\n resultForAssistant: `Agent blocked by onStart hook: ${hookResult.reason}`,\n }\n hasYieldedResult = true\n return\n }\n } catch (error) {\n debugLogger.warn('TASK_AGENT_ONSTART_HOOK_FAILED', {\n agentId,\n agentType,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n // Note: temperature is not currently in our agent configs\n // but could be added in the future\n }\n\n // Apply model resolution with intelligent fallback\n // Priority: model_name (explicit) > model (alias) > agent config > task pointer > main model\n if (model) {\n // Model aliases are semantic hints, not hardcoded model names\n // Map to Minto's model pointer system for proper resolution\n const modelPointerMap: Record<string, string> = {\n sonnet: 'main', // Use main model for standard tasks\n opus: 'reasoning', // Use reasoning model for complex tasks\n haiku: 'quick', // Use quick model for fast tasks\n }\n\n const pointerType = modelPointerMap[model] || 'task'\n const modelManager = getModelManager()\n const resolvedModelName = modelManager.getModelName(pointerType as any)\n\n if (resolvedModelName) {\n effectiveModel = resolvedModelName\n }\n // If resolution fails, keep the previous effectiveModel (from agent config or 'task' default)\n }\n\n // Initialize messages: either resume from transcript or start fresh\n const messages: MessageType[] = resumedTranscript\n ? [...resumedTranscript.messages]\n : [createUserMessage(effectivePrompt)]\n\n let tools = await getTaskTools(safeMode)\n\n // Apply tool filtering if specified by subagent config\n // Claude Code spec: tools (allowlist) + disallowedTools (denylist) combination\n // Priority: disallowedTools always takes precedence over tools\n if (toolFilter) {\n // Back-compat: ['*'] means all tools\n const isAllArray =\n Array.isArray(toolFilter) &&\n toolFilter.length === 1 &&\n toolFilter[0] === '*'\n if (toolFilter === '*' || isAllArray) {\n // no-op, keep all tools (allowlist permits all)\n } else if (Array.isArray(toolFilter)) {\n tools = tools.filter(tool => toolFilter.includes(tool.name))\n }\n }\n\n // Apply disallowedTools filter (denylist takes precedence over allowlist)\n if (disallowedToolFilter?.length) {\n tools = tools.filter(tool => !disallowedToolFilter!.includes(tool.name))\n }\n\n // Apply permission mode tool restrictions (Claude Code spec)\n // Some permission modes only allow specific tools\n if (effectivePermissionMode !== 'default') {\n const modeConfig = MODE_CONFIGS[effectivePermissionMode]\n if (modeConfig && modeConfig.allowedTools[0] !== '*') {\n tools = tools.filter(tool => modeConfig.allowedTools.includes(tool.name))\n }\n }\n\n // Model already resolved in effectiveModel variable above\n const modelToUse = effectiveModel\n\n // Display initial task information with separate progress lines\n if (resumedTranscript) {\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Resuming agent: ${agentType} (${agentId})`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Restored ${resumedTranscript.messages.length} messages, ${resumedTranscript.toolUseCount} tool uses`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n } else {\n yield {\n type: 'progress',\n content: createAssistantMessage(`Starting agent: ${agentType}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(`Using model: ${modelToUse}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(`Task: ${description}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Prompt: ${prompt.length > 150 ? prompt.substring(0, 150) + '...' : prompt}`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n const [taskPrompt, context, maxThinkingTokens] = await Promise.all([\n getAgentPrompt(),\n getContext(),\n getMaxThinkingTokens(messages),\n ])\n\n // Inject model context to prevent self-referential expert consultations\n taskPrompt.push(\n `\\nIMPORTANT: You are currently running as ${modelToUse}. You do not need to consult ${modelToUse} via AskExpertModel since you ARE ${modelToUse}. Complete tasks directly using your capabilities.`,\n )\n\n // Initialize tool use count (restore from transcript if resuming)\n let toolUseCount = resumedTranscript?.toolUseCount || 0\n\n const getSidechainNumber = memoize(() =>\n getNextAvailableLogSidechainNumber(messageLogName, forkNumber),\n )\n\n // Create or update transcript for this agent execution\n if (!resumedTranscript) {\n createAgentTranscript({\n agentId,\n agentType,\n toolUseId, // Include toolUseId for event-driven UI updates\n description,\n prompt,\n model: modelToUse,\n forkNumber,\n messageLogName,\n messages: [...messages],\n toolUseCount: 0,\n })\n } else {\n // Update transcript status to running when resuming\n appendMessageToTranscript(\n agentId,\n createUserMessage(`[Resumed] ${prompt}`),\n )\n }\n\n // Build query options, adding temperature if specified\n // Use agent-configured maxThinkingTokens if available, otherwise use default\n const effectiveMaxThinkingTokens =\n agentMaxThinkingTokens ?? maxThinkingTokens\n const queryOptions = {\n safeMode,\n forkNumber,\n messageLogName,\n tools,\n commands: [],\n verbose,\n maxThinkingTokens: effectiveMaxThinkingTokens,\n model: modelToUse,\n }\n\n // Add temperature if specified by subagent config\n if (temperature !== undefined) {\n queryOptions['temperature'] = temperature\n }\n\n // \uD83D\uDD27 CRITICAL FIX: Wrap entire query execution in try-catch-finally\n // This ensures we ALWAYS yield a result, even if query() throws an error\n\n // Push agent context so streaming state is isolated for this subagent\n pushAgentContext(agentId)\n\n // Track turn count for max_turns limit\n let turnCount = 0\n\n try {\n for await (const message of query(\n messages,\n taskPrompt,\n context,\n hasPermissionsToUseTool,\n {\n abortController,\n options: queryOptions,\n messageId: getLastAssistantMessageId(messages),\n agentId,\n readFileTimestamps,\n setToolJSX: () => {}, // No-op implementation for TaskTool\n },\n )) {\n messages.push(message)\n\n // Persist message to transcript for resume capability\n appendMessageToTranscript(agentId, message)\n\n overwriteLog(\n getMessagesPath(messageLogName, forkNumber, getSidechainNumber()),\n messages.filter(_ => _.type !== 'progress'),\n )\n\n if (message.type !== 'assistant') {\n continue\n }\n\n // Increment turn count for each assistant message (API round-trip)\n turnCount++\n\n // Check max_turns limit\n if (max_turns && turnCount >= max_turns) {\n debugLogger.info('TASK_AGENT_MAX_TURNS_REACHED', {\n agentId,\n turnCount,\n max_turns,\n })\n // Break out of the query loop - will proceed to normal completion handling\n break\n }\n\n // Real-time token usage update for running task display\n if (message.message.usage) {\n updateAgentTranscript(agentId, {\n tokenUsage: {\n inputTokens: message.message.usage.input_tokens,\n outputTokens: message.message.usage.output_tokens,\n cacheReadTokens: message.message.usage.cache_read_input_tokens,\n cacheCreationTokens:\n message.message.usage.cache_creation_input_tokens,\n },\n })\n }\n\n const normalizedMessages = normalizeMessages(messages)\n\n // Process tool uses and text content for better visibility\n for (const content of message.message.content) {\n if (\n content.type === 'text' &&\n content.text &&\n content.text !== INTERRUPT_MESSAGE\n ) {\n // Show agent's reasoning/responses\n const preview =\n content.text.length > 200\n ? content.text.substring(0, 200) + '...'\n : content.text\n yield {\n type: 'progress',\n content: createAssistantMessage(`${preview}`),\n normalizedMessages,\n tools,\n }\n } else if (content.type === 'tool_use') {\n toolUseCount++\n\n // Show which tool is being used with agent context\n const toolMessage = normalizedMessages.find(\n _ =>\n _.type === 'assistant' &&\n _.message.content[0]?.type === 'tool_use' &&\n _.message.content[0].id === content.id,\n ) as AssistantMessage\n\n if (toolMessage) {\n // Clone and modify the message to show agent context\n const modifiedMessage = {\n ...toolMessage,\n message: {\n ...toolMessage.message,\n content: toolMessage.message.content.map(c => {\n if (c.type === 'tool_use' && c.id === content.id) {\n // Add agent context to tool name display\n return {\n ...c,\n name: c.name, // Keep original name, UI will handle display\n }\n }\n return c\n }),\n },\n }\n\n yield {\n type: 'progress',\n content: modifiedMessage,\n normalizedMessages,\n tools,\n }\n }\n }\n }\n }\n\n const normalizedMessages = normalizeMessages(messages)\n const lastMessage = last(messages)\n if (lastMessage?.type !== 'assistant') {\n throw new Error('Last message was not an assistant message')\n }\n\n // Calculate token usage for transcript\n const tokenUsage = {\n inputTokens: lastMessage.message.usage.input_tokens,\n outputTokens: lastMessage.message.usage.output_tokens,\n cacheReadTokens: lastMessage.message.usage.cache_read_input_tokens,\n cacheCreationTokens:\n lastMessage.message.usage.cache_creation_input_tokens,\n }\n\n // Check for interrupt\n const isInterrupted = lastMessage.message.content.some(\n _ => _.type === 'text' && _.text === INTERRUPT_MESSAGE,\n )\n\n if (isInterrupted) {\n // Mark transcript as interrupted (can be resumed later)\n interruptAgentTranscript(agentId)\n debugLogger.info('TASK_AGENT_INTERRUPTED', { agentId, toolUseCount })\n } else {\n // Mark transcript as completed\n completeAgentTranscript(agentId, tokenUsage)\n debugLogger.info('TASK_AGENT_COMPLETED', { agentId, toolUseCount })\n\n // Execute onComplete hooks if configured (Claude Code spec)\n if (loadedAgentConfig?.hooks?.onComplete?.length) {\n try {\n const hookContext = createHookContext({\n sessionId: agentId,\n agentId,\n agentType,\n result: this.renderResultForAssistant(\n lastMessage.message.content.filter(_ => _.type === 'text'),\n ),\n })\n await executeAgentHooks('onComplete', loadedAgentConfig, hookContext)\n } catch (hookError) {\n debugLogger.warn('TASK_AGENT_ONCOMPLETE_HOOK_FAILED', {\n agentId,\n agentType,\n error:\n hookError instanceof Error\n ? hookError.message\n : String(hookError),\n })\n }\n }\n\n // Save agent memory if configured (Claude Code spec)\n if (loadedAgentConfig?.memory) {\n try {\n // Save the agent's final response as memory\n const finalResponse = lastMessage.message.content\n .filter(_ => _.type === 'text')\n .map(_ => (_ as { type: 'text'; text: string }).text)\n .join('\\n')\n if (finalResponse.trim()) {\n await saveAgentMemory(\n agentType,\n loadedAgentConfig.memory,\n finalResponse,\n )\n }\n } catch (memoryError) {\n debugLogger.warn('TASK_AGENT_MEMORY_SAVE_FAILED', {\n agentId,\n agentType,\n error:\n memoryError instanceof Error\n ? memoryError.message\n : String(memoryError),\n })\n }\n }\n\n const result = [\n toolUseCount === 1 ? '1 tool use' : `${toolUseCount} tool uses`,\n formatNumber(\n (lastMessage.message.usage.cache_creation_input_tokens ?? 0) +\n (lastMessage.message.usage.cache_read_input_tokens ?? 0) +\n lastMessage.message.usage.input_tokens +\n lastMessage.message.usage.output_tokens,\n ) + ' tokens',\n formatDuration(Date.now() - startTime),\n ]\n yield {\n type: 'progress',\n content: createAssistantMessage(`Done (${result.join(' \u00B7 ')})`),\n normalizedMessages,\n tools,\n }\n }\n\n // Output is an AssistantMessage, but since TaskTool is a tool, it needs\n // to serialize its response to UserMessage-compatible content.\n const data = lastMessage.message.content.filter(_ => _.type === 'text')\n\n // Include agentId in result for potential resume\n const resultWithAgentId = isInterrupted\n ? `[Interrupted - Agent ID: ${agentId}]\\n${this.renderResultForAssistant(data)}`\n : this.renderResultForAssistant(data)\n\n yield {\n type: 'result',\n data,\n resultForAssistant: resultWithAgentId,\n }\n hasYieldedResult = true\n } catch (error) {\n // \uD83D\uDD27 CRITICAL: On error, we MUST yield a result to clear UI state\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n\n // \uD83D\uDD27 FIX: Check if this is an AbortError (ESC interrupt)\n // AbortError indicates user interrupted, should mark as 'interrupted' not 'failed'\n const isAbortError =\n error instanceof Error &&\n (error.name === 'AbortError' ||\n error.message.includes('aborted') ||\n error.message.includes('abort'))\n\n if (isAbortError) {\n // Mark transcript as interrupted (can be resumed later)\n interruptAgentTranscript(agentId)\n debugLogger.info('TASK_AGENT_INTERRUPTED_BY_ABORT', {\n agentId,\n toolUseCount,\n })\n\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Task [${agentType}] interrupted\\n[Agent ID: ${agentId}]`,\n },\n ] as TextBlock[],\n resultForAssistant: `Task [${agentType}] interrupted by user\\n[Agent ID: ${agentId} - can be resumed]`,\n }\n } else {\n // Convert to user-friendly error for better UX\n const friendlyError =\n error instanceof UserFriendlyError\n ? error\n : new UserFriendlyError(error, {\n operation: 'agent task',\n model: agentType,\n })\n const friendlyMessage = friendlyError.getUserMessage()\n\n logError(`TaskTool [${agentType}] error: ${errorMessage}`)\n\n // Mark transcript as failed with friendly message\n failAgentTranscript(agentId, friendlyMessage)\n debugLogger.error('TASK_AGENT_FAILED', {\n agentId,\n error: errorMessage,\n errorId: friendlyError.id,\n })\n\n // Execute onError hooks if configured (Claude Code spec)\n if (loadedAgentConfig?.hooks?.onError?.length) {\n try {\n const hookContext = createHookContext({\n sessionId: agentId,\n agentId,\n agentType,\n error: error instanceof Error ? error : new Error(String(error)),\n })\n await executeAgentHooks('onError', loadedAgentConfig, hookContext)\n } catch (hookError) {\n debugLogger.warn('TASK_AGENT_ONERROR_HOOK_FAILED', {\n agentId,\n agentType,\n error:\n hookError instanceof Error\n ? hookError.message\n : String(hookError),\n })\n }\n }\n\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `${friendlyMessage}\\n[Agent ID: ${agentId}]`,\n },\n ] as TextBlock[],\n resultForAssistant: `Task [${agentType}] failed: ${errorMessage}\\n[Agent ID: ${agentId} - can be resumed]`,\n }\n }\n hasYieldedResult = true\n } finally {\n // Pop agent context and clean up streaming state\n popAgentContext()\n cleanupAgentStreamingState(agentId)\n\n // \uD83D\uDD27 SAFETY NET: Ensure we always yield a result even in unexpected scenarios\n if (!hasYieldedResult) {\n // Mark as interrupted if we haven't yielded a result\n interruptAgentTranscript(agentId)\n\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Task [${agentType}] terminated unexpectedly\\n[Agent ID: ${agentId}]`,\n },\n ] as TextBlock[],\n resultForAssistant: `Task [${agentType}] terminated unexpectedly\\n[Agent ID: ${agentId} - can be resumed]`,\n }\n }\n }\n },\n\n isReadOnly() {\n return true // for now...\n },\n isConcurrencySafe() {\n return true // Task tool supports concurrent execution in official implementation\n },\n async validateInput(input, context) {\n if (!input.description || typeof input.description !== 'string') {\n return {\n result: false,\n message: 'Description is required and must be a string',\n }\n }\n if (!input.prompt || typeof input.prompt !== 'string') {\n return {\n result: false,\n message: 'Prompt is required and must be a string',\n }\n }\n\n // Model validation - similar to Edit tool error handling\n if (input.model_name) {\n const modelManager = getModelManager()\n const availableModels = modelManager.getAllAvailableModelNames()\n\n if (!availableModels.includes(input.model_name)) {\n return {\n result: false,\n message: `Model '${input.model_name}' does not exist. Available models: ${availableModels.join(', ')}`,\n meta: {\n model_name: input.model_name,\n availableModels,\n },\n }\n }\n }\n\n // Validate subagent_type if provided\n if (input.subagent_type) {\n const availableTypes = await getAvailableAgentTypes()\n if (!availableTypes.includes(input.subagent_type)) {\n return {\n result: false,\n message: `Agent type '${input.subagent_type}' does not exist. Available types: ${availableTypes.join(', ')}`,\n meta: {\n subagent_type: input.subagent_type,\n availableTypes,\n },\n }\n }\n }\n\n // Validate resume parameter if provided\n if (input.resume) {\n if (!canResumeTranscript(input.resume)) {\n return {\n result: false,\n message: `Cannot resume agent '${input.resume}': transcript not found or not resumable (status must be 'running' or 'interrupted')`,\n meta: {\n resume: input.resume,\n },\n }\n }\n }\n\n return { result: true }\n },\n async isEnabled() {\n return true\n },\n userFacingName(input?: any) {\n // Return agent name with proper prefix\n const agentType = input?.subagent_type || 'general-purpose'\n return `agent-${agentType}`\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(data: TextBlock[]) {\n return data\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n },\n renderToolUseMessage(\n { description, prompt, model_name, subagent_type },\n { verbose },\n ) {\n if (!description || !prompt) return null\n\n const modelManager = getModelManager()\n const defaultTaskModel = modelManager.getModelName('task')\n const actualModel = model_name || defaultTaskModel\n const agentType = subagent_type || 'general-purpose'\n const promptPreview =\n prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt\n\n const theme = getTheme()\n\n if (verbose) {\n return (\n <Box flexDirection=\"column\">\n <Text>\n [{agentType}] {actualModel}: {description}\n </Text>\n <Box\n paddingLeft={2}\n borderLeftStyle=\"single\"\n borderLeftColor={theme.secondaryBorder}\n >\n <Text color={theme.secondaryText}>{promptPreview}</Text>\n </Box>\n </Box>\n )\n }\n\n // Simple display: agent type, model and description\n return `[${agentType}] ${actualModel}: ${description}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(content, options?: { verbose?: boolean }) {\n const theme = getTheme()\n const verbose = options?.verbose ?? false\n\n // Guard against undefined or null content\n if (!content) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.success}>Done</Text>\n </Box>\n )\n }\n\n if (Array.isArray(content)) {\n const textBlocks = content.filter(\n (block): block is { type: 'text'; text: string } =>\n block && block.type === 'text',\n )\n const totalLength = textBlocks.reduce(\n (sum, block) => sum + (block.text?.length || 0),\n 0,\n )\n // Use exact match for interrupt detection\n const isInterrupted = content.some(\n block =>\n block && block.type === 'text' && block.text === INTERRUPT_MESSAGE,\n )\n\n if (isInterrupted) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.error}>Interrupted by user</Text>\n </Box>\n )\n }\n\n // Extract output content for display based on verbosity\n const outputText = textBlocks.map(b => b.text).join('\\n')\n\n // Determine how much content to show based on displayMode\n // minimal/compact (verbose=false): Just show \"Task completed (X characters)\"\n // detailed (verbose=true): Show preview of the actual output\n const getOutputPreview = () => {\n if (!verbose || !outputText) return null\n const maxLen = 500\n if (outputText.length <= maxLen) return outputText\n return outputText.substring(0, maxLen) + '...'\n }\n\n const outputPreview = getOutputPreview()\n\n return (\n <Box flexDirection=\"column\">\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.success}>Done</Text>\n {textBlocks.length > 0 && verbose && (\n <Text color={theme.secondaryText}> ({totalLength} chars)</Text>\n )}\n </Box>\n </Box>\n {outputPreview && (\n <Box marginTop={1} paddingLeft={4}>\n <Text color={theme.mutedText}>{outputPreview}</Text>\n </Box>\n )}\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.success}>Done</Text>\n </Box>\n )\n },\n} satisfies Tool<typeof inputSchema, TextBlock[]>\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { TextBlock } from '@anthropic-ai/sdk/resources/index.mjs'\nimport chalk from 'chalk'\nimport { last, memoize } from 'lodash-es'\nimport { EOL } from 'os'\nimport { dirname } from 'path'\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text } from 'ink'\nimport { z } from 'zod'\nimport { Tool, ValidationResult } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { getAgentPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { AssistantMessage, Message as MessageType, query } from '@query'\nimport { formatDuration, formatNumber } from '@utils/format'\nimport {\n getMessagesPath,\n getNextAvailableLogSidechainNumber,\n overwriteLog,\n logError,\n} from '@utils/log'\nimport { applyMarkdown } from '@utils/markdown'\nimport {\n createAssistantMessage,\n createUserMessage,\n getLastAssistantMessageId,\n INTERRUPT_MESSAGE,\n normalizeMessages,\n} from '@utils/messages'\nimport { getModelManager } from '@utils/model'\nimport { getMaxThinkingTokens } from '@utils/thinking'\nimport { getTheme } from '@utils/theme'\nimport { generateAgentId } from '@utils/agentStorage'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { getTaskTools, getPrompt } from './prompt'\nimport { TOOL_NAME } from './constants'\nimport {\n getActiveAgents,\n getAgentByType,\n getAvailableAgentTypes,\n} from '@utils/agentLoader'\nimport {\n createAgentTranscript,\n getAgentTranscript,\n getResumableTranscript,\n appendMessageToTranscript,\n updateAgentTranscript,\n completeAgentTranscript,\n failAgentTranscript,\n interruptAgentTranscript,\n canResumeTranscript,\n registerToolUseAgent,\n type AgentTranscript,\n} from '@utils/agentTranscripts'\n// Background agent imports removed - run_in_background feature deprecated\nimport { UserFriendlyError, formatErrorForUser } from '@utils/userFriendlyError'\nimport { execSync } from 'child_process'\nimport {\n pushAgentContext,\n popAgentContext,\n cleanupAgentStreamingState,\n} from '@utils/streamingState'\nimport {\n validateAgentPermission,\n MODE_CONFIGS,\n type PermissionMode,\n} from '@minto-types/PermissionMode'\nimport { executeAgentHooks, createHookContext } from '@utils/agentHookExecutor'\nimport {\n loadAgentMemory,\n saveAgentMemory,\n formatMemoryForPrompt,\n} from '@utils/agentMemory'\nimport { getSkill, loadSkillContent } from '@utils/skillLoader'\nimport { getCwd } from '@utils/state'\nimport { getHookManager } from '@utils/hookManager'\nimport { substituteVariables } from '@utils/stringSubstitution'\n\nconst inputSchema = z.object({\n description: z\n .string()\n .describe('A short (3-5 word) description of the task'),\n prompt: z.string().describe('The task for the agent to perform'),\n model_name: z\n .string()\n .optional()\n .describe(\n 'Optional: Specific model name to use for this task. If not provided, uses the default task model pointer.',\n ),\n model: z\n .enum(['sonnet', 'opus', 'haiku'])\n .optional()\n .describe(\n 'Optional model hint for this agent. Maps to configured model pointers: sonnet\u2192main, opus\u2192reasoning, haiku\u2192quick. If not specified, uses the task model pointer. Prefer haiku for quick, straightforward tasks.',\n ),\n subagent_type: z\n .string()\n .optional()\n .describe(\n 'The specialized agent type to use. MUST be an exact name from the available agents list in the tool description. Defaults to \"general-purpose\" if not specified.',\n ),\n resume: z\n .string()\n .optional()\n .describe(\n 'Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript.',\n ),\n max_turns: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Maximum number of agentic turns (API round-trips) before stopping. Used internally for warmup.',\n ),\n // run_in_background parameter removed - concurrent execution is automatic\n})\n\nexport const TaskTool = {\n async prompt({ safeMode }) {\n return await getPrompt(safeMode)\n },\n name: TOOL_NAME,\n async description() {\n // Dynamically load available agent types from plugins\n const availableTypes = await getAvailableAgentTypes()\n const typesList = availableTypes.join(', ')\n return `Launch a specialized agent to handle tasks autonomously. You MUST use an exact agent type name from this list: ${typesList}. Default to \"general-purpose\" if unsure.`\n },\n inputSchema,\n\n async *call(\n {\n description,\n prompt,\n model_name,\n model,\n subagent_type,\n resume,\n max_turns,\n },\n {\n abortController,\n options: { safeMode = false, forkNumber, messageLogName, verbose },\n readFileTimestamps,\n toolUseId,\n },\n ): AsyncGenerator<\n | { type: 'result'; data: TextBlock[]; resultForAssistant?: string }\n | {\n type: 'progress'\n content: any\n normalizedMessages?: any[]\n tools?: any[]\n },\n void,\n unknown\n > {\n const startTime = Date.now()\n\n // Default to general-purpose if no subagent_type specified\n const agentType = subagent_type || 'general-purpose'\n\n // Handle resume: check if we're resuming from a previous transcript\n let resumedTranscript: AgentTranscript | null = null\n let agentId: string\n\n if (resume) {\n resumedTranscript = getResumableTranscript(resume)\n if (!resumedTranscript) {\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Cannot resume agent '${resume}': transcript not found or not resumable (status must be 'running' or 'interrupted')`,\n },\n ] as TextBlock[],\n resultForAssistant: `Cannot resume agent '${resume}': transcript not found or not resumable`,\n }\n return\n }\n agentId = resume\n debugLogger.info('TASK_AGENT_RESUMING', {\n agentId,\n agentType: resumedTranscript.agentType,\n messageCount: resumedTranscript.messages.length,\n previousStatus: resumedTranscript.status,\n })\n } else {\n agentId = generateAgentId()\n }\n\n // Register toolUseId -> agentId mapping for UI association\n if (toolUseId) {\n registerToolUseAgent(toolUseId, agentId)\n }\n\n // \uD83D\uDD27 CRITICAL FIX: Track whether we've yielded a result to prevent UI stuck state\n let hasYieldedResult = false\n\n // Apply subagent configuration\n let effectivePrompt = prompt\n let effectiveModel = model_name || 'task'\n let toolFilter = null\n let disallowedToolFilter: string[] | null = null // Claude Code spec: disallowedTools denylist\n let temperature = undefined\n let agentMaxThinkingTokens: number | undefined = undefined\n let effectivePermissionMode: PermissionMode = 'default'\n let loadedAgentConfig: Awaited<ReturnType<typeof getAgentByType>> = null\n\n // Load agent configuration dynamically\n if (agentType) {\n const agentConfig = await getAgentByType(agentType)\n\n if (!agentConfig) {\n // If agent type not found, return helpful message instead of throwing\n const availableTypes = await getAvailableAgentTypes()\n const helpMessage = `Agent type '${agentType}' not found.\\n\\nAvailable agents:\\n${availableTypes.map(t => ` \u2022 ${t}`).join('\\n')}\\n\\nUse /agents command to manage agent configurations.`\n\n yield {\n type: 'result',\n data: [{ type: 'text', text: helpMessage }] as TextBlock[],\n resultForAssistant: helpMessage,\n }\n hasYieldedResult = true\n return\n }\n\n // Store config for later use (hooks, memory, etc.)\n loadedAgentConfig = agentConfig\n\n // Apply system prompt if configured\n if (agentConfig.systemPrompt) {\n effectivePrompt = `${agentConfig.systemPrompt}\\n\\n${prompt}`\n }\n\n // Apply model if not overridden by model_name parameter\n if (!model_name && agentConfig.model_name) {\n // Support inherit: keep pointer-based default\n if (agentConfig.model_name !== 'inherit') {\n effectiveModel = agentConfig.model_name as string\n }\n }\n\n // Store tool filter for later application\n toolFilter = agentConfig.tools\n\n // Store disallowed tools filter for later application (Claude Code spec compliance)\n if (agentConfig.disallowedTools?.length) {\n disallowedToolFilter = agentConfig.disallowedTools\n }\n\n // Apply maxThinkingTokens if configured (Claude Code spec)\n if (agentConfig.maxThinkingTokens) {\n agentMaxThinkingTokens = agentConfig.maxThinkingTokens\n }\n\n // Validate and apply permission mode (Claude Code spec)\n // Agent permission cannot exceed session permission level\n if (agentConfig.permissionMode) {\n const sessionMode: PermissionMode = safeMode ? 'plan' : 'default'\n effectivePermissionMode = validateAgentPermission(\n agentConfig.permissionMode,\n sessionMode,\n )\n }\n\n // Load agent memory if configured (Claude Code spec)\n if (agentConfig.memory) {\n try {\n const memoryContent = await loadAgentMemory(\n agentConfig.agentType,\n agentConfig.memory,\n )\n if (memoryContent) {\n // Inject memory into system prompt\n effectivePrompt =\n formatMemoryForPrompt(memoryContent, agentConfig.agentType) +\n '\\n' +\n effectivePrompt\n }\n } catch (error) {\n debugLogger.warn('TASK_AGENT_MEMORY_LOAD_FAILED', {\n agentId,\n agentType,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n // Preload skills if configured (Claude Code spec)\n if (agentConfig.skills?.length) {\n for (const skillName of agentConfig.skills) {\n try {\n const skill = getSkill(skillName)\n if (skill) {\n const skillContent = await loadSkillContent(skill)\n const skillBaseDir = dirname(skill.filePath)\n // Apply {baseDir} resolution and string substitution\n const resolvedContent = skillContent.replace(\n /\\{baseDir\\}/g,\n skillBaseDir,\n )\n const substitutedContent = await substituteVariables(\n resolvedContent,\n '', // No arguments for preloaded skills\n {\n sessionId: agentId,\n cwd: process.cwd(),\n env: { BASE_DIR: skillBaseDir },\n },\n )\n effectivePrompt += `\\n\\n<preloaded-skill name=\"${skillName}\">\\n${substitutedContent}\\n</preloaded-skill>`\n }\n } catch (error) {\n debugLogger.warn('TASK_AGENT_SKILL_PRELOAD_FAILED', {\n agentId,\n skillName,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n }\n\n // Execute onStart hooks if configured (Claude Code spec)\n if (agentConfig.hooks?.onStart?.length) {\n try {\n const hookContext = createHookContext({\n sessionId: agentId,\n agentId,\n agentType,\n })\n const hookResult = await executeAgentHooks(\n 'onStart',\n agentConfig,\n hookContext,\n )\n if (!hookResult.continue) {\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Agent ${agentType} blocked by onStart hook: ${hookResult.reason || 'Hook requested stop'}`,\n },\n ] as TextBlock[],\n resultForAssistant: `Agent blocked by onStart hook: ${hookResult.reason}`,\n }\n hasYieldedResult = true\n return\n }\n } catch (error) {\n debugLogger.warn('TASK_AGENT_ONSTART_HOOK_FAILED', {\n agentId,\n agentType,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n // Note: temperature is not currently in our agent configs\n // but could be added in the future\n }\n\n // Apply model resolution with intelligent fallback\n // Priority: model_name (explicit) > model (alias) > agent config > task pointer > main model\n if (model) {\n // Model aliases are semantic hints, not hardcoded model names\n // Map to Minto's model pointer system for proper resolution\n const modelPointerMap: Record<string, string> = {\n sonnet: 'main', // Use main model for standard tasks\n opus: 'reasoning', // Use reasoning model for complex tasks\n haiku: 'quick', // Use quick model for fast tasks\n }\n\n const pointerType = modelPointerMap[model] || 'task'\n const modelManager = getModelManager()\n const resolvedModelName = modelManager.getModelName(pointerType as any)\n\n if (resolvedModelName) {\n effectiveModel = resolvedModelName\n }\n // If resolution fails, keep the previous effectiveModel (from agent config or 'task' default)\n }\n\n // Git worktree isolation: create isolated worktree for parallel edits\n let worktreePath: string | null = null\n if (loadedAgentConfig?.isolation === 'worktree') {\n try {\n const tmpDir = `/tmp/minto-worktree-${agentId}`\n execSync(`git worktree add \"${tmpDir}\" HEAD`, {\n cwd: getCwd(),\n stdio: 'pipe',\n })\n worktreePath = tmpDir\n effectivePrompt = `[Working in isolated git worktree: ${tmpDir}]\\n\\n${effectivePrompt}`\n debugLogger.info('TASK_AGENT_WORKTREE_CREATED', {\n agentId,\n worktreePath,\n })\n } catch (err) {\n debugLogger.warn('TASK_AGENT_WORKTREE_FAILED', {\n agentId,\n error: err instanceof Error ? err.message : String(err),\n })\n // Continue without worktree \u2014 non-git repos or worktree errors\n }\n }\n\n // Initialize messages: either resume from transcript or start fresh\n const messages: MessageType[] = resumedTranscript\n ? [...resumedTranscript.messages]\n : [createUserMessage(effectivePrompt)]\n\n let tools = await getTaskTools(safeMode)\n\n // Apply tool filtering if specified by subagent config\n // Claude Code spec: tools (allowlist) + disallowedTools (denylist) combination\n // Priority: disallowedTools always takes precedence over tools\n // Supports Task(agent_type) syntax to restrict which subagent types can be spawned\n let allowedSubagentTypes: string[] | null = null\n if (toolFilter) {\n // Back-compat: ['*'] means all tools\n const isAllArray =\n Array.isArray(toolFilter) &&\n toolFilter.length === 1 &&\n toolFilter[0] === '*'\n if (toolFilter === '*' || isAllArray) {\n // no-op, keep all tools (allowlist permits all)\n } else if (Array.isArray(toolFilter)) {\n // Extract Task(type) restrictions\n const taskPatterns = toolFilter\n .filter((t: string) => t.startsWith('Task(') && t.endsWith(')'))\n .map((t: string) => t.slice(5, -1))\n if (taskPatterns.length > 0) {\n allowedSubagentTypes = taskPatterns\n }\n\n // Filter tools: include Task tool if any Task() pattern exists\n const baseToolNames = toolFilter\n .map((t: string) => (t.startsWith('Task(') ? 'Task' : t))\n .filter((t: string, i: number, arr: string[]) => arr.indexOf(t) === i)\n tools = tools.filter(tool => baseToolNames.includes(tool.name))\n }\n }\n\n // Apply disallowedTools filter (denylist takes precedence over allowlist)\n if (disallowedToolFilter?.length) {\n tools = tools.filter(tool => !disallowedToolFilter!.includes(tool.name))\n }\n\n // Apply permission mode tool restrictions (Claude Code spec)\n // Some permission modes only allow specific tools\n if (effectivePermissionMode !== 'default') {\n const modeConfig = MODE_CONFIGS[effectivePermissionMode]\n if (modeConfig && modeConfig.allowedTools[0] !== '*') {\n tools = tools.filter(tool =>\n modeConfig.allowedTools.includes(tool.name),\n )\n }\n }\n\n // Model already resolved in effectiveModel variable above\n const modelToUse = effectiveModel\n\n // Display initial task information with separate progress lines\n if (resumedTranscript) {\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Resuming agent: ${agentType} (${agentId})`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Restored ${resumedTranscript.messages.length} messages, ${resumedTranscript.toolUseCount} tool uses`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n } else {\n yield {\n type: 'progress',\n content: createAssistantMessage(`Starting agent: ${agentType}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(`Using model: ${modelToUse}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(`Task: ${description}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Prompt: ${prompt.length > 150 ? prompt.substring(0, 150) + '...' : prompt}`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n const [taskPrompt, context, maxThinkingTokens] = await Promise.all([\n getAgentPrompt(),\n getContext(),\n getMaxThinkingTokens(messages),\n ])\n\n // Inject model context to prevent self-referential expert consultations\n taskPrompt.push(\n `\\nIMPORTANT: You are currently running as ${modelToUse}. You do not need to consult ${modelToUse} via AskExpertModel since you ARE ${modelToUse}. Complete tasks directly using your capabilities.`,\n )\n\n // Initialize tool use count (restore from transcript if resuming)\n let toolUseCount = resumedTranscript?.toolUseCount || 0\n\n const getSidechainNumber = memoize(() =>\n getNextAvailableLogSidechainNumber(messageLogName, forkNumber),\n )\n\n // Fire SubagentStart hook (fire-and-forget)\n const hookMgr = getHookManager()\n if (hookMgr) {\n hookMgr\n .executeSubagentStart(agentType, description)\n .catch(err =>\n debugLogger.warn('SubagentStart hook failed', { error: err }),\n )\n }\n\n // Create or update transcript for this agent execution\n if (!resumedTranscript) {\n createAgentTranscript({\n agentId,\n agentType,\n toolUseId, // Include toolUseId for event-driven UI updates\n description,\n prompt,\n model: modelToUse,\n forkNumber,\n messageLogName,\n messages: [...messages],\n toolUseCount: 0,\n })\n } else {\n // Update transcript status to running when resuming\n appendMessageToTranscript(\n agentId,\n createUserMessage(`[Resumed] ${prompt}`),\n )\n }\n\n // Build query options, adding temperature if specified\n // Use agent-configured maxThinkingTokens if available, otherwise use default\n const effectiveMaxThinkingTokens =\n agentMaxThinkingTokens ?? maxThinkingTokens\n const queryOptions = {\n safeMode,\n forkNumber,\n messageLogName,\n tools,\n commands: [],\n verbose,\n maxThinkingTokens: effectiveMaxThinkingTokens,\n model: modelToUse,\n }\n\n // Add temperature if specified by subagent config\n if (temperature !== undefined) {\n queryOptions['temperature'] = temperature\n }\n\n // \uD83D\uDD27 CRITICAL FIX: Wrap entire query execution in try-catch-finally\n // This ensures we ALWAYS yield a result, even if query() throws an error\n\n // Push agent context so streaming state is isolated for this subagent\n pushAgentContext(agentId)\n\n // Track turn count for max_turns limit\n let turnCount = 0\n\n try {\n for await (const message of query(\n messages,\n taskPrompt,\n context,\n hasPermissionsToUseTool,\n {\n abortController,\n options: queryOptions,\n messageId: getLastAssistantMessageId(messages),\n agentId,\n readFileTimestamps,\n setToolJSX: () => {}, // No-op implementation for TaskTool\n },\n )) {\n messages.push(message)\n\n // Persist message to transcript for resume capability\n appendMessageToTranscript(agentId, message)\n\n overwriteLog(\n getMessagesPath(messageLogName, forkNumber, getSidechainNumber()),\n messages.filter(_ => _.type !== 'progress'),\n )\n\n if (message.type !== 'assistant') {\n continue\n }\n\n // Increment turn count for each assistant message (API round-trip)\n turnCount++\n\n // Check max_turns limit\n if (max_turns && turnCount >= max_turns) {\n debugLogger.info('TASK_AGENT_MAX_TURNS_REACHED', {\n agentId,\n turnCount,\n max_turns,\n })\n // Break out of the query loop - will proceed to normal completion handling\n break\n }\n\n // Real-time token usage update for running task display\n if (message.message.usage) {\n updateAgentTranscript(agentId, {\n tokenUsage: {\n inputTokens: message.message.usage.input_tokens,\n outputTokens: message.message.usage.output_tokens,\n cacheReadTokens: message.message.usage.cache_read_input_tokens,\n cacheCreationTokens:\n message.message.usage.cache_creation_input_tokens,\n },\n })\n }\n\n const normalizedMessages = normalizeMessages(messages)\n\n // Process tool uses and text content for better visibility\n for (const content of message.message.content) {\n if (\n content.type === 'text' &&\n content.text &&\n content.text !== INTERRUPT_MESSAGE\n ) {\n // Show agent's reasoning/responses\n const preview =\n content.text.length > 200\n ? content.text.substring(0, 200) + '...'\n : content.text\n yield {\n type: 'progress',\n content: createAssistantMessage(`${preview}`),\n normalizedMessages,\n tools,\n }\n } else if (content.type === 'tool_use') {\n toolUseCount++\n\n // Show which tool is being used with agent context\n const toolMessage = normalizedMessages.find(\n _ =>\n _.type === 'assistant' &&\n _.message.content[0]?.type === 'tool_use' &&\n _.message.content[0].id === content.id,\n ) as AssistantMessage\n\n if (toolMessage) {\n // Clone and modify the message to show agent context\n const modifiedMessage = {\n ...toolMessage,\n message: {\n ...toolMessage.message,\n content: toolMessage.message.content.map(c => {\n if (c.type === 'tool_use' && c.id === content.id) {\n // Add agent context to tool name display\n return {\n ...c,\n name: c.name, // Keep original name, UI will handle display\n }\n }\n return c\n }),\n },\n }\n\n yield {\n type: 'progress',\n content: modifiedMessage,\n normalizedMessages,\n tools,\n }\n }\n }\n }\n }\n\n const normalizedMessages = normalizeMessages(messages)\n const lastMessage = last(messages)\n if (lastMessage?.type !== 'assistant') {\n throw new Error('Last message was not an assistant message')\n }\n\n // Calculate token usage for transcript\n const tokenUsage = {\n inputTokens: lastMessage.message.usage.input_tokens,\n outputTokens: lastMessage.message.usage.output_tokens,\n cacheReadTokens: lastMessage.message.usage.cache_read_input_tokens,\n cacheCreationTokens:\n lastMessage.message.usage.cache_creation_input_tokens,\n }\n\n // Check for interrupt\n const isInterrupted = lastMessage.message.content.some(\n _ => _.type === 'text' && _.text === INTERRUPT_MESSAGE,\n )\n\n if (isInterrupted) {\n // Mark transcript as interrupted (can be resumed later)\n interruptAgentTranscript(agentId)\n debugLogger.info('TASK_AGENT_INTERRUPTED', { agentId, toolUseCount })\n } else {\n // Mark transcript as completed\n completeAgentTranscript(agentId, tokenUsage)\n debugLogger.info('TASK_AGENT_COMPLETED', { agentId, toolUseCount })\n\n // Fire SubagentStop hook (fire-and-forget)\n if (hookMgr) {\n hookMgr\n .executeSubagentStop(agentType, agentId)\n .catch(err =>\n debugLogger.warn('SubagentStop hook failed', { error: err }),\n )\n }\n\n // Execute onComplete hooks if configured (Claude Code spec)\n if (loadedAgentConfig?.hooks?.onComplete?.length) {\n try {\n const hookContext = createHookContext({\n sessionId: agentId,\n agentId,\n agentType,\n result: this.renderResultForAssistant(\n lastMessage.message.content.filter(_ => _.type === 'text'),\n ),\n })\n await executeAgentHooks(\n 'onComplete',\n loadedAgentConfig,\n hookContext,\n )\n } catch (hookError) {\n debugLogger.warn('TASK_AGENT_ONCOMPLETE_HOOK_FAILED', {\n agentId,\n agentType,\n error:\n hookError instanceof Error\n ? hookError.message\n : String(hookError),\n })\n }\n }\n\n // Save agent memory if configured (Claude Code spec)\n if (loadedAgentConfig?.memory) {\n try {\n // Save the agent's final response as memory\n const finalResponse = lastMessage.message.content\n .filter(_ => _.type === 'text')\n .map(_ => (_ as { type: 'text'; text: string }).text)\n .join('\\n')\n if (finalResponse.trim()) {\n await saveAgentMemory(\n agentType,\n loadedAgentConfig.memory,\n finalResponse,\n )\n }\n } catch (memoryError) {\n debugLogger.warn('TASK_AGENT_MEMORY_SAVE_FAILED', {\n agentId,\n agentType,\n error:\n memoryError instanceof Error\n ? memoryError.message\n : String(memoryError),\n })\n }\n }\n\n const result = [\n toolUseCount === 1 ? '1 tool use' : `${toolUseCount} tool uses`,\n formatNumber(\n (lastMessage.message.usage.cache_creation_input_tokens ?? 0) +\n (lastMessage.message.usage.cache_read_input_tokens ?? 0) +\n lastMessage.message.usage.input_tokens +\n lastMessage.message.usage.output_tokens,\n ) + ' tokens',\n formatDuration(Date.now() - startTime),\n ]\n yield {\n type: 'progress',\n content: createAssistantMessage(`Done (${result.join(' \u00B7 ')})`),\n normalizedMessages,\n tools,\n }\n }\n\n // Output is an AssistantMessage, but since TaskTool is a tool, it needs\n // to serialize its response to UserMessage-compatible content.\n const data = lastMessage.message.content.filter(_ => _.type === 'text')\n\n // Include agentId in result for potential resume\n const resultWithAgentId = isInterrupted\n ? `[Interrupted - Agent ID: ${agentId}]\\n${this.renderResultForAssistant(data)}`\n : this.renderResultForAssistant(data)\n\n yield {\n type: 'result',\n data,\n resultForAssistant: resultWithAgentId,\n }\n hasYieldedResult = true\n } catch (error) {\n // \uD83D\uDD27 CRITICAL: On error, we MUST yield a result to clear UI state\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n\n // \uD83D\uDD27 FIX: Check if this is an AbortError (ESC interrupt)\n // AbortError indicates user interrupted, should mark as 'interrupted' not 'failed'\n const isAbortError =\n error instanceof Error &&\n (error.name === 'AbortError' ||\n error.message.includes('aborted') ||\n error.message.includes('abort'))\n\n if (isAbortError) {\n // Mark transcript as interrupted (can be resumed later)\n interruptAgentTranscript(agentId)\n debugLogger.info('TASK_AGENT_INTERRUPTED_BY_ABORT', {\n agentId,\n toolUseCount,\n })\n\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Task [${agentType}] interrupted\\n[Agent ID: ${agentId}]`,\n },\n ] as TextBlock[],\n resultForAssistant: `Task [${agentType}] interrupted by user\\n[Agent ID: ${agentId} - can be resumed]`,\n }\n } else {\n // Convert to user-friendly error for better UX\n const friendlyError =\n error instanceof UserFriendlyError\n ? error\n : new UserFriendlyError(error, {\n operation: 'agent task',\n model: agentType,\n })\n const friendlyMessage = friendlyError.getUserMessage()\n\n logError(`TaskTool [${agentType}] error: ${errorMessage}`)\n\n // Mark transcript as failed with friendly message\n failAgentTranscript(agentId, friendlyMessage)\n debugLogger.error('TASK_AGENT_FAILED', {\n agentId,\n error: errorMessage,\n errorId: friendlyError.id,\n })\n\n // Execute onError hooks if configured (Claude Code spec)\n if (loadedAgentConfig?.hooks?.onError?.length) {\n try {\n const hookContext = createHookContext({\n sessionId: agentId,\n agentId,\n agentType,\n error: error instanceof Error ? error : new Error(String(error)),\n })\n await executeAgentHooks('onError', loadedAgentConfig, hookContext)\n } catch (hookError) {\n debugLogger.warn('TASK_AGENT_ONERROR_HOOK_FAILED', {\n agentId,\n agentType,\n error:\n hookError instanceof Error\n ? hookError.message\n : String(hookError),\n })\n }\n }\n\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `${friendlyMessage}\\n[Agent ID: ${agentId}]`,\n },\n ] as TextBlock[],\n resultForAssistant: `Task [${agentType}] failed: ${errorMessage}\\n[Agent ID: ${agentId} - can be resumed]`,\n }\n }\n hasYieldedResult = true\n } finally {\n // Cleanup git worktree if created\n if (worktreePath) {\n try {\n execSync(`git worktree remove \"${worktreePath}\" --force`, {\n cwd: getCwd(),\n stdio: 'pipe',\n })\n debugLogger.info('TASK_AGENT_WORKTREE_REMOVED', {\n agentId,\n worktreePath,\n })\n } catch {\n debugLogger.warn('TASK_AGENT_WORKTREE_CLEANUP_FAILED', {\n agentId,\n worktreePath,\n })\n }\n }\n\n // Pop agent context and clean up streaming state\n popAgentContext()\n cleanupAgentStreamingState(agentId)\n\n // \uD83D\uDD27 SAFETY NET: Ensure we always yield a result even in unexpected scenarios\n if (!hasYieldedResult) {\n // Mark as interrupted if we haven't yielded a result\n interruptAgentTranscript(agentId)\n\n yield {\n type: 'result',\n data: [\n {\n type: 'text',\n text: `Task [${agentType}] terminated unexpectedly\\n[Agent ID: ${agentId}]`,\n },\n ] as TextBlock[],\n resultForAssistant: `Task [${agentType}] terminated unexpectedly\\n[Agent ID: ${agentId} - can be resumed]`,\n }\n }\n }\n },\n\n isReadOnly() {\n return true // for now...\n },\n isConcurrencySafe() {\n return true // Task tool supports concurrent execution in official implementation\n },\n async validateInput(input, context) {\n if (!input.description || typeof input.description !== 'string') {\n return {\n result: false,\n message: 'Description is required and must be a string',\n }\n }\n if (!input.prompt || typeof input.prompt !== 'string') {\n return {\n result: false,\n message: 'Prompt is required and must be a string',\n }\n }\n\n // Model validation - similar to Edit tool error handling\n if (input.model_name) {\n const modelManager = getModelManager()\n const availableModels = modelManager.getAllAvailableModelNames()\n\n if (!availableModels.includes(input.model_name)) {\n return {\n result: false,\n message: `Model '${input.model_name}' does not exist. Available models: ${availableModels.join(', ')}`,\n meta: {\n model_name: input.model_name,\n availableModels,\n },\n }\n }\n }\n\n // Validate subagent_type if provided\n if (input.subagent_type) {\n const availableTypes = await getAvailableAgentTypes()\n if (!availableTypes.includes(input.subagent_type)) {\n return {\n result: false,\n message: `Agent type '${input.subagent_type}' does not exist. Available types: ${availableTypes.join(', ')}`,\n meta: {\n subagent_type: input.subagent_type,\n availableTypes,\n },\n }\n }\n }\n\n // Validate resume parameter if provided\n if (input.resume) {\n if (!canResumeTranscript(input.resume)) {\n return {\n result: false,\n message: `Cannot resume agent '${input.resume}': transcript not found or not resumable (status must be 'running' or 'interrupted')`,\n meta: {\n resume: input.resume,\n },\n }\n }\n }\n\n return { result: true }\n },\n async isEnabled() {\n return true\n },\n userFacingName(input?: any) {\n // Return agent name with proper prefix\n const agentType = input?.subagent_type || 'general-purpose'\n return `agent-${agentType}`\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(data: TextBlock[]) {\n return data\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n },\n renderToolUseMessage(\n { description, prompt, model_name, subagent_type },\n { verbose },\n ) {\n if (!description || !prompt) return null\n\n const modelManager = getModelManager()\n const defaultTaskModel = modelManager.getModelName('task')\n const actualModel = model_name || defaultTaskModel\n const agentType = subagent_type || 'general-purpose'\n const promptPreview =\n prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt\n\n const theme = getTheme()\n\n if (verbose) {\n return (\n <Box flexDirection=\"column\">\n <Text>\n [{agentType}] {actualModel}: {description}\n </Text>\n <Box\n paddingLeft={2}\n borderLeftStyle=\"single\"\n borderLeftColor={theme.secondaryBorder}\n >\n <Text color={theme.secondaryText}>{promptPreview}</Text>\n </Box>\n </Box>\n )\n }\n\n // Simple display: agent type, model and description\n return `[${agentType}] ${actualModel}: ${description}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(content, options?: { verbose?: boolean }) {\n const theme = getTheme()\n const verbose = options?.verbose ?? false\n\n // Guard against undefined or null content\n if (!content) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.success}>Done</Text>\n </Box>\n )\n }\n\n if (Array.isArray(content)) {\n const textBlocks = content.filter(\n (block): block is { type: 'text'; text: string } =>\n block && block.type === 'text',\n )\n const totalLength = textBlocks.reduce(\n (sum, block) => sum + (block.text?.length || 0),\n 0,\n )\n // Use exact match for interrupt detection\n const isInterrupted = content.some(\n block =>\n block && block.type === 'text' && block.text === INTERRUPT_MESSAGE,\n )\n\n if (isInterrupted) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.error}>Interrupted by user</Text>\n </Box>\n )\n }\n\n // Extract output content for display based on verbosity\n const outputText = textBlocks.map(b => b.text).join('\\n')\n\n // Determine how much content to show based on displayMode\n // minimal/compact (verbose=false): Just show \"Task completed (X characters)\"\n // detailed (verbose=true): Show preview of the actual output\n const getOutputPreview = () => {\n if (!verbose || !outputText) return null\n const maxLen = 500\n if (outputText.length <= maxLen) return outputText\n return outputText.substring(0, maxLen) + '...'\n }\n\n const outputPreview = getOutputPreview()\n\n return (\n <Box flexDirection=\"column\">\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.success}>Done</Text>\n {textBlocks.length > 0 && verbose && (\n <Text color={theme.secondaryText}> ({totalLength} chars)</Text>\n )}\n </Box>\n </Box>\n {outputPreview && (\n <Box marginTop={1} paddingLeft={4}>\n <Text color={theme.mutedText}>{outputPreview}</Text>\n </Box>\n )}\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={theme.success}>Done</Text>\n </Box>\n )\n },\n} satisfies Tool\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["normalizedMessages"]
|
|
7
7
|
}
|
|
@@ -48,12 +48,18 @@ When NOT to use the Agent tool:
|
|
|
48
48
|
- Other tasks that are not related to the agent descriptions above
|
|
49
49
|
|
|
50
50
|
Usage notes:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
- Always include a short description (3-5 words) summarizing what the agent will do
|
|
52
|
+
- Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
|
|
53
|
+
- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
|
|
54
|
+
- You can optionally run agents in the background using the run_in_background parameter. When an agent runs in the background, the tool result will include an output_file path. To check on the agent's progress or retrieve its results, use the Read tool to read the output file, or use Bash with \`tail\` to see recent output. You can continue working while background agents run.
|
|
55
|
+
- Agents can be resumed using the \`resume\` parameter by passing the agent ID from a previous invocation. When resumed, the agent continues with its full previous context preserved. When NOT resuming, each invocation starts fresh and you should provide a detailed task description with all necessary context.
|
|
56
|
+
- When the agent is done, it will return a single message back to you along with its agent ID. You can use this ID to resume the agent later if needed for follow-up work.
|
|
57
|
+
- Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.
|
|
58
|
+
- Agents with "access to current context" can see the full conversation history before the tool call. When using these agents, you can write concise prompts that reference earlier context (e.g., "investigate the error discussed above") instead of repeating information. The agent will receive all prior messages and understand the context.
|
|
59
|
+
- The agent's outputs should generally be trusted
|
|
60
|
+
- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
|
|
61
|
+
- If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
|
|
62
|
+
- If the user specifies that they want you to run agents "in parallel", you MUST send a single message with multiple Task tool use content blocks.
|
|
57
63
|
|
|
58
64
|
Example usage:
|
|
59
65
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskTool/prompt.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Tool } from '@tool'\nimport { getTools, getReadOnlyTools } from '@tools'\nimport { TaskTool } from './TaskTool'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { FileWriteTool } from '@tools/FileWriteTool/FileWriteTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\nimport { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { GlobTool } from '@tools/GlobTool/GlobTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { getModelManager } from '@utils/model'\nimport { getActiveAgents } from '@utils/agentLoader'\n\nexport async function getTaskTools(safeMode: boolean): Promise<Tool[]> {\n // No recursive tasks, yet..\n return (await (!safeMode ? getTools() : getReadOnlyTools())).filter(\n _ => _.name !== TaskTool.name,\n )\n}\n\nexport async function getPrompt(safeMode: boolean): Promise<string> {\n const agents = await getActiveAgents()\n\n // Format: (Tools: tool1, tool2)\n const agentDescriptions = agents\n .map(agent => {\n const toolsStr = Array.isArray(agent.tools) ? agent.tools.join(', ') : '*'\n return `- ${agent.agentType}: ${agent.whenToUse} (Tools: ${toolsStr})`\n })\n .join('\\n')\n\n return `Launch a new agent to handle complex, multi-step tasks autonomously. \n\nAvailable agent types and the tools they have access to:\n${agentDescriptions}\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n\uD83D\uDEA8 CRITICAL: You MUST use the EXACT agent type name from the list above. Common mistakes to avoid:\n\nNAMING FORMAT:\n- \u2705 ALWAYS use hyphens (-): \"strategic-market-analyzer\", \"business-analyst\", \"qa-engineer\"\n- \u274C NEVER use underscores (_): \"strategic_market_analyzer\", \"business_analyst\"\n- \u274C NEVER use spaces: \"strategic market analyzer\", \"business analyst\"\n- \u274C NEVER invent names: \"researcher\", \"analyst\", \"data_analyst\"\n\nSELECTION RULES:\n1. For market/business analysis \u2192 use \"strategic-market-analyzer\" or \"business-analyst\"\n2. For data analysis \u2192 use \"data-scientist\"\n3. For general tasks \u2192 use \"general-purpose\"\n4. For code/QA tasks \u2192 use \"qa-engineer\" or \"code-reviewer\"\n\nIf unsure, use \"general-purpose\" - it has access to all tools.\n\nWhen to use the Agent tool:\n- When you are instructed to execute custom slash commands. Use the Agent tool with the slash command invocation as the entire prompt. The slash command can take arguments. For example: Task(description=\"Check the file\", prompt=\"/check-file path/to/file.py\")\n\nWhen NOT to use the Agent tool:\n- If you want to read a specific file path, use the ${FileReadTool.name} or ${GlobTool.name} tool instead of the Agent tool, to find the match more quickly\n- If you are searching for a specific class definition like \"class Foo\", use the ${GlobTool.name} tool instead, to find the match more quickly\n- If you are searching for code within a specific file or set of 2-3 files, use the ${FileReadTool.name} tool instead of the Agent tool, to find the match more quickly\n- Other tasks that are not related to the agent descriptions above\n\nUsage notes:\
|
|
5
|
-
"mappings": "AACA,SAAS,UAAU,wBAAwB;AAC3C,SAAS,gBAAgB;AAEzB,SAAS,qBAAqB;AAG9B,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,eAAsB,aAAa,UAAoC;AAErE,UAAQ,OAAO,CAAC,WAAW,SAAS,IAAI,iBAAiB,IAAI;AAAA,IAC3D,OAAK,EAAE,SAAS,SAAS;AAAA,EAC3B;AACF;AAEA,eAAsB,UAAU,UAAoC;AAClE,QAAM,SAAS,MAAM,gBAAgB;AAGrC,QAAM,oBAAoB,OACvB,IAAI,WAAS;AACZ,UAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,IAAI,IAAI;AACvE,WAAO,KAAK,MAAM,SAAS,KAAK,MAAM,SAAS,YAAY,QAAQ;AAAA,EACrE,CAAC,EACA,KAAK,IAAI;AAEZ,SAAO;AAAA;AAAA;AAAA,EAGP,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAwBmC,aAAa,IAAI,OAAO,SAAS,IAAI;AAAA,mFACR,SAAS,IAAI;AAAA,sFACV,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { type Tool } from '@tool'\nimport { getTools, getReadOnlyTools } from '@tools'\nimport { TaskTool } from './TaskTool'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { FileWriteTool } from '@tools/FileWriteTool/FileWriteTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\nimport { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { GlobTool } from '@tools/GlobTool/GlobTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { getModelManager } from '@utils/model'\nimport { getActiveAgents } from '@utils/agentLoader'\n\nexport async function getTaskTools(safeMode: boolean): Promise<Tool[]> {\n // No recursive tasks, yet..\n return (await (!safeMode ? getTools() : getReadOnlyTools())).filter(\n _ => _.name !== TaskTool.name,\n )\n}\n\nexport async function getPrompt(safeMode: boolean): Promise<string> {\n const agents = await getActiveAgents()\n\n // Format: (Tools: tool1, tool2)\n const agentDescriptions = agents\n .map(agent => {\n const toolsStr = Array.isArray(agent.tools) ? agent.tools.join(', ') : '*'\n return `- ${agent.agentType}: ${agent.whenToUse} (Tools: ${toolsStr})`\n })\n .join('\\n')\n\n return `Launch a new agent to handle complex, multi-step tasks autonomously. \n\nAvailable agent types and the tools they have access to:\n${agentDescriptions}\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n\uD83D\uDEA8 CRITICAL: You MUST use the EXACT agent type name from the list above. Common mistakes to avoid:\n\nNAMING FORMAT:\n- \u2705 ALWAYS use hyphens (-): \"strategic-market-analyzer\", \"business-analyst\", \"qa-engineer\"\n- \u274C NEVER use underscores (_): \"strategic_market_analyzer\", \"business_analyst\"\n- \u274C NEVER use spaces: \"strategic market analyzer\", \"business analyst\"\n- \u274C NEVER invent names: \"researcher\", \"analyst\", \"data_analyst\"\n\nSELECTION RULES:\n1. For market/business analysis \u2192 use \"strategic-market-analyzer\" or \"business-analyst\"\n2. For data analysis \u2192 use \"data-scientist\"\n3. For general tasks \u2192 use \"general-purpose\"\n4. For code/QA tasks \u2192 use \"qa-engineer\" or \"code-reviewer\"\n\nIf unsure, use \"general-purpose\" - it has access to all tools.\n\nWhen to use the Agent tool:\n- When you are instructed to execute custom slash commands. Use the Agent tool with the slash command invocation as the entire prompt. The slash command can take arguments. For example: Task(description=\"Check the file\", prompt=\"/check-file path/to/file.py\")\n\nWhen NOT to use the Agent tool:\n- If you want to read a specific file path, use the ${FileReadTool.name} or ${GlobTool.name} tool instead of the Agent tool, to find the match more quickly\n- If you are searching for a specific class definition like \"class Foo\", use the ${GlobTool.name} tool instead, to find the match more quickly\n- If you are searching for code within a specific file or set of 2-3 files, use the ${FileReadTool.name} tool instead of the Agent tool, to find the match more quickly\n- Other tasks that are not related to the agent descriptions above\n\nUsage notes:\n- Always include a short description (3-5 words) summarizing what the agent will do\n- Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n- You can optionally run agents in the background using the run_in_background parameter. When an agent runs in the background, the tool result will include an output_file path. To check on the agent's progress or retrieve its results, use the Read tool to read the output file, or use Bash with \\`tail\\` to see recent output. You can continue working while background agents run.\n- Agents can be resumed using the \\`resume\\` parameter by passing the agent ID from a previous invocation. When resumed, the agent continues with its full previous context preserved. When NOT resuming, each invocation starts fresh and you should provide a detailed task description with all necessary context.\n- When the agent is done, it will return a single message back to you along with its agent ID. You can use this ID to resume the agent later if needed for follow-up work.\n- Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.\n- Agents with \"access to current context\" can see the full conversation history before the tool call. When using these agents, you can write concise prompts that reference earlier context (e.g., \"investigate the error discussed above\") instead of repeating information. The agent will receive all prior messages and understand the context.\n- The agent's outputs should generally be trusted\n- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent\n- If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n- If the user specifies that they want you to run agents \"in parallel\", you MUST send a single message with multiple Task tool use content blocks.\n\nExample usage:\n\n<example>\n<scenario>Market research analysis with multiple files</scenario>\nuser: \"Analyze these 3 market research reports and summarize findings\"\nassistant: I'll use multiple subagents to analyze the reports in parallel.\n<uses Task tool>\nsubagent_type: \"strategic-market-analyzer\"\nprompt: \"Analyze market_report_1.md and provide key insights...\"\n</uses Task tool>\n<uses Task tool>\nsubagent_type: \"strategic-market-analyzer\"\nprompt: \"Analyze market_report_2.md and provide key insights...\"\n</uses Task tool>\n<uses Task tool>\nsubagent_type: \"business-analyst\"\nprompt: \"Analyze financial_report.md and provide key insights...\"\n</uses Task tool>\n</example>\n\n<example>\n<scenario>Code review after implementation</scenario>\nuser: \"Please write a function that checks if a number is prime\"\nassistant: First let me use the ${FileWriteTool.name} tool to write the function\n<writes code>\nassistant: Now let me use the code-reviewer agent to review the code\n<uses Task tool>\nsubagent_type: \"code-reviewer\"\nprompt: \"Review the isPrime function in utils.js for correctness and performance\"\n</uses Task tool>\n</example>\n\n<example>\n<scenario>Data analysis task</scenario>\nuser: \"Analyze the CSV data in sales.csv and find trends\"\nassistant: I'll use the data-scientist agent to analyze this data\n<uses Task tool>\nsubagent_type: \"data-scientist\"\nprompt: \"Analyze sales.csv and identify trends, patterns, and anomalies\"\n</uses Task tool>\n</example>\n\n\u274C WRONG EXAMPLES (DO NOT DO THIS):\n<wrong_example>\nsubagent_type: \"researcher\" \u2190 WRONG! This agent type doesn't exist\nsubagent_type: \"market_analyzer\" \u2190 WRONG! Uses underscore instead of hyphen\nsubagent_type: \"data analyst\" \u2190 WRONG! Uses space instead of hyphen\n</wrong_example>`\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,UAAU,wBAAwB;AAC3C,SAAS,gBAAgB;AAEzB,SAAS,qBAAqB;AAG9B,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,eAAsB,aAAa,UAAoC;AAErE,UAAQ,OAAO,CAAC,WAAW,SAAS,IAAI,iBAAiB,IAAI;AAAA,IAC3D,OAAK,EAAE,SAAS,SAAS;AAAA,EAC3B;AACF;AAEA,eAAsB,UAAU,UAAoC;AAClE,QAAM,SAAS,MAAM,gBAAgB;AAGrC,QAAM,oBAAoB,OACvB,IAAI,WAAS;AACZ,UAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,IAAI,IAAI;AACvE,WAAO,KAAK,MAAM,SAAS,KAAK,MAAM,SAAS,YAAY,QAAQ;AAAA,EACrE,CAAC,EACA,KAAK,IAAI;AAEZ,SAAO;AAAA;AAAA;AAAA,EAGP,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAwBmC,aAAa,IAAI,OAAO,SAAS,IAAI;AAAA,mFACR,SAAS,IAAI;AAAA,sFACV,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAwCrE,cAAc,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBpD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskUpdateTool/TaskUpdateTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { updateTask, getTaskById } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n taskId: z.string().describe('The ID of the task to update'),\n status: z\n .enum(['pending', 'in_progress', 'completed', 'deleted'])\n .optional()\n .describe('New status for the task'),\n subject: z.string().optional().describe('New subject for the task'),\n description: z.string().optional().describe('New description for the task'),\n activeForm: z\n .string()\n .optional()\n .describe(\n 'Present continuous form shown in spinner when in_progress (e.g., \"Running tests\")',\n ),\n owner: z.string().optional().describe('New owner for the task'),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe(\n 'Metadata keys to merge into the task. Set a key to null to delete it.',\n ),\n addBlocks: z\n .array(z.string())\n .optional()\n .describe('Task IDs that this task blocks'),\n addBlockedBy: z\n .array(z.string())\n .optional()\n .describe('Task IDs that block this task'),\n})\n\nexport const TaskUpdateTool = {\n name: 'TaskUpdate',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Update Task'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const parts: string[] = [`taskId: ${input.taskId}`]\n if (input.status) {\n parts.push(`status: ${input.status}`)\n }\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: {\n taskId: string\n status?: string\n deleted?: boolean\n }) {\n if (!output || !output.taskId) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>Task updated</Text>\n </Box>\n )\n }\n\n if (output.deleted) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>\n Task #{output.taskId} deleted\n </Text>\n </Box>\n )\n }\n\n const statusColor =\n output.status === 'completed'\n ? getTheme().success\n : output.status === 'in_progress'\n ? getTheme().warning\n : getTheme().secondaryText\n\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>\n Updated task #{output.taskId}\n {output.status && <Text color={statusColor}> \u2192 {output.status}</Text>}\n </Text>\n </Box>\n )\n },\n renderResultForAssistant(result: {\n taskId: string\n status?: string\n deleted?: boolean\n }) {\n if (result.deleted) {\n return `Task #${result.taskId} has been deleted`\n }\n return `Updated task #${result.taskId}${result.status ? ` status` : ''}`\n },\n async validateInput({ taskId }: z.infer<typeof inputSchema>) {\n if (!taskId?.trim()) {\n return {\n result: false,\n message: 'Task ID is required',\n }\n }\n\n const task = getTaskById(taskId)\n if (!task) {\n return {\n result: false,\n message: `Task with ID '${taskId}' not found`,\n }\n }\n\n return { result: true }\n },\n async *call(input: z.infer<typeof inputSchema>) {\n try {\n const isDeleting = input.status === 'deleted'\n\n const task = updateTask({\n taskId: input.taskId,\n status: input.status,\n subject: input.subject,\n description: input.description,\n activeForm: input.activeForm,\n owner: input.owner,\n metadata: input.metadata,\n addBlocks: input.addBlocks,\n addBlockedBy: input.addBlockedBy,\n })\n\n if (!task) {\n yield {\n type: 'result',\n data: { error: 'Task not found' },\n resultForAssistant: `Error: Task with ID '${input.taskId}' not found`,\n }\n return\n }\n\n const result = {\n taskId: task.id,\n status: task.status,\n deleted: isDeleting,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n yield {\n type: 'result',\n data: { error: errorMessage },\n resultForAssistant: `Error updating task: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { updateTask, getTaskById } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n taskId: z.string().describe('The ID of the task to update'),\n status: z\n .enum(['pending', 'in_progress', 'completed', 'deleted'])\n .optional()\n .describe('New status for the task'),\n subject: z.string().optional().describe('New subject for the task'),\n description: z.string().optional().describe('New description for the task'),\n activeForm: z\n .string()\n .optional()\n .describe(\n 'Present continuous form shown in spinner when in_progress (e.g., \"Running tests\")',\n ),\n owner: z.string().optional().describe('New owner for the task'),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe(\n 'Metadata keys to merge into the task. Set a key to null to delete it.',\n ),\n addBlocks: z\n .array(z.string())\n .optional()\n .describe('Task IDs that this task blocks'),\n addBlockedBy: z\n .array(z.string())\n .optional()\n .describe('Task IDs that block this task'),\n})\n\nexport const TaskUpdateTool = {\n name: 'TaskUpdate',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Update Task'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const parts: string[] = [`taskId: ${input.taskId}`]\n if (input.status) {\n parts.push(`status: ${input.status}`)\n }\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: {\n taskId: string\n status?: string\n deleted?: boolean\n }) {\n if (!output || !output.taskId) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>Task updated</Text>\n </Box>\n )\n }\n\n if (output.deleted) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>\n Task #{output.taskId} deleted\n </Text>\n </Box>\n )\n }\n\n const statusColor =\n output.status === 'completed'\n ? getTheme().success\n : output.status === 'in_progress'\n ? getTheme().warning\n : getTheme().secondaryText\n\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>\n Updated task #{output.taskId}\n {output.status && <Text color={statusColor}> \u2192 {output.status}</Text>}\n </Text>\n </Box>\n )\n },\n renderResultForAssistant(result: {\n taskId: string\n status?: string\n deleted?: boolean\n }) {\n if (result.deleted) {\n return `Task #${result.taskId} has been deleted`\n }\n return `Updated task #${result.taskId}${result.status ? ` status` : ''}`\n },\n async validateInput({ taskId }: z.infer<typeof inputSchema>) {\n if (!taskId?.trim()) {\n return {\n result: false,\n message: 'Task ID is required',\n }\n }\n\n const task = getTaskById(taskId)\n if (!task) {\n return {\n result: false,\n message: `Task with ID '${taskId}' not found`,\n }\n }\n\n return { result: true }\n },\n async *call(input: z.infer<typeof inputSchema>) {\n try {\n const isDeleting = input.status === 'deleted'\n\n const task = updateTask({\n taskId: input.taskId,\n status: input.status,\n subject: input.subject,\n description: input.description,\n activeForm: input.activeForm,\n owner: input.owner,\n metadata: input.metadata,\n addBlocks: input.addBlocks,\n addBlockedBy: input.addBlockedBy,\n })\n\n if (!task) {\n yield {\n type: 'result',\n data: { error: 'Task not found' },\n resultForAssistant: `Error: Task with ID '${input.taskId}' not found`,\n }\n return\n }\n\n const result = {\n taskId: task.id,\n status: task.status,\n deleted: isDeleting,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n yield {\n type: 'result',\n data: { error: errorMessage },\n resultForAssistant: `Error updating task: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/ThinkTool/ThinkTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\nimport React from 'react'\nimport { Text } from 'ink'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\nimport { MessageResponse } from '@components/MessageResponse'\nimport { USE_BEDROCK, USE_VERTEX } from '@utils/model'\n\nconst thinkToolSchema = z.object({\n thought: z.string().describe('Your thoughts.'),\n})\n\nexport const ThinkTool = {\n name: 'Think',\n userFacingName: () => 'Think',\n description: async () => DESCRIPTION,\n inputSchema: thinkToolSchema,\n isEnabled: async () => Boolean(process.env.THINK_TOOL),\n isReadOnly: () => true,\n isConcurrencySafe: () => true, // ThinkTool is read-only, safe for concurrent execution\n needsPermissions: () => false,\n prompt: async () => PROMPT,\n\n async *call(input, { messageId }) {\n yield {\n type: 'result',\n resultForAssistant: 'Your thought has been logged.',\n data: { thought: input.thought },\n }\n },\n\n // This is never called -- it's special-cased in AssistantToolUseMessage\n renderToolUseMessage(input) {\n return input.thought\n },\n\n renderToolUseRejectedMessage() {\n return (\n <MessageResponse\n children={<Text color={getTheme().error}>Thought cancelled</Text>}\n />\n )\n },\n\n renderResultForAssistant: () => 'Your thought has been logged.',\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport React from 'react'\nimport { Text } from 'ink'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\nimport { MessageResponse } from '@components/MessageResponse'\nimport { USE_BEDROCK, USE_VERTEX } from '@utils/model'\n\nconst thinkToolSchema = z.object({\n thought: z.string().describe('Your thoughts.'),\n})\n\nexport const ThinkTool = {\n name: 'Think',\n userFacingName: () => 'Think',\n description: async () => DESCRIPTION,\n inputSchema: thinkToolSchema,\n isEnabled: async () => Boolean(process.env.THINK_TOOL),\n isReadOnly: () => true,\n isConcurrencySafe: () => true, // ThinkTool is read-only, safe for concurrent execution\n needsPermissions: () => false,\n prompt: async () => PROMPT,\n\n async *call(input, { messageId }) {\n yield {\n type: 'result',\n resultForAssistant: 'Your thought has been logged.',\n data: { thought: input.thought },\n }\n },\n\n // This is never called -- it's special-cased in AssistantToolUseMessage\n renderToolUseMessage(input) {\n return input.thought\n },\n\n renderToolUseRejectedMessage() {\n return (\n <MessageResponse\n children={<Text color={getTheme().error}>Thought cancelled</Text>}\n />\n )\n },\n\n renderResultForAssistant: () => 'Your thought has been logged.',\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,SAAS;AAClB,OAAO,WAAW;AAClB,SAAS,YAAY;AAErB,SAAS,aAAa,cAAc;AACpC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAGhC,MAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,SAAS,EAAE,OAAO,EAAE,SAAS,gBAAgB;AAC/C,CAAC;AAEM,MAAM,YAAY;AAAA,EACvB,MAAM;AAAA,EACN,gBAAgB,MAAM;AAAA,EACtB,aAAa,YAAY;AAAA,EACzB,aAAa;AAAA,EACb,WAAW,YAAY,QAAQ,QAAQ,IAAI,UAAU;AAAA,EACrD,YAAY,MAAM;AAAA,EAClB,mBAAmB,MAAM;AAAA;AAAA,EACzB,kBAAkB,MAAM;AAAA,EACxB,QAAQ,YAAY;AAAA,EAEpB,OAAO,KAAK,OAAO,EAAE,UAAU,GAAG;AAChC,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,MAAM,EAAE,SAAS,MAAM,QAAQ;AAAA,IACjC;AAAA,EACF;AAAA;AAAA,EAGA,qBAAqB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,+BAA+B;AAC7B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,mBAAiB;AAAA;AAAA,IAC5D;AAAA,EAEJ;AAAA,EAEA,0BAA0B,MAAM;AAClC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TodoWriteTool/TodoWriteTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool, ValidationResult } from '@tool'\nimport { setTodos, getTodos, TodoItem } from '@utils/todoStorage'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { startWatchingTodoFile } from '@services/fileFreshness'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst TodoItemSchema = z.object({\n content: z.string().min(1).describe('The task description or content'),\n activeForm: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'The present continuous form of the task (e.g., \"Running tests\" for \"Run tests\"). If not provided, will be auto-generated from content.',\n ),\n status: z\n .enum(['pending', 'in_progress', 'completed'])\n .describe('Current status of the task'),\n priority: z\n .enum(['high', 'medium', 'low'])\n .describe('Priority level of the task'),\n id: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'Unique identifier for the task. If not provided, will be auto-generated.',\n ),\n})\n\nconst inputSchema = z.strictObject({\n todos: z.array(TodoItemSchema).describe('The updated todo list'),\n})\n\n/**\n * Auto-generates activeForm from content if not provided\n * Converts imperative form to present continuous\n * Examples: \"Run tests\" -> \"Running tests\", \"Fix bug\" -> \"Fixing bug\"\n */\nfunction generateActiveForm(content: string): string {\n const trimmed = content.trim()\n\n // Common verb patterns for imperative -> present continuous\n const patterns = [\n { regex: /^(Run|run)\\s+(.+)$/i, replacement: 'Running $2' },\n { regex: /^(Build|build)\\s+(.+)$/i, replacement: 'Building $2' },\n { regex: /^(Fix|fix)\\s+(.+)$/i, replacement: 'Fixing $2' },\n { regex: /^(Add|add)\\s+(.+)$/i, replacement: 'Adding $2' },\n { regex: /^(Create|create)\\s+(.+)$/i, replacement: 'Creating $2' },\n { regex: /^(Update|update)\\s+(.+)$/i, replacement: 'Updating $2' },\n { regex: /^(Delete|delete)\\s+(.+)$/i, replacement: 'Deleting $2' },\n { regex: /^(Test|test)\\s+(.+)$/i, replacement: 'Testing $2' },\n { regex: /^(Deploy|deploy)\\s+(.+)$/i, replacement: 'Deploying $2' },\n { regex: /^(Analyze|analyze)\\s+(.+)$/i, replacement: 'Analyzing $2' },\n { regex: /^(Review|review)\\s+(.+)$/i, replacement: 'Reviewing $2' },\n { regex: /^(Write|write)\\s+(.+)$/i, replacement: 'Writing $2' },\n ]\n\n for (const { regex, replacement } of patterns) {\n if (regex.test(trimmed)) {\n return trimmed.replace(regex, replacement)\n }\n }\n\n // Fallback: add \"Working on\" prefix\n return `Working on: ${trimmed}`\n}\n\nfunction validateTodos(todos: TodoItem[]): ValidationResult {\n // Check for duplicate IDs (only among todos that have IDs)\n const ids = todos.map(todo => todo.id).filter(Boolean) as string[]\n const uniqueIds = new Set(ids)\n if (ids.length !== uniqueIds.size) {\n return {\n result: false,\n errorCode: 1,\n message: 'Duplicate todo IDs found',\n meta: {\n duplicateIds: ids.filter((id, index) => ids.indexOf(id) !== index),\n },\n }\n }\n\n // Check for multiple in_progress tasks\n const inProgressTasks = todos.filter(todo => todo.status === 'in_progress')\n if (inProgressTasks.length > 1) {\n return {\n result: false,\n errorCode: 2,\n message: 'Only one task can be in_progress at a time',\n meta: { inProgressTaskIds: inProgressTasks.map(t => t.id) },\n }\n }\n\n // Validate each todo\n for (let i = 0; i < todos.length; i++) {\n const todo = todos[i]\n const todoIdentifier = todo.id || `index ${i}`\n\n if (!todo.content?.trim()) {\n return {\n result: false,\n errorCode: 3,\n message: `Todo at ${todoIdentifier} has empty content`,\n meta: { todoId: todo.id, index: i },\n }\n }\n if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {\n return {\n result: false,\n errorCode: 4,\n message: `Invalid status \"${todo.status}\" for todo at ${todoIdentifier}`,\n meta: { todoId: todo.id, index: i, invalidStatus: todo.status },\n }\n }\n if (!['high', 'medium', 'low'].includes(todo.priority)) {\n return {\n result: false,\n errorCode: 5,\n message: `Invalid priority \"${todo.priority}\" for todo at ${todoIdentifier}`,\n meta: { todoId: todo.id, index: i, invalidPriority: todo.priority },\n }\n }\n }\n\n return { result: true }\n}\n\nfunction generateTodoSummary(todos: TodoItem[]): string {\n const stats = {\n total: todos.length,\n pending: todos.filter(t => t.status === 'pending').length,\n inProgress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n }\n\n // Enhanced summary with statistics\n let summary = `Updated ${stats.total} todo(s)`\n if (stats.total > 0) {\n summary += ` (${stats.pending} pending, ${stats.inProgress} in progress, ${stats.completed} completed)`\n }\n summary += '. Continue tracking your progress with the todo list.'\n\n return summary\n}\n\nexport const TodoWriteTool = {\n name: 'TodoWrite',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Update Todos'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // TodoWrite modifies state, not safe for concurrent execution\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(result) {\n // Match official implementation - return static confirmation message\n return 'Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable'\n },\n renderToolUseMessage(input, { verbose }) {\n // Format: \"(1 running, 2 pending): taskName\"\n const todos = input?.todos ?? []\n if (todos.length === 0) return 'cleared'\n\n const stats = {\n pending: todos.filter(t => t.status === 'pending').length,\n inProgress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n }\n\n // Find current running task or next pending task for display\n const currentTask =\n todos.find(t => t.status === 'in_progress') ||\n todos.find(t => t.status === 'pending')\n const taskName = currentTask\n ? currentTask.content.slice(0, 40) +\n (currentTask.content.length > 40 ? '...' : '')\n : ''\n\n // Build stats string with parentheses around stats only\n // AssistantToolUseMessage handles TodoWriteTool specially - doesn't wrap in extra parens\n const statsParts = []\n if (stats.inProgress > 0) statsParts.push(`${stats.inProgress} running`)\n if (stats.pending > 0) statsParts.push(`${stats.pending} pending`)\n if (stats.completed > 0) statsParts.push(`${stats.completed} done`)\n const statsStr = statsParts.length > 0 ? `(${statsParts.join(', ')})` : ''\n\n // Format: \" (stats): taskName\" with leading space for proper spacing after tool name\n // Result: \"Update Todos (1 running, 2 pending): \u968F\u673A\u9009\u62E93\u4E2A\u6587\u4EF6\u2026\"\n if (taskName) {\n return statsStr ? ` ${statsStr}: ${taskName}` : `: ${taskName}`\n }\n return statsStr ? ` ${statsStr}` : ''\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n // All info shown in renderToolUseMessage - only show errors here\n const isError = typeof output === 'string' && output.startsWith('Error')\n\n if (isError) {\n return (\n <Box flexDirection=\"row\" width=\"100%\">\n <Text color={getTheme().error}>\n \u23BF \n {typeof output === 'string' ? output : JSON.stringify(output)}\n </Text>\n </Box>\n )\n }\n\n // Return empty fragment for successful updates - info already in tool use message\n // Using React.Fragment instead of null to avoid DefaultToolResult fallback\n return <React.Fragment />\n },\n async validateInput({ todos }: z.infer<typeof inputSchema>) {\n // Type assertion to ensure todos match TodoItem[] interface\n const todoItems = todos as TodoItem[]\n const validation = validateTodos(todoItems)\n if (!validation.result) {\n return validation\n }\n return { result: true }\n },\n async *call({ todos }: z.infer<typeof inputSchema>, context) {\n try {\n // Get agent ID from context\n const agentId = context?.agentId\n\n // Start watching todo file for this agent if not already watching\n if (agentId) {\n startWatchingTodoFile(agentId)\n }\n\n // Store previous todos for comparison (agent-scoped)\n const previousTodos = getTodos(agentId)\n\n // Type assertion to ensure todos match TodoItem[] interface\n // Auto-generate activeForm and id for todos that don't have them\n const todoItems = todos.map((todo, index) => ({\n ...todo,\n id: todo.id || `todo-${Date.now()}-${index}`,\n activeForm: todo.activeForm || generateActiveForm(todo.content),\n })) as TodoItem[]\n\n // Note: Validation already done in validateInput, no need for duplicate validation\n // This eliminates the double validation issue\n\n // Update the todos in storage (agent-scoped)\n setTodos(todoItems, agentId)\n\n // Emit todo change event for system reminders (optimized - only if todos actually changed)\n const hasChanged =\n JSON.stringify(previousTodos) !== JSON.stringify(todoItems)\n if (hasChanged) {\n emitReminderEvent('todo:changed', {\n previousTodos,\n newTodos: todoItems,\n timestamp: Date.now(),\n agentId: agentId || 'default',\n changeType:\n todoItems.length > previousTodos.length\n ? 'added'\n : todoItems.length < previousTodos.length\n ? 'removed'\n : 'modified',\n })\n }\n\n // Generate enhanced summary\n const summary = generateTodoSummary(todoItems)\n\n // Create result with embedded todo snapshot for history restore\n // This ensures the render can display the correct state even after session restart\n const resultWithSnapshot = JSON.stringify({\n _type: 'todo_snapshot',\n summary,\n todos: todoItems,\n })\n\n yield {\n type: 'result',\n data: resultWithSnapshot,\n resultForAssistant: summary,\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const errorResult = `Error updating todos: ${errorMessage}`\n\n // Emit error event for system monitoring\n emitReminderEvent('todo:error', {\n error: errorMessage,\n timestamp: Date.now(),\n agentId: context?.agentId || 'default',\n context: 'TodoWriteTool.call',\n })\n\n yield {\n type: 'result',\n data: errorResult,\n resultForAssistant: errorResult,\n }\n }\n },\n} satisfies Tool<typeof inputSchema, string>\n"],
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool, ValidationResult } from '@tool'\nimport { setTodos, getTodos, TodoItem } from '@utils/todoStorage'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { startWatchingTodoFile } from '@services/fileFreshness'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst TodoItemSchema = z.object({\n content: z.string().min(1).describe('The task description or content'),\n activeForm: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'The present continuous form of the task (e.g., \"Running tests\" for \"Run tests\"). If not provided, will be auto-generated from content.',\n ),\n status: z\n .enum(['pending', 'in_progress', 'completed'])\n .describe('Current status of the task'),\n priority: z\n .enum(['high', 'medium', 'low'])\n .describe('Priority level of the task'),\n id: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'Unique identifier for the task. If not provided, will be auto-generated.',\n ),\n})\n\nconst inputSchema = z.strictObject({\n todos: z.array(TodoItemSchema).describe('The updated todo list'),\n})\n\n/**\n * Auto-generates activeForm from content if not provided\n * Converts imperative form to present continuous\n * Examples: \"Run tests\" -> \"Running tests\", \"Fix bug\" -> \"Fixing bug\"\n */\nfunction generateActiveForm(content: string): string {\n const trimmed = content.trim()\n\n // Common verb patterns for imperative -> present continuous\n const patterns = [\n { regex: /^(Run|run)\\s+(.+)$/i, replacement: 'Running $2' },\n { regex: /^(Build|build)\\s+(.+)$/i, replacement: 'Building $2' },\n { regex: /^(Fix|fix)\\s+(.+)$/i, replacement: 'Fixing $2' },\n { regex: /^(Add|add)\\s+(.+)$/i, replacement: 'Adding $2' },\n { regex: /^(Create|create)\\s+(.+)$/i, replacement: 'Creating $2' },\n { regex: /^(Update|update)\\s+(.+)$/i, replacement: 'Updating $2' },\n { regex: /^(Delete|delete)\\s+(.+)$/i, replacement: 'Deleting $2' },\n { regex: /^(Test|test)\\s+(.+)$/i, replacement: 'Testing $2' },\n { regex: /^(Deploy|deploy)\\s+(.+)$/i, replacement: 'Deploying $2' },\n { regex: /^(Analyze|analyze)\\s+(.+)$/i, replacement: 'Analyzing $2' },\n { regex: /^(Review|review)\\s+(.+)$/i, replacement: 'Reviewing $2' },\n { regex: /^(Write|write)\\s+(.+)$/i, replacement: 'Writing $2' },\n ]\n\n for (const { regex, replacement } of patterns) {\n if (regex.test(trimmed)) {\n return trimmed.replace(regex, replacement)\n }\n }\n\n // Fallback: add \"Working on\" prefix\n return `Working on: ${trimmed}`\n}\n\nfunction validateTodos(todos: TodoItem[]): ValidationResult {\n // Check for duplicate IDs (only among todos that have IDs)\n const ids = todos.map(todo => todo.id).filter(Boolean) as string[]\n const uniqueIds = new Set(ids)\n if (ids.length !== uniqueIds.size) {\n return {\n result: false,\n errorCode: 1,\n message: 'Duplicate todo IDs found',\n meta: {\n duplicateIds: ids.filter((id, index) => ids.indexOf(id) !== index),\n },\n }\n }\n\n // Check for multiple in_progress tasks\n const inProgressTasks = todos.filter(todo => todo.status === 'in_progress')\n if (inProgressTasks.length > 1) {\n return {\n result: false,\n errorCode: 2,\n message: 'Only one task can be in_progress at a time',\n meta: { inProgressTaskIds: inProgressTasks.map(t => t.id) },\n }\n }\n\n // Validate each todo\n for (let i = 0; i < todos.length; i++) {\n const todo = todos[i]\n const todoIdentifier = todo.id || `index ${i}`\n\n if (!todo.content?.trim()) {\n return {\n result: false,\n errorCode: 3,\n message: `Todo at ${todoIdentifier} has empty content`,\n meta: { todoId: todo.id, index: i },\n }\n }\n if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {\n return {\n result: false,\n errorCode: 4,\n message: `Invalid status \"${todo.status}\" for todo at ${todoIdentifier}`,\n meta: { todoId: todo.id, index: i, invalidStatus: todo.status },\n }\n }\n if (!['high', 'medium', 'low'].includes(todo.priority)) {\n return {\n result: false,\n errorCode: 5,\n message: `Invalid priority \"${todo.priority}\" for todo at ${todoIdentifier}`,\n meta: { todoId: todo.id, index: i, invalidPriority: todo.priority },\n }\n }\n }\n\n return { result: true }\n}\n\nfunction generateTodoSummary(todos: TodoItem[]): string {\n const stats = {\n total: todos.length,\n pending: todos.filter(t => t.status === 'pending').length,\n inProgress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n }\n\n // Enhanced summary with statistics\n let summary = `Updated ${stats.total} todo(s)`\n if (stats.total > 0) {\n summary += ` (${stats.pending} pending, ${stats.inProgress} in progress, ${stats.completed} completed)`\n }\n summary += '. Continue tracking your progress with the todo list.'\n\n return summary\n}\n\nexport const TodoWriteTool = {\n name: 'TodoWrite',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Update Todos'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // TodoWrite modifies state, not safe for concurrent execution\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(result) {\n // Match official implementation - return static confirmation message\n return 'Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable'\n },\n renderToolUseMessage(input, { verbose }) {\n // Format: \"(1 running, 2 pending): taskName\"\n const todos = input?.todos ?? []\n if (todos.length === 0) return 'cleared'\n\n const stats = {\n pending: todos.filter(t => t.status === 'pending').length,\n inProgress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n }\n\n // Find current running task or next pending task for display\n const currentTask =\n todos.find(t => t.status === 'in_progress') ||\n todos.find(t => t.status === 'pending')\n const taskName = currentTask\n ? currentTask.content.slice(0, 40) +\n (currentTask.content.length > 40 ? '...' : '')\n : ''\n\n // Build stats string with parentheses around stats only\n // AssistantToolUseMessage handles TodoWriteTool specially - doesn't wrap in extra parens\n const statsParts = []\n if (stats.inProgress > 0) statsParts.push(`${stats.inProgress} running`)\n if (stats.pending > 0) statsParts.push(`${stats.pending} pending`)\n if (stats.completed > 0) statsParts.push(`${stats.completed} done`)\n const statsStr = statsParts.length > 0 ? `(${statsParts.join(', ')})` : ''\n\n // Format: \" (stats): taskName\" with leading space for proper spacing after tool name\n // Result: \"Update Todos (1 running, 2 pending): \u968F\u673A\u9009\u62E93\u4E2A\u6587\u4EF6\u2026\"\n if (taskName) {\n return statsStr ? ` ${statsStr}: ${taskName}` : `: ${taskName}`\n }\n return statsStr ? ` ${statsStr}` : ''\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n // All info shown in renderToolUseMessage - only show errors here\n const isError = typeof output === 'string' && output.startsWith('Error')\n\n if (isError) {\n return (\n <Box flexDirection=\"row\" width=\"100%\">\n <Text color={getTheme().error}>\n \u23BF \n {typeof output === 'string' ? output : JSON.stringify(output)}\n </Text>\n </Box>\n )\n }\n\n // Return empty fragment for successful updates - info already in tool use message\n // Using React.Fragment instead of null to avoid DefaultToolResult fallback\n return <React.Fragment />\n },\n async validateInput({ todos }: z.infer<typeof inputSchema>) {\n // Type assertion to ensure todos match TodoItem[] interface\n const todoItems = todos as TodoItem[]\n const validation = validateTodos(todoItems)\n if (!validation.result) {\n return validation\n }\n return { result: true }\n },\n async *call({ todos }: z.infer<typeof inputSchema>, context) {\n try {\n // Get agent ID from context\n const agentId = context?.agentId\n\n // Start watching todo file for this agent if not already watching\n if (agentId) {\n startWatchingTodoFile(agentId)\n }\n\n // Store previous todos for comparison (agent-scoped)\n const previousTodos = getTodos(agentId)\n\n // Type assertion to ensure todos match TodoItem[] interface\n // Auto-generate activeForm and id for todos that don't have them\n const todoItems = todos.map((todo, index) => ({\n ...todo,\n id: todo.id || `todo-${Date.now()}-${index}`,\n activeForm: todo.activeForm || generateActiveForm(todo.content),\n })) as TodoItem[]\n\n // Note: Validation already done in validateInput, no need for duplicate validation\n // This eliminates the double validation issue\n\n // Update the todos in storage (agent-scoped)\n setTodos(todoItems, agentId)\n\n // Emit todo change event for system reminders (optimized - only if todos actually changed)\n const hasChanged =\n JSON.stringify(previousTodos) !== JSON.stringify(todoItems)\n if (hasChanged) {\n emitReminderEvent('todo:changed', {\n previousTodos,\n newTodos: todoItems,\n timestamp: Date.now(),\n agentId: agentId || 'default',\n changeType:\n todoItems.length > previousTodos.length\n ? 'added'\n : todoItems.length < previousTodos.length\n ? 'removed'\n : 'modified',\n })\n }\n\n // Generate enhanced summary\n const summary = generateTodoSummary(todoItems)\n\n // Create result with embedded todo snapshot for history restore\n // This ensures the render can display the correct state even after session restart\n const resultWithSnapshot = JSON.stringify({\n _type: 'todo_snapshot',\n summary,\n todos: todoItems,\n })\n\n yield {\n type: 'result',\n data: resultWithSnapshot,\n resultForAssistant: summary,\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const errorResult = `Error updating todos: ${errorMessage}`\n\n // Emit error event for system monitoring\n emitReminderEvent('todo:error', {\n error: errorMessage,\n timestamp: Date.now(),\n agentId: context?.agentId || 'default',\n context: 'TodoWriteTool.call',\n })\n\n yield {\n type: 'result',\n data: errorResult,\n resultForAssistant: errorResult,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/URLFetcherTool/URLFetcherTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport fetch from 'node-fetch'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool, ToolUseContext } from '@tool'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { convertHtmlToMarkdown } from './htmlToMarkdown'\nimport { urlCache } from './cache'\nimport { queryQuick } from '@services/claude'\nimport { formatUrl, truncateText } from '@utils/format'\n\nconst inputSchema = z.strictObject({\n url: z.string().url().describe('The URL to fetch content from'),\n prompt: z.string().describe('The prompt to run on the fetched content'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = {\n url: string\n fromCache: boolean\n aiAnalysis: string\n}\n\nfunction normalizeUrl(url: string): string {\n // Auto-upgrade HTTP to HTTPS\n if (url.startsWith('http://')) {\n return url.replace('http://', 'https://')\n }\n return url\n}\n\nexport const URLFetcherTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName: () => 'URL Fetcher',\n inputSchema,\n isReadOnly: () => true,\n isConcurrencySafe: () => true,\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ url, prompt }: Input) {\n const displayUrl = formatUrl(url, 40)\n const displayPrompt = truncateText(prompt, 30)\n return `${displayUrl} \u00B7 \"${displayPrompt}\"`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF URL fetch completed</Text>\n </Box>\n </Box>\n )\n }\n\n const statusText = output.fromCache ? 'from cache' : 'fetched'\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF Content </Text>\n <Text bold>{statusText} </Text>\n <Text>and analyzed</Text>\n </Box>\n <Cost costUSD={0} durationMs={0} debug={false} />\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (!output.aiAnalysis.trim()) {\n return `No content could be analyzed from URL: ${output.url}`\n }\n\n return output.aiAnalysis\n },\n async *call({ url, prompt }: Input, {}: ToolUseContext) {\n const normalizedUrl = normalizeUrl(url)\n\n try {\n let content: string\n let fromCache = false\n\n // Check cache first\n const cachedContent = urlCache.get(normalizedUrl)\n if (cachedContent) {\n content = cachedContent\n fromCache = true\n } else {\n // Fetch from URL with AbortController for timeout\n const abortController = new AbortController()\n const timeout = setTimeout(() => abortController.abort(), 30000)\n\n const response = await fetch(normalizedUrl, {\n method: 'GET',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; URLFetcher/1.0)',\n Accept:\n 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\n 'Accept-Language': 'en-US,en;q=0.5',\n 'Accept-Encoding': 'gzip, deflate',\n Connection: 'keep-alive',\n 'Upgrade-Insecure-Requests': '1',\n },\n signal: abortController.signal,\n redirect: 'follow',\n })\n\n clearTimeout(timeout)\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const contentType = response.headers.get('content-type') || ''\n if (\n !contentType.includes('text/') &&\n !contentType.includes('application/')\n ) {\n throw new Error(`Unsupported content type: ${contentType}`)\n }\n\n const html = await response.text()\n content = convertHtmlToMarkdown(html)\n\n // Cache the result\n urlCache.set(normalizedUrl, content)\n fromCache = false\n }\n\n // Truncate content if too large (keep within reasonable token limits)\n const maxContentLength = 50000 // ~15k tokens approximately\n const truncatedContent =\n content.length > maxContentLength\n ? content.substring(0, maxContentLength) +\n '\\n\\n[Content truncated due to length]'\n : content\n\n // AI Analysis - always performed fresh, even with cached content\n const systemPrompt = [\n \"You are analyzing web content based on a user's specific request.\",\n 'The content has been extracted from a webpage and converted to markdown.',\n \"Provide a focused response that directly addresses the user's prompt.\",\n ]\n\n const userPrompt = `Here is the content from ${normalizedUrl}:\n\n${truncatedContent}\n\nUser request: ${prompt}`\n\n const aiResponse = await queryQuick({\n systemPrompt,\n userPrompt,\n enablePromptCaching: false,\n })\n\n const output: Output = {\n url: normalizedUrl,\n fromCache,\n aiAnalysis:\n aiResponse.message.content[0]?.text || 'Unable to analyze content',\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } catch (error: any) {\n const output: Output = {\n url: normalizedUrl,\n fromCache: false,\n aiAnalysis: '',\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: `Error processing URL ${normalizedUrl}: ${error.message}`,\n data: output,\n }\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport fetch from 'node-fetch'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool, ToolUseContext } from '@tool'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { convertHtmlToMarkdown } from './htmlToMarkdown'\nimport { urlCache } from './cache'\nimport { queryQuick } from '@services/claude'\nimport { formatUrl, truncateText } from '@utils/format'\n\nconst inputSchema = z.strictObject({\n url: z.string().url().describe('The URL to fetch content from'),\n prompt: z.string().describe('The prompt to run on the fetched content'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = {\n url: string\n fromCache: boolean\n aiAnalysis: string\n}\n\nfunction normalizeUrl(url: string): string {\n // Auto-upgrade HTTP to HTTPS\n if (url.startsWith('http://')) {\n return url.replace('http://', 'https://')\n }\n return url\n}\n\nexport const URLFetcherTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName: () => 'URL Fetcher',\n inputSchema,\n isReadOnly: () => true,\n isConcurrencySafe: () => true,\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ url, prompt }: Input) {\n const displayUrl = formatUrl(url, 40)\n const displayPrompt = truncateText(prompt, 30)\n return `${displayUrl} \u00B7 \"${displayPrompt}\"`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF URL fetch completed</Text>\n </Box>\n </Box>\n )\n }\n\n const statusText = output.fromCache ? 'from cache' : 'fetched'\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF Content </Text>\n <Text bold>{statusText} </Text>\n <Text>and analyzed</Text>\n </Box>\n <Cost costUSD={0} durationMs={0} debug={false} />\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (!output.aiAnalysis.trim()) {\n return `No content could be analyzed from URL: ${output.url}`\n }\n\n return output.aiAnalysis\n },\n async *call({ url, prompt }: Input, {}: ToolUseContext) {\n const normalizedUrl = normalizeUrl(url)\n\n try {\n let content: string\n let fromCache = false\n\n // Check cache first\n const cachedContent = urlCache.get(normalizedUrl)\n if (cachedContent) {\n content = cachedContent\n fromCache = true\n } else {\n // Fetch from URL with AbortController for timeout\n const abortController = new AbortController()\n const timeout = setTimeout(() => abortController.abort(), 30000)\n\n const response = await fetch(normalizedUrl, {\n method: 'GET',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; URLFetcher/1.0)',\n Accept:\n 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\n 'Accept-Language': 'en-US,en;q=0.5',\n 'Accept-Encoding': 'gzip, deflate',\n Connection: 'keep-alive',\n 'Upgrade-Insecure-Requests': '1',\n },\n signal: abortController.signal,\n redirect: 'follow',\n })\n\n clearTimeout(timeout)\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const contentType = response.headers.get('content-type') || ''\n if (\n !contentType.includes('text/') &&\n !contentType.includes('application/')\n ) {\n throw new Error(`Unsupported content type: ${contentType}`)\n }\n\n const html = await response.text()\n content = convertHtmlToMarkdown(html)\n\n // Cache the result\n urlCache.set(normalizedUrl, content)\n fromCache = false\n }\n\n // Truncate content if too large (keep within reasonable token limits)\n const maxContentLength = 50000 // ~15k tokens approximately\n const truncatedContent =\n content.length > maxContentLength\n ? content.substring(0, maxContentLength) +\n '\\n\\n[Content truncated due to length]'\n : content\n\n // AI Analysis - always performed fresh, even with cached content\n const systemPrompt = [\n \"You are analyzing web content based on a user's specific request.\",\n 'The content has been extracted from a webpage and converted to markdown.',\n \"Provide a focused response that directly addresses the user's prompt.\",\n ]\n\n const userPrompt = `Here is the content from ${normalizedUrl}:\n\n${truncatedContent}\n\nUser request: ${prompt}`\n\n const aiResponse = await queryQuick({\n systemPrompt,\n userPrompt,\n enablePromptCaching: false,\n })\n\n const output: Output = {\n url: normalizedUrl,\n fromCache,\n aiAnalysis:\n aiResponse.message.content[0]?.text || 'Unable to analyze content',\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } catch (error: any) {\n const output: Output = {\n url: normalizedUrl,\n fromCache: false,\n aiAnalysis: '',\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: `Error processing URL ${normalizedUrl}: ${error.message}`,\n data: output,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/WebSearchTool/WebSearchTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool, ToolUseContext } from '@tool'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { SearchResult, searchProviders } from './searchProviders'\n\nconst inputSchema = z.strictObject({\n query: z.string().describe('The search query'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = {\n durationMs: number\n results: SearchResult[]\n}\n\nexport const WebSearchTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName: () => 'Web Search',\n inputSchema,\n isReadOnly: () => true,\n isConcurrencySafe: () => true,\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ query }: Input) {\n return `Searching for: \"${query}\" using DuckDuckGo`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF Search completed</Text>\n </Box>\n </Box>\n )\n }\n\n const resultsLength = output.results?.length ?? 0\n const durationMs = output.durationMs ?? 0\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF Found </Text>\n <Text bold>{resultsLength} </Text>\n <Text>\n {resultsLength === 1 ? 'result' : 'results'} using DuckDuckGo\n </Text>\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (output.results.length === 0) {\n return `No results found using DuckDuckGo.`\n }\n\n let result = `Found ${output.results.length} search results using DuckDuckGo:\\n\\n`\n\n output.results.forEach((item, index) => {\n result += `${index + 1}. **${item.title}**\\n`\n result += ` ${item.snippet}\\n`\n result += ` Link: ${item.link}\\n\\n`\n })\n\n result += `You can reference these results to provide current, accurate information to the user.`\n return result\n },\n async *call({ query }: Input, {}: ToolUseContext) {\n const start = Date.now()\n\n try {\n const searchResults = await searchProviders.duckduckgo.search(query)\n\n const output: Output = {\n results: searchResults,\n durationMs: Date.now() - start,\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } catch (error: any) {\n const output: Output = {\n results: [],\n durationMs: Date.now() - start,\n }\n yield {\n type: 'result' as const,\n resultForAssistant: `An error occurred during web search with DuckDuckGo: ${error.message}`,\n data: output,\n }\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool, ToolUseContext } from '@tool'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { SearchResult, searchProviders } from './searchProviders'\n\nconst inputSchema = z.strictObject({\n query: z.string().describe('The search query'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = {\n durationMs: number\n results: SearchResult[]\n}\n\nexport const WebSearchTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName: () => 'Web Search',\n inputSchema,\n isReadOnly: () => true,\n isConcurrencySafe: () => true,\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ query }: Input) {\n return `Searching for: \"${query}\" using DuckDuckGo`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF Search completed</Text>\n </Box>\n </Box>\n )\n }\n\n const resultsLength = output.results?.length ?? 0\n const durationMs = output.durationMs ?? 0\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text> \u23BF Found </Text>\n <Text bold>{resultsLength} </Text>\n <Text>\n {resultsLength === 1 ? 'result' : 'results'} using DuckDuckGo\n </Text>\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (output.results.length === 0) {\n return `No results found using DuckDuckGo.`\n }\n\n let result = `Found ${output.results.length} search results using DuckDuckGo:\\n\\n`\n\n output.results.forEach((item, index) => {\n result += `${index + 1}. **${item.title}**\\n`\n result += ` ${item.snippet}\\n`\n result += ` Link: ${item.link}\\n\\n`\n })\n\n result += `You can reference these results to provide current, accurate information to the user.`\n return result\n },\n async *call({ query }: Input, {}: ToolUseContext) {\n const start = Date.now()\n\n try {\n const searchResults = await searchProviders.duckduckgo.search(query)\n\n const output: Output = {\n results: searchResults,\n durationMs: Date.now() - start,\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } catch (error: any) {\n const output: Output = {\n results: [],\n durationMs: Date.now() - start,\n }\n yield {\n type: 'result' as const,\n resultForAssistant: `An error occurred during web search with DuckDuckGo: ${error.message}`,\n data: output,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,OAAO,WAAW;AAClB,SAAS,SAAS;AAClB,SAAS,YAAY;AACrB,SAAS,sCAAsC;AAE/C,SAAS,aAAa,4BAA4B;AAClD,SAAuB,uBAAuB;AAE9C,MAAM,cAAc,EAAE,aAAa;AAAA,EACjC,OAAO,EAAE,OAAO,EAAE,SAAS,kBAAkB;AAC/C,CAAC;AAQM,MAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,gBAAgB,MAAM;AAAA,EACtB;AAAA,EACA,YAAY,MAAM;AAAA,EAClB,mBAAmB,MAAM;AAAA,EACzB,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB,EAAE,MAAM,GAAU;AACrC,WAAO,mBAAmB,KAAK;AAAA,EACjC;AAAA,EACA,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,wBAAwB,QAAgB;AAEtC,QAAI,CAAC,QAAQ;AACX,aACE,oCAAC,OAAI,gBAAe,iBAAgB,OAAM,UACxC,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qCAAoC,CAC5C,CACF;AAAA,IAEJ;AAEA,UAAM,gBAAgB,OAAO,SAAS,UAAU;AAChD,UAAM,aAAa,OAAO,cAAc;AAExC,WACE,oCAAC,OAAI,gBAAe,iBAAgB,OAAM,UACxC,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,2BAA0B,GAChC,oCAAC,QAAK,MAAI,QAAE,eAAc,GAAC,GAC3B,oCAAC,YACE,kBAAkB,IAAI,WAAW,WAAU,mBAC9C,CACF,GACA,oCAAC,QAAK,SAAS,GAAG,YAAwB,OAAO,OAAO,CAC1D;AAAA,EAEJ;AAAA,EACA,yBAAyB,QAAgB;AACvC,QAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,SAAS,OAAO,QAAQ,MAAM;AAAA;AAAA;AAE3C,WAAO,QAAQ,QAAQ,CAAC,MAAM,UAAU;AACtC,gBAAU,GAAG,QAAQ,CAAC,OAAO,KAAK,KAAK;AAAA;AACvC,gBAAU,MAAM,KAAK,OAAO;AAAA;AAC5B,gBAAU,YAAY,KAAK,IAAI;AAAA;AAAA;AAAA,IACjC,CAAC;AAED,cAAU;AACV,WAAO;AAAA,EACT;AAAA,EACA,OAAO,KAAK,EAAE,MAAM,GAAU,CAAC,GAAmB;AAChD,UAAM,QAAQ,KAAK,IAAI;AAEvB,QAAI;AACF,YAAM,gBAAgB,MAAM,gBAAgB,WAAW,OAAO,KAAK;AAEnE,YAAM,SAAiB;AAAA,QACrB,SAAS;AAAA,QACT,YAAY,KAAK,IAAI,IAAI;AAAA,MAC3B;AAEA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,oBAAoB,KAAK,yBAAyB,MAAM;AAAA,QACxD,MAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAY;AACnB,YAAM,SAAiB;AAAA,QACrB,SAAS,CAAC;AAAA,QACV,YAAY,KAAK,IAAI,IAAI;AAAA,MAC3B;AACA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,oBAAoB,wDAAwD,MAAM,OAAO;AAAA,QACzF,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|