@swarmclawai/swarmclaw 0.7.1 → 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 (237) hide show
  1. package/README.md +155 -150
  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 +37 -9
  5. package/src/app/api/agents/route.ts +13 -2
  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/{sessions → chats}/[id]/browser/route.ts +5 -1
  9. package/src/app/api/{sessions → chats}/[id]/chat/route.ts +7 -3
  10. package/src/app/api/{sessions → chats}/[id]/checkpoints/route.ts +1 -1
  11. package/src/app/api/chats/[id]/main-loop/route.ts +13 -0
  12. package/src/app/api/{sessions → chats}/[id]/messages/route.ts +19 -13
  13. package/src/app/api/{sessions → chats}/[id]/restore/route.ts +1 -1
  14. package/src/app/api/{sessions → chats}/[id]/route.ts +22 -52
  15. package/src/app/api/{sessions → chats}/[id]/stop/route.ts +6 -1
  16. package/src/app/api/{sessions → chats}/route.ts +21 -7
  17. package/src/app/api/connectors/[id]/doctor/route.ts +26 -0
  18. package/src/app/api/connectors/doctor/route.ts +13 -0
  19. package/src/app/api/files/open/route.ts +16 -14
  20. package/src/app/api/memory/maintenance/route.ts +11 -1
  21. package/src/app/api/openclaw/agent-files/route.ts +27 -4
  22. package/src/app/api/openclaw/skills/route.ts +11 -3
  23. package/src/app/api/plugins/dependencies/route.ts +24 -0
  24. package/src/app/api/plugins/install/route.ts +15 -92
  25. package/src/app/api/plugins/route.ts +6 -26
  26. package/src/app/api/plugins/settings/route.ts +40 -0
  27. package/src/app/api/plugins/ui/route.ts +1 -0
  28. package/src/app/api/settings/route.ts +49 -7
  29. package/src/app/api/tasks/[id]/route.ts +15 -6
  30. package/src/app/api/tasks/bulk/route.ts +2 -2
  31. package/src/app/api/tasks/route.ts +9 -4
  32. package/src/app/api/usage/route.ts +30 -0
  33. package/src/app/api/webhooks/[id]/route.ts +8 -1
  34. package/src/app/page.tsx +9 -2
  35. package/src/cli/index.js +39 -33
  36. package/src/cli/index.ts +43 -49
  37. package/src/cli/spec.js +29 -27
  38. package/src/components/agents/agent-card.tsx +16 -13
  39. package/src/components/agents/agent-chat-list.tsx +104 -4
  40. package/src/components/agents/agent-list.tsx +54 -22
  41. package/src/components/agents/agent-sheet.tsx +209 -18
  42. package/src/components/agents/cron-job-form.tsx +3 -3
  43. package/src/components/agents/inspector-panel.tsx +110 -50
  44. package/src/components/auth/access-key-gate.tsx +36 -97
  45. package/src/components/auth/setup-wizard.tsx +5 -38
  46. package/src/components/chat/chat-area.tsx +39 -27
  47. package/src/components/{sessions/session-card.tsx → chat/chat-card.tsx} +7 -23
  48. package/src/components/chat/chat-header.tsx +299 -314
  49. package/src/components/{sessions/session-list.tsx → chat/chat-list.tsx} +11 -14
  50. package/src/components/chat/chat-tool-toggles.tsx +26 -17
  51. package/src/components/chat/checkpoint-timeline.tsx +4 -4
  52. package/src/components/chat/message-bubble.tsx +4 -1
  53. package/src/components/chat/message-list.tsx +5 -3
  54. package/src/components/chat/session-debug-panel.tsx +1 -1
  55. package/src/components/chat/tool-request-banner.tsx +3 -3
  56. package/src/components/chatrooms/agent-hover-card.tsx +3 -3
  57. package/src/components/chatrooms/chatroom-tool-request-banner.tsx +2 -2
  58. package/src/components/chatrooms/chatroom-view.tsx +347 -205
  59. package/src/components/connectors/connector-list.tsx +265 -127
  60. package/src/components/connectors/connector-sheet.tsx +218 -1
  61. package/src/components/home/home-view.tsx +129 -5
  62. package/src/components/layout/app-layout.tsx +392 -182
  63. package/src/components/layout/mobile-header.tsx +26 -8
  64. package/src/components/plugins/plugin-list.tsx +487 -254
  65. package/src/components/plugins/plugin-sheet.tsx +236 -13
  66. package/src/components/projects/project-detail.tsx +183 -0
  67. package/src/components/settings/gateway-connection-panel.tsx +1 -1
  68. package/src/components/shared/agent-picker-list.tsx +2 -2
  69. package/src/components/shared/command-palette.tsx +111 -25
  70. package/src/components/shared/settings/plugin-manager.tsx +20 -4
  71. package/src/components/shared/settings/section-capability-policy.tsx +105 -0
  72. package/src/components/shared/settings/section-heartbeat.tsx +78 -1
  73. package/src/components/shared/settings/section-orchestrator.tsx +3 -3
  74. package/src/components/shared/settings/section-providers.tsx +1 -1
  75. package/src/components/shared/settings/section-runtime-loop.tsx +5 -5
  76. package/src/components/shared/settings/section-secrets.tsx +6 -6
  77. package/src/components/shared/settings/section-user-preferences.tsx +1 -1
  78. package/src/components/shared/settings/section-voice.tsx +5 -1
  79. package/src/components/shared/settings/section-web-search.tsx +10 -2
  80. package/src/components/shared/settings/settings-page.tsx +244 -56
  81. package/src/components/tasks/approvals-panel.tsx +205 -18
  82. package/src/components/tasks/task-board.tsx +242 -46
  83. package/src/components/usage/metrics-dashboard.tsx +147 -1
  84. package/src/components/wallets/wallet-panel.tsx +17 -5
  85. package/src/components/webhooks/webhook-sheet.tsx +8 -8
  86. package/src/lib/auth.ts +17 -0
  87. package/src/lib/chat-streaming-state.test.ts +108 -0
  88. package/src/lib/chat-streaming-state.ts +108 -0
  89. package/src/lib/chat.ts +1 -1
  90. package/src/lib/{sessions.ts → chats.ts} +28 -18
  91. package/src/lib/openclaw-agent-id.test.ts +14 -0
  92. package/src/lib/openclaw-agent-id.ts +31 -0
  93. package/src/lib/providers/claude-cli.ts +1 -1
  94. package/src/lib/server/agent-assignment.test.ts +112 -0
  95. package/src/lib/server/agent-assignment.ts +169 -0
  96. package/src/lib/server/approval-connector-notify.test.ts +253 -0
  97. package/src/lib/server/approvals-auto-approve.test.ts +205 -0
  98. package/src/lib/server/approvals.ts +483 -75
  99. package/src/lib/server/autonomy-runtime.test.ts +341 -0
  100. package/src/lib/server/browser-state.test.ts +118 -0
  101. package/src/lib/server/browser-state.ts +123 -0
  102. package/src/lib/server/build-llm.test.ts +36 -0
  103. package/src/lib/server/build-llm.ts +11 -4
  104. package/src/lib/server/builtin-plugins.ts +34 -0
  105. package/src/lib/server/capability-router.ts +10 -8
  106. package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
  107. package/src/lib/server/chat-execution-tool-events.test.ts +134 -0
  108. package/src/lib/server/chat-execution.ts +285 -165
  109. package/src/lib/server/chatroom-health.test.ts +26 -0
  110. package/src/lib/server/chatroom-health.ts +2 -3
  111. package/src/lib/server/chatroom-helpers.test.ts +67 -2
  112. package/src/lib/server/chatroom-helpers.ts +48 -8
  113. package/src/lib/server/connectors/discord.ts +175 -11
  114. package/src/lib/server/connectors/doctor.test.ts +80 -0
  115. package/src/lib/server/connectors/doctor.ts +116 -0
  116. package/src/lib/server/connectors/manager.ts +948 -112
  117. package/src/lib/server/connectors/policy.test.ts +222 -0
  118. package/src/lib/server/connectors/policy.ts +452 -0
  119. package/src/lib/server/connectors/slack.ts +188 -9
  120. package/src/lib/server/connectors/telegram.ts +65 -15
  121. package/src/lib/server/connectors/thread-context.test.ts +44 -0
  122. package/src/lib/server/connectors/thread-context.ts +72 -0
  123. package/src/lib/server/connectors/types.ts +41 -11
  124. package/src/lib/server/cost.ts +34 -1
  125. package/src/lib/server/daemon-state.ts +61 -3
  126. package/src/lib/server/data-dir.ts +13 -0
  127. package/src/lib/server/delegation-jobs.test.ts +140 -0
  128. package/src/lib/server/delegation-jobs.ts +248 -0
  129. package/src/lib/server/document-utils.test.ts +47 -0
  130. package/src/lib/server/document-utils.ts +397 -0
  131. package/src/lib/server/heartbeat-service.ts +14 -40
  132. package/src/lib/server/heartbeat-source.test.ts +22 -0
  133. package/src/lib/server/heartbeat-source.ts +7 -0
  134. package/src/lib/server/identity-continuity.test.ts +77 -0
  135. package/src/lib/server/identity-continuity.ts +127 -0
  136. package/src/lib/server/mailbox-utils.ts +347 -0
  137. package/src/lib/server/main-agent-loop.ts +28 -1103
  138. package/src/lib/server/memory-db.ts +4 -6
  139. package/src/lib/server/memory-tiers.ts +40 -0
  140. package/src/lib/server/openclaw-agent-resolver.test.ts +70 -0
  141. package/src/lib/server/openclaw-agent-resolver.ts +128 -0
  142. package/src/lib/server/openclaw-exec-config.ts +5 -6
  143. package/src/lib/server/openclaw-skills-normalize.test.ts +56 -0
  144. package/src/lib/server/openclaw-skills-normalize.ts +136 -0
  145. package/src/lib/server/openclaw-sync.ts +3 -2
  146. package/src/lib/server/orchestrator-lg.ts +20 -9
  147. package/src/lib/server/orchestrator.ts +7 -7
  148. package/src/lib/server/playwright-proxy.mjs +27 -3
  149. package/src/lib/server/plugins.test.ts +207 -0
  150. package/src/lib/server/plugins.ts +927 -66
  151. package/src/lib/server/provider-health.ts +38 -6
  152. package/src/lib/server/queue.ts +13 -28
  153. package/src/lib/server/scheduler.ts +2 -0
  154. package/src/lib/server/session-archive-memory.test.ts +85 -0
  155. package/src/lib/server/session-archive-memory.ts +230 -0
  156. package/src/lib/server/session-mailbox.ts +8 -18
  157. package/src/lib/server/session-reset-policy.test.ts +99 -0
  158. package/src/lib/server/session-reset-policy.ts +311 -0
  159. package/src/lib/server/session-run-manager.ts +33 -82
  160. package/src/lib/server/session-tools/autonomy-tools.test.ts +105 -0
  161. package/src/lib/server/session-tools/calendar.ts +366 -0
  162. package/src/lib/server/session-tools/canvas.ts +1 -1
  163. package/src/lib/server/session-tools/chatroom.ts +4 -2
  164. package/src/lib/server/session-tools/connector.ts +114 -10
  165. package/src/lib/server/session-tools/context.ts +21 -5
  166. package/src/lib/server/session-tools/crawl.ts +447 -0
  167. package/src/lib/server/session-tools/crud.ts +74 -28
  168. package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
  169. package/src/lib/server/session-tools/delegate.ts +497 -24
  170. package/src/lib/server/session-tools/discovery.ts +24 -6
  171. package/src/lib/server/session-tools/document.ts +283 -0
  172. package/src/lib/server/session-tools/edit_file.ts +4 -2
  173. package/src/lib/server/session-tools/email.ts +320 -0
  174. package/src/lib/server/session-tools/extract.ts +137 -0
  175. package/src/lib/server/session-tools/file-normalize.test.ts +93 -0
  176. package/src/lib/server/session-tools/file-send.test.ts +84 -1
  177. package/src/lib/server/session-tools/file.ts +241 -25
  178. package/src/lib/server/session-tools/git.ts +1 -1
  179. package/src/lib/server/session-tools/http.ts +1 -1
  180. package/src/lib/server/session-tools/human-loop.ts +227 -0
  181. package/src/lib/server/session-tools/image-gen.ts +380 -0
  182. package/src/lib/server/session-tools/index.ts +130 -50
  183. package/src/lib/server/session-tools/mailbox.ts +276 -0
  184. package/src/lib/server/session-tools/memory.ts +172 -3
  185. package/src/lib/server/session-tools/monitor.ts +151 -8
  186. package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
  187. package/src/lib/server/session-tools/openclaw-nodes.ts +1 -1
  188. package/src/lib/server/session-tools/openclaw-workspace.ts +1 -1
  189. package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
  190. package/src/lib/server/session-tools/platform.ts +148 -7
  191. package/src/lib/server/session-tools/plugin-creator.ts +89 -26
  192. package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
  193. package/src/lib/server/session-tools/replicate.ts +301 -0
  194. package/src/lib/server/session-tools/sample-ui.ts +1 -1
  195. package/src/lib/server/session-tools/sandbox.ts +4 -2
  196. package/src/lib/server/session-tools/schedule.ts +24 -12
  197. package/src/lib/server/session-tools/session-info.ts +43 -7
  198. package/src/lib/server/session-tools/session-tools-wiring.test.ts +31 -17
  199. package/src/lib/server/session-tools/shell.ts +5 -2
  200. package/src/lib/server/session-tools/subagent.ts +194 -28
  201. package/src/lib/server/session-tools/table.ts +587 -0
  202. package/src/lib/server/session-tools/wallet.ts +42 -12
  203. package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
  204. package/src/lib/server/session-tools/web.ts +926 -91
  205. package/src/lib/server/storage.ts +255 -16
  206. package/src/lib/server/stream-agent-chat.ts +116 -268
  207. package/src/lib/server/structured-extract.test.ts +72 -0
  208. package/src/lib/server/structured-extract.ts +373 -0
  209. package/src/lib/server/task-mention.test.ts +16 -2
  210. package/src/lib/server/task-mention.ts +61 -10
  211. package/src/lib/server/tool-aliases.ts +66 -18
  212. package/src/lib/server/tool-capability-policy.test.ts +9 -9
  213. package/src/lib/server/tool-capability-policy.ts +38 -27
  214. package/src/lib/server/tool-retry.ts +2 -0
  215. package/src/lib/server/watch-jobs.test.ts +173 -0
  216. package/src/lib/server/watch-jobs.ts +532 -0
  217. package/src/lib/server/ws-hub.ts +5 -3
  218. package/src/lib/tool-definitions.ts +4 -0
  219. package/src/lib/validation/schemas.test.ts +26 -0
  220. package/src/lib/validation/schemas.ts +10 -1
  221. package/src/lib/ws-client.ts +14 -12
  222. package/src/proxy.ts +5 -5
  223. package/src/stores/use-app-store.ts +5 -11
  224. package/src/stores/use-chat-store.ts +38 -9
  225. package/src/types/index.ts +352 -47
  226. package/src/app/api/sessions/[id]/main-loop/route.ts +0 -94
  227. package/src/components/sessions/new-session-sheet.tsx +0 -253
  228. package/src/lib/server/main-session.ts +0 -24
  229. package/src/lib/server/session-run-manager.test.ts +0 -23
  230. /package/src/app/api/{sessions → chats}/[id]/clear/route.ts +0 -0
  231. /package/src/app/api/{sessions → chats}/[id]/deploy/route.ts +0 -0
  232. /package/src/app/api/{sessions → chats}/[id]/devserver/route.ts +0 -0
  233. /package/src/app/api/{sessions → chats}/[id]/edit-resend/route.ts +0 -0
  234. /package/src/app/api/{sessions → chats}/[id]/fork/route.ts +0 -0
  235. /package/src/app/api/{sessions → chats}/[id]/mailbox/route.ts +0 -0
  236. /package/src/app/api/{sessions → chats}/[id]/retry/route.ts +0 -0
  237. /package/src/app/api/{sessions → chats}/heartbeat/route.ts +0 -0
@@ -24,6 +24,27 @@ export interface Message {
24
24
  streaming?: boolean
25
25
  }
26
26
 
27
+ export type SessionResetMode = 'idle' | 'daily'
28
+ export type SessionResetType = 'direct' | 'group' | 'thread' | 'main'
29
+
30
+ export interface IdentityContinuityState {
31
+ selfSummary?: string | null
32
+ relationshipSummary?: string | null
33
+ personaLabel?: string | null
34
+ toneStyle?: string | null
35
+ boundaries?: string[]
36
+ continuityNotes?: string[]
37
+ updatedAt?: number | null
38
+ }
39
+
40
+ export interface SessionArchiveState {
41
+ memoryId?: string | null
42
+ lastSyncedAt?: number | null
43
+ lastHash?: string | null
44
+ messageCount?: number
45
+ exportPath?: string | null
46
+ }
47
+
27
48
  export type ProviderType = 'claude-cli' | 'codex-cli' | 'opencode-cli' | 'openai' | 'ollama' | 'anthropic' | 'openclaw' | 'google' | 'deepseek' | 'groq' | 'together' | 'mistral' | 'xai' | 'fireworks'
28
49
 
29
50
  export interface ProviderInfo {
@@ -49,6 +70,7 @@ export type Credentials = Record<string, Credential>
49
70
  export interface Session {
50
71
  id: string
51
72
  name: string
73
+ shortcutForAgentId?: string | null
52
74
  cwd: string
53
75
  user: string
54
76
  provider: ProviderType
@@ -63,60 +85,70 @@ export interface Session {
63
85
  claudeCode?: string | null
64
86
  codex?: string | null
65
87
  opencode?: string | null
88
+ gemini?: string | null
66
89
  }
67
90
  messages: Message[]
68
91
  createdAt: number
69
92
  lastActiveAt: number
70
93
  active?: boolean
71
- mainSession?: boolean
72
94
  sessionType?: SessionType
73
95
  agentId?: string | null
74
96
  parentSessionId?: string | null
97
+ plugins?: string[]
98
+ /** @deprecated Use `plugins` instead. Kept for backward compat with stored data. */
75
99
  tools?: string[]
76
100
  heartbeatEnabled?: boolean | null
77
101
  heartbeatIntervalSec?: number | null
78
102
  heartbeatTarget?: 'last' | 'none' | string | null
103
+ sessionResetMode?: SessionResetMode | null
104
+ sessionIdleTimeoutSec?: number | null
105
+ sessionMaxAgeSec?: number | null
106
+ sessionDailyResetAt?: string | null
107
+ sessionResetTimezone?: string | null
108
+ thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high'
109
+ browserProfileId?: string | null
110
+ connectorThinkLevel?: 'minimal' | 'low' | 'medium' | 'high'
111
+ connectorSessionScope?: 'main' | 'channel' | 'peer' | 'channel-peer' | 'thread'
112
+ connectorReplyMode?: 'off' | 'first' | 'all'
113
+ connectorThreadBinding?: 'off' | 'prefer' | 'strict'
114
+ connectorGroupPolicy?: 'open' | 'mention' | 'reply-or-mention' | 'disabled'
115
+ connectorIdleTimeoutSec?: number | null
116
+ connectorMaxAgeSec?: number | null
117
+ mailbox?: MailboxEnvelope[] | null
118
+ connectorContext?: {
119
+ connectorId?: string | null
120
+ platform?: ConnectorPlatform | null
121
+ channelId?: string | null
122
+ senderId?: string | null
123
+ senderName?: string | null
124
+ sessionKey?: string | null
125
+ peerKey?: string | null
126
+ scope?: 'main' | 'channel' | 'peer' | 'channel-peer' | 'thread' | null
127
+ replyMode?: 'off' | 'first' | 'all' | null
128
+ threadBinding?: 'off' | 'prefer' | 'strict' | null
129
+ groupPolicy?: 'open' | 'mention' | 'reply-or-mention' | 'disabled' | null
130
+ threadId?: string | null
131
+ threadTitle?: string | null
132
+ threadPersonaLabel?: string | null
133
+ threadParentChannelId?: string | null
134
+ threadParentChannelName?: string | null
135
+ isGroup?: boolean
136
+ lastInboundAt?: number | null
137
+ lastInboundMessageId?: string | null
138
+ lastInboundReplyToMessageId?: string | null
139
+ lastInboundThreadId?: string | null
140
+ lastOutboundAt?: number | null
141
+ lastOutboundMessageId?: string | null
142
+ lastResetAt?: number | null
143
+ lastResetReason?: string | null
144
+ }
79
145
  lastAutoMemoryAt?: number | null
80
146
  lastHeartbeatText?: string | null
81
147
  lastHeartbeatSentAt?: number | null
82
- mainLoopState?: {
83
- goal?: string | null
84
- goalContract?: GoalContract | null
85
- status?: 'idle' | 'progress' | 'blocked' | 'ok'
86
- summary?: string | null
87
- nextAction?: string | null
88
- planSteps?: string[]
89
- currentPlanStep?: string | null
90
- reviewNote?: string | null
91
- reviewConfidence?: number | null
92
- missionTaskId?: string | null
93
- momentumScore?: number
94
- paused?: boolean
95
- autonomyMode?: 'assist' | 'autonomous'
96
- pendingEvents?: Array<{
97
- id: string
98
- type: string
99
- text: string
100
- createdAt: number
101
- }>
102
- timeline?: Array<{
103
- id: string
104
- at: number
105
- source: string
106
- note: string
107
- status?: 'idle' | 'progress' | 'blocked' | 'ok'
108
- }>
109
- missionTokens?: number
110
- missionCostUsd?: number
111
- followupChainCount?: number
112
- metaMissCount?: number
113
- workingMemoryNotes?: string[]
114
- lastMemoryNoteAt?: number | null
115
- lastPlannedAt?: number | null
116
- lastReviewedAt?: number | null
117
- lastTickAt?: number | null
118
- updatedAt?: number
119
- }
148
+ lastSessionResetAt?: number | null
149
+ lastSessionResetReason?: string | null
150
+ identityState?: IdentityContinuityState | null
151
+ sessionArchiveState?: SessionArchiveState | null
120
152
  pinned?: boolean
121
153
  file?: string | null
122
154
  queuedCount?: number
@@ -146,10 +178,16 @@ export type SessionTool =
146
178
  | 'canvas'
147
179
  | 'http_request'
148
180
  | 'git'
181
+ | 'mailbox'
182
+ | 'ask_human'
183
+ | 'document'
184
+ | 'extract'
185
+ | 'table'
186
+ | 'crawl'
149
187
 
150
188
  // --- Approvals ---
151
189
 
152
- export type ApprovalCategory = 'tool_access' | 'wallet_transfer' | 'plugin_scaffold' | 'plugin_install' | 'task_tool'
190
+ export type ApprovalCategory = 'tool_access' | 'wallet_transfer' | 'plugin_scaffold' | 'plugin_install' | 'task_tool' | 'human_loop'
153
191
 
154
192
  export interface ApprovalRequest {
155
193
  id: string
@@ -163,10 +201,48 @@ export interface ApprovalRequest {
163
201
  createdAt: number
164
202
  updatedAt: number
165
203
  status: 'pending' | 'approved' | 'rejected'
204
+ connectorNotification?: {
205
+ attemptedAt?: number | null
206
+ sentAt?: number | null
207
+ connectorId?: string | null
208
+ channelId?: string | null
209
+ threadId?: string | null
210
+ messageId?: string | null
211
+ lastError?: string | null
212
+ } | null
166
213
  }
167
214
 
168
215
  export type Approvals = Record<string, ApprovalRequest>
169
216
 
217
+ export type MailboxStatus = 'new' | 'ack'
218
+
219
+ export interface MailboxEnvelope {
220
+ id: string
221
+ type: string
222
+ payload: string
223
+ fromSessionId?: string | null
224
+ fromAgentId?: string | null
225
+ toSessionId: string
226
+ toAgentId?: string | null
227
+ correlationId?: string | null
228
+ status: MailboxStatus
229
+ createdAt: number
230
+ expiresAt?: number | null
231
+ ackAt?: number | null
232
+ }
233
+
234
+ export interface PluginInvocationRecord {
235
+ pluginId: string
236
+ toolName: string
237
+ inputTokens: number
238
+ outputTokens: number
239
+ }
240
+
241
+ export interface PluginDefinitionCost {
242
+ pluginId: string
243
+ estimatedTokens: number
244
+ }
245
+
170
246
  export interface UsageRecord {
171
247
  sessionId: string
172
248
  messageIndex: number
@@ -178,6 +254,8 @@ export interface UsageRecord {
178
254
  estimatedCost: number
179
255
  timestamp: number
180
256
  durationMs?: number
257
+ pluginDefinitionCosts?: PluginDefinitionCost[]
258
+ pluginInvocations?: PluginInvocationRecord[]
181
259
  }
182
260
 
183
261
  // --- Plugin System ---
@@ -186,9 +264,12 @@ export interface PluginHooks {
186
264
  beforeAgentStart?: (ctx: { session: Session; message: string }) => Promise<void> | void
187
265
  afterAgentComplete?: (ctx: { session: Session; response: string }) => Promise<void> | void
188
266
  beforeToolExec?: (ctx: { toolName: string; input: Record<string, unknown> | null }) => Promise<Record<string, unknown> | void> | Record<string, unknown> | void
189
- afterToolExec?: (ctx: { toolName: string; input: Record<string, unknown> | null; output: string }) => Promise<void> | void
267
+ afterToolExec?: (ctx: { session: Session; toolName: string; input: Record<string, unknown> | null; output: string }) => Promise<void> | void
190
268
  onMessage?: (ctx: { session: Session; message: Message }) => Promise<void> | void
191
269
 
270
+ // Post-turn hook — fires after a full chat exchange (user message → agent response)
271
+ afterChatTurn?: (ctx: { session: Session; message: string; response: string; source: string; internal: boolean }) => Promise<void> | void
272
+
192
273
  // Orchestration & Swarm Hooks
193
274
  onTaskComplete?: (ctx: { taskId: string; result: unknown }) => Promise<void> | void
194
275
  onAgentDelegation?: (ctx: { sourceAgentId: string; targetAgentId: string; task: string }) => Promise<void> | void
@@ -196,6 +277,15 @@ export interface PluginHooks {
196
277
  // Chat Middleware (Transform messages)
197
278
  transformInboundMessage?: (ctx: { session: Session; text: string }) => Promise<string> | string
198
279
  transformOutboundMessage?: (ctx: { session: Session; text: string }) => Promise<string> | string
280
+
281
+ // Context injection — return a markdown string to inject into the agent's state modifier, or null/undefined to skip
282
+ getAgentContext?: (ctx: { session: Session; enabledPlugins: string[]; message: string; history: Message[] }) => Promise<string | null | undefined> | string | null | undefined
283
+
284
+ // Self-description — returns a capability line for the system prompt (e.g., "I can remember things across conversations")
285
+ getCapabilityDescription?: () => string | null | undefined
286
+
287
+ // Operating guidance — returns operational hints for the agent when this plugin is active
288
+ getOperatingGuidance?: () => string | string[] | null | undefined
199
289
  }
200
290
 
201
291
  export interface PluginToolDef {
@@ -205,6 +295,17 @@ export interface PluginToolDef {
205
295
  execute: (args: Record<string, unknown>, ctx: { session: Session; message: string }) => Promise<string | object> | string | object
206
296
  }
207
297
 
298
+ export interface PluginSettingsField {
299
+ key: string
300
+ label: string
301
+ type: 'text' | 'number' | 'boolean' | 'select' | 'secret'
302
+ placeholder?: string
303
+ help?: string
304
+ options?: Array<{ value: string; label: string }>
305
+ defaultValue?: string | number | boolean
306
+ required?: boolean
307
+ }
308
+
208
309
  export interface PluginUIExtension {
209
310
  sidebarItems?: Array<{
210
311
  id: string
@@ -226,6 +327,22 @@ export interface PluginUIExtension {
226
327
  action: 'message' | 'link' | 'tool'
227
328
  value: string
228
329
  }>
330
+ /** Settings fields declared by the plugin, rendered in the plugin settings panel */
331
+ settingsFields?: PluginSettingsField[]
332
+ /** Chat panels the plugin provides (e.g., browser view, terminal) */
333
+ chatPanels?: Array<{
334
+ id: string
335
+ label: string
336
+ icon?: string
337
+ /** WS topic to subscribe to for updates (e.g., 'browser:{sessionId}') */
338
+ wsTopic?: string
339
+ }>
340
+ /** Badges to show on agent cards when this plugin is enabled */
341
+ agentBadges?: Array<{
342
+ id: string
343
+ label: string
344
+ icon?: string
345
+ }>
229
346
  }
230
347
 
231
348
  export interface PluginProviderExtension {
@@ -252,6 +369,9 @@ export interface Plugin {
252
369
  name: string
253
370
  version?: string
254
371
  description?: string
372
+ author?: string
373
+ openclaw?: boolean
374
+ enabledByDefault?: boolean
255
375
  hooks?: PluginHooks
256
376
  tools?: PluginToolDef[]
257
377
  ui?: PluginUIExtension
@@ -264,6 +384,7 @@ export interface PluginMeta {
264
384
  description?: string
265
385
  filename: string
266
386
  enabled: boolean
387
+ isBuiltin?: boolean
267
388
  author?: string
268
389
  version?: string
269
390
  source?: 'local' | 'marketplace'
@@ -279,7 +400,19 @@ export interface PluginMeta {
279
400
  providerCount?: number
280
401
  connectorCount?: number
281
402
  createdByAgentId?: string | null
403
+ settingsFields?: PluginSettingsField[]
404
+ hasDependencyManifest?: boolean
405
+ dependencyCount?: number
406
+ devDependencyCount?: number
407
+ packageManager?: PluginPackageManager
408
+ dependencyInstallStatus?: PluginDependencyInstallStatus
409
+ dependencyInstallError?: string
410
+ dependencyInstalledAt?: number
282
411
  }
412
+
413
+ export type PluginPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun'
414
+ export type PluginDependencyInstallStatus = 'none' | 'ready' | 'installing' | 'installed' | 'error'
415
+
283
416
  export interface MarketplacePlugin {
284
417
  id: string
285
418
  name: string
@@ -337,6 +470,7 @@ export interface Agent {
337
470
  name: string
338
471
  description: string
339
472
  soul?: string
473
+ identityState?: IdentityContinuityState | null
340
474
  emoji?: string
341
475
  creature?: string
342
476
  vibe?: string
@@ -350,13 +484,15 @@ export interface Agent {
350
484
  apiEndpoint?: string | null
351
485
  isOrchestrator?: boolean
352
486
  subAgentIds?: string[]
353
- tools?: string[] // e.g. ['browser'] — available tool integrations
487
+ plugins?: string[] // e.g. ['browser', 'memory'] — enabled plugin IDs
488
+ /** @deprecated Use `plugins` instead. Kept for backward compat with stored data. */
489
+ tools?: string[]
354
490
  skills?: string[] // e.g. ['frontend-design'] — Claude Code skills to use
355
491
  skillIds?: string[] // IDs of uploaded skills from the Skills manager
356
492
  mcpServerIds?: string[] // IDs of configured MCP servers to inject tools from
357
493
  mcpDisabledTools?: string[] // MCP tool names disabled for this agent (denylist)
358
494
  capabilities?: string[] // e.g. ['frontend', 'screenshots', 'research', 'devops']
359
- threadSessionId?: string | null // persistent chat thread session for agent-centric UI
495
+ threadSessionId?: string | null // persistent shortcut chat session for agent-centric UI
360
496
  platformAssignScope?: 'self' | 'all' // defaults to 'self'
361
497
  heartbeatEnabled?: boolean
362
498
  heartbeatIntervalSec?: number | null
@@ -369,6 +505,11 @@ export interface Agent {
369
505
  heartbeatTarget?: 'last' | 'none' | string | null
370
506
  heartbeatGoal?: string | null
371
507
  heartbeatNextAction?: string | null
508
+ sessionResetMode?: SessionResetMode | null
509
+ sessionIdleTimeoutSec?: number | null
510
+ sessionMaxAgeSec?: number | null
511
+ sessionDailyResetAt?: string | null
512
+ sessionResetTimezone?: string | null
372
513
  thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high'
373
514
  elevenLabsVoiceId?: string | null
374
515
  projectId?: string
@@ -473,6 +614,152 @@ export interface Schedule {
473
614
  createdAt: number
474
615
  }
475
616
 
617
+ export type BrowserSessionStatus = 'active' | 'idle' | 'closed' | 'error'
618
+
619
+ export interface BrowserSessionTab {
620
+ index: number
621
+ title?: string | null
622
+ url?: string | null
623
+ }
624
+
625
+ export interface BrowserSessionArtifact {
626
+ kind: 'snapshot' | 'screenshot' | 'download' | 'pdf'
627
+ path: string
628
+ url?: string | null
629
+ filename?: string | null
630
+ createdAt: number
631
+ }
632
+
633
+ export interface BrowserObservationLink {
634
+ text: string
635
+ href: string
636
+ }
637
+
638
+ export interface BrowserObservationFormField {
639
+ name?: string | null
640
+ label?: string | null
641
+ type: string
642
+ required?: boolean
643
+ }
644
+
645
+ export interface BrowserObservationForm {
646
+ index: number
647
+ action?: string | null
648
+ method?: string | null
649
+ fields: BrowserObservationFormField[]
650
+ }
651
+
652
+ export interface BrowserObservationTable {
653
+ index: number
654
+ headers: string[]
655
+ rowCount: number
656
+ rows?: string[][]
657
+ }
658
+
659
+ export interface BrowserObservation {
660
+ capturedAt: number
661
+ url?: string | null
662
+ title?: string | null
663
+ textPreview?: string | null
664
+ activeTabIndex?: number | null
665
+ tabs?: BrowserSessionTab[]
666
+ links?: BrowserObservationLink[]
667
+ forms?: BrowserObservationForm[]
668
+ tables?: BrowserObservationTable[]
669
+ errors?: string[]
670
+ }
671
+
672
+ export interface BrowserSessionRecord {
673
+ id: string
674
+ sessionId: string
675
+ profileId: string
676
+ profileDir: string
677
+ status: BrowserSessionStatus
678
+ inheritedFromSessionId?: string | null
679
+ currentUrl?: string | null
680
+ pageTitle?: string | null
681
+ activeTabIndex?: number | null
682
+ tabs?: BrowserSessionTab[]
683
+ lastAction?: string | null
684
+ lastError?: string | null
685
+ lastObservation?: BrowserObservation | null
686
+ artifacts?: BrowserSessionArtifact[]
687
+ createdAt: number
688
+ updatedAt: number
689
+ lastUsedAt: number
690
+ }
691
+
692
+ export type WatchJobType = 'time' | 'http' | 'file' | 'task' | 'webhook' | 'page' | 'email' | 'mailbox' | 'approval'
693
+ export type WatchJobStatus = 'active' | 'triggered' | 'failed' | 'cancelled'
694
+
695
+ export interface WatchJob {
696
+ id: string
697
+ type: WatchJobType
698
+ status: WatchJobStatus
699
+ description?: string | null
700
+ sessionId?: string | null
701
+ agentId?: string | null
702
+ createdByAgentId?: string | null
703
+ browserProfileId?: string | null
704
+ resumeMessage: string
705
+ target: Record<string, unknown>
706
+ condition: Record<string, unknown>
707
+ runAt?: number | null
708
+ nextCheckAt?: number | null
709
+ intervalMs?: number | null
710
+ timeoutAt?: number | null
711
+ lastCheckedAt?: number | null
712
+ lastTriggeredAt?: number | null
713
+ lastError?: string | null
714
+ result?: Record<string, unknown> | null
715
+ createdAt: number
716
+ updatedAt: number
717
+ }
718
+
719
+ export type DelegationJobKind = 'subagent' | 'delegate'
720
+ export type DelegationJobStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'
721
+
722
+ export interface DelegationJobCheckpoint {
723
+ at: number
724
+ note: string
725
+ status?: DelegationJobStatus
726
+ }
727
+
728
+ export interface DelegationJobArtifact {
729
+ type: 'text' | 'file' | 'image' | 'link'
730
+ value: string
731
+ label?: string | null
732
+ }
733
+
734
+ export interface DelegationJobRecord {
735
+ id: string
736
+ kind: DelegationJobKind
737
+ status: DelegationJobStatus
738
+ backend?: 'claude' | 'codex' | 'opencode' | 'gemini' | null
739
+ parentSessionId?: string | null
740
+ childSessionId?: string | null
741
+ agentId?: string | null
742
+ agentName?: string | null
743
+ cwd?: string | null
744
+ task: string
745
+ result?: string | null
746
+ resultPreview?: string | null
747
+ error?: string | null
748
+ checkpoints?: DelegationJobCheckpoint[]
749
+ artifacts?: DelegationJobArtifact[]
750
+ resumeId?: string | null
751
+ resumeIds?: {
752
+ claudeCode?: string | null
753
+ codex?: string | null
754
+ opencode?: string | null
755
+ gemini?: string | null
756
+ }
757
+ createdAt: number
758
+ updatedAt: number
759
+ startedAt?: number | null
760
+ completedAt?: number | null
761
+ }
762
+
476
763
  export interface FileReference {
477
764
  path: string
478
765
  contextSnippet?: string
@@ -525,7 +812,7 @@ export interface MemoryEntry {
525
812
  updatedAt: number
526
813
  }
527
814
 
528
- export type SessionType = 'human' | 'orchestrated'
815
+ export type SessionType = 'human'
529
816
  export type AppView = 'home' | 'agents' | 'chatrooms' | 'schedules' | 'memory' | 'tasks' | 'approvals' | 'secrets' | 'providers' | 'skills' | 'connectors' | 'webhooks' | 'mcp_servers' | 'knowledge' | 'plugins' | 'usage' | 'wallets' | 'runs' | 'logs' | 'settings' | 'projects' | 'activity'
530
817
 
531
818
  // --- Chatrooms ---
@@ -707,10 +994,13 @@ export interface AppSettings {
707
994
  userAvatarSeed?: string
708
995
  elevenLabsEnabled?: boolean
709
996
  elevenLabsApiKey?: string | null
997
+ elevenLabsApiKeyConfigured?: boolean
710
998
  elevenLabsVoiceId?: string | null
711
999
  speechRecognitionLang?: string | null
712
1000
  tavilyApiKey?: string | null
1001
+ tavilyApiKeyConfigured?: boolean
713
1002
  braveApiKey?: string | null
1003
+ braveApiKeyConfigured?: boolean
714
1004
  heartbeatPrompt?: string | null
715
1005
  heartbeatIntervalSec?: number | null
716
1006
  heartbeatInterval?: string | number | null
@@ -722,12 +1012,21 @@ export interface AppSettings {
722
1012
  heartbeatActiveStart?: string | null
723
1013
  heartbeatActiveEnd?: string | null
724
1014
  heartbeatTimezone?: string | null
1015
+ sessionResetMode?: SessionResetMode | null
1016
+ sessionIdleTimeoutSec?: number | null
1017
+ sessionMaxAgeSec?: number | null
1018
+ sessionDailyResetAt?: string | null
1019
+ sessionResetTimezone?: string | null
725
1020
  // Task resiliency and supervision
726
1021
  defaultTaskMaxAttempts?: number
727
1022
  taskRetryBackoffSec?: number
728
1023
  taskStallTimeoutMin?: number
729
1024
  // Safety rails
1025
+ approvalsEnabled?: boolean
730
1026
  safetyRequireApprovalForOutbound?: boolean
1027
+ approvalAutoApproveCategories?: ApprovalCategory[]
1028
+ approvalConnectorNotifyEnabled?: boolean
1029
+ approvalConnectorNotifyDelaySec?: number | null
731
1030
  safetyMaxDailySpendUsd?: number | null
732
1031
  safetyBlockedTools?: string[]
733
1032
  capabilityPolicyMode?: 'permissive' | 'balanced' | 'strict'
@@ -784,9 +1083,11 @@ export interface AppSettings {
784
1083
  taskQualityGateRequireReport?: boolean
785
1084
  // Integrity monitor
786
1085
  integrityMonitorEnabled?: boolean
1086
+ // Per-plugin settings (keyed by pluginId)
1087
+ pluginSettings?: Record<string, Record<string, unknown>>
787
1088
  }
788
1089
 
789
- // --- Orchestrator Secrets ---
1090
+ // --- Agent Secrets ---
790
1091
 
791
1092
  export interface OrchestratorSecret {
792
1093
  id: string
@@ -794,7 +1095,7 @@ export interface OrchestratorSecret {
794
1095
  service: string // e.g. 'gmail', 'ahrefs', 'custom'
795
1096
  encryptedValue: string
796
1097
  scope: 'global' | 'agent'
797
- agentIds: string[] // if scope === 'agent', which orchestrators can use it
1098
+ agentIds: string[] // if scope === 'agent', which agents can use it
798
1099
  createdAt: number
799
1100
  updatedAt: number
800
1101
  }
@@ -806,7 +1107,7 @@ export type BoardTaskStatus = 'backlog' | 'queued' | 'running' | 'completed' | '
806
1107
  export interface TaskComment {
807
1108
  id: string
808
1109
  author: string // agent name or 'user'
809
- agentId?: string // if from an orchestrator
1110
+ agentId?: string // if from an agent
810
1111
  text: string
811
1112
  createdAt: number
812
1113
  }
@@ -876,6 +1177,9 @@ export interface MessageSource {
876
1177
  channelId?: string
877
1178
  senderId?: string
878
1179
  senderName?: string
1180
+ messageId?: string
1181
+ replyToMessageId?: string
1182
+ threadId?: string
879
1183
  }
880
1184
 
881
1185
  export interface Connector {
@@ -977,6 +1281,7 @@ export interface BoardTask {
977
1281
  claudeResumeId?: string | null
978
1282
  codexResumeId?: string | null
979
1283
  opencodeResumeId?: string | null
1284
+ geminiResumeId?: string | null
980
1285
  checkpoint?: {
981
1286
  lastRunId?: string | null
982
1287
  lastSessionId?: string | null
@@ -1,94 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { enqueueSessionRun } from '@/lib/server/session-run-manager'
3
- import { loadSessions } from '@/lib/server/storage'
4
- import {
5
- buildMainLoopHeartbeatPrompt,
6
- getMainLoopStateForSession,
7
- isMainSession,
8
- pushMainLoopEventToMainSessions,
9
- setMainLoopStateForSession,
10
- } from '@/lib/server/main-agent-loop'
11
-
12
- export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
13
- const { id } = await params
14
- const sessions = loadSessions()
15
- const session = sessions[id]
16
- if (!session) return new NextResponse('Session not found', { status: 404 })
17
- if (!isMainSession(session)) return new NextResponse('Main-loop controls only apply to __main__ sessions', { status: 400 })
18
- const state = getMainLoopStateForSession(id)
19
- return NextResponse.json({ sessionId: id, state })
20
- }
21
-
22
- export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
23
- const { id } = await params
24
- const body = await req.json().catch(() => ({}))
25
- const action = typeof body.action === 'string' ? body.action.trim() : ''
26
-
27
- const sessions = loadSessions()
28
- const session = sessions[id]
29
- if (!session) return new NextResponse('Session not found', { status: 404 })
30
- if (!isMainSession(session)) return new NextResponse('Main-loop controls only apply to __main__ sessions', { status: 400 })
31
-
32
- if (action === 'pause') {
33
- const state = setMainLoopStateForSession(id, { paused: true })
34
- return NextResponse.json({ ok: true, action, state })
35
- }
36
-
37
- if (action === 'resume') {
38
- const state = setMainLoopStateForSession(id, { paused: false })
39
- return NextResponse.json({ ok: true, action, state })
40
- }
41
-
42
- if (action === 'set_goal') {
43
- const goal = typeof body.goal === 'string' ? body.goal.trim() : ''
44
- if (!goal) return new NextResponse('goal is required for set_goal', { status: 400 })
45
- const state = setMainLoopStateForSession(id, {
46
- goal,
47
- status: 'progress',
48
- paused: false,
49
- followupChainCount: 0,
50
- })
51
- pushMainLoopEventToMainSessions({
52
- type: 'operator_goal',
53
- text: `Operator set mission goal: ${goal}`,
54
- user: session.user || null,
55
- })
56
- return NextResponse.json({ ok: true, action, state })
57
- }
58
-
59
- if (action === 'set_mode') {
60
- const mode = body.mode === 'assist' ? 'assist' : body.mode === 'autonomous' ? 'autonomous' : null
61
- if (!mode) return new NextResponse('mode must be "assist" or "autonomous"', { status: 400 })
62
- const state = setMainLoopStateForSession(id, { autonomyMode: mode })
63
- return NextResponse.json({ ok: true, action, state })
64
- }
65
-
66
- if (action === 'clear_events') {
67
- const state = setMainLoopStateForSession(id, { pendingEvents: [] })
68
- return NextResponse.json({ ok: true, action, state })
69
- }
70
-
71
- if (action === 'nudge') {
72
- const state = getMainLoopStateForSession(id)
73
- if (state?.paused) {
74
- return new NextResponse('Mission loop is paused; resume first', { status: 409 })
75
- }
76
- const note = typeof body.note === 'string' ? body.note.trim() : ''
77
- const prompt = buildMainLoopHeartbeatPrompt(
78
- session,
79
- 'Operator requested manual nudge: execute one concrete next step now and report concise progress.',
80
- )
81
- const message = note ? `${prompt}\nOperator note: ${note.slice(0, 500)}` : prompt
82
- const run = enqueueSessionRun({
83
- sessionId: id,
84
- message,
85
- internal: true,
86
- source: 'mission-control',
87
- mode: 'collect',
88
- dedupeKey: `mission-control:nudge:${id}`,
89
- })
90
- return NextResponse.json({ ok: true, action, runId: run.runId, position: run.position, deduped: run.deduped || false, state })
91
- }
92
-
93
- return new NextResponse('Unknown action. Use pause, resume, set_goal, set_mode, clear_events, or nudge.', { status: 400 })
94
- }