@swarmclawai/swarmclaw 0.6.8 → 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.
Files changed (166) hide show
  1. package/README.md +70 -45
  2. package/next.config.ts +31 -6
  3. package/package.json +3 -2
  4. package/src/app/api/agents/[id]/thread/route.ts +1 -0
  5. package/src/app/api/agents/route.ts +18 -5
  6. package/src/app/api/approvals/route.ts +22 -0
  7. package/src/app/api/clawhub/install/route.ts +2 -2
  8. package/src/app/api/mcp-servers/[id]/conformance/route.ts +26 -0
  9. package/src/app/api/mcp-servers/[id]/invoke/route.ts +81 -0
  10. package/src/app/api/memory/route.ts +36 -5
  11. package/src/app/api/notifications/route.ts +3 -0
  12. package/src/app/api/plugins/install/route.ts +57 -5
  13. package/src/app/api/plugins/marketplace/route.ts +73 -22
  14. package/src/app/api/plugins/route.ts +61 -1
  15. package/src/app/api/plugins/ui/route.ts +34 -0
  16. package/src/app/api/settings/route.ts +62 -0
  17. package/src/app/api/setup/doctor/route.ts +22 -5
  18. package/src/app/api/tasks/[id]/approve/route.ts +4 -3
  19. package/src/app/api/tasks/[id]/route.ts +11 -3
  20. package/src/app/api/tasks/route.ts +8 -2
  21. package/src/app/globals.css +27 -0
  22. package/src/app/page.tsx +10 -5
  23. package/src/cli/index.js +13 -0
  24. package/src/components/activity/activity-feed.tsx +9 -2
  25. package/src/components/agents/agent-avatar.tsx +5 -1
  26. package/src/components/agents/agent-card.tsx +55 -9
  27. package/src/components/agents/agent-sheet.tsx +86 -29
  28. package/src/components/agents/inspector-panel.tsx +1 -1
  29. package/src/components/auth/access-key-gate.tsx +63 -54
  30. package/src/components/auth/user-picker.tsx +37 -32
  31. package/src/components/chat/chat-area.tsx +11 -0
  32. package/src/components/chat/chat-header.tsx +69 -25
  33. package/src/components/chat/chat-tool-toggles.tsx +2 -2
  34. package/src/components/chat/code-block.tsx +3 -1
  35. package/src/components/chat/exec-approval-card.tsx +8 -1
  36. package/src/components/chat/message-bubble.tsx +164 -4
  37. package/src/components/chat/message-list.tsx +30 -4
  38. package/src/components/chat/session-approval-card.tsx +80 -0
  39. package/src/components/chat/streaming-bubble.tsx +6 -5
  40. package/src/components/chat/thinking-indicator.tsx +48 -12
  41. package/src/components/chat/tool-request-banner.tsx +39 -20
  42. package/src/components/chatrooms/chatroom-list.tsx +11 -4
  43. package/src/components/chatrooms/chatroom-sheet.tsx +7 -2
  44. package/src/components/connectors/connector-list.tsx +33 -11
  45. package/src/components/connectors/connector-sheet.tsx +29 -6
  46. package/src/components/home/home-view.tsx +20 -14
  47. package/src/components/input/chat-input.tsx +22 -1
  48. package/src/components/knowledge/knowledge-list.tsx +17 -18
  49. package/src/components/knowledge/knowledge-sheet.tsx +9 -5
  50. package/src/components/layout/app-layout.tsx +73 -21
  51. package/src/components/mcp-servers/mcp-server-list.tsx +352 -50
  52. package/src/components/mcp-servers/mcp-server-sheet.tsx +25 -9
  53. package/src/components/memory/memory-list.tsx +20 -13
  54. package/src/components/plugins/plugin-list.tsx +213 -59
  55. package/src/components/plugins/plugin-sheet.tsx +119 -24
  56. package/src/components/projects/project-list.tsx +17 -9
  57. package/src/components/providers/provider-list.tsx +21 -6
  58. package/src/components/providers/provider-sheet.tsx +42 -25
  59. package/src/components/runs/run-list.tsx +17 -13
  60. package/src/components/schedules/schedule-card.tsx +10 -3
  61. package/src/components/schedules/schedule-list.tsx +2 -2
  62. package/src/components/schedules/schedule-sheet.tsx +19 -7
  63. package/src/components/secrets/secret-sheet.tsx +7 -2
  64. package/src/components/secrets/secrets-list.tsx +18 -5
  65. package/src/components/sessions/new-session-sheet.tsx +183 -376
  66. package/src/components/sessions/session-card.tsx +10 -2
  67. package/src/components/settings/gateway-connection-panel.tsx +9 -8
  68. package/src/components/shared/command-palette.tsx +13 -5
  69. package/src/components/shared/empty-state.tsx +20 -8
  70. package/src/components/shared/notification-center.tsx +134 -86
  71. package/src/components/shared/profile-sheet.tsx +4 -0
  72. package/src/components/shared/settings/plugin-manager.tsx +360 -135
  73. package/src/components/shared/settings/section-capability-policy.tsx +3 -3
  74. package/src/components/shared/settings/section-runtime-loop.tsx +144 -0
  75. package/src/components/skills/clawhub-browser.tsx +1 -0
  76. package/src/components/skills/skill-list.tsx +31 -12
  77. package/src/components/skills/skill-sheet.tsx +20 -7
  78. package/src/components/tasks/approvals-panel.tsx +170 -66
  79. package/src/components/tasks/task-board.tsx +20 -12
  80. package/src/components/tasks/task-card.tsx +21 -7
  81. package/src/components/tasks/task-column.tsx +4 -3
  82. package/src/components/tasks/task-list.tsx +1 -1
  83. package/src/components/tasks/task-sheet.tsx +130 -1
  84. package/src/components/ui/dialog.tsx +1 -0
  85. package/src/components/ui/sheet.tsx +1 -0
  86. package/src/components/usage/metrics-dashboard.tsx +66 -64
  87. package/src/components/wallets/wallet-panel.tsx +65 -41
  88. package/src/components/wallets/wallet-section.tsx +9 -3
  89. package/src/components/webhooks/webhook-list.tsx +21 -12
  90. package/src/components/webhooks/webhook-sheet.tsx +13 -3
  91. package/src/lib/approval-display.test.ts +45 -0
  92. package/src/lib/approval-display.ts +62 -0
  93. package/src/lib/clipboard.ts +38 -0
  94. package/src/lib/memory.ts +8 -0
  95. package/src/lib/providers/claude-cli.ts +5 -3
  96. package/src/lib/providers/index.ts +67 -21
  97. package/src/lib/runtime-loop.ts +3 -2
  98. package/src/lib/server/approvals.ts +150 -0
  99. package/src/lib/server/chat-execution.ts +223 -62
  100. package/src/lib/server/clawhub-client.ts +82 -6
  101. package/src/lib/server/connectors/manager.ts +27 -1
  102. package/src/lib/server/cost.test.ts +73 -0
  103. package/src/lib/server/cost.ts +165 -34
  104. package/src/lib/server/daemon-state.ts +42 -0
  105. package/src/lib/server/data-dir.ts +18 -1
  106. package/src/lib/server/integrity-monitor.ts +208 -0
  107. package/src/lib/server/llm-response-cache.test.ts +102 -0
  108. package/src/lib/server/llm-response-cache.ts +227 -0
  109. package/src/lib/server/main-agent-loop.ts +1 -1
  110. package/src/lib/server/main-session.ts +6 -3
  111. package/src/lib/server/mcp-conformance.test.ts +18 -0
  112. package/src/lib/server/mcp-conformance.ts +233 -0
  113. package/src/lib/server/memory-db.ts +180 -17
  114. package/src/lib/server/memory-retrieval.test.ts +56 -0
  115. package/src/lib/server/orchestrator-lg.ts +4 -1
  116. package/src/lib/server/orchestrator.ts +4 -3
  117. package/src/lib/server/plugins.ts +650 -142
  118. package/src/lib/server/process-manager.ts +18 -0
  119. package/src/lib/server/queue.ts +253 -11
  120. package/src/lib/server/runtime-settings.ts +9 -0
  121. package/src/lib/server/session-run-manager.test.ts +23 -0
  122. package/src/lib/server/session-run-manager.ts +11 -1
  123. package/src/lib/server/session-tools/canvas.ts +85 -50
  124. package/src/lib/server/session-tools/chatroom.ts +130 -127
  125. package/src/lib/server/session-tools/connector.ts +233 -454
  126. package/src/lib/server/session-tools/context-mgmt.ts +87 -105
  127. package/src/lib/server/session-tools/crud.ts +84 -7
  128. package/src/lib/server/session-tools/delegate.ts +351 -752
  129. package/src/lib/server/session-tools/discovery.ts +198 -0
  130. package/src/lib/server/session-tools/edit_file.ts +82 -0
  131. package/src/lib/server/session-tools/file-send.test.ts +39 -0
  132. package/src/lib/server/session-tools/file.ts +257 -425
  133. package/src/lib/server/session-tools/git.ts +87 -47
  134. package/src/lib/server/session-tools/http.ts +85 -33
  135. package/src/lib/server/session-tools/index.ts +205 -160
  136. package/src/lib/server/session-tools/memory.ts +152 -265
  137. package/src/lib/server/session-tools/monitor.ts +126 -0
  138. package/src/lib/server/session-tools/normalize-tool-args.test.ts +61 -0
  139. package/src/lib/server/session-tools/normalize-tool-args.ts +48 -0
  140. package/src/lib/server/session-tools/openclaw-nodes.ts +82 -99
  141. package/src/lib/server/session-tools/openclaw-workspace.ts +103 -93
  142. package/src/lib/server/session-tools/platform.ts +86 -0
  143. package/src/lib/server/session-tools/plugin-creator.ts +239 -0
  144. package/src/lib/server/session-tools/sample-ui.ts +97 -0
  145. package/src/lib/server/session-tools/sandbox.ts +175 -148
  146. package/src/lib/server/session-tools/schedule.ts +66 -31
  147. package/src/lib/server/session-tools/session-info.ts +104 -410
  148. package/src/lib/server/session-tools/shell-normalize.test.ts +43 -0
  149. package/src/lib/server/session-tools/shell.ts +171 -143
  150. package/src/lib/server/session-tools/subagent.ts +77 -77
  151. package/src/lib/server/session-tools/wallet.ts +182 -106
  152. package/src/lib/server/session-tools/web.ts +179 -349
  153. package/src/lib/server/storage.ts +24 -0
  154. package/src/lib/server/stream-agent-chat.ts +301 -244
  155. package/src/lib/server/task-quality-gate.test.ts +44 -0
  156. package/src/lib/server/task-quality-gate.ts +67 -0
  157. package/src/lib/server/task-validation.test.ts +78 -0
  158. package/src/lib/server/task-validation.ts +67 -2
  159. package/src/lib/server/tool-aliases.ts +68 -0
  160. package/src/lib/server/tool-capability-policy.ts +23 -5
  161. package/src/lib/tasks.ts +7 -1
  162. package/src/lib/tool-definitions.ts +23 -23
  163. package/src/lib/validation/schemas.ts +12 -0
  164. package/src/lib/view-routes.ts +2 -24
  165. package/src/stores/use-app-store.ts +23 -1
  166. package/src/types/index.ts +121 -7
@@ -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
- export function buildChatroomTools(bctx: ToolBuildContext): StructuredToolInterface[] {
10
- const tools: StructuredToolInterface[] = []
11
- const { hasTool } = bctx
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
- if (hasTool('manage_chatrooms')) {
14
- tools.push(
15
- tool(
16
- async ({ action, chatroomId, name, description, agentIds, agentId, message, chatMode, autoAddress }) => {
17
- try {
18
- const chatrooms = loadChatrooms() as Record<string, Chatroom>
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
- if (action === 'list_chatrooms') {
21
- const list = Object.values(chatrooms).map((cr) => ({
22
- id: cr.id,
23
- name: cr.name,
24
- description: cr.description,
25
- memberCount: cr.agentIds.length,
26
- messageCount: cr.messages.length,
27
- }))
28
- return JSON.stringify(list)
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
- if (action === 'create_chatroom') {
32
- const id = genId()
33
- const agents = loadAgents()
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
- if (!chatroomId) return 'Error: chatroomId is required for this action.'
58
- const chatroom = chatrooms[chatroomId]
59
- if (!chatroom) return `Error: chatroom not found: ${chatroomId}`
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
- if (action === 'add_agent') {
62
- if (!agentId) return 'Error: agentId is required.'
63
- const agents = loadAgents()
64
- if (!agents[agentId]) return `Error: agent not found: ${agentId}`
65
- if (!chatroom.agentIds.includes(agentId)) {
66
- chatroom.agentIds.push(agentId)
67
- chatroom.updatedAt = Date.now()
68
- chatrooms[chatroomId] = chatroom
69
- saveChatrooms(chatrooms)
70
- notify('chatrooms')
71
- notify(`chatroom:${chatroomId}`)
72
- }
73
- return JSON.stringify({ ok: true, agentIds: chatroom.agentIds })
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
- if (action === 'remove_agent') {
77
- if (!agentId) return 'Error: agentId is required.'
78
- chatroom.agentIds = chatroom.agentIds.filter((id: string) => id !== agentId)
79
- chatroom.updatedAt = Date.now()
80
- chatrooms[chatroomId] = chatroom
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
- if (action === 'list_members') {
88
- const agents = loadAgents()
89
- const members = chatroom.agentIds.map((id: string) => {
90
- const agent = agents[id]
91
- return agent ? { id, name: agent.name, description: agent.description } : { id, name: 'Unknown' }
92
- })
93
- return JSON.stringify(members)
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
- if (action === 'send_message') {
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
- return `Error: unknown action "${action}". Valid actions: list_chatrooms, create_chatroom, add_agent, remove_agent, list_members, send_message`
120
- } catch (err: unknown) {
121
- return `Error: ${err instanceof Error ? err.message : String(err)}`
122
- }
123
- },
124
- {
125
- name: 'manage_chatrooms',
126
- description: 'Manage chatrooms for multi-agent collaboration. Actions: list_chatrooms, create_chatroom, add_agent, remove_agent, list_members, send_message.',
127
- schema: z.object({
128
- action: z.enum(['list_chatrooms', 'create_chatroom', 'add_agent', 'remove_agent', 'list_members', 'send_message'])
129
- .describe('The action to perform'),
130
- chatroomId: z.string().optional().describe('Chatroom ID (required for most actions except list/create)'),
131
- name: z.string().optional().describe('Chatroom name (for create_chatroom)'),
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
  }