snow-ai 0.4.15 → 0.4.17
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/bundle/cli.mjs +477445 -0
- package/bundle/sql-wasm.wasm +0 -0
- package/package.json +31 -26
- package/dist/agents/codebaseIndexAgent.d.ts +0 -102
- package/dist/agents/codebaseIndexAgent.js +0 -641
- package/dist/agents/codebaseReviewAgent.d.ts +0 -61
- package/dist/agents/codebaseReviewAgent.js +0 -301
- package/dist/agents/compactAgent.d.ts +0 -55
- package/dist/agents/compactAgent.js +0 -306
- package/dist/agents/promptOptimizeAgent.d.ts +0 -54
- package/dist/agents/promptOptimizeAgent.js +0 -268
- package/dist/agents/reviewAgent.d.ts +0 -50
- package/dist/agents/reviewAgent.js +0 -265
- package/dist/agents/summaryAgent.d.ts +0 -57
- package/dist/agents/summaryAgent.js +0 -260
- package/dist/api/anthropic.d.ts +0 -44
- package/dist/api/anthropic.js +0 -598
- package/dist/api/chat.d.ts +0 -73
- package/dist/api/chat.js +0 -386
- package/dist/api/embedding.d.ts +0 -34
- package/dist/api/embedding.js +0 -80
- package/dist/api/gemini.d.ts +0 -31
- package/dist/api/gemini.js +0 -445
- package/dist/api/models.d.ts +0 -15
- package/dist/api/models.js +0 -139
- package/dist/api/responses.d.ts +0 -38
- package/dist/api/responses.js +0 -515
- package/dist/api/systemPrompt.d.ts +0 -4
- package/dist/api/systemPrompt.js +0 -408
- package/dist/api/types.d.ts +0 -53
- package/dist/api/types.js +0 -4
- package/dist/app.d.ts +0 -8
- package/dist/app.js +0 -112
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -199
- package/dist/hooks/useAgentPicker.d.ts +0 -14
- package/dist/hooks/useAgentPicker.js +0 -119
- package/dist/hooks/useClipboard.d.ts +0 -4
- package/dist/hooks/useClipboard.js +0 -175
- package/dist/hooks/useCommandHandler.d.ts +0 -35
- package/dist/hooks/useCommandHandler.js +0 -346
- package/dist/hooks/useCommandPanel.d.ts +0 -17
- package/dist/hooks/useCommandPanel.js +0 -114
- package/dist/hooks/useConversation.d.ts +0 -49
- package/dist/hooks/useConversation.js +0 -1052
- package/dist/hooks/useFilePicker.d.ts +0 -18
- package/dist/hooks/useFilePicker.js +0 -224
- package/dist/hooks/useGlobalExit.d.ts +0 -5
- package/dist/hooks/useGlobalExit.js +0 -34
- package/dist/hooks/useGlobalNavigation.d.ts +0 -6
- package/dist/hooks/useGlobalNavigation.js +0 -17
- package/dist/hooks/useHistoryNavigation.d.ts +0 -35
- package/dist/hooks/useHistoryNavigation.js +0 -133
- package/dist/hooks/useInputBuffer.d.ts +0 -6
- package/dist/hooks/useInputBuffer.js +0 -45
- package/dist/hooks/useKeyboardInput.d.ts +0 -80
- package/dist/hooks/useKeyboardInput.js +0 -608
- package/dist/hooks/useSessionManagement.d.ts +0 -10
- package/dist/hooks/useSessionManagement.js +0 -43
- package/dist/hooks/useSessionSave.d.ts +0 -8
- package/dist/hooks/useSessionSave.js +0 -63
- package/dist/hooks/useSnapshotState.d.ts +0 -26
- package/dist/hooks/useSnapshotState.js +0 -28
- package/dist/hooks/useStreamingState.d.ts +0 -33
- package/dist/hooks/useStreamingState.js +0 -105
- package/dist/hooks/useTerminalFocus.d.ts +0 -28
- package/dist/hooks/useTerminalFocus.js +0 -87
- package/dist/hooks/useTerminalSize.d.ts +0 -4
- package/dist/hooks/useTerminalSize.js +0 -20
- package/dist/hooks/useTodoPicker.d.ts +0 -16
- package/dist/hooks/useTodoPicker.js +0 -94
- package/dist/hooks/useToolConfirmation.d.ts +0 -19
- package/dist/hooks/useToolConfirmation.js +0 -61
- package/dist/hooks/useVSCodeState.d.ts +0 -8
- package/dist/hooks/useVSCodeState.js +0 -81
- package/dist/i18n/I18nContext.d.ts +0 -14
- package/dist/i18n/I18nContext.js +0 -24
- package/dist/i18n/index.d.ts +0 -3
- package/dist/i18n/index.js +0 -2
- package/dist/i18n/lang/en.d.ts +0 -2
- package/dist/i18n/lang/en.js +0 -502
- package/dist/i18n/lang/es.d.ts +0 -2
- package/dist/i18n/lang/es.js +0 -502
- package/dist/i18n/lang/ja.d.ts +0 -2
- package/dist/i18n/lang/ja.js +0 -502
- package/dist/i18n/lang/ko.d.ts +0 -2
- package/dist/i18n/lang/ko.js +0 -502
- package/dist/i18n/lang/zh-TW.d.ts +0 -2
- package/dist/i18n/lang/zh-TW.js +0 -502
- package/dist/i18n/lang/zh.d.ts +0 -2
- package/dist/i18n/lang/zh.js +0 -502
- package/dist/i18n/translations.d.ts +0 -2
- package/dist/i18n/translations.js +0 -14
- package/dist/i18n/types.d.ts +0 -478
- package/dist/i18n/types.js +0 -1
- package/dist/mcp/aceCodeSearch.d.ts +0 -247
- package/dist/mcp/aceCodeSearch.js +0 -1058
- package/dist/mcp/bash.d.ts +0 -50
- package/dist/mcp/bash.js +0 -153
- package/dist/mcp/codebaseSearch.d.ts +0 -44
- package/dist/mcp/codebaseSearch.js +0 -275
- package/dist/mcp/filesystem.d.ts +0 -392
- package/dist/mcp/filesystem.js +0 -1445
- package/dist/mcp/ideDiagnostics.d.ts +0 -36
- package/dist/mcp/ideDiagnostics.js +0 -90
- package/dist/mcp/notebook.d.ts +0 -10
- package/dist/mcp/notebook.js +0 -367
- package/dist/mcp/subagent.d.ts +0 -37
- package/dist/mcp/subagent.js +0 -113
- package/dist/mcp/todo.d.ts +0 -46
- package/dist/mcp/todo.js +0 -511
- package/dist/mcp/types/aceCodeSearch.types.d.ts +0 -92
- package/dist/mcp/types/aceCodeSearch.types.js +0 -4
- package/dist/mcp/types/bash.types.d.ts +0 -13
- package/dist/mcp/types/bash.types.js +0 -4
- package/dist/mcp/types/filesystem.types.d.ts +0 -210
- package/dist/mcp/types/filesystem.types.js +0 -27
- package/dist/mcp/types/todo.types.d.ts +0 -27
- package/dist/mcp/types/todo.types.js +0 -4
- package/dist/mcp/types/websearch.types.d.ts +0 -30
- package/dist/mcp/types/websearch.types.js +0 -4
- package/dist/mcp/utils/aceCodeSearch/filesystem.utils.d.ts +0 -34
- package/dist/mcp/utils/aceCodeSearch/filesystem.utils.js +0 -146
- package/dist/mcp/utils/aceCodeSearch/language.utils.d.ts +0 -14
- package/dist/mcp/utils/aceCodeSearch/language.utils.js +0 -418
- package/dist/mcp/utils/aceCodeSearch/search.utils.d.ts +0 -31
- package/dist/mcp/utils/aceCodeSearch/search.utils.js +0 -136
- package/dist/mcp/utils/aceCodeSearch/symbol.utils.d.ts +0 -20
- package/dist/mcp/utils/aceCodeSearch/symbol.utils.js +0 -141
- package/dist/mcp/utils/bash/security.utils.d.ts +0 -20
- package/dist/mcp/utils/bash/security.utils.js +0 -34
- package/dist/mcp/utils/filesystem/batch-operations.utils.d.ts +0 -39
- package/dist/mcp/utils/filesystem/batch-operations.utils.js +0 -182
- package/dist/mcp/utils/filesystem/code-analysis.utils.d.ts +0 -18
- package/dist/mcp/utils/filesystem/code-analysis.utils.js +0 -165
- package/dist/mcp/utils/filesystem/match-finder.utils.d.ts +0 -16
- package/dist/mcp/utils/filesystem/match-finder.utils.js +0 -85
- package/dist/mcp/utils/filesystem/office-parser.utils.d.ts +0 -43
- package/dist/mcp/utils/filesystem/office-parser.utils.js +0 -163
- package/dist/mcp/utils/filesystem/path-fixer.utils.d.ts +0 -7
- package/dist/mcp/utils/filesystem/path-fixer.utils.js +0 -60
- package/dist/mcp/utils/filesystem/similarity.utils.d.ts +0 -22
- package/dist/mcp/utils/filesystem/similarity.utils.js +0 -75
- package/dist/mcp/utils/todo/date.utils.d.ts +0 -9
- package/dist/mcp/utils/todo/date.utils.js +0 -14
- package/dist/mcp/utils/websearch/browser.utils.d.ts +0 -8
- package/dist/mcp/utils/websearch/browser.utils.js +0 -58
- package/dist/mcp/utils/websearch/text.utils.d.ts +0 -16
- package/dist/mcp/utils/websearch/text.utils.js +0 -39
- package/dist/mcp/websearch.d.ts +0 -88
- package/dist/mcp/websearch.js +0 -375
- package/dist/test/logger-test.d.ts +0 -1
- package/dist/test/logger-test.js +0 -7
- package/dist/types/index.d.ts +0 -15
- package/dist/types/index.js +0 -1
- package/dist/ui/components/AgentPickerPanel.d.ts +0 -10
- package/dist/ui/components/AgentPickerPanel.js +0 -74
- package/dist/ui/components/ChatInput.d.ts +0 -46
- package/dist/ui/components/ChatInput.js +0 -379
- package/dist/ui/components/CommandPanel.d.ts +0 -15
- package/dist/ui/components/CommandPanel.js +0 -80
- package/dist/ui/components/DiffViewer.d.ts +0 -11
- package/dist/ui/components/DiffViewer.js +0 -178
- package/dist/ui/components/FileList.d.ts +0 -15
- package/dist/ui/components/FileList.js +0 -360
- package/dist/ui/components/FileRollbackConfirmation.d.ts +0 -8
- package/dist/ui/components/FileRollbackConfirmation.js +0 -108
- package/dist/ui/components/HelpPanel.d.ts +0 -2
- package/dist/ui/components/HelpPanel.js +0 -67
- package/dist/ui/components/MCPInfoPanel.d.ts +0 -2
- package/dist/ui/components/MCPInfoPanel.js +0 -108
- package/dist/ui/components/MCPInfoScreen.d.ts +0 -7
- package/dist/ui/components/MCPInfoScreen.js +0 -115
- package/dist/ui/components/MarkdownRenderer.d.ts +0 -6
- package/dist/ui/components/MarkdownRenderer.js +0 -70
- package/dist/ui/components/Menu.d.ts +0 -17
- package/dist/ui/components/Menu.js +0 -88
- package/dist/ui/components/MessageList.d.ts +0 -56
- package/dist/ui/components/MessageList.js +0 -97
- package/dist/ui/components/PendingMessages.d.ts +0 -13
- package/dist/ui/components/PendingMessages.js +0 -29
- package/dist/ui/components/PendingToolCalls.d.ts +0 -11
- package/dist/ui/components/PendingToolCalls.js +0 -35
- package/dist/ui/components/ScrollableSelectInput.d.ts +0 -29
- package/dist/ui/components/ScrollableSelectInput.js +0 -157
- package/dist/ui/components/SessionListPanel.d.ts +0 -7
- package/dist/ui/components/SessionListPanel.js +0 -175
- package/dist/ui/components/SessionListScreen.d.ts +0 -7
- package/dist/ui/components/SessionListScreen.js +0 -217
- package/dist/ui/components/SessionListScreenWrapper.d.ts +0 -7
- package/dist/ui/components/SessionListScreenWrapper.js +0 -14
- package/dist/ui/components/ShimmerText.d.ts +0 -9
- package/dist/ui/components/ShimmerText.js +0 -30
- package/dist/ui/components/TodoPickerPanel.d.ts +0 -14
- package/dist/ui/components/TodoPickerPanel.js +0 -119
- package/dist/ui/components/TodoTree.d.ts +0 -15
- package/dist/ui/components/TodoTree.js +0 -60
- package/dist/ui/components/ToolConfirmation.d.ts +0 -21
- package/dist/ui/components/ToolConfirmation.js +0 -204
- package/dist/ui/components/ToolResultPreview.d.ts +0 -13
- package/dist/ui/components/ToolResultPreview.js +0 -337
- package/dist/ui/components/UsagePanel.d.ts +0 -2
- package/dist/ui/components/UsagePanel.js +0 -394
- package/dist/ui/contexts/ThemeContext.d.ts +0 -13
- package/dist/ui/contexts/ThemeContext.js +0 -28
- package/dist/ui/pages/ChatScreen.d.ts +0 -6
- package/dist/ui/pages/ChatScreen.js +0 -1495
- package/dist/ui/pages/CodeBaseConfigScreen.d.ts +0 -8
- package/dist/ui/pages/CodeBaseConfigScreen.js +0 -350
- package/dist/ui/pages/ConfigScreen.d.ts +0 -8
- package/dist/ui/pages/ConfigScreen.js +0 -1101
- package/dist/ui/pages/CustomHeadersScreen.d.ts +0 -6
- package/dist/ui/pages/CustomHeadersScreen.js +0 -502
- package/dist/ui/pages/HeadlessModeScreen.d.ts +0 -7
- package/dist/ui/pages/HeadlessModeScreen.js +0 -381
- package/dist/ui/pages/LanguageSettingsScreen.d.ts +0 -7
- package/dist/ui/pages/LanguageSettingsScreen.js +0 -91
- package/dist/ui/pages/MCPConfigScreen.d.ts +0 -6
- package/dist/ui/pages/MCPConfigScreen.js +0 -55
- package/dist/ui/pages/ProxyConfigScreen.d.ts +0 -8
- package/dist/ui/pages/ProxyConfigScreen.js +0 -149
- package/dist/ui/pages/SensitiveCommandConfigScreen.d.ts +0 -7
- package/dist/ui/pages/SensitiveCommandConfigScreen.js +0 -271
- package/dist/ui/pages/SubAgentConfigScreen.d.ts +0 -9
- package/dist/ui/pages/SubAgentConfigScreen.js +0 -435
- package/dist/ui/pages/SubAgentListScreen.d.ts +0 -9
- package/dist/ui/pages/SubAgentListScreen.js +0 -131
- package/dist/ui/pages/SystemPromptConfigScreen.d.ts +0 -6
- package/dist/ui/pages/SystemPromptConfigScreen.js +0 -326
- package/dist/ui/pages/ThemeSettingsScreen.d.ts +0 -7
- package/dist/ui/pages/ThemeSettingsScreen.js +0 -106
- package/dist/ui/pages/WelcomeScreen.d.ts +0 -7
- package/dist/ui/pages/WelcomeScreen.js +0 -217
- package/dist/ui/themes/index.d.ts +0 -23
- package/dist/ui/themes/index.js +0 -140
- package/dist/utils/apiConfig.d.ts +0 -126
- package/dist/utils/apiConfig.js +0 -423
- package/dist/utils/autoCompress.d.ts +0 -15
- package/dist/utils/autoCompress.js +0 -24
- package/dist/utils/chatExporter.d.ts +0 -9
- package/dist/utils/chatExporter.js +0 -118
- package/dist/utils/checkpointManager.d.ts +0 -74
- package/dist/utils/checkpointManager.js +0 -181
- package/dist/utils/codebaseConfig.d.ts +0 -16
- package/dist/utils/codebaseConfig.js +0 -67
- package/dist/utils/codebaseDatabase.d.ts +0 -102
- package/dist/utils/codebaseDatabase.js +0 -333
- package/dist/utils/codebaseSearchEvents.d.ts +0 -16
- package/dist/utils/codebaseSearchEvents.js +0 -13
- package/dist/utils/commandExecutor.d.ts +0 -13
- package/dist/utils/commandExecutor.js +0 -26
- package/dist/utils/commands/agent.d.ts +0 -2
- package/dist/utils/commands/agent.js +0 -12
- package/dist/utils/commands/clear.d.ts +0 -2
- package/dist/utils/commands/clear.js +0 -12
- package/dist/utils/commands/compact.d.ts +0 -2
- package/dist/utils/commands/compact.js +0 -12
- package/dist/utils/commands/export.d.ts +0 -2
- package/dist/utils/commands/export.js +0 -12
- package/dist/utils/commands/help.d.ts +0 -2
- package/dist/utils/commands/help.js +0 -11
- package/dist/utils/commands/home.d.ts +0 -2
- package/dist/utils/commands/home.js +0 -34
- package/dist/utils/commands/ide.d.ts +0 -2
- package/dist/utils/commands/ide.js +0 -32
- package/dist/utils/commands/init.d.ts +0 -2
- package/dist/utils/commands/init.js +0 -93
- package/dist/utils/commands/mcp.d.ts +0 -2
- package/dist/utils/commands/mcp.js +0 -12
- package/dist/utils/commands/resume.d.ts +0 -2
- package/dist/utils/commands/resume.js +0 -12
- package/dist/utils/commands/review.d.ts +0 -2
- package/dist/utils/commands/review.js +0 -81
- package/dist/utils/commands/role.d.ts +0 -2
- package/dist/utils/commands/role.js +0 -37
- package/dist/utils/commands/todoPicker.d.ts +0 -2
- package/dist/utils/commands/todoPicker.js +0 -12
- package/dist/utils/commands/usage.d.ts +0 -2
- package/dist/utils/commands/usage.js +0 -12
- package/dist/utils/commands/yolo.d.ts +0 -2
- package/dist/utils/commands/yolo.js +0 -12
- package/dist/utils/configManager.d.ts +0 -45
- package/dist/utils/configManager.js +0 -303
- package/dist/utils/contextCompressor.d.ts +0 -16
- package/dist/utils/contextCompressor.js +0 -334
- package/dist/utils/devMode.d.ts +0 -13
- package/dist/utils/devMode.js +0 -54
- package/dist/utils/escapeHandler.d.ts +0 -79
- package/dist/utils/escapeHandler.js +0 -153
- package/dist/utils/fileDialog.d.ts +0 -9
- package/dist/utils/fileDialog.js +0 -74
- package/dist/utils/fileUtils.d.ts +0 -40
- package/dist/utils/fileUtils.js +0 -185
- package/dist/utils/historyManager.d.ts +0 -45
- package/dist/utils/historyManager.js +0 -159
- package/dist/utils/incrementalSnapshot.d.ts +0 -109
- package/dist/utils/incrementalSnapshot.js +0 -383
- package/dist/utils/index.d.ts +0 -11
- package/dist/utils/index.js +0 -18
- package/dist/utils/languageConfig.d.ts +0 -21
- package/dist/utils/languageConfig.js +0 -61
- package/dist/utils/logger.d.ts +0 -37
- package/dist/utils/logger.js +0 -122
- package/dist/utils/mcpToolsManager.d.ts +0 -52
- package/dist/utils/mcpToolsManager.js +0 -878
- package/dist/utils/messageFormatter.d.ts +0 -12
- package/dist/utils/messageFormatter.js +0 -115
- package/dist/utils/notebookManager.d.ts +0 -59
- package/dist/utils/notebookManager.js +0 -213
- package/dist/utils/patch-highlight.d.ts +0 -5
- package/dist/utils/patch-highlight.js +0 -23
- package/dist/utils/processManager.d.ts +0 -27
- package/dist/utils/processManager.js +0 -75
- package/dist/utils/proxyUtils.d.ts +0 -15
- package/dist/utils/proxyUtils.js +0 -50
- package/dist/utils/resourceMonitor.d.ts +0 -65
- package/dist/utils/resourceMonitor.js +0 -175
- package/dist/utils/retryUtils.d.ts +0 -49
- package/dist/utils/retryUtils.js +0 -303
- package/dist/utils/sensitiveCommandManager.d.ts +0 -53
- package/dist/utils/sensitiveCommandManager.js +0 -308
- package/dist/utils/sessionConverter.d.ts +0 -7
- package/dist/utils/sessionConverter.js +0 -306
- package/dist/utils/sessionManager.d.ts +0 -53
- package/dist/utils/sessionManager.js +0 -371
- package/dist/utils/subAgentConfig.d.ts +0 -50
- package/dist/utils/subAgentConfig.js +0 -221
- package/dist/utils/subAgentExecutor.d.ts +0 -40
- package/dist/utils/subAgentExecutor.js +0 -434
- package/dist/utils/terminal.d.ts +0 -5
- package/dist/utils/terminal.js +0 -13
- package/dist/utils/textBuffer.d.ts +0 -99
- package/dist/utils/textBuffer.js +0 -547
- package/dist/utils/textUtils.d.ts +0 -37
- package/dist/utils/textUtils.js +0 -102
- package/dist/utils/themeConfig.d.ts +0 -21
- package/dist/utils/themeConfig.js +0 -61
- package/dist/utils/todoPreprocessor.d.ts +0 -5
- package/dist/utils/todoPreprocessor.js +0 -18
- package/dist/utils/todoScanner.d.ts +0 -8
- package/dist/utils/todoScanner.js +0 -148
- package/dist/utils/toolDisplayConfig.d.ts +0 -16
- package/dist/utils/toolDisplayConfig.js +0 -47
- package/dist/utils/toolExecutor.d.ts +0 -37
- package/dist/utils/toolExecutor.js +0 -224
- package/dist/utils/usageLogger.d.ts +0 -11
- package/dist/utils/usageLogger.js +0 -114
- package/dist/utils/vscodeConnection.d.ts +0 -76
- package/dist/utils/vscodeConnection.js +0 -430
- package/dist/utils/workspaceSnapshot.d.ts +0 -63
- package/dist/utils/workspaceSnapshot.js +0 -300
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
import { randomUUID } from 'crypto';
|
|
5
|
-
import { getTodoService } from './mcpToolsManager.js';
|
|
6
|
-
import { logger } from './logger.js';
|
|
7
|
-
import { summaryAgent } from '../agents/summaryAgent.js';
|
|
8
|
-
class SessionManager {
|
|
9
|
-
constructor() {
|
|
10
|
-
Object.defineProperty(this, "sessionsDir", {
|
|
11
|
-
enumerable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
writable: true,
|
|
14
|
-
value: void 0
|
|
15
|
-
});
|
|
16
|
-
Object.defineProperty(this, "currentSession", {
|
|
17
|
-
enumerable: true,
|
|
18
|
-
configurable: true,
|
|
19
|
-
writable: true,
|
|
20
|
-
value: null
|
|
21
|
-
});
|
|
22
|
-
this.sessionsDir = path.join(os.homedir(), '.snow', 'sessions');
|
|
23
|
-
}
|
|
24
|
-
async ensureSessionsDir(date) {
|
|
25
|
-
try {
|
|
26
|
-
await fs.mkdir(this.sessionsDir, { recursive: true });
|
|
27
|
-
if (date) {
|
|
28
|
-
const dateFolder = this.formatDateForFolder(date);
|
|
29
|
-
const sessionDir = path.join(this.sessionsDir, dateFolder);
|
|
30
|
-
await fs.mkdir(sessionDir, { recursive: true });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
// Directory already exists or other error
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
getSessionPath(sessionId, date) {
|
|
38
|
-
const sessionDate = date || new Date();
|
|
39
|
-
const dateFolder = this.formatDateForFolder(sessionDate);
|
|
40
|
-
const sessionDir = path.join(this.sessionsDir, dateFolder);
|
|
41
|
-
return path.join(sessionDir, `${sessionId}.json`);
|
|
42
|
-
}
|
|
43
|
-
formatDateForFolder(date) {
|
|
44
|
-
const year = date.getFullYear();
|
|
45
|
-
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
46
|
-
const day = String(date.getDate()).padStart(2, '0');
|
|
47
|
-
return `${year}-${month}-${day}`;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Clean title by removing newlines and extra spaces
|
|
51
|
-
*/
|
|
52
|
-
cleanTitle(title) {
|
|
53
|
-
return title
|
|
54
|
-
.replace(/[\r\n]+/g, ' ') // Replace newlines with space
|
|
55
|
-
.replace(/\s+/g, ' ') // Replace multiple spaces with single space
|
|
56
|
-
.trim(); // Remove leading/trailing spaces
|
|
57
|
-
}
|
|
58
|
-
async createNewSession() {
|
|
59
|
-
await this.ensureSessionsDir(new Date());
|
|
60
|
-
// 使用 UUID v4 生成唯一会话 ID,避免并发冲突
|
|
61
|
-
const sessionId = randomUUID();
|
|
62
|
-
const session = {
|
|
63
|
-
id: sessionId,
|
|
64
|
-
title: 'New Chat',
|
|
65
|
-
summary: '',
|
|
66
|
-
createdAt: Date.now(),
|
|
67
|
-
updatedAt: Date.now(),
|
|
68
|
-
messages: [],
|
|
69
|
-
messageCount: 0,
|
|
70
|
-
};
|
|
71
|
-
this.currentSession = session;
|
|
72
|
-
await this.saveSession(session);
|
|
73
|
-
return session;
|
|
74
|
-
}
|
|
75
|
-
async saveSession(session) {
|
|
76
|
-
const sessionDate = new Date(session.createdAt);
|
|
77
|
-
await this.ensureSessionsDir(sessionDate);
|
|
78
|
-
const sessionPath = this.getSessionPath(session.id, sessionDate);
|
|
79
|
-
await fs.writeFile(sessionPath, JSON.stringify(session, null, 2));
|
|
80
|
-
}
|
|
81
|
-
async loadSession(sessionId) {
|
|
82
|
-
// 首先尝试从旧格式加载(向下兼容)
|
|
83
|
-
try {
|
|
84
|
-
const oldSessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
|
|
85
|
-
const data = await fs.readFile(oldSessionPath, 'utf-8');
|
|
86
|
-
const session = JSON.parse(data);
|
|
87
|
-
this.currentSession = session;
|
|
88
|
-
return session;
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
// 旧格式不存在,搜索日期文件夹
|
|
92
|
-
}
|
|
93
|
-
// 在日期文件夹中查找会话
|
|
94
|
-
try {
|
|
95
|
-
const session = await this.findSessionInDateFolders(sessionId);
|
|
96
|
-
if (session) {
|
|
97
|
-
this.currentSession = session;
|
|
98
|
-
return session;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
// 搜索失败
|
|
103
|
-
}
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
async findSessionInDateFolders(sessionId) {
|
|
107
|
-
try {
|
|
108
|
-
const files = await fs.readdir(this.sessionsDir);
|
|
109
|
-
for (const file of files) {
|
|
110
|
-
const filePath = path.join(this.sessionsDir, file);
|
|
111
|
-
const stat = await fs.stat(filePath);
|
|
112
|
-
if (stat.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(file)) {
|
|
113
|
-
// 这是日期文件夹,查找会话文件
|
|
114
|
-
const sessionPath = path.join(filePath, `${sessionId}.json`);
|
|
115
|
-
try {
|
|
116
|
-
const data = await fs.readFile(sessionPath, 'utf-8');
|
|
117
|
-
const session = JSON.parse(data);
|
|
118
|
-
return session;
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
// 文件不存在或读取失败,继续搜索
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
catch (error) {
|
|
128
|
-
// 目录读取失败
|
|
129
|
-
}
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
async listSessions() {
|
|
133
|
-
await this.ensureSessionsDir();
|
|
134
|
-
const sessions = [];
|
|
135
|
-
try {
|
|
136
|
-
// 首先处理新的日期文件夹结构
|
|
137
|
-
const files = await fs.readdir(this.sessionsDir);
|
|
138
|
-
for (const file of files) {
|
|
139
|
-
const filePath = path.join(this.sessionsDir, file);
|
|
140
|
-
const stat = await fs.stat(filePath);
|
|
141
|
-
if (stat.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(file)) {
|
|
142
|
-
// 这是日期文件夹,读取其中的会话文件
|
|
143
|
-
await this.readSessionsFromDir(filePath, sessions);
|
|
144
|
-
}
|
|
145
|
-
else if (file.endsWith('.json')) {
|
|
146
|
-
// 这是旧格式的会话文件(向下兼容)
|
|
147
|
-
try {
|
|
148
|
-
const data = await fs.readFile(filePath, 'utf-8');
|
|
149
|
-
const session = JSON.parse(data);
|
|
150
|
-
sessions.push({
|
|
151
|
-
id: session.id,
|
|
152
|
-
title: this.cleanTitle(session.title),
|
|
153
|
-
summary: session.summary,
|
|
154
|
-
createdAt: session.createdAt,
|
|
155
|
-
updatedAt: session.updatedAt,
|
|
156
|
-
messageCount: session.messageCount,
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
// Skip invalid session files
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
// Sort by updatedAt (newest first)
|
|
166
|
-
return sessions.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
167
|
-
}
|
|
168
|
-
catch (error) {
|
|
169
|
-
return [];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
async readSessionsFromDir(dirPath, sessions) {
|
|
173
|
-
try {
|
|
174
|
-
const files = await fs.readdir(dirPath);
|
|
175
|
-
for (const file of files) {
|
|
176
|
-
if (file.endsWith('.json')) {
|
|
177
|
-
try {
|
|
178
|
-
const sessionPath = path.join(dirPath, file);
|
|
179
|
-
const data = await fs.readFile(sessionPath, 'utf-8');
|
|
180
|
-
const session = JSON.parse(data);
|
|
181
|
-
sessions.push({
|
|
182
|
-
id: session.id,
|
|
183
|
-
title: this.cleanTitle(session.title),
|
|
184
|
-
summary: session.summary,
|
|
185
|
-
createdAt: session.createdAt,
|
|
186
|
-
updatedAt: session.updatedAt,
|
|
187
|
-
messageCount: session.messageCount,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
// Skip invalid session files
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
// Skip directory if it can't be read
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
async addMessage(message) {
|
|
202
|
-
if (!this.currentSession) {
|
|
203
|
-
this.currentSession = await this.createNewSession();
|
|
204
|
-
}
|
|
205
|
-
// Check if this exact message already exists to prevent duplicates
|
|
206
|
-
// For assistant messages with tool_calls, also compare tool_call_id to ensure uniqueness
|
|
207
|
-
const existingMessage = this.currentSession.messages.find(m => {
|
|
208
|
-
if (m.role !== message.role)
|
|
209
|
-
return false;
|
|
210
|
-
if (m.content !== message.content)
|
|
211
|
-
return false;
|
|
212
|
-
if (Math.abs(m.timestamp - message.timestamp) >= 5000)
|
|
213
|
-
return false;
|
|
214
|
-
// If both messages have tool_calls, compare tool call IDs
|
|
215
|
-
if (m.tool_calls && message.tool_calls) {
|
|
216
|
-
// Create sets of tool call IDs for comparison
|
|
217
|
-
const existingIds = new Set(m.tool_calls.map(tc => tc.id));
|
|
218
|
-
const newIds = new Set(message.tool_calls.map(tc => tc.id));
|
|
219
|
-
// If IDs are different, these are different messages
|
|
220
|
-
if (existingIds.size !== newIds.size)
|
|
221
|
-
return false;
|
|
222
|
-
for (const id of newIds) {
|
|
223
|
-
if (!existingIds.has(id))
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
else if (m.tool_calls || message.tool_calls) {
|
|
228
|
-
// One has tool_calls, the other doesn't - different messages
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
// If both have tool_call_id (tool response), compare them
|
|
232
|
-
if (m.tool_call_id && message.tool_call_id) {
|
|
233
|
-
return m.tool_call_id === message.tool_call_id;
|
|
234
|
-
}
|
|
235
|
-
else if (m.tool_call_id || message.tool_call_id) {
|
|
236
|
-
// One has tool_call_id, the other doesn't - different messages
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
return true;
|
|
240
|
-
});
|
|
241
|
-
if (existingMessage) {
|
|
242
|
-
return; // Don't add duplicate message
|
|
243
|
-
}
|
|
244
|
-
this.currentSession.messages.push(message);
|
|
245
|
-
this.currentSession.messageCount = this.currentSession.messages.length;
|
|
246
|
-
this.currentSession.updatedAt = Date.now();
|
|
247
|
-
// Generate simple title and summary from first user message
|
|
248
|
-
if (this.currentSession.messageCount === 1 && message.role === 'user') {
|
|
249
|
-
// Use first 50 chars as title, first 100 chars as summary
|
|
250
|
-
const title = message.content.slice(0, 50) + (message.content.length > 50 ? '...' : '');
|
|
251
|
-
const summary = message.content.slice(0, 100) + (message.content.length > 100 ? '...' : '');
|
|
252
|
-
this.currentSession.title = this.cleanTitle(title);
|
|
253
|
-
this.currentSession.summary = this.cleanTitle(summary);
|
|
254
|
-
}
|
|
255
|
-
// After the first complete conversation exchange (user + assistant), generate AI summary
|
|
256
|
-
// Only run once when messageCount becomes 2 and the second message is from assistant
|
|
257
|
-
if (this.currentSession.messageCount === 2 && message.role === 'assistant') {
|
|
258
|
-
// Run summary generation in background without blocking
|
|
259
|
-
this.generateAndUpdateSummary().catch(error => {
|
|
260
|
-
logger.error('Failed to generate conversation summary:', error);
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
await this.saveSession(this.currentSession);
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Generate AI-powered summary for the first conversation exchange
|
|
267
|
-
* This runs in the background without blocking the main flow
|
|
268
|
-
*/
|
|
269
|
-
async generateAndUpdateSummary() {
|
|
270
|
-
if (!this.currentSession || this.currentSession.messages.length < 2) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
// Extract first user and assistant messages
|
|
275
|
-
const firstUserMessage = this.currentSession.messages.find(m => m.role === 'user');
|
|
276
|
-
const firstAssistantMessage = this.currentSession.messages.find(m => m.role === 'assistant');
|
|
277
|
-
if (!firstUserMessage || !firstAssistantMessage) {
|
|
278
|
-
logger.warn('Summary agent: Could not find first user/assistant messages');
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
// Generate summary using summary agent
|
|
282
|
-
const result = await summaryAgent.generateSummary(firstUserMessage.content, firstAssistantMessage.content);
|
|
283
|
-
if (result) {
|
|
284
|
-
// Update session with generated summary
|
|
285
|
-
this.currentSession.title = result.title;
|
|
286
|
-
this.currentSession.summary = result.summary;
|
|
287
|
-
// Save updated session
|
|
288
|
-
await this.saveSession(this.currentSession);
|
|
289
|
-
logger.info('Summary agent: Successfully updated session summary', {
|
|
290
|
-
sessionId: this.currentSession.id,
|
|
291
|
-
title: result.title,
|
|
292
|
-
summary: result.summary
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
catch (error) {
|
|
297
|
-
// Silently fail - don't disrupt main conversation flow
|
|
298
|
-
logger.error('Summary agent: Failed to generate summary', error);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
getCurrentSession() {
|
|
302
|
-
return this.currentSession;
|
|
303
|
-
}
|
|
304
|
-
setCurrentSession(session) {
|
|
305
|
-
this.currentSession = session;
|
|
306
|
-
}
|
|
307
|
-
clearCurrentSession() {
|
|
308
|
-
this.currentSession = null;
|
|
309
|
-
}
|
|
310
|
-
async deleteSession(sessionId) {
|
|
311
|
-
let sessionDeleted = false;
|
|
312
|
-
// 首先尝试删除旧格式(向下兼容)
|
|
313
|
-
try {
|
|
314
|
-
const oldSessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
|
|
315
|
-
await fs.unlink(oldSessionPath);
|
|
316
|
-
sessionDeleted = true;
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
// 旧格式不存在,搜索日期文件夹
|
|
320
|
-
}
|
|
321
|
-
// 在日期文件夹中查找并删除会话
|
|
322
|
-
if (!sessionDeleted) {
|
|
323
|
-
try {
|
|
324
|
-
const files = await fs.readdir(this.sessionsDir);
|
|
325
|
-
for (const file of files) {
|
|
326
|
-
const filePath = path.join(this.sessionsDir, file);
|
|
327
|
-
const stat = await fs.stat(filePath);
|
|
328
|
-
if (stat.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(file)) {
|
|
329
|
-
// 这是日期文件夹,查找会话文件
|
|
330
|
-
const sessionPath = path.join(filePath, `${sessionId}.json`);
|
|
331
|
-
try {
|
|
332
|
-
await fs.unlink(sessionPath);
|
|
333
|
-
sessionDeleted = true;
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
|
-
catch (error) {
|
|
337
|
-
// 文件不存在,继续搜索
|
|
338
|
-
continue;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
catch (error) {
|
|
344
|
-
// 目录读取失败
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
// 如果会话删除成功,同时删除对应的TODO列表
|
|
348
|
-
if (sessionDeleted) {
|
|
349
|
-
try {
|
|
350
|
-
const todoService = getTodoService();
|
|
351
|
-
await todoService.deleteTodoList(sessionId);
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
// TODO删除失败不影响会话删除结果
|
|
355
|
-
logger.warn(`Failed to delete TODO list for session ${sessionId}:`, error);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
return sessionDeleted;
|
|
359
|
-
}
|
|
360
|
-
async truncateMessages(messageCount) {
|
|
361
|
-
if (!this.currentSession) {
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
// Truncate messages array to specified count
|
|
365
|
-
this.currentSession.messages = this.currentSession.messages.slice(0, messageCount);
|
|
366
|
-
this.currentSession.messageCount = this.currentSession.messages.length;
|
|
367
|
-
this.currentSession.updatedAt = Date.now();
|
|
368
|
-
await this.saveSession(this.currentSession);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
export const sessionManager = new SessionManager();
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export interface SubAgent {
|
|
2
|
-
id: string;
|
|
3
|
-
name: string;
|
|
4
|
-
description: string;
|
|
5
|
-
role?: string;
|
|
6
|
-
tools: string[];
|
|
7
|
-
createdAt: string;
|
|
8
|
-
updatedAt: string;
|
|
9
|
-
builtin?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export interface SubAgentsConfig {
|
|
12
|
-
agents: SubAgent[];
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Get user-configured sub-agents only (exported for MCP tool generation)
|
|
16
|
-
*/
|
|
17
|
-
export declare function getUserSubAgents(): SubAgent[];
|
|
18
|
-
/**
|
|
19
|
-
* Get all sub-agents (built-in + user-configured)
|
|
20
|
-
*/
|
|
21
|
-
export declare function getSubAgents(): SubAgent[];
|
|
22
|
-
/**
|
|
23
|
-
* Get a sub-agent by ID (checks both built-in and user-configured)
|
|
24
|
-
*/
|
|
25
|
-
export declare function getSubAgent(id: string): SubAgent | null;
|
|
26
|
-
/**
|
|
27
|
-
* Create a new sub-agent (user-configured only)
|
|
28
|
-
*/
|
|
29
|
-
export declare function createSubAgent(name: string, description: string, tools: string[], role?: string): SubAgent;
|
|
30
|
-
/**
|
|
31
|
-
* Update an existing sub-agent (only user-configured agents can be updated)
|
|
32
|
-
*/
|
|
33
|
-
export declare function updateSubAgent(id: string, updates: {
|
|
34
|
-
name?: string;
|
|
35
|
-
description?: string;
|
|
36
|
-
role?: string;
|
|
37
|
-
tools?: string[];
|
|
38
|
-
}): SubAgent | null;
|
|
39
|
-
/**
|
|
40
|
-
* Delete a sub-agent (only user-configured agents can be deleted)
|
|
41
|
-
*/
|
|
42
|
-
export declare function deleteSubAgent(id: string): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Validate sub-agent data
|
|
45
|
-
*/
|
|
46
|
-
export declare function validateSubAgent(data: {
|
|
47
|
-
name: string;
|
|
48
|
-
description: string;
|
|
49
|
-
tools: string[];
|
|
50
|
-
}): string[];
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
const CONFIG_DIR = join(homedir(), '.snow');
|
|
5
|
-
const SUB_AGENTS_CONFIG_FILE = join(CONFIG_DIR, 'sub-agents.json');
|
|
6
|
-
/**
|
|
7
|
-
* Built-in sub-agents (hardcoded, always available)
|
|
8
|
-
*/
|
|
9
|
-
const BUILTIN_AGENTS = [
|
|
10
|
-
{
|
|
11
|
-
id: 'agent_explore',
|
|
12
|
-
name: 'Explore Agent',
|
|
13
|
-
description: 'Specialized for quickly exploring and understanding codebases. Excels at searching code, finding definitions, analyzing code structure and dependencies. Read-only operations.',
|
|
14
|
-
role: 'You are a specialized code exploration agent. Your task is to help users understand codebase structure, locate specific code, and analyze dependencies. Use search and analysis tools to explore code, but do not modify any files or execute commands. Focus on code discovery and understanding.',
|
|
15
|
-
tools: [
|
|
16
|
-
'filesystem-read',
|
|
17
|
-
'ace-find_definition',
|
|
18
|
-
'ace-find_references',
|
|
19
|
-
'ace-semantic_search',
|
|
20
|
-
'ace-text_search',
|
|
21
|
-
'ace-file_outline',
|
|
22
|
-
'codebase-search',
|
|
23
|
-
'websearch-search',
|
|
24
|
-
'websearch-fetch',
|
|
25
|
-
],
|
|
26
|
-
createdAt: '2024-01-01T00:00:00.000Z',
|
|
27
|
-
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
28
|
-
builtin: true,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: 'agent_plan',
|
|
32
|
-
name: 'Plan Agent',
|
|
33
|
-
description: 'Specialized for planning complex tasks. Analyzes requirements, explores code, identifies relevant files, and creates detailed implementation plans. Read-only operations.',
|
|
34
|
-
role: 'You are a specialized task planning agent. Your task is to analyze user requirements, explore existing codebase, identify relevant files and dependencies, and then create detailed implementation plans. Use search and analysis tools to gather information, check diagnostics to understand current state, but do not execute actual modifications. Output clear step-by-step plans including files to modify, suggested implementation approaches, and important considerations.',
|
|
35
|
-
tools: [
|
|
36
|
-
'filesystem-read',
|
|
37
|
-
'ace-find_definition',
|
|
38
|
-
'ace-find_references',
|
|
39
|
-
'ace-semantic_search',
|
|
40
|
-
'ace-text_search',
|
|
41
|
-
'ace-file_outline',
|
|
42
|
-
'ide-get_diagnostics',
|
|
43
|
-
'codebase-search',
|
|
44
|
-
'websearch-search',
|
|
45
|
-
'websearch-fetch',
|
|
46
|
-
],
|
|
47
|
-
createdAt: '2024-01-01T00:00:00.000Z',
|
|
48
|
-
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
49
|
-
builtin: true,
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
id: 'agent_general',
|
|
53
|
-
name: 'General Purpose Agent',
|
|
54
|
-
description: 'General-purpose multi-step task execution agent. Has complete tool access for searching, modifying files, and executing commands. Best for complex tasks requiring actual operations.',
|
|
55
|
-
role: 'You are a general-purpose task execution agent. You can perform various complex multi-step tasks, including searching code, modifying files, executing commands, etc. When given a task, systematically break it down and execute. You have access to all tools and should select appropriate tools as needed to complete tasks efficiently.',
|
|
56
|
-
tools: [
|
|
57
|
-
'filesystem-read',
|
|
58
|
-
'filesystem-create',
|
|
59
|
-
'filesystem-edit',
|
|
60
|
-
'filesystem-edit_search',
|
|
61
|
-
'terminal-execute',
|
|
62
|
-
'ace-find_definition',
|
|
63
|
-
'ace-find_references',
|
|
64
|
-
'ace-semantic_search',
|
|
65
|
-
'ace-text_search',
|
|
66
|
-
'ace-file_outline',
|
|
67
|
-
'websearch-search',
|
|
68
|
-
'websearch-fetch',
|
|
69
|
-
'ide-get_diagnostics',
|
|
70
|
-
'codebase-search',
|
|
71
|
-
],
|
|
72
|
-
createdAt: '2024-01-01T00:00:00.000Z',
|
|
73
|
-
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
74
|
-
builtin: true,
|
|
75
|
-
},
|
|
76
|
-
];
|
|
77
|
-
function ensureConfigDirectory() {
|
|
78
|
-
if (!existsSync(CONFIG_DIR)) {
|
|
79
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function generateId() {
|
|
83
|
-
return `agent_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Get user-configured sub-agents only (exported for MCP tool generation)
|
|
87
|
-
*/
|
|
88
|
-
export function getUserSubAgents() {
|
|
89
|
-
try {
|
|
90
|
-
ensureConfigDirectory();
|
|
91
|
-
if (!existsSync(SUB_AGENTS_CONFIG_FILE)) {
|
|
92
|
-
return [];
|
|
93
|
-
}
|
|
94
|
-
const configData = readFileSync(SUB_AGENTS_CONFIG_FILE, 'utf8');
|
|
95
|
-
const config = JSON.parse(configData);
|
|
96
|
-
return config.agents || [];
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
console.error('Failed to load sub-agents:', error);
|
|
100
|
-
return [];
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Get all sub-agents (built-in + user-configured)
|
|
105
|
-
*/
|
|
106
|
-
export function getSubAgents() {
|
|
107
|
-
const userAgents = getUserSubAgents();
|
|
108
|
-
// Return built-in agents first, then user-configured agents
|
|
109
|
-
return [...BUILTIN_AGENTS, ...userAgents];
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Get a sub-agent by ID (checks both built-in and user-configured)
|
|
113
|
-
*/
|
|
114
|
-
export function getSubAgent(id) {
|
|
115
|
-
const agents = getSubAgents();
|
|
116
|
-
return agents.find(agent => agent.id === id) || null;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Save user-configured sub-agents only (never saves built-in agents)
|
|
120
|
-
*/
|
|
121
|
-
function saveSubAgents(agents) {
|
|
122
|
-
try {
|
|
123
|
-
ensureConfigDirectory();
|
|
124
|
-
// Filter out built-in agents (should never be saved to config)
|
|
125
|
-
const userAgents = agents.filter(agent => !agent.builtin);
|
|
126
|
-
const config = { agents: userAgents };
|
|
127
|
-
const configData = JSON.stringify(config, null, 2);
|
|
128
|
-
writeFileSync(SUB_AGENTS_CONFIG_FILE, configData, 'utf8');
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
throw new Error(`Failed to save sub-agents: ${error}`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Create a new sub-agent (user-configured only)
|
|
136
|
-
*/
|
|
137
|
-
export function createSubAgent(name, description, tools, role) {
|
|
138
|
-
const userAgents = getUserSubAgents();
|
|
139
|
-
const now = new Date().toISOString();
|
|
140
|
-
const newAgent = {
|
|
141
|
-
id: generateId(),
|
|
142
|
-
name,
|
|
143
|
-
description,
|
|
144
|
-
role,
|
|
145
|
-
tools,
|
|
146
|
-
createdAt: now,
|
|
147
|
-
updatedAt: now,
|
|
148
|
-
builtin: false,
|
|
149
|
-
};
|
|
150
|
-
userAgents.push(newAgent);
|
|
151
|
-
saveSubAgents(userAgents);
|
|
152
|
-
return newAgent;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Update an existing sub-agent (only user-configured agents can be updated)
|
|
156
|
-
*/
|
|
157
|
-
export function updateSubAgent(id, updates) {
|
|
158
|
-
// Prevent updating built-in agents
|
|
159
|
-
const agent = getSubAgent(id);
|
|
160
|
-
if (agent?.builtin) {
|
|
161
|
-
throw new Error('Cannot update built-in agents');
|
|
162
|
-
}
|
|
163
|
-
const userAgents = getUserSubAgents();
|
|
164
|
-
const index = userAgents.findIndex(agent => agent.id === id);
|
|
165
|
-
if (index === -1) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
const existingAgent = userAgents[index];
|
|
169
|
-
if (!existingAgent) {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
const updatedAgent = {
|
|
173
|
-
id: existingAgent.id,
|
|
174
|
-
name: updates.name ?? existingAgent.name,
|
|
175
|
-
description: updates.description ?? existingAgent.description,
|
|
176
|
-
role: updates.role ?? existingAgent.role,
|
|
177
|
-
tools: updates.tools ?? existingAgent.tools,
|
|
178
|
-
createdAt: existingAgent.createdAt,
|
|
179
|
-
updatedAt: new Date().toISOString(),
|
|
180
|
-
builtin: false,
|
|
181
|
-
};
|
|
182
|
-
userAgents[index] = updatedAgent;
|
|
183
|
-
saveSubAgents(userAgents);
|
|
184
|
-
return updatedAgent;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Delete a sub-agent (only user-configured agents can be deleted)
|
|
188
|
-
*/
|
|
189
|
-
export function deleteSubAgent(id) {
|
|
190
|
-
// Prevent deleting built-in agents
|
|
191
|
-
const agent = getSubAgent(id);
|
|
192
|
-
if (agent?.builtin) {
|
|
193
|
-
throw new Error('Cannot delete built-in agents');
|
|
194
|
-
}
|
|
195
|
-
const userAgents = getUserSubAgents();
|
|
196
|
-
const filteredAgents = userAgents.filter(agent => agent.id !== id);
|
|
197
|
-
if (filteredAgents.length === userAgents.length) {
|
|
198
|
-
return false; // Agent not found
|
|
199
|
-
}
|
|
200
|
-
saveSubAgents(filteredAgents);
|
|
201
|
-
return true;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Validate sub-agent data
|
|
205
|
-
*/
|
|
206
|
-
export function validateSubAgent(data) {
|
|
207
|
-
const errors = [];
|
|
208
|
-
if (!data.name || data.name.trim().length === 0) {
|
|
209
|
-
errors.push('Agent name is required');
|
|
210
|
-
}
|
|
211
|
-
if (data.name && data.name.length > 100) {
|
|
212
|
-
errors.push('Agent name must be less than 100 characters');
|
|
213
|
-
}
|
|
214
|
-
if (data.description && data.description.length > 500) {
|
|
215
|
-
errors.push('Description must be less than 500 characters');
|
|
216
|
-
}
|
|
217
|
-
if (!data.tools || data.tools.length === 0) {
|
|
218
|
-
errors.push('At least one tool must be selected');
|
|
219
|
-
}
|
|
220
|
-
return errors;
|
|
221
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { ConfirmationResult } from '../ui/components/ToolConfirmation.js';
|
|
2
|
-
export interface SubAgentMessage {
|
|
3
|
-
type: 'sub_agent_message';
|
|
4
|
-
agentId: string;
|
|
5
|
-
agentName: string;
|
|
6
|
-
message: any;
|
|
7
|
-
}
|
|
8
|
-
export interface TokenUsage {
|
|
9
|
-
inputTokens: number;
|
|
10
|
-
outputTokens: number;
|
|
11
|
-
cacheCreationInputTokens?: number;
|
|
12
|
-
cacheReadInputTokens?: number;
|
|
13
|
-
}
|
|
14
|
-
export interface SubAgentResult {
|
|
15
|
-
success: boolean;
|
|
16
|
-
result: string;
|
|
17
|
-
error?: string;
|
|
18
|
-
usage?: TokenUsage;
|
|
19
|
-
}
|
|
20
|
-
export interface ToolConfirmationCallback {
|
|
21
|
-
(toolName: string, toolArgs: any): Promise<ConfirmationResult>;
|
|
22
|
-
}
|
|
23
|
-
export interface ToolApprovalChecker {
|
|
24
|
-
(toolName: string): boolean;
|
|
25
|
-
}
|
|
26
|
-
export interface AddToAlwaysApprovedCallback {
|
|
27
|
-
(toolName: string): void;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Execute a sub-agent as a tool
|
|
31
|
-
* @param agentId - The ID of the sub-agent to execute
|
|
32
|
-
* @param prompt - The task prompt to send to the sub-agent
|
|
33
|
-
* @param onMessage - Callback for streaming sub-agent messages (for UI display)
|
|
34
|
-
* @param abortSignal - Optional abort signal
|
|
35
|
-
* @param requestToolConfirmation - Callback to request tool confirmation from user
|
|
36
|
-
* @param isToolAutoApproved - Function to check if a tool is auto-approved
|
|
37
|
-
* @param yoloMode - Whether YOLO mode is enabled (auto-approve all tools)
|
|
38
|
-
* @returns The final result from the sub-agent
|
|
39
|
-
*/
|
|
40
|
-
export declare function executeSubAgent(agentId: string, prompt: string, onMessage?: (message: SubAgentMessage) => void, abortSignal?: AbortSignal, requestToolConfirmation?: ToolConfirmationCallback, isToolAutoApproved?: ToolApprovalChecker, yoloMode?: boolean, addToAlwaysApproved?: AddToAlwaysApprovedCallback): Promise<SubAgentResult>;
|