@swarmclawai/swarmclaw 1.2.6 → 1.2.8

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 (112) hide show
  1. package/README.md +24 -17
  2. package/next.config.ts +1 -0
  3. package/package.json +3 -2
  4. package/scripts/easy-setup.mjs +1 -1
  5. package/scripts/postinstall.mjs +1 -1
  6. package/skills/swarmclaw.md +115 -0
  7. package/skills/tools/browser.md +131 -0
  8. package/skills/tools/execute.md +98 -0
  9. package/skills/tools/files.md +98 -0
  10. package/skills/tools/memory.md +104 -0
  11. package/skills/tools/platform.md +144 -0
  12. package/skills/tools/skills.md +83 -0
  13. package/src/app/api/chats/[id]/messages/route.ts +23 -19
  14. package/src/app/api/chats/messages-route.test.ts +105 -51
  15. package/src/app/api/mcp-servers/[id]/test/route.ts +3 -2
  16. package/src/app/api/openclaw/deploy/route.ts +2 -0
  17. package/src/app/api/setup/doctor/route.ts +4 -4
  18. package/src/components/agents/agent-chat-list.tsx +23 -1
  19. package/src/components/agents/inspector-panel.tsx +165 -48
  20. package/src/components/chat/chat-area.tsx +38 -9
  21. package/src/components/chat/message-list.tsx +33 -19
  22. package/src/components/gateways/gateway-sheet.tsx +5 -2
  23. package/src/lib/agent-execute-defaults.test.ts +24 -0
  24. package/src/lib/agent-execute-defaults.ts +62 -0
  25. package/src/lib/chat/queued-message-queue.test.ts +134 -1
  26. package/src/lib/chat/queued-message-queue.ts +77 -2
  27. package/src/lib/server/agents/agent-service.ts +5 -0
  28. package/src/lib/server/builtin-extensions.ts +1 -0
  29. package/src/lib/server/chat-execution/chat-execution-advanced.test.ts +1 -1
  30. package/src/lib/server/chat-execution/chat-execution-tool-events.test.ts +1 -0
  31. package/src/lib/server/chat-execution/chat-execution-utils.ts +2 -2
  32. package/src/lib/server/chat-execution/chat-turn-preparation.ts +79 -42
  33. package/src/lib/server/chat-execution/chat-turn-stream-execution.ts +4 -0
  34. package/src/lib/server/chat-execution/continuation-evaluator.ts +8 -0
  35. package/src/lib/server/chat-execution/memory-mutation-tools.ts +1 -1
  36. package/src/lib/server/chat-execution/message-classifier.ts +11 -1
  37. package/src/lib/server/chat-execution/prompt-builder.test.ts +28 -0
  38. package/src/lib/server/chat-execution/prompt-builder.ts +14 -1
  39. package/src/lib/server/chat-execution/prompt-mode.test.ts +24 -0
  40. package/src/lib/server/chat-execution/prompt-mode.ts +5 -1
  41. package/src/lib/server/chat-execution/stream-agent-chat.test.ts +6 -4
  42. package/src/lib/server/chat-execution/stream-agent-chat.ts +45 -16
  43. package/src/lib/server/chatrooms/chatroom-routing.test.ts +4 -0
  44. package/src/lib/server/connectors/discord.ts +2 -2
  45. package/src/lib/server/connectors/matrix.ts +3 -2
  46. package/src/lib/server/connectors/signal.ts +5 -4
  47. package/src/lib/server/connectors/slack.ts +10 -9
  48. package/src/lib/server/connectors/teams.ts +3 -2
  49. package/src/lib/server/connectors/telegram.ts +4 -4
  50. package/src/lib/server/connectors/whatsapp.ts +2 -2
  51. package/src/lib/server/daemon/controller.ts +7 -0
  52. package/src/lib/server/gateways/gateway-profile-service.ts +19 -1
  53. package/src/lib/server/messages/message-repository.test.ts +70 -0
  54. package/src/lib/server/messages/message-repository.ts +11 -6
  55. package/src/lib/server/openclaw/deploy.ts +32 -2
  56. package/src/lib/server/plugins-advanced.test.ts +1 -2
  57. package/src/lib/server/provider-health.ts +1 -1
  58. package/src/lib/server/runtime/process-manager.ts +13 -9
  59. package/src/lib/server/runtime/session-run-manager/queries.ts +15 -0
  60. package/src/lib/server/runtime/session-run-manager.test.ts +58 -0
  61. package/src/lib/server/sandbox/session-runtime.test.ts +18 -1
  62. package/src/lib/server/sandbox/session-runtime.ts +40 -28
  63. package/src/lib/server/session-tools/autonomy-tools.test.ts +7 -9
  64. package/src/lib/server/session-tools/context.ts +1 -1
  65. package/src/lib/server/session-tools/credential-env.ts +109 -0
  66. package/src/lib/server/session-tools/crud.ts +3 -3
  67. package/src/lib/server/session-tools/edit_file.ts +3 -2
  68. package/src/lib/server/session-tools/execute.test.ts +58 -0
  69. package/src/lib/server/session-tools/execute.ts +334 -0
  70. package/src/lib/server/session-tools/files-tool.ts +635 -0
  71. package/src/lib/server/session-tools/index.ts +14 -4
  72. package/src/lib/server/session-tools/memory-tool.ts +242 -0
  73. package/src/lib/server/session-tools/memory.ts +1 -1
  74. package/src/lib/server/session-tools/openclaw-nodes.ts +3 -2
  75. package/src/lib/server/session-tools/openclaw-workspace.ts +3 -2
  76. package/src/lib/server/session-tools/platform-tool.ts +617 -0
  77. package/src/lib/server/session-tools/session-info.ts +3 -2
  78. package/src/lib/server/session-tools/session-tools-wiring.test.ts +3 -4
  79. package/src/lib/server/session-tools/shell.ts +7 -122
  80. package/src/lib/server/session-tools/skills-tool.ts +396 -0
  81. package/src/lib/server/session-tools/web.ts +2 -2
  82. package/src/lib/server/storage-normalization.ts +2 -0
  83. package/src/lib/server/tool-aliases.ts +2 -1
  84. package/src/lib/server/tool-capability-policy-advanced.test.ts +9 -2
  85. package/src/lib/server/tool-capability-policy.test.ts +2 -1
  86. package/src/lib/server/tool-capability-policy.ts +60 -33
  87. package/src/lib/server/tool-planning.ts +11 -0
  88. package/src/lib/setup-defaults.ts +5 -0
  89. package/src/lib/tool-definitions.ts +1 -0
  90. package/src/lib/validation/schemas.test.ts +16 -0
  91. package/src/lib/validation/schemas.ts +16 -0
  92. package/src/stores/use-chat-store.test.ts +231 -0
  93. package/src/stores/use-chat-store.ts +62 -13
  94. package/src/types/agent.ts +348 -0
  95. package/src/types/app-settings.ts +175 -0
  96. package/src/types/approval.ts +27 -0
  97. package/src/types/connector.ts +187 -0
  98. package/src/types/extension.ts +386 -0
  99. package/src/types/index.ts +16 -3555
  100. package/src/types/message.ts +57 -0
  101. package/src/types/misc.ts +739 -0
  102. package/src/types/mission.ts +185 -0
  103. package/src/types/protocol.ts +422 -0
  104. package/src/types/provider.ts +52 -0
  105. package/src/types/run.ts +183 -0
  106. package/src/types/schedule.ts +59 -0
  107. package/src/types/session.ts +265 -0
  108. package/src/types/skill.ts +157 -0
  109. package/src/types/task.ts +140 -0
  110. package/src/types/working-state.ts +211 -0
  111. package/src/views/settings/section-heartbeat.tsx +2 -2
  112. package/src/lib/server/session-tools/sandbox.ts +0 -281
@@ -0,0 +1,187 @@
1
+ import type { WhatsAppApprovedContact } from './app-settings'
2
+
3
+ // --- Connector Health Events ---
4
+
5
+ export type ConnectorHealthEventType = 'started' | 'stopped' | 'error' | 'reconnected' | 'disconnected'
6
+
7
+ export interface ConnectorHealthEvent {
8
+ id: string
9
+ connectorId: string
10
+ event: ConnectorHealthEventType
11
+ message?: string
12
+ timestamp: string
13
+ }
14
+
15
+ // --- Connectors (Chat Platform Bridges) ---
16
+
17
+ export type ConnectorPlatform =
18
+ | 'discord'
19
+ | 'telegram'
20
+ | 'slack'
21
+ | 'whatsapp'
22
+ | 'openclaw'
23
+ | 'bluebubbles'
24
+ | 'signal'
25
+ | 'teams'
26
+ | 'googlechat'
27
+ | 'matrix'
28
+ | 'email'
29
+ | 'webchat'
30
+ | 'mockmail'
31
+ export type ConnectorStatus = 'stopped' | 'running' | 'error'
32
+
33
+ export interface MessageSource {
34
+ platform: ConnectorPlatform
35
+ connectorId: string
36
+ connectorName: string
37
+ channelId?: string
38
+ senderId?: string
39
+ senderName?: string
40
+ messageId?: string
41
+ replyToMessageId?: string
42
+ threadId?: string
43
+ deliveryMode?: 'text' | 'voice_note'
44
+ deliveryTranscript?: string | null
45
+ }
46
+
47
+ export interface Connector {
48
+ id: string
49
+ name: string
50
+ platform: ConnectorPlatform
51
+ agentId?: string | null // which agent handles incoming messages (optional if using chatroomId)
52
+ chatroomId?: string | null // route to a chatroom instead of a single agent
53
+ credentialId?: string | null // bot token stored as encrypted credential
54
+ config: Record<string, string> // platform-specific settings
55
+ isEnabled: boolean
56
+ status: ConnectorStatus
57
+ lastError?: string | null
58
+ /** WhatsApp QR code data URL (runtime only) */
59
+ qrDataUrl?: string | null
60
+ /** WhatsApp authenticated/paired state (runtime only) */
61
+ authenticated?: boolean
62
+ /** WhatsApp has stored credentials from previous pairing (runtime only) */
63
+ hasCredentials?: boolean
64
+ /** Connector presence info (runtime only) */
65
+ presence?: { lastMessageAt?: number | null; channelId?: string | null }
66
+ createdAt: number
67
+ updatedAt: number
68
+ }
69
+
70
+ export type ConnectorDmAddressingMode = 'open' | 'addressed'
71
+
72
+ export interface ConnectorAccessSenderStatus {
73
+ senderIds: string[]
74
+ isOwnerOverride: boolean
75
+ isBlocked: boolean
76
+ isApproved: boolean
77
+ isConfigAllowed: boolean
78
+ isStoredAllowed: boolean
79
+ isGlobalAllowed: boolean
80
+ isPending: boolean
81
+ pendingCode?: string | null
82
+ dmAddressingOverride: ConnectorDmAddressingMode | null
83
+ effectiveDmAddressingMode: ConnectorDmAddressingMode
84
+ requiresDirectAddress: boolean
85
+ }
86
+
87
+ export interface ConnectorAccessSnapshot {
88
+ connectorId: string
89
+ platform: ConnectorPlatform
90
+ dmPolicy: 'open' | 'allowlist' | 'pairing' | 'disabled'
91
+ dmAddressingMode: ConnectorDmAddressingMode
92
+ allowFrom: string[]
93
+ denyFrom: string[]
94
+ ownerSenderId: string | null
95
+ storedAllowedSenderIds: string[]
96
+ senderAddressingOverrides: Array<{
97
+ senderId: string
98
+ dmAddressingMode: ConnectorDmAddressingMode
99
+ }>
100
+ pendingPairingRequests: Array<{
101
+ code: string
102
+ senderId: string
103
+ senderName?: string
104
+ channelId?: string
105
+ createdAt: number
106
+ updatedAt: number
107
+ }>
108
+ globalWhatsAppApprovedContacts: WhatsAppApprovedContact[]
109
+ senderStatus?: ConnectorAccessSenderStatus | null
110
+ }
111
+
112
+ export type ConnectorAccessMutationAction =
113
+ | 'set_policy'
114
+ | 'set_dm_addressing_mode'
115
+ | 'allow_sender'
116
+ | 'remove_allowed_sender'
117
+ | 'block_sender'
118
+ | 'unblock_sender'
119
+ | 'approve_pairing'
120
+ | 'reject_pairing'
121
+ | 'set_owner'
122
+ | 'clear_owner'
123
+ | 'set_sender_dm_addressing'
124
+ | 'clear_sender_dm_addressing'
125
+
126
+ export interface ConnectorAccessMutationResponse {
127
+ ok: boolean
128
+ snapshot: ConnectorAccessSnapshot
129
+ }
130
+
131
+ export type InboundMediaType = 'image' | 'video' | 'audio' | 'document' | 'file'
132
+
133
+ export interface InboundThreadHistoryEntry {
134
+ role: 'user' | 'assistant'
135
+ senderName: string
136
+ text: string
137
+ messageId?: string
138
+ }
139
+
140
+ export interface InboundMedia {
141
+ type: InboundMediaType
142
+ fileName?: string
143
+ mimeType?: string
144
+ sizeBytes?: number
145
+ url?: string
146
+ localPath?: string
147
+ }
148
+
149
+ export interface InboundMessage {
150
+ platform: string
151
+ channelId: string
152
+ channelIdAlt?: string
153
+ channelName?: string
154
+ senderId: string
155
+ senderIdAlt?: string
156
+ senderName: string
157
+ senderAvatarUrl?: string
158
+ text: string
159
+ isGroup?: boolean
160
+ messageId?: string
161
+ imageUrl?: string
162
+ media?: InboundMedia[]
163
+ replyToMessageId?: string
164
+ threadId?: string
165
+ threadTitle?: string
166
+ threadStarterText?: string
167
+ threadStarterSenderName?: string
168
+ threadPersonaLabel?: string
169
+ threadParentChannelId?: string
170
+ threadParentChannelName?: string
171
+ threadHistory?: InboundThreadHistoryEntry[]
172
+ mentionsBot?: boolean
173
+ agentIdOverride?: string
174
+ isOwnerConversation?: boolean
175
+ }
176
+
177
+ export interface OutboundSendOptions {
178
+ imageUrl?: string
179
+ fileUrl?: string
180
+ mediaPath?: string
181
+ mimeType?: string
182
+ fileName?: string
183
+ caption?: string
184
+ ptt?: boolean
185
+ replyToMessageId?: string
186
+ threadId?: string
187
+ }
@@ -0,0 +1,386 @@
1
+ import type { ProviderId } from './provider'
2
+ import type { Session } from './session'
3
+ import type { Message } from './message'
4
+ import type { ApprovalRequest } from './approval'
5
+ import type { MessageToolEvent } from './message'
6
+ import type { InboundMessage, OutboundSendOptions } from './connector'
7
+
8
+ export interface ExtensionPromptBuildResult {
9
+ systemPrompt?: string
10
+ prependContext?: string
11
+ prependSystemContext?: string
12
+ appendSystemContext?: string
13
+ }
14
+
15
+ export interface ExtensionModelResolveResult {
16
+ providerOverride?: ProviderId
17
+ modelOverride?: string
18
+ apiEndpointOverride?: string | null
19
+ }
20
+
21
+ export interface ExtensionToolCallResult {
22
+ input?: Record<string, unknown> | null
23
+ params?: Record<string, unknown>
24
+ block?: boolean
25
+ blockReason?: string
26
+ warning?: string
27
+ }
28
+
29
+ export interface ExtensionMessagePersistResult {
30
+ message?: Message
31
+ }
32
+
33
+ export interface ExtensionBeforeMessageWriteResult extends ExtensionMessagePersistResult {
34
+ block?: boolean
35
+ }
36
+
37
+ export interface ExtensionSubagentSpawningResult {
38
+ status: 'ok' | 'error'
39
+ error?: string
40
+ }
41
+
42
+ export interface ExtensionHooks {
43
+ beforeAgentStart?: (ctx: { session: Session; message: string }) => Promise<void> | void
44
+ afterAgentComplete?: (ctx: { session: Session; response: string }) => Promise<void> | void
45
+ beforeModelResolve?: (ctx: {
46
+ session: Session
47
+ prompt: string
48
+ message: string
49
+ provider: ProviderId
50
+ model: string
51
+ apiEndpoint?: string | null
52
+ }) => Promise<ExtensionModelResolveResult | void> | ExtensionModelResolveResult | void
53
+ beforeToolExec?: (ctx: { toolName: string; input: Record<string, unknown> | null }) => Promise<Record<string, unknown> | void> | Record<string, unknown> | void
54
+ beforePromptBuild?: (ctx: {
55
+ session: Session
56
+ prompt: string
57
+ message: string
58
+ history: Message[]
59
+ messages: Message[]
60
+ }) => Promise<ExtensionPromptBuildResult | void> | ExtensionPromptBuildResult | void
61
+ beforeToolCall?: (ctx: {
62
+ session: Session
63
+ toolName: string
64
+ input: Record<string, unknown> | null
65
+ runId?: string
66
+ toolCallId?: string
67
+ }) => Promise<ExtensionToolCallResult | Record<string, unknown> | void> | ExtensionToolCallResult | Record<string, unknown> | void
68
+ llmInput?: (ctx: {
69
+ session: Session
70
+ runId: string
71
+ provider: ProviderId
72
+ model: string
73
+ systemPrompt?: string
74
+ prompt: string
75
+ historyMessages: Message[]
76
+ imagesCount: number
77
+ }) => Promise<void> | void
78
+ llmOutput?: (ctx: {
79
+ session: Session
80
+ runId: string
81
+ provider: ProviderId
82
+ model: string
83
+ assistantTexts: string[]
84
+ response: string
85
+ usage?: {
86
+ input?: number
87
+ output?: number
88
+ total?: number
89
+ estimatedCost?: number
90
+ }
91
+ }) => Promise<void> | void
92
+ toolResultPersist?: (ctx: {
93
+ session: Session
94
+ message: Message
95
+ toolName?: string
96
+ toolCallId?: string
97
+ isSynthetic?: boolean
98
+ }) => Promise<ExtensionMessagePersistResult | Message | void> | ExtensionMessagePersistResult | Message | void
99
+ beforeMessageWrite?: (ctx: {
100
+ session: Session
101
+ message: Message
102
+ phase?: 'user' | 'system' | 'assistant_partial' | 'assistant_final' | 'heartbeat'
103
+ runId?: string
104
+ }) => Promise<ExtensionBeforeMessageWriteResult | Message | void> | ExtensionBeforeMessageWriteResult | Message | void
105
+ afterToolExec?: (ctx: { session: Session; toolName: string; input: Record<string, unknown> | null; output: string }) => Promise<void> | void
106
+ onMessage?: (ctx: { session: Session; message: Message }) => Promise<void> | void
107
+ sessionStart?: (ctx: {
108
+ session: Session
109
+ resumedFrom?: string | null
110
+ }) => Promise<void> | void
111
+ sessionEnd?: (ctx: {
112
+ sessionId: string
113
+ session?: Session | null
114
+ messageCount: number
115
+ durationMs?: number
116
+ reason?: string | null
117
+ }) => Promise<void> | void
118
+ subagentSpawning?: (ctx: {
119
+ parentSessionId?: string | null
120
+ agentId: string
121
+ agentName: string
122
+ message: string
123
+ cwd: string
124
+ mode: 'run' | 'session'
125
+ threadRequested: boolean
126
+ }) => Promise<ExtensionSubagentSpawningResult | void> | ExtensionSubagentSpawningResult | void
127
+ subagentSpawned?: (ctx: {
128
+ parentSessionId?: string | null
129
+ childSessionId: string
130
+ agentId: string
131
+ agentName: string
132
+ runId: string
133
+ mode: 'run' | 'session'
134
+ threadRequested: boolean
135
+ }) => Promise<void> | void
136
+ subagentEnded?: (ctx: {
137
+ parentSessionId?: string | null
138
+ childSessionId: string
139
+ agentId: string
140
+ agentName: string
141
+ status: 'completed' | 'failed' | 'cancelled' | 'timed_out'
142
+ response?: string | null
143
+ error?: string | null
144
+ durationMs?: number
145
+ }) => Promise<void> | void
146
+
147
+ // Post-turn hook — fires after a full chat exchange (user message → agent response)
148
+ afterChatTurn?: (ctx: {
149
+ session: Session
150
+ message: string
151
+ response: string
152
+ source: string
153
+ internal: boolean
154
+ toolEvents?: MessageToolEvent[]
155
+ }) => Promise<void> | void
156
+
157
+ // Orchestration & Swarm Hooks
158
+ onTaskComplete?: (ctx: { taskId: string; result: unknown }) => Promise<void> | void
159
+ onAgentDelegation?: (ctx: { sourceAgentId: string; targetAgentId: string; task: string }) => Promise<void> | void
160
+
161
+ // Chat Middleware (Transform messages)
162
+ transformInboundMessage?: (ctx: { session: Session; text: string }) => Promise<string> | string
163
+ transformOutboundMessage?: (ctx: { session: Session; text: string }) => Promise<string> | string
164
+
165
+ // Context injection — return a markdown string to inject into the agent's state modifier, or null/undefined to skip
166
+ getAgentContext?: (ctx: { session: Session; enabledExtensions: string[]; message: string; history: Message[] }) => Promise<string | null | undefined> | string | null | undefined
167
+
168
+ // Self-description — returns a capability line for the system prompt (e.g., "I can remember things across conversations")
169
+ getCapabilityDescription?: () => string | null | undefined
170
+
171
+ // Operating guidance — returns operational hints for the agent when this extension is active
172
+ getOperatingGuidance?: () => string | string[] | null | undefined
173
+
174
+ // Approval guidance — returns approval-scoped instructions when this extension is active
175
+ getApprovalGuidance?: (ctx: {
176
+ approval: ApprovalRequest
177
+ phase: 'request' | 'resume' | 'connector_reminder'
178
+ approved?: boolean
179
+ }) => string | string[] | null | undefined
180
+ }
181
+
182
+ export interface ExtensionToolPlanning {
183
+ /**
184
+ * Capability tags that the harness can use for prompt guidance and tool routing.
185
+ * Examples: research.search, research.fetch, browser.capture, artifact.pdf,
186
+ * delivery.media, delivery.voice_note.
187
+ */
188
+ capabilities?: string[]
189
+ /**
190
+ * Concrete usage guidance that should be injected into the system prompt when
191
+ * this tool is enabled.
192
+ */
193
+ disciplineGuidance?: string[]
194
+ }
195
+
196
+ export interface ExtensionToolDef {
197
+ name: string
198
+ description: string
199
+ parameters: Record<string, unknown>
200
+ planning?: ExtensionToolPlanning
201
+ execute: (args: Record<string, unknown>, ctx: { session: Session; message: string }) => Promise<string | object> | string | object
202
+ }
203
+
204
+ export interface ExtensionSettingsField {
205
+ key: string
206
+ label: string
207
+ type: 'text' | 'number' | 'boolean' | 'select' | 'secret'
208
+ placeholder?: string
209
+ help?: string
210
+ options?: Array<{ value: string; label: string }>
211
+ defaultValue?: string | number | boolean
212
+ required?: boolean
213
+ }
214
+
215
+ export interface ExtensionUIDefinition {
216
+ sidebarItems?: Array<{
217
+ id: string
218
+ label: string
219
+ icon?: string
220
+ href: string
221
+ position?: 'top' | 'bottom'
222
+ }>
223
+ headerWidgets?: Array<{
224
+ id: string
225
+ label: string
226
+ icon?: string
227
+ }>
228
+ chatInputActions?: Array<{
229
+ id: string
230
+ label: string
231
+ icon?: string
232
+ tooltip?: string
233
+ action: 'message' | 'link' | 'tool'
234
+ value: string
235
+ }>
236
+ /** Settings fields declared by the extension, rendered in the extension settings panel */
237
+ settingsFields?: ExtensionSettingsField[]
238
+ /** Chat panels the extension provides (e.g., browser view, terminal) */
239
+ chatPanels?: Array<{
240
+ id: string
241
+ label: string
242
+ icon?: string
243
+ /** WS topic to subscribe to for updates (e.g., 'browser:{sessionId}') */
244
+ wsTopic?: string
245
+ }>
246
+ /** Badges to show on agent cards when this extension is enabled */
247
+ agentBadges?: Array<{
248
+ id: string
249
+ label: string
250
+ icon?: string
251
+ }>
252
+ }
253
+
254
+ export interface ExtensionProviderDefinition {
255
+ id: string
256
+ name: string
257
+ models: string[]
258
+ requiresApiKey: boolean
259
+ requiresEndpoint: boolean
260
+ defaultEndpoint?: string
261
+ streamChat: (opts: {
262
+ session: { id: string } & Record<string, unknown>
263
+ message: string
264
+ imagePath?: string
265
+ imageUrl?: string
266
+ apiKey?: string | null
267
+ systemPrompt?: string
268
+ write: (data: string) => void
269
+ active: Map<string, unknown>
270
+ loadHistory: (sessionId: string) => unknown[]
271
+ onUsage?: (usage: { inputTokens: number; outputTokens: number }) => void
272
+ signal?: AbortSignal
273
+ }) => Promise<string>
274
+ }
275
+
276
+ export interface ExtensionConnectorDefinition {
277
+ id: string
278
+ name: string
279
+ description: string
280
+ supportsBinaryMedia?: boolean
281
+ // For sending outbound
282
+ sendMessage?: (
283
+ channelId: string,
284
+ text: string,
285
+ options?: OutboundSendOptions,
286
+ ) => Promise<{ messageId?: string } | void>
287
+ // For polling/listening
288
+ startListener?: (onMessage: (msg: InboundMessage) => void) => Promise<() => void>
289
+ }
290
+
291
+ export interface Extension {
292
+ name: string
293
+ version?: string
294
+ description?: string
295
+ author?: string
296
+ openclaw?: boolean
297
+ enabledByDefault?: boolean
298
+ hooks?: ExtensionHooks
299
+ tools?: ExtensionToolDef[]
300
+ ui?: ExtensionUIDefinition
301
+ providers?: ExtensionProviderDefinition[]
302
+ connectors?: ExtensionConnectorDefinition[]
303
+ }
304
+
305
+ export interface ExtensionMeta {
306
+ name: string
307
+ description?: string
308
+ filename: string
309
+ enabled: boolean
310
+ isBuiltin?: boolean
311
+ author?: string
312
+ version?: string
313
+ source?: 'local' | 'manual' | 'marketplace'
314
+ sourceLabel?: ExtensionPublisherSource
315
+ installSource?: ExtensionInstallSource
316
+ sourceUrl?: string
317
+ openclaw?: boolean
318
+ failureCount?: number
319
+ lastFailureAt?: number
320
+ lastFailureStage?: string
321
+ lastFailureError?: string
322
+ autoDisabled?: boolean
323
+ toolCount?: number
324
+ hookCount?: number
325
+ hasUI?: boolean
326
+ providerCount?: number
327
+ connectorCount?: number
328
+ createdByAgentId?: string | null
329
+ settingsFields?: ExtensionSettingsField[]
330
+ hasDependencyManifest?: boolean
331
+ dependencyCount?: number
332
+ devDependencyCount?: number
333
+ packageManager?: ExtensionPackageManager
334
+ dependencyInstallStatus?: ExtensionDependencyInstallStatus
335
+ dependencyInstallError?: string
336
+ dependencyInstalledAt?: number
337
+ }
338
+
339
+ export type ExtensionPublisherSource =
340
+ | 'builtin'
341
+ | 'local'
342
+ | 'manual'
343
+ | 'swarmclaw'
344
+ | 'swarmforge'
345
+ | 'clawhub'
346
+
347
+ export type ExtensionCatalogSource =
348
+ | 'swarmclaw'
349
+ | 'swarmclaw-site'
350
+ | 'swarmforge'
351
+ | 'clawhub'
352
+
353
+ export type ExtensionInstallSource =
354
+ | 'builtin'
355
+ | 'local'
356
+ | 'manual'
357
+ | ExtensionCatalogSource
358
+
359
+ export type ExtensionPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun'
360
+ export type ExtensionDependencyInstallStatus = 'none' | 'ready' | 'installing' | 'installed' | 'error'
361
+
362
+ export interface MarketplaceExtension {
363
+ id: string
364
+ name: string
365
+ description: string
366
+ author: string
367
+ version: string
368
+ url: string
369
+ source?: ExtensionPublisherSource
370
+ catalogSource?: ExtensionCatalogSource
371
+ tags?: string[]
372
+ openclaw?: boolean
373
+ downloads?: number
374
+ }
375
+
376
+ export interface ExtensionInvocationRecord {
377
+ extensionId: string
378
+ toolName: string
379
+ inputTokens: number
380
+ outputTokens: number
381
+ }
382
+
383
+ export interface ExtensionDefinitionCost {
384
+ extensionId: string
385
+ estimatedTokens: number
386
+ }