@swarmclawai/swarmclaw 0.7.2 → 0.7.3

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 (197) hide show
  1. package/README.md +81 -22
  2. package/package.json +1 -1
  3. package/src/app/api/agents/[id]/route.ts +26 -0
  4. package/src/app/api/agents/[id]/thread/route.ts +36 -7
  5. package/src/app/api/agents/route.ts +12 -1
  6. package/src/app/api/auth/route.ts +76 -7
  7. package/src/app/api/chatrooms/[id]/chat/route.ts +7 -2
  8. package/src/app/api/chats/[id]/browser/route.ts +5 -1
  9. package/src/app/api/chats/[id]/chat/route.ts +7 -3
  10. package/src/app/api/chats/[id]/main-loop/route.ts +7 -88
  11. package/src/app/api/chats/[id]/messages/route.ts +19 -13
  12. package/src/app/api/chats/[id]/route.ts +18 -0
  13. package/src/app/api/chats/[id]/stop/route.ts +6 -1
  14. package/src/app/api/chats/route.ts +16 -0
  15. package/src/app/api/connectors/[id]/doctor/route.ts +26 -0
  16. package/src/app/api/connectors/doctor/route.ts +13 -0
  17. package/src/app/api/files/open/route.ts +16 -14
  18. package/src/app/api/memory/maintenance/route.ts +11 -1
  19. package/src/app/api/openclaw/agent-files/route.ts +27 -4
  20. package/src/app/api/openclaw/skills/route.ts +11 -3
  21. package/src/app/api/plugins/dependencies/route.ts +24 -0
  22. package/src/app/api/plugins/install/route.ts +15 -92
  23. package/src/app/api/plugins/route.ts +3 -26
  24. package/src/app/api/plugins/settings/route.ts +17 -12
  25. package/src/app/api/plugins/ui/route.ts +1 -0
  26. package/src/app/api/settings/route.ts +49 -7
  27. package/src/app/api/tasks/[id]/route.ts +15 -6
  28. package/src/app/api/tasks/bulk/route.ts +2 -2
  29. package/src/app/api/tasks/route.ts +9 -4
  30. package/src/app/api/webhooks/[id]/route.ts +8 -1
  31. package/src/app/page.tsx +9 -2
  32. package/src/cli/index.js +4 -0
  33. package/src/cli/index.ts +3 -10
  34. package/src/components/agents/agent-card.tsx +15 -12
  35. package/src/components/agents/agent-chat-list.tsx +101 -1
  36. package/src/components/agents/agent-list.tsx +46 -9
  37. package/src/components/agents/agent-sheet.tsx +207 -16
  38. package/src/components/agents/inspector-panel.tsx +108 -48
  39. package/src/components/auth/access-key-gate.tsx +36 -97
  40. package/src/components/chat/chat-area.tsx +29 -13
  41. package/src/components/chat/chat-card.tsx +4 -20
  42. package/src/components/chat/chat-header.tsx +255 -353
  43. package/src/components/chat/chat-list.tsx +7 -9
  44. package/src/components/chat/checkpoint-timeline.tsx +1 -1
  45. package/src/components/chat/message-list.tsx +3 -1
  46. package/src/components/chatrooms/chatroom-view.tsx +347 -205
  47. package/src/components/connectors/connector-list.tsx +265 -127
  48. package/src/components/connectors/connector-sheet.tsx +217 -0
  49. package/src/components/home/home-view.tsx +128 -4
  50. package/src/components/layout/app-layout.tsx +383 -194
  51. package/src/components/layout/mobile-header.tsx +26 -8
  52. package/src/components/plugins/plugin-list.tsx +15 -3
  53. package/src/components/plugins/plugin-sheet.tsx +118 -9
  54. package/src/components/projects/project-detail.tsx +183 -0
  55. package/src/components/shared/agent-picker-list.tsx +2 -2
  56. package/src/components/shared/command-palette.tsx +111 -24
  57. package/src/components/shared/settings/plugin-manager.tsx +20 -4
  58. package/src/components/shared/settings/section-capability-policy.tsx +105 -0
  59. package/src/components/shared/settings/section-heartbeat.tsx +77 -0
  60. package/src/components/shared/settings/section-orchestrator.tsx +3 -3
  61. package/src/components/shared/settings/section-runtime-loop.tsx +5 -5
  62. package/src/components/shared/settings/section-secrets.tsx +6 -6
  63. package/src/components/shared/settings/section-user-preferences.tsx +1 -1
  64. package/src/components/shared/settings/section-voice.tsx +5 -1
  65. package/src/components/shared/settings/section-web-search.tsx +10 -2
  66. package/src/components/shared/settings/settings-page.tsx +245 -46
  67. package/src/components/tasks/approvals-panel.tsx +205 -18
  68. package/src/components/tasks/task-board.tsx +242 -46
  69. package/src/components/usage/metrics-dashboard.tsx +74 -1
  70. package/src/components/wallets/wallet-panel.tsx +17 -5
  71. package/src/components/webhooks/webhook-sheet.tsx +7 -7
  72. package/src/lib/auth.ts +17 -0
  73. package/src/lib/chat-streaming-state.test.ts +108 -0
  74. package/src/lib/chat-streaming-state.ts +108 -0
  75. package/src/lib/openclaw-agent-id.test.ts +14 -0
  76. package/src/lib/openclaw-agent-id.ts +31 -0
  77. package/src/lib/server/agent-assignment.test.ts +112 -0
  78. package/src/lib/server/agent-assignment.ts +169 -0
  79. package/src/lib/server/approval-connector-notify.test.ts +253 -0
  80. package/src/lib/server/approvals-auto-approve.test.ts +205 -0
  81. package/src/lib/server/approvals.ts +483 -75
  82. package/src/lib/server/autonomy-runtime.test.ts +341 -0
  83. package/src/lib/server/browser-state.test.ts +118 -0
  84. package/src/lib/server/browser-state.ts +123 -0
  85. package/src/lib/server/build-llm.test.ts +36 -0
  86. package/src/lib/server/build-llm.ts +11 -4
  87. package/src/lib/server/builtin-plugins.ts +34 -0
  88. package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
  89. package/src/lib/server/chat-execution-tool-events.test.ts +134 -0
  90. package/src/lib/server/chat-execution.ts +250 -61
  91. package/src/lib/server/chatroom-health.test.ts +26 -0
  92. package/src/lib/server/chatroom-health.ts +2 -3
  93. package/src/lib/server/chatroom-helpers.test.ts +67 -2
  94. package/src/lib/server/chatroom-helpers.ts +45 -5
  95. package/src/lib/server/connectors/discord.ts +175 -11
  96. package/src/lib/server/connectors/doctor.test.ts +80 -0
  97. package/src/lib/server/connectors/doctor.ts +116 -0
  98. package/src/lib/server/connectors/manager.ts +946 -110
  99. package/src/lib/server/connectors/policy.test.ts +222 -0
  100. package/src/lib/server/connectors/policy.ts +452 -0
  101. package/src/lib/server/connectors/slack.ts +188 -9
  102. package/src/lib/server/connectors/telegram.ts +65 -15
  103. package/src/lib/server/connectors/thread-context.test.ts +44 -0
  104. package/src/lib/server/connectors/thread-context.ts +72 -0
  105. package/src/lib/server/connectors/types.ts +41 -11
  106. package/src/lib/server/daemon-state.ts +59 -1
  107. package/src/lib/server/data-dir.ts +13 -0
  108. package/src/lib/server/delegation-jobs.test.ts +140 -0
  109. package/src/lib/server/delegation-jobs.ts +248 -0
  110. package/src/lib/server/document-utils.test.ts +47 -0
  111. package/src/lib/server/document-utils.ts +397 -0
  112. package/src/lib/server/heartbeat-service.ts +13 -39
  113. package/src/lib/server/heartbeat-source.test.ts +22 -0
  114. package/src/lib/server/heartbeat-source.ts +7 -0
  115. package/src/lib/server/identity-continuity.test.ts +77 -0
  116. package/src/lib/server/identity-continuity.ts +127 -0
  117. package/src/lib/server/mailbox-utils.ts +347 -0
  118. package/src/lib/server/main-agent-loop.ts +27 -967
  119. package/src/lib/server/memory-db.ts +4 -6
  120. package/src/lib/server/memory-tiers.ts +40 -0
  121. package/src/lib/server/openclaw-agent-resolver.test.ts +70 -0
  122. package/src/lib/server/openclaw-agent-resolver.ts +128 -0
  123. package/src/lib/server/openclaw-exec-config.ts +5 -6
  124. package/src/lib/server/openclaw-skills-normalize.test.ts +56 -0
  125. package/src/lib/server/openclaw-skills-normalize.ts +136 -0
  126. package/src/lib/server/openclaw-sync.ts +3 -2
  127. package/src/lib/server/orchestrator-lg.ts +17 -6
  128. package/src/lib/server/orchestrator.ts +2 -2
  129. package/src/lib/server/playwright-proxy.mjs +27 -3
  130. package/src/lib/server/plugins.test.ts +207 -0
  131. package/src/lib/server/plugins.ts +822 -69
  132. package/src/lib/server/provider-health.ts +33 -3
  133. package/src/lib/server/queue.ts +3 -20
  134. package/src/lib/server/scheduler.ts +2 -0
  135. package/src/lib/server/session-archive-memory.test.ts +85 -0
  136. package/src/lib/server/session-archive-memory.ts +230 -0
  137. package/src/lib/server/session-mailbox.ts +8 -18
  138. package/src/lib/server/session-reset-policy.test.ts +99 -0
  139. package/src/lib/server/session-reset-policy.ts +311 -0
  140. package/src/lib/server/session-run-manager.ts +33 -80
  141. package/src/lib/server/session-tools/autonomy-tools.test.ts +105 -0
  142. package/src/lib/server/session-tools/calendar.ts +2 -12
  143. package/src/lib/server/session-tools/connector.ts +109 -8
  144. package/src/lib/server/session-tools/context.ts +14 -2
  145. package/src/lib/server/session-tools/crawl.ts +447 -0
  146. package/src/lib/server/session-tools/crud.ts +70 -32
  147. package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
  148. package/src/lib/server/session-tools/delegate.ts +406 -20
  149. package/src/lib/server/session-tools/discovery.ts +22 -4
  150. package/src/lib/server/session-tools/document.ts +283 -0
  151. package/src/lib/server/session-tools/email.ts +1 -3
  152. package/src/lib/server/session-tools/extract.ts +137 -0
  153. package/src/lib/server/session-tools/file-normalize.test.ts +93 -0
  154. package/src/lib/server/session-tools/file-send.test.ts +84 -1
  155. package/src/lib/server/session-tools/file.ts +237 -24
  156. package/src/lib/server/session-tools/human-loop.ts +227 -0
  157. package/src/lib/server/session-tools/image-gen.ts +1 -3
  158. package/src/lib/server/session-tools/index.ts +56 -1
  159. package/src/lib/server/session-tools/mailbox.ts +276 -0
  160. package/src/lib/server/session-tools/memory.ts +35 -3
  161. package/src/lib/server/session-tools/monitor.ts +150 -7
  162. package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
  163. package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
  164. package/src/lib/server/session-tools/platform.ts +142 -4
  165. package/src/lib/server/session-tools/plugin-creator.ts +86 -23
  166. package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
  167. package/src/lib/server/session-tools/replicate.ts +1 -3
  168. package/src/lib/server/session-tools/schedule.ts +20 -10
  169. package/src/lib/server/session-tools/session-info.ts +36 -3
  170. package/src/lib/server/session-tools/session-tools-wiring.test.ts +31 -17
  171. package/src/lib/server/session-tools/subagent.ts +193 -27
  172. package/src/lib/server/session-tools/table.ts +587 -0
  173. package/src/lib/server/session-tools/wallet.ts +13 -10
  174. package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
  175. package/src/lib/server/session-tools/web.ts +896 -100
  176. package/src/lib/server/storage.ts +226 -7
  177. package/src/lib/server/stream-agent-chat.ts +46 -21
  178. package/src/lib/server/structured-extract.test.ts +72 -0
  179. package/src/lib/server/structured-extract.ts +373 -0
  180. package/src/lib/server/task-mention.test.ts +16 -2
  181. package/src/lib/server/task-mention.ts +61 -10
  182. package/src/lib/server/tool-aliases.ts +44 -7
  183. package/src/lib/server/tool-capability-policy.ts +6 -0
  184. package/src/lib/server/tool-retry.ts +2 -0
  185. package/src/lib/server/watch-jobs.test.ts +173 -0
  186. package/src/lib/server/watch-jobs.ts +532 -0
  187. package/src/lib/server/ws-hub.ts +5 -3
  188. package/src/lib/validation/schemas.test.ts +26 -0
  189. package/src/lib/validation/schemas.ts +7 -0
  190. package/src/lib/ws-client.ts +14 -12
  191. package/src/proxy.ts +5 -5
  192. package/src/stores/use-app-store.ts +0 -6
  193. package/src/stores/use-chat-store.ts +31 -2
  194. package/src/types/index.ts +287 -44
  195. package/src/components/chat/new-chat-sheet.tsx +0 -253
  196. package/src/lib/server/main-session.ts +0 -17
  197. package/src/lib/server/session-run-manager.test.ts +0 -26
@@ -3,13 +3,24 @@ import { tool, type StructuredToolInterface } from '@langchain/core/tools'
3
3
  import { genId } from '@/lib/id'
4
4
  import { DEFAULT_DELEGATION_MAX_DEPTH } from '@/lib/runtime-loop'
5
5
  import { loadAgents, loadSessions, saveSessions } from '../storage'
6
- import { executeSessionChatTurn } from '../chat-execution'
7
- import { log } from '../logger'
6
+ import { enqueueSessionRun } from '../session-run-manager'
8
7
  import { loadRuntimeSettings } from '../runtime-settings'
9
8
  import type { ToolBuildContext } from './context'
10
9
  import type { Plugin, PluginHooks } from '@/types'
11
10
  import { getPluginManager } from '../plugins'
12
11
  import { normalizeToolInputArgs } from './normalize-tool-args'
12
+ import {
13
+ appendDelegationCheckpoint,
14
+ cancelDelegationJob,
15
+ completeDelegationJob,
16
+ createDelegationJob,
17
+ failDelegationJob,
18
+ getDelegationJob,
19
+ listDelegationJobs,
20
+ recoverStaleDelegationJobs,
21
+ registerDelegationRuntime,
22
+ startDelegationJob,
23
+ } from '../delegation-jobs'
13
24
 
14
25
  function getSessionDepth(sessionId: string | undefined, maxDepth: number): number {
15
26
  if (!sessionId) return 0
@@ -25,40 +36,186 @@ function getSessionDepth(sessionId: string | undefined, maxDepth: number): numbe
25
36
  return depth
26
37
  }
27
38
 
39
+ function sleep(ms: number) {
40
+ return new Promise((resolve) => setTimeout(resolve, ms))
41
+ }
42
+
43
+ export function resolveSubagentBrowserProfileId(
44
+ parentSession: Record<string, unknown> | null | undefined,
45
+ childSessionId: string,
46
+ shareBrowserProfile: boolean,
47
+ ): string {
48
+ if (!shareBrowserProfile) return childSessionId
49
+ const inherited = typeof parentSession?.browserProfileId === 'string' && parentSession.browserProfileId.trim()
50
+ ? parentSession.browserProfileId.trim()
51
+ : typeof parentSession?.id === 'string' && parentSession.id.trim()
52
+ ? parentSession.id.trim()
53
+ : ''
54
+ return inherited || childSessionId
55
+ }
56
+
57
+ async function startSubagentJob(jobId: string, args: {
58
+ agentId: string
59
+ message: string
60
+ cwd?: string
61
+ shareBrowserProfile?: boolean
62
+ }, context: { sessionId?: string; cwd: string }) {
63
+ const runtime = loadRuntimeSettings()
64
+ const maxDepth = runtime.delegationMaxDepth || DEFAULT_DELEGATION_MAX_DEPTH
65
+ const agents = loadAgents()
66
+ const agent = agents[args.agentId]
67
+ if (!agent) throw new Error(`Agent "${args.agentId}" not found.`)
68
+
69
+ const depth = getSessionDepth(context.sessionId, maxDepth)
70
+ if (depth >= maxDepth) throw new Error('Max subagent depth reached.')
71
+
72
+ const sid = genId()
73
+ const now = Date.now()
74
+ const sessions = loadSessions()
75
+ const parent = context.sessionId ? sessions[context.sessionId] : null
76
+ const browserProfileId = resolveSubagentBrowserProfileId(parent, sid, args.shareBrowserProfile === true)
77
+ sessions[sid] = {
78
+ id: sid,
79
+ name: `subagent-${agent.name}`,
80
+ cwd: args.cwd || context.cwd,
81
+ user: 'agent',
82
+ provider: agent.provider,
83
+ model: agent.model,
84
+ credentialId: agent.credentialId || null,
85
+ messages: [],
86
+ createdAt: now,
87
+ lastActiveAt: now,
88
+ sessionType: 'orchestrated',
89
+ agentId: agent.id,
90
+ parentSessionId: context.sessionId || null,
91
+ plugins: agent.plugins || agent.tools || [],
92
+ browserProfileId,
93
+ }
94
+ saveSessions(sessions)
95
+
96
+ startDelegationJob(jobId, {
97
+ childSessionId: sid,
98
+ agentId: agent.id,
99
+ agentName: agent.name,
100
+ cwd: args.cwd || context.cwd,
101
+ })
102
+ appendDelegationCheckpoint(jobId, `Created child session ${sid}`, 'running')
103
+
104
+ const run = enqueueSessionRun({
105
+ sessionId: sid,
106
+ message: args.message,
107
+ internal: true,
108
+ source: 'subagent',
109
+ mode: 'followup',
110
+ })
111
+
112
+ registerDelegationRuntime(jobId, {
113
+ cancel: () => run.abort(),
114
+ })
115
+
116
+ run.promise
117
+ .then((result) => {
118
+ const latest = getDelegationJob(jobId)
119
+ if (latest?.status === 'cancelled') return
120
+ appendDelegationCheckpoint(jobId, 'Child session completed', 'completed')
121
+ completeDelegationJob(jobId, result.text.slice(0, 8000), { childSessionId: sid })
122
+ })
123
+ .catch((err: unknown) => {
124
+ const message = err instanceof Error ? err.message : String(err)
125
+ const latest = getDelegationJob(jobId)
126
+ if (latest?.status === 'cancelled') return
127
+ appendDelegationCheckpoint(jobId, `Child session failed: ${message}`, 'failed')
128
+ failDelegationJob(jobId, message, { childSessionId: sid })
129
+ })
130
+
131
+ return { run, sid, agent }
132
+ }
133
+
134
+ async function waitForSubagentJob(jobId: string, timeoutSec = 30): Promise<string> {
135
+ const timeoutAt = Date.now() + Math.max(1, timeoutSec) * 1000
136
+ while (Date.now() < timeoutAt) {
137
+ const job = getDelegationJob(jobId)
138
+ if (!job) return `Error: delegation job "${jobId}" not found.`
139
+ if (job.status === 'completed' || job.status === 'failed' || job.status === 'cancelled') {
140
+ return JSON.stringify(job)
141
+ }
142
+ await sleep(1000)
143
+ }
144
+ const latest = getDelegationJob(jobId)
145
+ return latest ? JSON.stringify(latest) : `Error: delegation job "${jobId}" not found.`
146
+ }
147
+
28
148
  /**
29
149
  * Core Subagent Execution Logic
30
150
  */
31
151
  async function executeSubagentAction(args: any, context: { sessionId?: string; cwd: string }) {
32
152
  const normalized = normalizeToolInputArgs((args ?? {}) as Record<string, unknown>)
153
+ const action = String(normalized.action || '').trim().toLowerCase()
33
154
  const agentId = (normalized.agentId ?? normalized.agent_id) as string | undefined
34
155
  const message = normalized.message as string | undefined
35
156
  const cwd = normalized.cwd as string | undefined
157
+ const shareBrowserProfile = normalized.shareBrowserProfile === true || normalized.share_browser_profile === true
158
+ const jobId = typeof normalized.jobId === 'string' ? normalized.jobId.trim() : ''
159
+ const waitForCompletion = normalized.waitForCompletion !== false && normalized.background !== true
160
+
161
+ recoverStaleDelegationJobs()
162
+
36
163
  try {
37
- const runtime = loadRuntimeSettings()
38
- const maxDepth = runtime.delegationMaxDepth || DEFAULT_DELEGATION_MAX_DEPTH
39
- const agents = loadAgents()
164
+ if (action === 'status') {
165
+ if (!jobId) return 'Error: jobId is required.'
166
+ const job = getDelegationJob(jobId)
167
+ return job ? JSON.stringify(job) : `Error: delegation job "${jobId}" not found.`
168
+ }
169
+ if (action === 'list') {
170
+ return JSON.stringify(listDelegationJobs({ parentSessionId: context.sessionId || null }))
171
+ }
172
+ if (action === 'cancel') {
173
+ if (!jobId) return 'Error: jobId is required.'
174
+ const job = cancelDelegationJob(jobId)
175
+ return job ? JSON.stringify(job) : `Error: delegation job "${jobId}" not found.`
176
+ }
177
+ if (action === 'wait') {
178
+ if (!jobId) return 'Error: jobId is required.'
179
+ const timeoutSec = typeof normalized.timeoutSec === 'number' ? normalized.timeoutSec : 30
180
+ return waitForSubagentJob(jobId, timeoutSec)
181
+ }
182
+
40
183
  if (!agentId) return 'Error: agentId is required.'
41
184
  if (!message) return 'Error: message is required.'
42
- const agent = agents[agentId]
43
- if (!agent) return `Error: Agent "${agentId}" not found.`
44
-
45
- const depth = getSessionDepth(context.sessionId, maxDepth)
46
- if (depth >= maxDepth) return `Error: Max subagent depth reached.`
47
-
48
- const sid = genId()
49
- const now = Date.now()
50
- const sessions = loadSessions()
51
- sessions[sid] = {
52
- id: sid, name: `subagent-${agent.name}`, cwd: cwd || context.cwd, user: 'agent',
53
- provider: agent.provider, model: agent.model, credentialId: agent.credentialId || null,
54
- messages: [], createdAt: now, lastActiveAt: now, sessionType: 'orchestrated',
55
- agentId: agent.id, parentSessionId: context.sessionId || null, plugins: agent.plugins || agent.tools || [],
185
+
186
+ const job = createDelegationJob({
187
+ kind: 'subagent',
188
+ parentSessionId: context.sessionId || null,
189
+ agentId,
190
+ task: message,
191
+ cwd: cwd || context.cwd,
192
+ })
193
+ appendDelegationCheckpoint(job.id, `Starting subagent ${agentId}`, 'queued')
194
+ const started = await startSubagentJob(job.id, { agentId, message, cwd, shareBrowserProfile }, context)
195
+
196
+ if (!waitForCompletion) {
197
+ return JSON.stringify({
198
+ jobId: job.id,
199
+ status: 'running',
200
+ agentId,
201
+ agentName: started.agent.name,
202
+ sessionId: started.sid,
203
+ })
56
204
  }
57
- saveSessions(sessions)
58
205
 
59
- const result = await executeSessionChatTurn({ sessionId: sid, message, internal: true, source: 'subagent' })
60
- return JSON.stringify({ agentId, agentName: agent.name, sessionId: sid, response: result.text.slice(0, 8000) })
61
- } catch (err: any) { return `Error: ${err.message}` }
206
+ const result = await started.run.promise
207
+ const completed = getDelegationJob(job.id)
208
+ return JSON.stringify({
209
+ jobId: job.id,
210
+ status: completed?.status || 'completed',
211
+ agentId,
212
+ agentName: started.agent.name,
213
+ sessionId: started.sid,
214
+ response: result.text.slice(0, 8000),
215
+ })
216
+ } catch (err: any) {
217
+ return `Error: ${err.message}`
218
+ }
62
219
  }
63
220
 
64
221
  /**
@@ -66,20 +223,29 @@ async function executeSubagentAction(args: any, context: { sessionId?: string; c
66
223
  */
67
224
  const SubagentPlugin: Plugin = {
68
225
  name: 'Core Subagents',
69
- description: 'Delegate tasks to other specialized agents.',
226
+ description: 'Delegate tasks to other specialized agents with resumable job handles.',
70
227
  hooks: {} as PluginHooks,
71
228
  tools: [
72
229
  {
73
230
  name: 'spawn_subagent',
74
- description: 'Delegate a task to another agent.',
231
+ description: 'Delegate a task to another agent. Supports background jobs with action=status|list|wait|cancel and waitForCompletion=false.',
75
232
  parameters: {
76
233
  type: 'object',
77
234
  properties: {
235
+ action: { type: 'string', enum: ['start', 'status', 'list', 'wait', 'cancel'] },
78
236
  agentId: { type: 'string' },
79
237
  message: { type: 'string' },
80
- cwd: { type: 'string' }
238
+ cwd: { type: 'string' },
239
+ shareBrowserProfile: {
240
+ type: 'boolean',
241
+ description: 'When true, inherit the parent session browser profile. Defaults to false so subagents get isolated browser state.',
242
+ },
243
+ jobId: { type: 'string' },
244
+ waitForCompletion: { type: 'boolean' },
245
+ background: { type: 'boolean' },
246
+ timeoutSec: { type: 'number' },
81
247
  },
82
- required: ['agentId', 'message']
248
+ required: []
83
249
  },
84
250
  execute: async (args, context) => executeSubagentAction(args, { sessionId: context.session.id, cwd: context.session.cwd || process.cwd() })
85
251
  }