@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
|
@@ -3,65 +3,100 @@ import { tool, type StructuredToolInterface } from '@langchain/core/tools'
|
|
|
3
3
|
import { loadSessions, saveSessions } from '../storage'
|
|
4
4
|
import { notify } from '../ws-hub'
|
|
5
5
|
import type { ToolBuildContext } from './context'
|
|
6
|
+
import type { Plugin, PluginHooks } from '@/types'
|
|
7
|
+
import { getPluginManager } from '../plugins'
|
|
8
|
+
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Core Canvas Execution Logic
|
|
12
|
+
*/
|
|
13
|
+
async function executeCanvasAction(args: Record<string, unknown>, context: { sessionId?: string }) {
|
|
14
|
+
const normalized = normalizeToolInputArgs(args)
|
|
15
|
+
const action = normalized.action as string
|
|
16
|
+
const content = normalized.content as string | undefined
|
|
17
|
+
try {
|
|
18
|
+
const sessionId = context.sessionId
|
|
19
|
+
if (!sessionId) return 'Error: no active session for canvas.'
|
|
10
20
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
const sessionId = ctx?.sessionId
|
|
16
|
-
if (!sessionId) return 'Error: no active session for canvas.'
|
|
21
|
+
const sessions = loadSessions()
|
|
22
|
+
const session = sessions[sessionId]
|
|
23
|
+
if (!session) return 'Error: session not found.'
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
if (action === 'present') {
|
|
26
|
+
if (!content) return 'Error: content is required for present action.'
|
|
27
|
+
;(session as Record<string, unknown>).canvasContent = content
|
|
28
|
+
session.lastActiveAt = Date.now()
|
|
29
|
+
sessions[sessionId] = session
|
|
30
|
+
saveSessions(sessions)
|
|
31
|
+
notify(`canvas:${sessionId}`)
|
|
32
|
+
return JSON.stringify({ ok: true, action: 'present', contentLength: content.length })
|
|
33
|
+
}
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
35
|
+
if (action === 'hide') {
|
|
36
|
+
;(session as Record<string, unknown>).canvasContent = null
|
|
37
|
+
session.lastActiveAt = Date.now()
|
|
38
|
+
sessions[sessionId] = session
|
|
39
|
+
saveSessions(sessions)
|
|
40
|
+
notify(`canvas:${sessionId}`)
|
|
41
|
+
return JSON.stringify({ ok: true, action: 'hide' })
|
|
42
|
+
}
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
if (action === 'snapshot') {
|
|
45
|
+
const current = (session as Record<string, unknown>).canvasContent
|
|
46
|
+
return JSON.stringify({
|
|
47
|
+
ok: true,
|
|
48
|
+
action: 'snapshot',
|
|
49
|
+
hasContent: !!current,
|
|
50
|
+
contentLength: typeof current === 'string' ? current.length : 0,
|
|
51
|
+
preview: typeof current === 'string' ? current.slice(0, 500) : null,
|
|
52
|
+
})
|
|
53
|
+
}
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
hasContent: !!current,
|
|
47
|
-
contentLength: typeof current === 'string' ? current.length : 0,
|
|
48
|
-
preview: typeof current === 'string' ? current.slice(0, 500) : null,
|
|
49
|
-
})
|
|
50
|
-
}
|
|
55
|
+
return `Unknown canvas action "${action}".`
|
|
56
|
+
} catch (err: unknown) {
|
|
57
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`
|
|
58
|
+
}
|
|
59
|
+
}
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Register as a Built-in Plugin
|
|
63
|
+
*/
|
|
64
|
+
const CanvasPlugin: Plugin = {
|
|
65
|
+
name: 'Core Canvas',
|
|
66
|
+
description: 'Present live HTML/CSS/JS content to the user in an interactive canvas panel.',
|
|
67
|
+
hooks: {} as PluginHooks,
|
|
68
|
+
tools: [
|
|
69
|
+
{
|
|
70
|
+
name: 'canvas',
|
|
71
|
+
description: 'Interact with the live canvas panel.',
|
|
72
|
+
parameters: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
action: { type: 'string', enum: ['present', 'hide', 'snapshot'] },
|
|
76
|
+
content: { type: 'string' }
|
|
77
|
+
},
|
|
78
|
+
required: ['action']
|
|
56
79
|
},
|
|
80
|
+
execute: async (args, context) => executeCanvasAction(args, { sessionId: context.session.id })
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getPluginManager().registerBuiltin('canvas', CanvasPlugin)
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Legacy Bridge
|
|
89
|
+
*/
|
|
90
|
+
export function buildCanvasTools(bctx: ToolBuildContext): StructuredToolInterface[] {
|
|
91
|
+
if (!bctx.hasTool('canvas')) return []
|
|
92
|
+
return [
|
|
93
|
+
tool(
|
|
94
|
+
async (args) => executeCanvasAction(args, { sessionId: bctx.ctx?.sessionId || undefined }),
|
|
57
95
|
{
|
|
58
96
|
name: 'canvas',
|
|
59
|
-
description:
|
|
60
|
-
schema: z.object({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}),
|
|
64
|
-
},
|
|
65
|
-
),
|
|
97
|
+
description: CanvasPlugin.tools![0].description,
|
|
98
|
+
schema: z.object({}).passthrough()
|
|
99
|
+
}
|
|
100
|
+
)
|
|
66
101
|
]
|
|
67
102
|
}
|
|
@@ -4,142 +4,145 @@ import { loadChatrooms, saveChatrooms, loadAgents } from '../storage'
|
|
|
4
4
|
import { genId } from '@/lib/id'
|
|
5
5
|
import { notify } from '../ws-hub'
|
|
6
6
|
import type { ToolBuildContext } from './context'
|
|
7
|
-
import type { Chatroom } from '@/types'
|
|
7
|
+
import type { Chatroom, Plugin, PluginHooks } from '@/types'
|
|
8
|
+
import { getPluginManager } from '../plugins'
|
|
9
|
+
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Core Chatroom Execution Logic
|
|
13
|
+
*/
|
|
14
|
+
async function executeChatroomAction(args: Record<string, unknown>, context: { agentId?: string | null }) {
|
|
15
|
+
const normalized = normalizeToolInputArgs(args)
|
|
16
|
+
const action = normalized.action as string
|
|
17
|
+
const chatroomId = (normalized.chatroomId ?? normalized.chatroom_id) as string | undefined
|
|
18
|
+
const name = normalized.name as string | undefined
|
|
19
|
+
const description = normalized.description as string | undefined
|
|
20
|
+
const agentIds = (normalized.agentIds ?? normalized.agent_ids) as string[] | undefined
|
|
21
|
+
const agentId = (normalized.agentId ?? normalized.agent_id) as string | undefined
|
|
22
|
+
const message = (normalized.message ?? normalized.text) as string | undefined
|
|
23
|
+
const chatMode = (normalized.chatMode ?? normalized.chat_mode) as string | undefined
|
|
24
|
+
const autoAddress = (normalized.autoAddress ?? normalized.auto_address) as boolean | undefined
|
|
25
|
+
try {
|
|
26
|
+
const chatrooms = loadChatrooms() as Record<string, Chatroom>
|
|
12
27
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
if (action === 'list_chatrooms') {
|
|
29
|
+
const list = Object.values(chatrooms).map((cr) => ({
|
|
30
|
+
id: cr.id,
|
|
31
|
+
name: cr.name,
|
|
32
|
+
description: cr.description,
|
|
33
|
+
memberCount: cr.agentIds.length,
|
|
34
|
+
messageCount: cr.messages.length,
|
|
35
|
+
}))
|
|
36
|
+
return JSON.stringify(list)
|
|
37
|
+
}
|
|
19
38
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
39
|
+
if (action === 'create_chatroom') {
|
|
40
|
+
const id = genId()
|
|
41
|
+
const agents = loadAgents()
|
|
42
|
+
const requestedAgentIds = agentIds || []
|
|
43
|
+
const validAgentIds = requestedAgentIds.filter((aid: string) => !!agents[aid])
|
|
44
|
+
|
|
45
|
+
const chatroom: Chatroom = {
|
|
46
|
+
id,
|
|
47
|
+
name: name || 'New Chatroom',
|
|
48
|
+
description: description || '',
|
|
49
|
+
agentIds: validAgentIds,
|
|
50
|
+
messages: [],
|
|
51
|
+
chatMode: chatMode === 'parallel' ? 'parallel' : 'sequential',
|
|
52
|
+
autoAddress: Boolean(autoAddress),
|
|
53
|
+
createdAt: Date.now(),
|
|
54
|
+
updatedAt: Date.now(),
|
|
55
|
+
}
|
|
56
|
+
chatrooms[id] = chatroom
|
|
57
|
+
saveChatrooms(chatrooms)
|
|
58
|
+
notify('chatrooms')
|
|
59
|
+
return JSON.stringify({ ok: true, chatroom: { id, name: chatroom.name, agentIds: validAgentIds } })
|
|
60
|
+
}
|
|
30
61
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const requestedAgentIds = agentIds || []
|
|
35
|
-
const invalidAgentIds = requestedAgentIds.filter((aid: string) => !agents[aid])
|
|
36
|
-
if (invalidAgentIds.length > 0) {
|
|
37
|
-
return `Error: unknown agent IDs: ${invalidAgentIds.join(', ')}`
|
|
38
|
-
}
|
|
39
|
-
const validAgentIds = requestedAgentIds
|
|
40
|
-
const chatroom: Chatroom = {
|
|
41
|
-
id,
|
|
42
|
-
name: name || 'New Chatroom',
|
|
43
|
-
description: description || '',
|
|
44
|
-
agentIds: validAgentIds,
|
|
45
|
-
messages: [],
|
|
46
|
-
chatMode: chatMode === 'parallel' ? 'parallel' : 'sequential',
|
|
47
|
-
autoAddress: Boolean(autoAddress),
|
|
48
|
-
createdAt: Date.now(),
|
|
49
|
-
updatedAt: Date.now(),
|
|
50
|
-
}
|
|
51
|
-
chatrooms[id] = chatroom
|
|
52
|
-
saveChatrooms(chatrooms)
|
|
53
|
-
notify('chatrooms')
|
|
54
|
-
return JSON.stringify({ ok: true, chatroom: { id, name: chatroom.name, agentIds: validAgentIds } })
|
|
55
|
-
}
|
|
62
|
+
if (!chatroomId) return 'Error: chatroomId is required.'
|
|
63
|
+
const chatroom = chatrooms[chatroomId]
|
|
64
|
+
if (!chatroom) return `Error: chatroom not found.`
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
if (action === 'add_agent') {
|
|
67
|
+
if (!agentId) return 'Error: agentId required.'
|
|
68
|
+
if (!chatroom.agentIds.includes(agentId)) {
|
|
69
|
+
chatroom.agentIds.push(agentId)
|
|
70
|
+
chatroom.updatedAt = Date.now()
|
|
71
|
+
saveChatrooms(chatrooms)
|
|
72
|
+
notify('chatrooms'); notify(`chatroom:${chatroomId}`)
|
|
73
|
+
}
|
|
74
|
+
return JSON.stringify({ ok: true, agentIds: chatroom.agentIds })
|
|
75
|
+
}
|
|
60
76
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
if (action === 'send_message') {
|
|
78
|
+
if (!message) return 'Error: message required.'
|
|
79
|
+
const msgId = genId()
|
|
80
|
+
const agents = loadAgents()
|
|
81
|
+
const senderName = context.agentId ? (agents[context.agentId]?.name || 'Agent') : 'Agent'
|
|
82
|
+
chatroom.messages.push({
|
|
83
|
+
id: msgId,
|
|
84
|
+
senderId: context.agentId || 'agent',
|
|
85
|
+
senderName,
|
|
86
|
+
role: 'assistant' as const,
|
|
87
|
+
text: message,
|
|
88
|
+
mentions: [],
|
|
89
|
+
reactions: [],
|
|
90
|
+
time: Date.now(),
|
|
91
|
+
})
|
|
92
|
+
chatroom.updatedAt = Date.now()
|
|
93
|
+
saveChatrooms(chatrooms)
|
|
94
|
+
notify(`chatroom:${chatroomId}`)
|
|
95
|
+
return JSON.stringify({ ok: true, messageId: msgId })
|
|
96
|
+
}
|
|
75
97
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
saveChatrooms(chatrooms)
|
|
82
|
-
notify('chatrooms')
|
|
83
|
-
notify(`chatroom:${chatroomId}`)
|
|
84
|
-
return JSON.stringify({ ok: true, agentIds: chatroom.agentIds })
|
|
85
|
-
}
|
|
98
|
+
return `Unknown action "${action}".`
|
|
99
|
+
} catch (err: unknown) {
|
|
100
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`
|
|
101
|
+
}
|
|
102
|
+
}
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Register as a Built-in Plugin
|
|
106
|
+
*/
|
|
107
|
+
const ChatroomPlugin: Plugin = {
|
|
108
|
+
name: 'Core Chatrooms',
|
|
109
|
+
description: 'Manage SwarmClaw routing rules and multi-agent chatrooms.',
|
|
110
|
+
hooks: {} as PluginHooks,
|
|
111
|
+
tools: [
|
|
112
|
+
{
|
|
113
|
+
name: 'manage_chatrooms',
|
|
114
|
+
description: 'Manage multi-agent chatrooms and collaboration.',
|
|
115
|
+
parameters: {
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {
|
|
118
|
+
action: { type: 'string', enum: ['list_chatrooms', 'create_chatroom', 'add_agent', 'remove_agent', 'list_members', 'send_message'] },
|
|
119
|
+
chatroomId: { type: 'string' },
|
|
120
|
+
name: { type: 'string' },
|
|
121
|
+
agentId: { type: 'string' },
|
|
122
|
+
message: { type: 'string' }
|
|
123
|
+
},
|
|
124
|
+
required: ['action']
|
|
125
|
+
},
|
|
126
|
+
execute: async (args, context) => executeChatroomAction(args, { agentId: context.session.agentId })
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
95
130
|
|
|
96
|
-
|
|
97
|
-
if (!message) return 'Error: message is required.'
|
|
98
|
-
const msgId = genId()
|
|
99
|
-
const senderName = bctx.ctx?.agentId
|
|
100
|
-
? (loadAgents()[bctx.ctx.agentId]?.name || 'Agent')
|
|
101
|
-
: 'Agent'
|
|
102
|
-
chatroom.messages.push({
|
|
103
|
-
id: msgId,
|
|
104
|
-
senderId: bctx.ctx?.agentId || 'agent',
|
|
105
|
-
senderName,
|
|
106
|
-
role: 'assistant' as const,
|
|
107
|
-
text: message,
|
|
108
|
-
mentions: [],
|
|
109
|
-
reactions: [],
|
|
110
|
-
time: Date.now(),
|
|
111
|
-
})
|
|
112
|
-
chatroom.updatedAt = Date.now()
|
|
113
|
-
chatrooms[chatroomId] = chatroom
|
|
114
|
-
saveChatrooms(chatrooms)
|
|
115
|
-
notify(`chatroom:${chatroomId}`)
|
|
116
|
-
return JSON.stringify({ ok: true, messageId: msgId })
|
|
117
|
-
}
|
|
131
|
+
getPluginManager().registerBuiltin('chatroom', ChatroomPlugin)
|
|
118
132
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
description: z.string().optional().describe('Chatroom description (for create_chatroom)'),
|
|
133
|
-
agentIds: z.array(z.string()).optional().describe('Initial agent IDs (for create_chatroom)'),
|
|
134
|
-
chatMode: z.enum(['sequential', 'parallel']).optional().describe('Optional orchestration mode for create_chatroom'),
|
|
135
|
-
autoAddress: z.boolean().optional().describe('Whether to auto-address all members when no @mention is present'),
|
|
136
|
-
agentId: z.string().optional().describe('Agent ID (for add_agent/remove_agent)'),
|
|
137
|
-
message: z.string().optional().describe('Message text (for send_message)'),
|
|
138
|
-
}),
|
|
139
|
-
},
|
|
140
|
-
),
|
|
133
|
+
/**
|
|
134
|
+
* Legacy Bridge
|
|
135
|
+
*/
|
|
136
|
+
export function buildChatroomTools(bctx: ToolBuildContext): StructuredToolInterface[] {
|
|
137
|
+
if (!bctx.hasTool('manage_chatrooms')) return []
|
|
138
|
+
return [
|
|
139
|
+
tool(
|
|
140
|
+
async (args) => executeChatroomAction(args, { agentId: bctx.ctx?.agentId }),
|
|
141
|
+
{
|
|
142
|
+
name: 'manage_chatrooms',
|
|
143
|
+
description: ChatroomPlugin.tools![0].description,
|
|
144
|
+
schema: z.object({}).passthrough()
|
|
145
|
+
}
|
|
141
146
|
)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return tools
|
|
147
|
+
]
|
|
145
148
|
}
|