@swarmclawai/swarmclaw 0.6.7 → 0.7.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/README.md +82 -39
- package/next.config.ts +31 -6
- package/package.json +3 -2
- package/src/app/api/agents/[id]/thread/route.ts +1 -0
- package/src/app/api/agents/route.ts +19 -5
- package/src/app/api/approvals/route.ts +22 -0
- package/src/app/api/chatrooms/[id]/chat/route.ts +4 -0
- package/src/app/api/clawhub/install/route.ts +2 -2
- package/src/app/api/eval/run/route.ts +37 -0
- package/src/app/api/eval/scenarios/route.ts +24 -0
- package/src/app/api/eval/suite/route.ts +29 -0
- package/src/app/api/mcp-servers/[id]/conformance/route.ts +26 -0
- package/src/app/api/mcp-servers/[id]/invoke/route.ts +81 -0
- package/src/app/api/memory/graph/route.ts +46 -0
- package/src/app/api/memory/route.ts +36 -5
- package/src/app/api/notifications/route.ts +3 -0
- package/src/app/api/plugins/install/route.ts +57 -5
- package/src/app/api/plugins/marketplace/route.ts +73 -22
- package/src/app/api/plugins/route.ts +61 -1
- package/src/app/api/plugins/ui/route.ts +34 -0
- package/src/app/api/sessions/[id]/checkpoints/route.ts +31 -0
- package/src/app/api/sessions/[id]/restore/route.ts +36 -0
- package/src/app/api/settings/route.ts +62 -0
- package/src/app/api/setup/doctor/route.ts +22 -5
- package/src/app/api/souls/[id]/route.ts +65 -0
- package/src/app/api/souls/route.ts +70 -0
- package/src/app/api/tasks/[id]/approve/route.ts +4 -3
- package/src/app/api/tasks/[id]/route.ts +16 -3
- package/src/app/api/tasks/route.ts +10 -2
- package/src/app/api/usage/route.ts +9 -2
- package/src/app/globals.css +27 -0
- package/src/app/page.tsx +10 -5
- package/src/cli/index.js +37 -0
- package/src/components/activity/activity-feed.tsx +9 -2
- package/src/components/agents/agent-avatar.tsx +5 -1
- package/src/components/agents/agent-card.tsx +55 -9
- package/src/components/agents/agent-sheet.tsx +112 -34
- package/src/components/agents/inspector-panel.tsx +1 -1
- package/src/components/agents/soul-library-picker.tsx +84 -13
- package/src/components/auth/access-key-gate.tsx +63 -54
- package/src/components/auth/user-picker.tsx +37 -32
- package/src/components/chat/activity-moment.tsx +2 -0
- package/src/components/chat/chat-area.tsx +11 -0
- package/src/components/chat/chat-header.tsx +69 -25
- package/src/components/chat/chat-tool-toggles.tsx +2 -2
- package/src/components/chat/checkpoint-timeline.tsx +112 -0
- package/src/components/chat/code-block.tsx +3 -1
- package/src/components/chat/exec-approval-card.tsx +8 -1
- package/src/components/chat/message-bubble.tsx +164 -4
- package/src/components/chat/message-list.tsx +46 -4
- package/src/components/chat/session-approval-card.tsx +80 -0
- package/src/components/chat/session-debug-panel.tsx +106 -84
- package/src/components/chat/streaming-bubble.tsx +6 -5
- package/src/components/chat/task-approval-card.tsx +78 -0
- package/src/components/chat/thinking-indicator.tsx +48 -12
- package/src/components/chat/tool-call-bubble.tsx +3 -0
- package/src/components/chat/tool-request-banner.tsx +39 -20
- package/src/components/chatrooms/chatroom-list.tsx +11 -4
- package/src/components/chatrooms/chatroom-sheet.tsx +7 -2
- package/src/components/connectors/connector-list.tsx +33 -11
- package/src/components/connectors/connector-sheet.tsx +37 -7
- package/src/components/home/home-view.tsx +54 -24
- package/src/components/input/chat-input.tsx +22 -1
- package/src/components/knowledge/knowledge-list.tsx +17 -18
- package/src/components/knowledge/knowledge-sheet.tsx +9 -5
- package/src/components/layout/app-layout.tsx +87 -19
- package/src/components/mcp-servers/mcp-server-list.tsx +352 -50
- package/src/components/mcp-servers/mcp-server-sheet.tsx +25 -9
- package/src/components/memory/memory-browser.tsx +73 -45
- package/src/components/memory/memory-graph-view.tsx +203 -0
- package/src/components/memory/memory-list.tsx +20 -13
- package/src/components/plugins/plugin-list.tsx +214 -60
- package/src/components/plugins/plugin-sheet.tsx +119 -24
- package/src/components/projects/project-list.tsx +17 -9
- package/src/components/providers/provider-list.tsx +21 -6
- package/src/components/providers/provider-sheet.tsx +42 -25
- package/src/components/runs/run-list.tsx +17 -13
- package/src/components/schedules/schedule-card.tsx +10 -3
- package/src/components/schedules/schedule-list.tsx +2 -2
- package/src/components/schedules/schedule-sheet.tsx +28 -9
- package/src/components/secrets/secret-sheet.tsx +7 -2
- package/src/components/secrets/secrets-list.tsx +18 -5
- package/src/components/sessions/new-session-sheet.tsx +183 -376
- package/src/components/sessions/session-card.tsx +10 -2
- package/src/components/settings/gateway-connection-panel.tsx +9 -8
- package/src/components/shared/command-palette.tsx +13 -5
- package/src/components/shared/empty-state.tsx +20 -8
- package/src/components/shared/hint-tip.tsx +31 -0
- package/src/components/shared/notification-center.tsx +134 -86
- package/src/components/shared/profile-sheet.tsx +4 -0
- package/src/components/shared/settings/plugin-manager.tsx +360 -135
- package/src/components/shared/settings/section-capability-policy.tsx +3 -3
- package/src/components/shared/settings/section-runtime-loop.tsx +149 -4
- package/src/components/skills/clawhub-browser.tsx +1 -0
- package/src/components/skills/skill-list.tsx +31 -12
- package/src/components/skills/skill-sheet.tsx +20 -7
- package/src/components/tasks/approvals-panel.tsx +224 -0
- package/src/components/tasks/task-board.tsx +20 -12
- package/src/components/tasks/task-card.tsx +21 -7
- package/src/components/tasks/task-column.tsx +4 -3
- package/src/components/tasks/task-list.tsx +1 -1
- package/src/components/tasks/task-sheet.tsx +130 -1
- package/src/components/ui/dialog.tsx +1 -0
- package/src/components/ui/sheet.tsx +1 -0
- package/src/components/usage/metrics-dashboard.tsx +72 -48
- package/src/components/wallets/wallet-panel.tsx +65 -41
- package/src/components/wallets/wallet-section.tsx +9 -3
- package/src/components/webhooks/webhook-list.tsx +21 -12
- package/src/components/webhooks/webhook-sheet.tsx +13 -3
- package/src/lib/approval-display.test.ts +45 -0
- package/src/lib/approval-display.ts +62 -0
- package/src/lib/clipboard.ts +38 -0
- package/src/lib/memory.ts +8 -0
- package/src/lib/providers/claude-cli.ts +5 -3
- package/src/lib/providers/index.ts +67 -21
- package/src/lib/runtime-loop.ts +3 -2
- package/src/lib/server/approvals.ts +150 -0
- package/src/lib/server/chat-execution.ts +319 -74
- package/src/lib/server/chatroom-helpers.ts +63 -5
- package/src/lib/server/chatroom-orchestration.ts +74 -0
- package/src/lib/server/clawhub-client.ts +82 -6
- package/src/lib/server/connectors/manager.ts +27 -1
- package/src/lib/server/context-manager.ts +132 -50
- package/src/lib/server/cost.test.ts +73 -0
- package/src/lib/server/cost.ts +165 -34
- package/src/lib/server/daemon-state.ts +112 -1
- package/src/lib/server/data-dir.ts +18 -1
- package/src/lib/server/eval/runner.ts +126 -0
- package/src/lib/server/eval/scenarios.ts +218 -0
- package/src/lib/server/eval/scorer.ts +96 -0
- package/src/lib/server/eval/store.ts +37 -0
- package/src/lib/server/eval/types.ts +48 -0
- package/src/lib/server/execution-log.ts +12 -8
- package/src/lib/server/guardian.ts +34 -0
- package/src/lib/server/heartbeat-service.ts +53 -1
- package/src/lib/server/integrity-monitor.ts +208 -0
- package/src/lib/server/langgraph-checkpoint.ts +10 -0
- package/src/lib/server/link-understanding.ts +55 -0
- package/src/lib/server/llm-response-cache.test.ts +102 -0
- package/src/lib/server/llm-response-cache.ts +227 -0
- package/src/lib/server/main-agent-loop.ts +115 -16
- package/src/lib/server/main-session.ts +6 -3
- package/src/lib/server/mcp-conformance.test.ts +18 -0
- package/src/lib/server/mcp-conformance.ts +233 -0
- package/src/lib/server/memory-db.ts +193 -19
- package/src/lib/server/memory-retrieval.test.ts +56 -0
- package/src/lib/server/mmr.ts +73 -0
- package/src/lib/server/orchestrator-lg.ts +7 -1
- package/src/lib/server/orchestrator.ts +4 -3
- package/src/lib/server/plugins.ts +662 -132
- package/src/lib/server/process-manager.ts +18 -0
- package/src/lib/server/query-expansion.ts +57 -0
- package/src/lib/server/queue.ts +280 -11
- package/src/lib/server/runtime-settings.ts +9 -0
- package/src/lib/server/session-run-manager.test.ts +23 -0
- package/src/lib/server/session-run-manager.ts +32 -2
- package/src/lib/server/session-tools/canvas.ts +85 -50
- package/src/lib/server/session-tools/chatroom.ts +130 -127
- package/src/lib/server/session-tools/connector.ts +233 -454
- package/src/lib/server/session-tools/context-mgmt.ts +87 -105
- package/src/lib/server/session-tools/crud.ts +84 -7
- package/src/lib/server/session-tools/delegate.ts +351 -752
- package/src/lib/server/session-tools/discovery.ts +198 -0
- package/src/lib/server/session-tools/edit_file.ts +82 -0
- package/src/lib/server/session-tools/file-send.test.ts +39 -0
- package/src/lib/server/session-tools/file.ts +257 -425
- package/src/lib/server/session-tools/git.ts +87 -47
- package/src/lib/server/session-tools/http.ts +95 -33
- package/src/lib/server/session-tools/index.ts +217 -138
- package/src/lib/server/session-tools/memory.ts +154 -239
- package/src/lib/server/session-tools/monitor.ts +126 -0
- package/src/lib/server/session-tools/normalize-tool-args.test.ts +61 -0
- package/src/lib/server/session-tools/normalize-tool-args.ts +48 -0
- package/src/lib/server/session-tools/openclaw-nodes.ts +82 -99
- package/src/lib/server/session-tools/openclaw-workspace.ts +103 -93
- package/src/lib/server/session-tools/platform.ts +86 -0
- package/src/lib/server/session-tools/plugin-creator.ts +239 -0
- package/src/lib/server/session-tools/sample-ui.ts +97 -0
- package/src/lib/server/session-tools/sandbox.ts +175 -148
- package/src/lib/server/session-tools/schedule.ts +78 -0
- package/src/lib/server/session-tools/session-info.ts +104 -410
- package/src/lib/server/session-tools/shell-normalize.test.ts +43 -0
- package/src/lib/server/session-tools/shell.ts +171 -143
- package/src/lib/server/session-tools/subagent.ts +77 -77
- package/src/lib/server/session-tools/wallet.ts +182 -106
- package/src/lib/server/session-tools/web.ts +181 -327
- package/src/lib/server/storage.ts +36 -0
- package/src/lib/server/stream-agent-chat.ts +348 -242
- package/src/lib/server/task-quality-gate.test.ts +44 -0
- package/src/lib/server/task-quality-gate.ts +67 -0
- package/src/lib/server/task-validation.test.ts +78 -0
- package/src/lib/server/task-validation.ts +67 -2
- package/src/lib/server/tool-aliases.ts +68 -0
- package/src/lib/server/tool-capability-policy.ts +24 -5
- package/src/lib/server/tool-retry.ts +62 -0
- package/src/lib/server/transcript-repair.ts +72 -0
- package/src/lib/setup-defaults.ts +1 -0
- package/src/lib/tasks.ts +7 -1
- package/src/lib/tool-definitions.ts +24 -23
- package/src/lib/validation/schemas.ts +13 -0
- package/src/lib/view-routes.ts +2 -23
- package/src/stores/use-app-store.ts +23 -1
- package/src/types/index.ts +155 -10
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { tool, type StructuredToolInterface } from '@langchain/core/tools'
|
|
3
|
+
import type { Session } from '@/types'
|
|
3
4
|
import { loadSettings, loadSessions, saveSessions, loadMcpServers } from '../storage'
|
|
4
5
|
import { loadRuntimeSettings } from '../runtime-settings'
|
|
5
6
|
import { log } from '../logger'
|
|
6
7
|
import { resolveSessionToolPolicy } from '../tool-capability-policy'
|
|
8
|
+
import { expandToolIds } from '../tool-aliases'
|
|
7
9
|
import type { ToolContext, SessionToolsResult, ToolBuildContext } from './context'
|
|
10
|
+
|
|
11
|
+
// Import all tool modules to trigger their builtin registration
|
|
8
12
|
import { buildShellTools } from './shell'
|
|
9
13
|
import { buildFileTools } from './file'
|
|
14
|
+
import { buildEditFileTools } from './edit_file'
|
|
10
15
|
import { buildDelegateTools } from './delegate'
|
|
11
16
|
import { buildWebTools, sweepOrphanedBrowsers, cleanupSessionBrowser, getActiveBrowserCount, hasActiveBrowser } from './web'
|
|
12
17
|
import { buildMemoryTools } from './memory'
|
|
13
|
-
import { buildCrudTools } from './crud'
|
|
14
|
-
import { buildSessionInfoTools } from './session-info'
|
|
15
|
-
import { buildConnectorTools } from './connector'
|
|
16
|
-
import { buildContextTools } from './context-mgmt'
|
|
17
18
|
import { buildSandboxTools } from './sandbox'
|
|
18
|
-
import { buildOpenClawNodeTools } from './openclaw-nodes'
|
|
19
19
|
import { buildChatroomTools } from './chatroom'
|
|
20
20
|
import { buildSubagentTools } from './subagent'
|
|
21
21
|
import { buildCanvasTools } from './canvas'
|
|
@@ -23,6 +23,20 @@ import { buildHttpTools } from './http'
|
|
|
23
23
|
import { buildGitTools } from './git'
|
|
24
24
|
import { buildWalletTools } from './wallet'
|
|
25
25
|
import { buildOpenClawWorkspaceTools } from './openclaw-workspace'
|
|
26
|
+
import { buildScheduleTools } from './schedule'
|
|
27
|
+
import { buildPlatformTools } from './platform'
|
|
28
|
+
import { buildSessionInfoTools } from './session-info'
|
|
29
|
+
import { buildOpenClawNodeTools } from './openclaw-nodes'
|
|
30
|
+
import { buildContextTools } from './context-mgmt'
|
|
31
|
+
import { buildConnectorTools } from './connector'
|
|
32
|
+
import { buildDiscoveryTools } from './discovery'
|
|
33
|
+
import { buildMonitorTools } from './monitor'
|
|
34
|
+
import { buildSampleUITools } from './sample-ui'
|
|
35
|
+
import { buildPluginCreatorTools } from './plugin-creator'
|
|
36
|
+
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
37
|
+
|
|
38
|
+
import { getPluginManager } from '../plugins'
|
|
39
|
+
import { jsonSchemaToZod } from '../mcp-client'
|
|
26
40
|
|
|
27
41
|
export type { ToolContext, SessionToolsResult }
|
|
28
42
|
export { sweepOrphanedBrowsers, cleanupSessionBrowser, getActiveBrowserCount, hasActiveBrowser }
|
|
@@ -30,155 +44,220 @@ export { sweepOrphanedBrowsers, cleanupSessionBrowser, getActiveBrowserCount, ha
|
|
|
30
44
|
export async function buildSessionTools(cwd: string, enabledTools: string[], ctx?: ToolContext): Promise<SessionToolsResult> {
|
|
31
45
|
const tools: StructuredToolInterface[] = []
|
|
32
46
|
const cleanupFns: (() => Promise<void>)[] = []
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const runtime = loadRuntimeSettings()
|
|
50
|
+
const commandTimeoutMs = runtime.shellCommandTimeoutMs
|
|
51
|
+
const claudeTimeoutMs = runtime.claudeCodeTimeoutMs
|
|
52
|
+
const cliProcessTimeoutMs = runtime.cliProcessTimeoutMs
|
|
53
|
+
const appSettings = loadSettings()
|
|
54
|
+
const toolPolicy = resolveSessionToolPolicy(enabledTools, appSettings)
|
|
55
|
+
const expandedEnabledTools = expandToolIds(toolPolicy.enabledTools)
|
|
56
|
+
const expandedBlockedTools = expandToolIds(toolPolicy.blockedTools.map((entry) => entry.tool))
|
|
57
|
+
const blockedToolSet = new Set(expandedBlockedTools)
|
|
58
|
+
const filteredEnabledTools = expandedEnabledTools.filter((toolId) => !blockedToolSet.has(toolId))
|
|
59
|
+
const activeTools = filteredEnabledTools.includes('shell')
|
|
60
|
+
&& !filteredEnabledTools.includes('process')
|
|
61
|
+
&& !blockedToolSet.has('process')
|
|
62
|
+
? [...filteredEnabledTools, 'process']
|
|
63
|
+
: filteredEnabledTools
|
|
64
|
+
const activeToolSet = new Set(activeTools)
|
|
65
|
+
const hasTool = (toolName: string) => activeToolSet.has(toolName)
|
|
43
66
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
if (toolPolicy.blockedTools.length > 0) {
|
|
68
|
+
log.info('session-tools', 'Capability policy blocked tool families', {
|
|
69
|
+
sessionId: ctx?.sessionId || null,
|
|
70
|
+
agentId: ctx?.agentId || null,
|
|
71
|
+
blockedTools: toolPolicy.blockedTools.map((entry) => `${entry.tool}:${entry.reason}`),
|
|
72
|
+
})
|
|
73
|
+
}
|
|
51
74
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
const resolveCurrentSession = (): Session | null => {
|
|
76
|
+
if (!ctx?.sessionId) return null
|
|
77
|
+
const sessions = loadSessions()
|
|
78
|
+
return sessions[ctx.sessionId] || null
|
|
79
|
+
}
|
|
57
80
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
const readStoredDelegateResumeId = (key: 'claudeCode' | 'codex' | 'opencode'): string | null => {
|
|
82
|
+
const session = resolveCurrentSession()
|
|
83
|
+
if (!session?.delegateResumeIds || typeof session.delegateResumeIds !== 'object') return null
|
|
84
|
+
const raw = session.delegateResumeIds[key]
|
|
85
|
+
return typeof raw === 'string' && raw.trim() ? raw.trim() : null
|
|
86
|
+
}
|
|
64
87
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
const persistDelegateResumeId = (key: 'claudeCode' | 'codex' | 'opencode', resumeId: string | null | undefined): void => {
|
|
89
|
+
const normalized = typeof resumeId === 'string' ? resumeId.trim() : ''
|
|
90
|
+
if (!normalized || !ctx?.sessionId) return
|
|
91
|
+
const sessions = loadSessions()
|
|
92
|
+
const target = sessions[ctx.sessionId]
|
|
93
|
+
if (!target) return
|
|
94
|
+
const current = (target.delegateResumeIds && typeof target.delegateResumeIds === 'object')
|
|
95
|
+
? target.delegateResumeIds
|
|
96
|
+
: {}
|
|
97
|
+
target.delegateResumeIds = {
|
|
98
|
+
...current,
|
|
99
|
+
[key]: normalized,
|
|
100
|
+
}
|
|
101
|
+
target.updatedAt = Date.now()
|
|
102
|
+
sessions[ctx.sessionId] = target
|
|
103
|
+
saveSessions(sessions)
|
|
77
104
|
}
|
|
78
|
-
target.updatedAt = Date.now()
|
|
79
|
-
sessions[ctx.sessionId] = target
|
|
80
|
-
saveSessions(sessions)
|
|
81
|
-
}
|
|
82
105
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
const bctx: ToolBuildContext = {
|
|
107
|
+
cwd,
|
|
108
|
+
ctx,
|
|
109
|
+
hasTool,
|
|
110
|
+
cleanupFns,
|
|
111
|
+
commandTimeoutMs,
|
|
112
|
+
claudeTimeoutMs,
|
|
113
|
+
cliProcessTimeoutMs,
|
|
114
|
+
persistDelegateResumeId,
|
|
115
|
+
readStoredDelegateResumeId,
|
|
116
|
+
resolveCurrentSession,
|
|
117
|
+
activeTools,
|
|
118
|
+
}
|
|
96
119
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
// 1. Build Native Bridge Tools (Legacy enablement)
|
|
121
|
+
tools.push(
|
|
122
|
+
...buildShellTools(bctx),
|
|
123
|
+
...buildFileTools(bctx),
|
|
124
|
+
...buildEditFileTools(bctx),
|
|
125
|
+
...buildDelegateTools(bctx),
|
|
126
|
+
...buildWebTools(bctx),
|
|
127
|
+
...buildMemoryTools(bctx),
|
|
128
|
+
...buildPlatformTools(bctx),
|
|
129
|
+
...buildSandboxTools(bctx),
|
|
130
|
+
...buildChatroomTools(bctx),
|
|
131
|
+
...buildSubagentTools(bctx),
|
|
132
|
+
...buildCanvasTools(bctx),
|
|
133
|
+
...buildHttpTools(bctx),
|
|
134
|
+
...buildGitTools(bctx),
|
|
135
|
+
...buildWalletTools(bctx),
|
|
136
|
+
...buildOpenClawWorkspaceTools(bctx),
|
|
137
|
+
...buildScheduleTools(bctx),
|
|
138
|
+
...buildSessionInfoTools(bctx),
|
|
139
|
+
...buildOpenClawNodeTools(bctx),
|
|
140
|
+
...buildContextTools(bctx),
|
|
141
|
+
...buildConnectorTools(bctx),
|
|
142
|
+
...buildDiscoveryTools(bctx),
|
|
143
|
+
...buildMonitorTools(bctx),
|
|
144
|
+
...buildSampleUITools(bctx),
|
|
145
|
+
...buildPluginCreatorTools(bctx),
|
|
146
|
+
)
|
|
117
147
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
148
|
+
// 2. Build Plugin Tools (Built-in + External)
|
|
149
|
+
try {
|
|
150
|
+
const pluginManager = getPluginManager()
|
|
151
|
+
const pluginTools = pluginManager.getTools(activeTools)
|
|
152
|
+
const existingNames = new Set(tools.map((t) => t.name))
|
|
153
|
+
|
|
154
|
+
for (const entry of pluginTools) {
|
|
155
|
+
const pt = entry.tool
|
|
156
|
+
if (existingNames.has(pt.name)) {
|
|
157
|
+
log.warn('session-tools', 'Skipping plugin tool due to duplicate name', {
|
|
158
|
+
toolName: pt.name,
|
|
159
|
+
pluginId: entry.pluginId,
|
|
160
|
+
})
|
|
161
|
+
continue
|
|
162
|
+
}
|
|
163
|
+
existingNames.add(pt.name)
|
|
122
164
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
165
|
+
tools.push(
|
|
166
|
+
tool(
|
|
167
|
+
async (args) => {
|
|
168
|
+
if (!pluginManager.isEnabled(entry.pluginId)) {
|
|
169
|
+
throw new Error(`Plugin "${entry.pluginId}" is disabled`)
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const normalizedArgs = normalizeToolInputArgs((args ?? {}) as Record<string, unknown>)
|
|
173
|
+
const res = await pt.execute(normalizedArgs, {
|
|
174
|
+
session: { ...ctx, cwd } as any,
|
|
175
|
+
message: '',
|
|
176
|
+
})
|
|
177
|
+
pluginManager.recordExternalToolSuccess(entry.pluginId)
|
|
178
|
+
return typeof res === 'string' ? res : JSON.stringify(res)
|
|
179
|
+
} catch (err: unknown) {
|
|
180
|
+
pluginManager.recordExternalToolFailure(entry.pluginId, pt.name, err)
|
|
181
|
+
throw err
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: pt.name,
|
|
186
|
+
description: pt.description,
|
|
187
|
+
schema: jsonSchemaToZod(pt.parameters),
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
} catch (err: unknown) {
|
|
193
|
+
log.error('session-tools', 'Failed to load plugin tools', { error: err instanceof Error ? err.message : String(err) })
|
|
194
|
+
}
|
|
126
195
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
196
|
+
// 3. MCP server tools
|
|
197
|
+
const disabledMcpToolNames = new Set<string>(ctx?.mcpDisabledTools ?? [])
|
|
198
|
+
if (ctx?.mcpServerIds?.length) {
|
|
199
|
+
const mcpConnections: Array<{ client: any; transport: any }> = []
|
|
200
|
+
const allMcpServers = loadMcpServers()
|
|
201
|
+
for (const serverId of ctx.mcpServerIds) {
|
|
202
|
+
const config = allMcpServers[serverId]
|
|
203
|
+
if (!config) continue
|
|
204
|
+
try {
|
|
205
|
+
const { connectMcpServer, mcpToolsToLangChain } = await import('../mcp-client')
|
|
206
|
+
const conn = await connectMcpServer(config)
|
|
207
|
+
mcpConnections.push(conn)
|
|
208
|
+
const mcpLcTools = await mcpToolsToLangChain(conn.client, config.name)
|
|
209
|
+
for (const t of mcpLcTools) {
|
|
210
|
+
if (!disabledMcpToolNames.has(t.name)) {
|
|
211
|
+
tools.push(t)
|
|
212
|
+
}
|
|
138
213
|
}
|
|
214
|
+
} catch (err: any) {
|
|
215
|
+
log.warn('session-tools', `Failed to connect MCP server "${config.name}"`, { serverId, error: err.message })
|
|
139
216
|
}
|
|
140
|
-
} catch (err: any) {
|
|
141
|
-
log.warn('session-tools', `Failed to connect MCP server "${config.name}"`, { serverId, error: err.message })
|
|
142
217
|
}
|
|
218
|
+
cleanupFns.push(async () => {
|
|
219
|
+
const { disconnectMcpServer } = await import('../mcp-client')
|
|
220
|
+
for (const conn of mcpConnections) {
|
|
221
|
+
await disconnectMcpServer(conn.client, conn.transport)
|
|
222
|
+
}
|
|
223
|
+
})
|
|
143
224
|
}
|
|
144
225
|
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
226
|
+
// 4. Always available: request_tool_access
|
|
227
|
+
tools.push(
|
|
228
|
+
tool(
|
|
229
|
+
async (args) => {
|
|
230
|
+
const normalized = normalizeToolInputArgs((args ?? {}) as Record<string, unknown>)
|
|
231
|
+
const toolId = normalized.toolId as string | undefined
|
|
232
|
+
const reason = normalized.reason as string | undefined
|
|
233
|
+
return JSON.stringify({
|
|
234
|
+
type: 'tool_request',
|
|
235
|
+
toolId,
|
|
236
|
+
reason,
|
|
237
|
+
message: `Tool access request sent to user for "${toolId}". The user will be prompted to grant access — once granted, a follow-up message will arrive and you should immediately proceed with the original task using the newly available tool.`,
|
|
238
|
+
})
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: 'request_tool_access',
|
|
242
|
+
description: 'Ask the user for access to a plugin I don\'t currently have.',
|
|
243
|
+
schema: z.object({
|
|
244
|
+
toolId: z.string().describe('The plugin ID to request access for'),
|
|
245
|
+
reason: z.string().describe('Brief explanation of why you need this plugin'),
|
|
246
|
+
}),
|
|
247
|
+
},
|
|
248
|
+
),
|
|
249
|
+
)
|
|
153
250
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
toolId,
|
|
161
|
-
reason,
|
|
162
|
-
message: `Tool access request sent to user for "${toolId}". The user will be prompted to grant access — once granted, a follow-up message will arrive and you should immediately proceed with the original task using the newly available tool.`,
|
|
163
|
-
})
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
name: 'request_tool_access',
|
|
167
|
-
description: 'Ask the user for access to a tool I don\'t currently have. They\'ll get a prompt to grant it, and once they do, I\'ll automatically continue where I left off. I should end my current response after calling this — no need to ask the user to confirm, it happens on its own.',
|
|
168
|
-
schema: z.object({
|
|
169
|
-
toolId: z.string().describe('The tool ID to request access for (e.g. manage_tasks, shell, claude_code)'),
|
|
170
|
-
reason: z.string().describe('Brief explanation of why you need this tool'),
|
|
171
|
-
}),
|
|
251
|
+
return {
|
|
252
|
+
tools,
|
|
253
|
+
cleanup: async () => {
|
|
254
|
+
for (const fn of cleanupFns) {
|
|
255
|
+
try { await fn() } catch { /* ignore */ }
|
|
256
|
+
}
|
|
172
257
|
},
|
|
173
|
-
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
tools,
|
|
178
|
-
cleanup: async () => {
|
|
179
|
-
for (const fn of cleanupFns) {
|
|
180
|
-
try { await fn() } catch { /* ignore */ }
|
|
181
|
-
}
|
|
182
|
-
},
|
|
258
|
+
}
|
|
259
|
+
} catch (err: any) {
|
|
260
|
+
console.error('[session-tools] buildSessionTools critical failure:', err.message)
|
|
261
|
+
throw err
|
|
183
262
|
}
|
|
184
263
|
}
|