@workclaw/openclaw-workclaw 1.0.23 → 1.0.26

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 (210) hide show
  1. package/dist/api.d.ts +4 -3
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +379 -3
  4. package/dist/channel-DSvR6Irx.js +50017 -0
  5. package/dist/cron-tasks-handler-C-mP3VmV.js +152 -0
  6. package/dist/index.d.ts +5 -4
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +2056 -232
  9. package/dist/jiti-4i2h0FGP.js +4814 -0
  10. package/dist/setup-entry.d.ts +2 -1
  11. package/dist/setup-entry.d.ts.map +1 -0
  12. package/dist/setup-entry.js +181 -11
  13. package/dist/src/accounts.d.ts +3 -2
  14. package/dist/src/accounts.d.ts.map +1 -0
  15. package/dist/src/api/accounts-api.d.ts +2 -1
  16. package/dist/src/api/accounts-api.d.ts.map +1 -0
  17. package/dist/src/api/prompts-api.d.ts +2 -1
  18. package/dist/src/api/prompts-api.d.ts.map +1 -0
  19. package/dist/src/api/session-api.d.ts +2 -1
  20. package/dist/src/api/session-api.d.ts.map +1 -0
  21. package/dist/src/api/skills-api.d.ts +2 -1
  22. package/dist/src/api/skills-api.d.ts.map +1 -0
  23. package/dist/src/api/workspace.d.ts +2 -1
  24. package/dist/src/api/workspace.d.ts.map +1 -0
  25. package/dist/src/channel.d.ts +3 -2
  26. package/dist/src/channel.d.ts.map +1 -0
  27. package/dist/src/config-schema.d.ts +1 -6
  28. package/dist/src/config-schema.d.ts.map +1 -0
  29. package/dist/src/connection/workclaw-client.d.ts +6 -4
  30. package/dist/src/connection/workclaw-client.d.ts.map +1 -0
  31. package/dist/src/gateway/agent-handlers.d.ts +3 -2
  32. package/dist/src/gateway/agent-handlers.d.ts.map +1 -0
  33. package/dist/src/gateway/config-writer.d.ts +3 -2
  34. package/dist/src/gateway/config-writer.d.ts.map +1 -0
  35. package/dist/src/gateway/cron-tasks-handler.d.ts +1 -0
  36. package/dist/src/gateway/cron-tasks-handler.d.ts.map +1 -0
  37. package/dist/src/gateway/message-context.d.ts +2 -1
  38. package/dist/src/gateway/message-context.d.ts.map +1 -0
  39. package/dist/src/gateway/message-dispatcher.d.ts +3 -4
  40. package/dist/src/gateway/message-dispatcher.d.ts.map +1 -0
  41. package/dist/src/gateway/reconnect.d.ts +3 -5
  42. package/dist/src/gateway/reconnect.d.ts.map +1 -0
  43. package/dist/src/gateway/skills-handler.d.ts +1 -0
  44. package/dist/src/gateway/skills-handler.d.ts.map +1 -0
  45. package/dist/src/gateway/skills-list-handler.d.ts +1 -0
  46. package/dist/src/gateway/skills-list-handler.d.ts.map +1 -0
  47. package/dist/src/gateway/tools-list-handler.d.ts +1 -0
  48. package/dist/src/gateway/tools-list-handler.d.ts.map +1 -0
  49. package/dist/src/gateway/workclaw-gateway.d.ts +4 -7
  50. package/dist/src/gateway/workclaw-gateway.d.ts.map +1 -0
  51. package/dist/src/media/upload.d.ts +1 -0
  52. package/dist/src/media/upload.d.ts.map +1 -0
  53. package/dist/src/outbound/index.d.ts +9 -6
  54. package/dist/src/outbound/index.d.ts.map +1 -0
  55. package/dist/src/outbound/workclaw-sender.d.ts +6 -4
  56. package/dist/src/outbound/workclaw-sender.d.ts.map +1 -0
  57. package/dist/src/runtime.d.ts +11 -9
  58. package/dist/src/runtime.d.ts.map +1 -0
  59. package/dist/src/secret-contract-api.d.ts +1 -0
  60. package/dist/src/secret-contract-api.d.ts.map +1 -0
  61. package/dist/src/send.d.ts +2 -1
  62. package/dist/src/send.d.ts.map +1 -0
  63. package/dist/src/setup-api.d.ts +4 -3
  64. package/dist/src/setup-api.d.ts.map +1 -0
  65. package/dist/src/setup-core.d.ts +2 -1
  66. package/dist/src/setup-core.d.ts.map +1 -0
  67. package/dist/src/setup-surface.d.ts +3 -2
  68. package/dist/src/setup-surface.d.ts.map +1 -0
  69. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts +2 -4
  70. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts.map +1 -0
  71. package/dist/src/tools/openclaw-workclaw-cron/index.d.ts +1 -0
  72. package/dist/src/tools/openclaw-workclaw-cron/index.d.ts.map +1 -0
  73. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.d.ts +2 -4
  74. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.d.ts.map +1 -0
  75. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.d.ts +2 -4
  76. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.d.ts.map +1 -0
  77. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.d.ts +2 -4
  78. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.d.ts.map +1 -0
  79. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.d.ts +2 -4
  80. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.d.ts.map +1 -0
  81. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.d.ts +2 -4
  82. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.d.ts.map +1 -0
  83. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.d.ts +2 -4
  84. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.d.ts.map +1 -0
  85. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.d.ts +2 -6
  86. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.d.ts.map +1 -0
  87. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.d.ts +2 -4
  88. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.d.ts.map +1 -0
  89. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.d.ts +2 -4
  90. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.d.ts.map +1 -0
  91. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.d.ts +2 -4
  92. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.d.ts.map +1 -0
  93. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.d.ts +2 -4
  94. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.d.ts.map +1 -0
  95. package/dist/src/tools/openclaw-workclaw-cron/types/index.d.ts +1 -0
  96. package/dist/src/tools/openclaw-workclaw-cron/types/index.d.ts.map +1 -0
  97. package/dist/src/tools/openclaw-workclaw-cron/utils/index.d.ts +1 -0
  98. package/dist/src/tools/openclaw-workclaw-cron/utils/index.d.ts.map +1 -0
  99. package/dist/src/tools/openclaw-workclaw-system/index.d.ts +1 -0
  100. package/dist/src/tools/openclaw-workclaw-system/index.d.ts.map +1 -0
  101. package/dist/src/tools/openclaw-workclaw-system/src/get/index.d.ts +2 -4
  102. package/dist/src/tools/openclaw-workclaw-system/src/get/index.d.ts.map +1 -0
  103. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts +2 -4
  104. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts.map +1 -0
  105. package/dist/src/types.d.ts +7 -7
  106. package/dist/src/types.d.ts.map +1 -0
  107. package/dist/src/utils/content.d.ts +1 -0
  108. package/dist/src/utils/content.d.ts.map +1 -0
  109. package/openclaw.plugin.json +6 -0
  110. package/package.json +69 -45
  111. package/api.ts +0 -3
  112. package/dist/src/accounts.js +0 -279
  113. package/dist/src/api/accounts-api.js +0 -130
  114. package/dist/src/api/prompts-api.js +0 -103
  115. package/dist/src/api/session-api.js +0 -207
  116. package/dist/src/api/skills-api.js +0 -64
  117. package/dist/src/api/workspace.js +0 -30
  118. package/dist/src/channel.js +0 -199
  119. package/dist/src/config-schema.js +0 -56
  120. package/dist/src/connection/workclaw-client.js +0 -351
  121. package/dist/src/gateway/agent-handlers.js +0 -433
  122. package/dist/src/gateway/config-writer.js +0 -302
  123. package/dist/src/gateway/cron-tasks-handler.js +0 -188
  124. package/dist/src/gateway/message-context.js +0 -509
  125. package/dist/src/gateway/message-dispatcher.js +0 -572
  126. package/dist/src/gateway/reconnect.js +0 -210
  127. package/dist/src/gateway/skills-handler.js +0 -615
  128. package/dist/src/gateway/skills-list-handler.js +0 -233
  129. package/dist/src/gateway/tools-list-handler.js +0 -101
  130. package/dist/src/gateway/workclaw-gateway.js +0 -237
  131. package/dist/src/media/upload.js +0 -125
  132. package/dist/src/outbound/index.js +0 -123
  133. package/dist/src/outbound/workclaw-sender.js +0 -95
  134. package/dist/src/runtime.js +0 -374
  135. package/dist/src/secret-contract-api.js +0 -4
  136. package/dist/src/send.js +0 -1
  137. package/dist/src/setup-api.js +0 -3
  138. package/dist/src/setup-core.js +0 -13
  139. package/dist/src/setup-surface.js +0 -363
  140. package/dist/src/tools/openclaw-workclaw-cron/api/index.js +0 -209
  141. package/dist/src/tools/openclaw-workclaw-cron/index.js +0 -33
  142. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.js +0 -152
  143. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.js +0 -162
  144. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.js +0 -80
  145. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.js +0 -107
  146. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.js +0 -80
  147. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.js +0 -107
  148. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.js +0 -127
  149. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.js +0 -87
  150. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.js +0 -107
  151. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.js +0 -164
  152. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.js +0 -135
  153. package/dist/src/tools/openclaw-workclaw-cron/types/index.js +0 -4
  154. package/dist/src/tools/openclaw-workclaw-cron/utils/index.js +0 -122
  155. package/dist/src/tools/openclaw-workclaw-system/index.js +0 -15
  156. package/dist/src/tools/openclaw-workclaw-system/src/get/index.js +0 -64
  157. package/dist/src/tools/openclaw-workclaw-system/src/token/index.js +0 -78
  158. package/dist/src/types.js +0 -1
  159. package/dist/src/utils/content.js +0 -38
  160. package/index.ts +0 -325
  161. package/setup-entry.ts +0 -13
  162. package/src/accounts.ts +0 -360
  163. package/src/api/accounts-api.ts +0 -156
  164. package/src/api/prompts-api.ts +0 -122
  165. package/src/api/session-api.ts +0 -246
  166. package/src/api/skills-api.ts +0 -74
  167. package/src/api/workspace.ts +0 -45
  168. package/src/channel.ts +0 -226
  169. package/src/config-schema.ts +0 -60
  170. package/src/connection/workclaw-client.ts +0 -618
  171. package/src/gateway/agent-handlers.ts +0 -551
  172. package/src/gateway/config-writer.ts +0 -378
  173. package/src/gateway/cron-tasks-handler.ts +0 -230
  174. package/src/gateway/message-context.ts +0 -645
  175. package/src/gateway/message-dispatcher.ts +0 -688
  176. package/src/gateway/reconnect.ts +0 -260
  177. package/src/gateway/skills-handler.ts +0 -805
  178. package/src/gateway/skills-list-handler.ts +0 -332
  179. package/src/gateway/tools-list-handler.ts +0 -161
  180. package/src/gateway/workclaw-gateway.ts +0 -298
  181. package/src/media/upload.ts +0 -168
  182. package/src/outbound/index.ts +0 -191
  183. package/src/outbound/workclaw-sender.ts +0 -161
  184. package/src/runtime.ts +0 -520
  185. package/src/secret-contract-api.ts +0 -4
  186. package/src/send.ts +0 -1
  187. package/src/setup-api.ts +0 -3
  188. package/src/setup-core.ts +0 -25
  189. package/src/setup-surface.ts +0 -498
  190. package/src/tools/openclaw-workclaw-cron/api/index.ts +0 -326
  191. package/src/tools/openclaw-workclaw-cron/index.ts +0 -39
  192. package/src/tools/openclaw-workclaw-cron/src/add/params.ts +0 -177
  193. package/src/tools/openclaw-workclaw-cron/src/add/sync.ts +0 -188
  194. package/src/tools/openclaw-workclaw-cron/src/disable/params.ts +0 -100
  195. package/src/tools/openclaw-workclaw-cron/src/disable/sync.ts +0 -127
  196. package/src/tools/openclaw-workclaw-cron/src/enable/params.ts +0 -100
  197. package/src/tools/openclaw-workclaw-cron/src/enable/sync.ts +0 -127
  198. package/src/tools/openclaw-workclaw-cron/src/notify/sync.ts +0 -148
  199. package/src/tools/openclaw-workclaw-cron/src/remove/params.ts +0 -109
  200. package/src/tools/openclaw-workclaw-cron/src/remove/sync.ts +0 -127
  201. package/src/tools/openclaw-workclaw-cron/src/update/params.ts +0 -195
  202. package/src/tools/openclaw-workclaw-cron/src/update/sync.ts +0 -161
  203. package/src/tools/openclaw-workclaw-cron/types/index.ts +0 -55
  204. package/src/tools/openclaw-workclaw-cron/utils/index.ts +0 -141
  205. package/src/tools/openclaw-workclaw-system/index.ts +0 -17
  206. package/src/tools/openclaw-workclaw-system/src/get/index.ts +0 -77
  207. package/src/tools/openclaw-workclaw-system/src/token/index.ts +0 -93
  208. package/src/types.ts +0 -50
  209. package/src/utils/content.ts +0 -40
  210. package/tsconfig.json +0 -34
@@ -1,688 +0,0 @@
1
- /**
2
- * Message Dispatcher - handles all WorkClaw WebSocket message types
3
- */
4
-
5
- import type { ResolvedWorkclawAccount, WorkClawAccountConfig, WorkClawBaseConfig } from '../types.js'
6
- import type { InboundMessage, ParseWorkClawResult } from './message-context.js'
7
-
8
- import { maybeResolveTextAlias, resolveNativeCommandSessionTargets } from 'openclaw/plugin-sdk/command-auth'
9
- import { request } from 'undici'
10
- import { resolveAccountByUserIdAndAgentId, resolveWorkclawAccountWithCache } from '../accounts.js'
11
- import { getWorkclawAccessToken, getWorkclawModelConfigByAppKey } from '../connection/workclaw-client.js'
12
- import { sendMessageWorkclaw } from '../outbound/index.js'
13
- import { getWorkclawRuntime, getWorkclawWsConnection, setToolContext } from '../runtime.js'
14
-
15
- import { handleAgentCreated, handleAgentDeleted, handleAgentUpdated } from './agent-handlers.js'
16
- import { initWorkclawAgent, saveOpenConversationId } from './config-writer.js'
17
- import { buildInboundContext, parseWorkClawMessage } from './message-context.js'
18
-
19
- import { handleSkillsEvent } from './skills-handler.js'
20
- import { handleSkillsListEvent as doHandleSkillsListEvent } from './skills-list-handler.js'
21
- import { handleToolsListEvent as doHandleToolsListEvent } from './tools-list-handler.js'
22
-
23
- export interface MessageDispatcherContext {
24
- accountId: string
25
- account: ResolvedWorkclawAccount
26
- cfg: any
27
- baseConfig: WorkClawBaseConfig
28
- accountConfig: WorkClawAccountConfig
29
- log?: {
30
- info?: (msg: string) => void
31
- warn?: (msg: string) => void
32
- error?: (msg: string) => void
33
- debug?: (msg: string) => void
34
- }
35
- scheduleReconnect: () => void
36
- }
37
-
38
- /** Log an error safely */
39
- function logError(log: MessageDispatcherContext['log'], context: string, err: unknown): void {
40
- const errAny = err as { stack?: string }
41
- const stack = typeof errAny?.stack === 'string' ? `\nStack: ${errAny.stack}` : ''
42
- log?.error?.(`Dispatcher ${context}: ${String(err)}${stack}`)
43
- }
44
-
45
- // ---------------------------------------------------------------------------
46
- // Individual message handlers
47
- // ---------------------------------------------------------------------------
48
-
49
- async function handlePing(ctx: MessageDispatcherContext, result: ParseWorkClawResult): Promise<void> {
50
- const { accountId, log } = ctx
51
- const ws = getWorkclawWsConnection(accountId)
52
- if (!ws)
53
- return
54
-
55
- try {
56
- const pongResponse = {
57
- code: 200,
58
- message: 'pong',
59
- metadata: { contentType: 'application/json' },
60
- data: JSON.stringify(result.pongData),
61
- }
62
- ws.send(JSON.stringify(pongResponse))
63
- log?.debug?.(`pong`)
64
- }
65
- catch (err) {
66
- logError(log, 'Failed to send pong', err)
67
- }
68
- }
69
-
70
- async function handleDisconnect(ctx: MessageDispatcherContext): Promise<void> {
71
- const { accountId, log, scheduleReconnect } = ctx
72
- const ws = getWorkclawWsConnection(accountId)
73
- if (ws) {
74
- try {
75
- ws.close()
76
- log?.info?.(`Closed WebSocket due to disconnect command`)
77
- }
78
- catch (err) {
79
- logError(log, 'Failed to close WebSocket', err)
80
- }
81
- }
82
- else {
83
- log?.info?.(`WebSocket already cleared, triggering reconnect...`)
84
- scheduleReconnect()
85
- }
86
- }
87
-
88
- async function handleAgentEvent(
89
- ctx: MessageDispatcherContext,
90
- result: ParseWorkClawResult,
91
- ): Promise<void> {
92
- const { cfg, log, baseConfig, accountId } = ctx
93
- const eventData = result.eventData
94
- if (!eventData) {
95
- log?.warn?.(`Received ${result.type} event but no data`)
96
- return
97
- }
98
-
99
- const agentId = String(eventData.id || '')
100
- const userId = String(eventData.futureId || '')
101
-
102
- if (!agentId) {
103
- log?.warn?.(`Received ${result.type} event but missing agent id`)
104
- return
105
- }
106
-
107
- log?.info?.(`Processing ${result.type} event for agent ${agentId}, userId: ${userId}`)
108
-
109
- const accountData = {
110
- agentId,
111
- userId,
112
- nickName: eventData.nickName,
113
- phone: eventData.phone,
114
- status: eventData.status,
115
- introduction: eventData.introduction,
116
- name: eventData.name,
117
- tip: eventData.tip,
118
- characterSettings: eventData.characterSettings,
119
- personFeatures: eventData.personFeatures,
120
- workFeatures: eventData.workFeatures,
121
- learningFeatures: eventData.learningFeatures,
122
- socializeFeatures: eventData.socializeFeatures,
123
- job: eventData.job,
124
- city: eventData.city,
125
- }
126
-
127
- switch (result.type) {
128
- case 'agent_created':
129
- await handleAgentCreated(accountData, cfg, log)
130
- handleAgentCreatedMessage(baseConfig, agentId, accountId, log)
131
- break
132
- case 'agent_updated':
133
- await handleAgentUpdated(accountData, cfg, log)
134
- break
135
- case 'agent_deleted':
136
- await handleAgentDeleted(accountData, cfg, log)
137
- break
138
- }
139
- }
140
-
141
- async function handleSkillsProcessingEvent(ctx: MessageDispatcherContext, result: ParseWorkClawResult): Promise<void> {
142
- const { accountId, baseConfig, log } = ctx
143
- if (!result.eventData)
144
- return
145
- try {
146
- const connConfig = {
147
- baseUrl: baseConfig.baseUrl || '',
148
- websocketUrl: baseConfig.websocketUrl,
149
- appKey: baseConfig.appKey,
150
- appSecret: baseConfig.appSecret,
151
- localIp: baseConfig.localIp,
152
- allowInsecureTls: baseConfig.allowInsecureTls,
153
- requestTimeout: baseConfig.requestTimeout,
154
- }
155
- const tokenCacheKey = baseConfig.appKey || accountId
156
- const token = await getWorkclawAccessToken(tokenCacheKey, connConfig)
157
- await handleSkillsEvent(result.eventData, token, connConfig.baseUrl, connConfig.appKey || accountId, log)
158
- }
159
- catch (err) {
160
- logError(log, 'handleSkillsEvent failed', err)
161
- }
162
- }
163
-
164
- async function handleToolsListEvent(ctx: MessageDispatcherContext, result: ParseWorkClawResult): Promise<void> {
165
- const { accountId, baseConfig, log } = ctx
166
- if (!result.eventData)
167
- return
168
- try {
169
- const connConfig = {
170
- baseUrl: baseConfig.baseUrl || '',
171
- websocketUrl: baseConfig.websocketUrl,
172
- appKey: baseConfig.appKey,
173
- appSecret: baseConfig.appSecret,
174
- localIp: baseConfig.localIp,
175
- allowInsecureTls: baseConfig.allowInsecureTls,
176
- requestTimeout: baseConfig.requestTimeout,
177
- }
178
- const tokenCacheKey = baseConfig.appKey || accountId
179
- const token = await getWorkclawAccessToken(tokenCacheKey, connConfig)
180
- await doHandleToolsListEvent(result.eventData, connConfig.baseUrl, token, log)
181
- }
182
- catch (err) {
183
- logError(log, 'handleToolsListEvent failed', err)
184
- }
185
- }
186
-
187
- async function handleSkillsListEvent(ctx: MessageDispatcherContext, result: ParseWorkClawResult): Promise<void> {
188
- const { accountId, baseConfig, log } = ctx
189
- if (!result.eventData)
190
- return
191
- try {
192
- const connConfig = {
193
- baseUrl: baseConfig.baseUrl || '',
194
- websocketUrl: baseConfig.websocketUrl,
195
- appKey: baseConfig.appKey,
196
- appSecret: baseConfig.appSecret,
197
- localIp: baseConfig.localIp,
198
- allowInsecureTls: baseConfig.allowInsecureTls,
199
- requestTimeout: baseConfig.requestTimeout,
200
- }
201
- const tokenCacheKey = baseConfig.appKey || accountId
202
- const token = await getWorkclawAccessToken(tokenCacheKey, connConfig)
203
- await doHandleSkillsListEvent(result.eventData, connConfig.baseUrl, token, log)
204
- }
205
- catch (err) {
206
- logError(log, 'handleSkillsListEvent failed', err)
207
- }
208
- }
209
-
210
- async function handleInitAgentEvent(
211
- ctx: MessageDispatcherContext,
212
- result: ParseWorkClawResult,
213
- ): Promise<void> {
214
- const { accountId, cfg, baseConfig, log } = ctx
215
- const initStartedAt = Date.now()
216
- const eventData = result.eventData
217
-
218
- if (!eventData) {
219
- log?.warn?.(`init_agent received but no data`)
220
- return
221
- }
222
-
223
- log?.info?.(
224
- `init_agent accountId=${accountId} eventDataType=${typeof eventData} preview=${JSON.stringify(eventData).slice(0, 200)}`,
225
- )
226
-
227
- const connConfig = {
228
- baseUrl: baseConfig.baseUrl || '',
229
- websocketUrl: baseConfig.websocketUrl,
230
- appKey: baseConfig.appKey,
231
- appSecret: baseConfig.appSecret,
232
- localIp: baseConfig.localIp,
233
- allowInsecureTls: baseConfig.allowInsecureTls,
234
- requestTimeout: baseConfig.requestTimeout,
235
- }
236
-
237
- // Fetch apiKey and init agent config in one write
238
- try {
239
- const tokenCacheKey = baseConfig.appKey || accountId
240
- const { baseUrl: modelBaseUrl, apiKey } = await getWorkclawModelConfigByAppKey(tokenCacheKey, connConfig)
241
- const maskedKey = apiKey ? `${String(apiKey).slice(0, 6)}...(${String(apiKey).length})` : 'missing'
242
-
243
- log?.info?.(`init_agent model fetched baseUrl=${modelBaseUrl} apiKey=${maskedKey}`)
244
-
245
- const agentId = String(eventData?.id || eventData?.agentId || '')
246
- const userId = String(eventData?.futureId || eventData?.userId || '')
247
-
248
- await initWorkclawAgent({ apiKey, agentId, userId, accountId: 'default' }, cfg, log)
249
- log?.info?.(`init_agent config saved elapsedMs=${Date.now() - initStartedAt}`)
250
- }
251
- catch (err) {
252
- logError(log, 'init_agent failed', err)
253
- }
254
-
255
- log?.info?.(`init_agent handled elapsedMs=${Date.now() - initStartedAt}`)
256
- }
257
-
258
- async function handleCronTaskEvent(ctx: MessageDispatcherContext, result: ParseWorkClawResult): Promise<void> {
259
- const { accountId, baseConfig, log } = ctx
260
- if (!result.cronTaskEvent)
261
- return
262
- try {
263
- const { handleCronTaskEvent } = await import('./cron-tasks-handler.js')
264
- const connConfig = {
265
- baseUrl: baseConfig.baseUrl || '',
266
- websocketUrl: baseConfig.websocketUrl,
267
- appKey: baseConfig.appKey,
268
- appSecret: baseConfig.appSecret,
269
- localIp: baseConfig.localIp,
270
- allowInsecureTls: baseConfig.allowInsecureTls,
271
- requestTimeout: baseConfig.requestTimeout,
272
- }
273
- const tokenCacheKey = baseConfig.appKey || accountId
274
- const token = await getWorkclawAccessToken(tokenCacheKey, connConfig)
275
- await handleCronTaskEvent(result.cronTaskEvent, token, connConfig.baseUrl, connConfig.appKey || accountId, log)
276
- }
277
- catch (err) {
278
- logError(log, 'handleCronTaskEvent failed', err)
279
- }
280
- }
281
-
282
- async function handleAgentMessage(
283
- ctx: MessageDispatcherContext,
284
- data: string,
285
- result: ParseWorkClawResult,
286
- ): Promise<void> {
287
- const { accountId, account, cfg, accountConfig, log } = ctx
288
- const { message } = result
289
- if (!message)
290
- return
291
-
292
- // 这里的msgAgentId是云平台的agentId
293
- const { text, userId, openConversationId, messageId: parsedMessageId, agentId: msgAgentId } = message
294
-
295
- // Resolve account from message
296
- let messageAccountId = accountId
297
- let messageAccount = account
298
-
299
- if (userId && msgAgentId) {
300
- const resolvedAccountId = resolveAccountByUserIdAndAgentId(cfg, String(userId), String(msgAgentId))
301
- if (resolvedAccountId) {
302
- const resolved = resolveWorkclawAccountWithCache({ cfg, accountId: resolvedAccountId })
303
- messageAccountId = resolvedAccountId
304
- messageAccount = resolved
305
- log?.info?.(`Resolved account ${resolvedAccountId} from message (userId=${userId}, agentId=${msgAgentId})`)
306
- }
307
- else if (String(msgAgentId) !== String(accountConfig.agentId)) {
308
- log?.warn?.(`Account not found for userId=${userId}, agentId=${msgAgentId}, ignoring`)
309
- return
310
- }
311
- }
312
-
313
- const resolvedAccountConfig = messageAccount.config as unknown as WorkClawAccountConfig
314
- const msgAgentIdResolved = msgAgentId ?? accountConfig.agentId
315
-
316
- // Save openConversationId if new
317
- if (openConversationId && openConversationId !== resolvedAccountConfig.openConversationId) {
318
- try {
319
- await saveOpenConversationId(messageAccountId, userId, openConversationId, cfg, log)
320
- log?.info?.(`Saved openConversationId ${openConversationId} to account ${messageAccountId}`)
321
- }
322
- catch (err) {
323
- logError(log, 'saveOpenConversationId failed', err)
324
- }
325
- }
326
-
327
- const resolvedOpenConversationId = openConversationId || resolvedAccountConfig.openConversationId || ''
328
- const to = userId
329
- const bodyText = text || data
330
-
331
- if (!bodyText) {
332
- log?.warn?.(`Empty body, ignoring`)
333
- return
334
- }
335
-
336
- // Route via bindings
337
- const bindings = cfg?.bindings ?? []
338
- let targetAgentId = 'default'
339
- const matchedBinding = bindings.find((binding: any) => {
340
- const match = binding?.match
341
- if (!match || match.channel !== 'openclaw-workclaw')
342
- return false
343
- return match.accountId === messageAccountId || match.accountId === '*'
344
- })
345
- if (matchedBinding) {
346
- targetAgentId = matchedBinding.agentId
347
- log?.info?.(`Routing to agent ${targetAgentId} via binding (account: ${messageAccountId})`)
348
- }
349
-
350
- if (!targetAgentId) {
351
- log?.warn?.(`Missing target, ignoring`)
352
- return
353
- }
354
-
355
- // 构建用于解析 sessionKey 的消息对象
356
- // to = agentId (智能体/机器人), from = userId (用户)
357
- const attachments = message.attachments
358
- const inboundMessage: InboundMessage = {
359
- text: bodyText,
360
- to,
361
- from: userId,
362
- chatType: 'dm',
363
- messageId: parsedMessageId,
364
- rawPayload: data,
365
- timestamp: Date.now(),
366
- attachments,
367
- }
368
- log?.info?.(`handleAgentMessage: text=${bodyText?.substring(0, 50)}, attachments=${attachments?.length || 0}, rawPayload=${data.substring(0, 300)}`)
369
- const pluginRuntime = getWorkclawRuntime()
370
-
371
- // 检测是否是框架命令(如 /new)
372
- const textForCommandCheck = bodyText?.replace(/^\[引用[^\]]*\]\s*/, '').trim() || ''
373
- const resolvedCommand = maybeResolveTextAlias(textForCommandCheck, messageAccount.config as any)
374
- const isFrameworkCommand = resolvedCommand !== null
375
- if (isFrameworkCommand) {
376
- log?.info?.(`[DELIVER] Framework command detected: ${bodyText}, will set CommandSource=native`)
377
- }
378
-
379
- // 使用扩展后的 buildInboundContext,它会处理完整的 session 流程
380
- const finalized = await buildInboundContext(
381
- inboundMessage,
382
- messageAccountId,
383
- messageAccount.config,
384
- targetAgentId,
385
- pluginRuntime,
386
- true,
387
- log,
388
- )
389
-
390
- // 如果是框架命令,设置 CommandSource 等字段,让 OpenClaw 框架识别为原生命令
391
- if (isFrameworkCommand) {
392
- const targetSessionKey = finalized.SessionKey as string
393
- const { sessionKey: commandSessionKey, commandTargetSessionKey } = resolveNativeCommandSessionTargets({
394
- agentId: targetAgentId,
395
- sessionPrefix: 'openclaw-workclaw:new',
396
- userId: String(userId ?? ''),
397
- targetSessionKey,
398
- });
399
- (finalized as any).SessionKey = commandSessionKey;
400
- (finalized as any).CommandTargetSessionKey = commandTargetSessionKey;
401
- (finalized as any).CommandSource = 'native';
402
- (finalized as any).CommandAuthorized = true
403
- log?.info?.(`[DELIVER] Set CommandSource=native, commandSessionKey=${commandSessionKey}, targetSessionKey=${targetSessionKey}`)
404
- }
405
-
406
- // 维护当前工具名称状态
407
- let currentToolName: string | null = null
408
- // 追踪是否有文本被 deliver 过
409
- let textDelivered = false
410
-
411
- // 发送工具消息的辅助函数
412
- const sendToolMessage = async (text: string, isStart: boolean = false) => {
413
- try {
414
- await sendMessageWorkclaw({
415
- cfg,
416
- to,
417
- text,
418
- accountId: messageAccountId,
419
- openConversationId: resolvedOpenConversationId,
420
- agentId: msgAgentIdResolved,
421
- replyToMessageId: parsedMessageId,
422
- last: false,
423
- source: 'deliver',
424
- })
425
- }
426
- catch (err) {
427
- logError(log, isStart ? 'Tool start message send failed' : 'Tool result message send failed', err)
428
- }
429
- }
430
-
431
- await pluginRuntime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
432
- ctx: finalized,
433
- cfg,
434
- replyOptions: {
435
- onAgentRunStart(runId: string) {
436
- // 保存 runId 和 ctx 的关联,供 hook 使用
437
- setToolContext(runId, {
438
- target: targetAgentId,
439
- replyToMessageId: parsedMessageId,
440
- openConversationId: resolvedOpenConversationId,
441
- accountId: messageAccountId,
442
- agentId: String(msgAgentIdResolved),
443
- sessionKey: (finalized.SessionKey as string) || '',
444
- })
445
- log?.info?.(`[AGENT] onAgentRunStart: runId=${runId} target=${targetAgentId}`)
446
- },
447
- /* onToolStart(payload) {
448
- log?.info?.(`[AGENT] onToolStart: ${JSON.stringify(payload)}`);
449
- if (payload.phase === "start") {
450
- currentToolName = payload.name ?? null;
451
- const hint = getToolStartHint(currentToolName);
452
- log?.info?.(`[TOOL] Starting tool: ${currentToolName}, sending hint: ${hint}`);
453
- sendToolMessage(hint, true).catch((err) => {
454
- logError(log, "Tool start hint send failed", err);
455
- });
456
- }
457
- } */
458
- },
459
- dispatcherOptions: {
460
- deliver: async (payload: any, info?: any) => {
461
- const resolvedReplyToId = payload?.replyToId || parsedMessageId
462
- const textOut = String(payload.text ?? payload.body ?? '')
463
- const target = to || String(payload.to ?? '')
464
- const kind = info?.kind
465
-
466
- if (!target) {
467
- log?.warn?.(`[DELIVER] skip: no target`)
468
- return
469
- }
470
-
471
- if (kind === 'tool') {
472
- // 工具结果已在工具 hook 中处理,此处跳过避免重复
473
- return
474
- }
475
-
476
- if (!textOut.trim()) {
477
- log?.warn?.(`[DELIVER] skip: empty text (kind=${kind})`)
478
- return
479
- }
480
-
481
- // 处理工具类型的 deliver
482
- /* if (info?.kind === "tool") {
483
- // log?.info?.(`[DELIVER] tool reply: ${JSON.stringify(payload)}`);
484
- const toolText = payload.text ?? "";
485
- if (toolText.trim()) {
486
- // 使用 formattedToolOutput 格式发送
487
- try {
488
- await sendMessageWorkclaw({
489
- cfg,
490
- to: targetAgentId,
491
- text: JSON.stringify({
492
- name: currentToolName || "Unknown",
493
- content: toolText,
494
- state: "result",
495
- }),
496
- msgType: "26",
497
- accountId: messageAccountId,
498
- openConversationId: resolvedOpenConversationId,
499
- agentId: msgAgentIdResolved,
500
- replyToMessageId: parsedMessageId,
501
- });
502
- } catch (err) {
503
- logError(log, "Tool result send failed", err);
504
- }
505
- }
506
- return;
507
- } */
508
-
509
- // last: true 统一由最后的 fallback 兜底发送,deliver 阶段全部传 false 避免重复触发
510
- try {
511
- const result = await sendMessageWorkclaw({
512
- cfg,
513
- to: target,
514
- text: textOut,
515
- accountId: messageAccountId,
516
- openConversationId: resolvedOpenConversationId,
517
- agentId: msgAgentIdResolved,
518
- replyToMessageId: resolvedReplyToId,
519
- last: false,
520
- source: 'deliver',
521
- })
522
- textDelivered = true
523
- log?.info?.(`[DELIVER] sent "${textOut.substring(0, 80)}" (last=false) kind=${kind} msgId=${result.messageId}`)
524
- }
525
- catch (err) {
526
- logError(log, 'Reply send failed', err)
527
- throw err
528
- }
529
- },
530
- },
531
- })
532
-
533
- currentToolName = null
534
-
535
- // 原始消息是命令但 AI 没有回复文本时,发送"命令已执行"确认
536
- if (!textDelivered && bodyText?.startsWith('/')) {
537
- log?.info?.(`[DELIVER] command ${bodyText} executed with no text reply, sending confirmation`)
538
- try {
539
- await sendMessageWorkclaw({
540
- cfg,
541
- to: to || String(userId || ''),
542
- text: `${bodyText} 已执行`,
543
- accountId: messageAccountId,
544
- openConversationId: resolvedOpenConversationId,
545
- agentId: msgAgentIdResolved,
546
- replyToMessageId: parsedMessageId,
547
- last: false,
548
- source: 'deliver',
549
- })
550
- }
551
- catch (err) {
552
- logError(log, 'Command confirmation send failed', err)
553
- }
554
- }
555
-
556
- // last: true 结束信号:每次回复最后都发,确保对话结束
557
- log?.info?.(`[DELIVER] sending last=true end signal`)
558
- try {
559
- await sendMessageWorkclaw({
560
- cfg,
561
- to: to || String(userId || ''),
562
- text: '',
563
- accountId: messageAccountId,
564
- openConversationId: resolvedOpenConversationId,
565
- agentId: msgAgentIdResolved,
566
- replyToMessageId: parsedMessageId,
567
- last: true,
568
- source: 'deliver',
569
- })
570
- }
571
- catch (err) {
572
- const errStr = String(err)
573
- if (errStr.includes("content can't be empty")) {
574
- log?.info?.(`[DELIVER] last=true skipped (empty content not supported)`)
575
- }
576
- else {
577
- logError(log, 'last=true signal send failed', err)
578
- }
579
- }
580
- }
581
-
582
- // ---------------------------------------------------------------------------
583
- // Main dispatcher
584
- // ---------------------------------------------------------------------------
585
-
586
- export async function dispatchWorkclawMessage(
587
- data: string,
588
- ctx: MessageDispatcherContext,
589
- ): Promise<void> {
590
- const { log } = ctx
591
-
592
- const rawHasAuthToken
593
- = data.includes('authToken')
594
- || data.toLowerCase().includes('authorization')
595
- || data.toLowerCase().includes('bearer ')
596
- const rawPreview = data.length > 300 ? `${data.slice(0, 300)}...` : data
597
- /* log?.info?.(
598
- `Raw message bytes=${data.length} hasAuthToken=${rawHasAuthToken} preview=${rawPreview}`,
599
- ); */
600
-
601
- const result = parseWorkClawMessage(data, log)
602
- if (!result) {
603
- log?.warn?.(`Failed to parse message`)
604
- return
605
- }
606
-
607
- log?.info?.(`Message type=${result.type}`)
608
-
609
- switch (result.type) {
610
- case 'ping':
611
- await handlePing(ctx, result)
612
- return
613
-
614
- case 'disconnect':
615
- await handleDisconnect(ctx)
616
- return
617
-
618
- case 'agent_created':
619
- case 'agent_updated':
620
- case 'agent_deleted':
621
- await handleAgentEvent(ctx, result)
622
- return
623
-
624
- case 'skills_event':
625
- await handleSkillsProcessingEvent(ctx, result)
626
- return
627
-
628
- case 'tools_list':
629
- await handleToolsListEvent(ctx, result)
630
- return
631
-
632
- case 'skills_list':
633
- await handleSkillsListEvent(ctx, result)
634
- return
635
-
636
- case 'init_agent':
637
- await handleInitAgentEvent(ctx, result)
638
- return
639
-
640
- case 'cron_task_event':
641
- await handleCronTaskEvent(ctx, result)
642
- return
643
-
644
- case 'ignored':
645
- log?.info?.(`Ignoring message type=${result.type}`)
646
- return
647
-
648
- case 'agent_message':
649
- await handleAgentMessage(ctx, data, result)
650
- return
651
-
652
- default:
653
- log?.info?.(`Unknown message type: ${result.type}, ignoring`)
654
- }
655
- }
656
-
657
- // 创建成功回调
658
- async function handleAgentCreatedMessage(baseConfig: WorkClawBaseConfig, agentId: string, accountId: string, log?: any) {
659
- // 通知
660
- try {
661
- const base = baseConfig.baseUrl.replace(/\/$/, '') // 去掉末尾多余的 /
662
- const callbackUrl = `${base}/open-apis/instance/agent-created/status`
663
- const tokenCacheKey = baseConfig.appKey || accountId
664
- const callbackData = {
665
- agentId,
666
- success: true,
667
- }
668
-
669
- log?.info?.(`[AgentCreated] Calling callback API: ${callbackUrl}`)
670
- const token = await getWorkclawAccessToken(tokenCacheKey, baseConfig)
671
-
672
- const response = await request(callbackUrl, {
673
- method: 'POST',
674
- headers: {
675
- 'Content-Type': 'application/json',
676
- 'Authorization': `Bearer ${token}`,
677
- },
678
- body: JSON.stringify(callbackData),
679
- })
680
-
681
- const responseBody = await response.body.text()
682
- log?.info?.(`[AgentCreated] Callback API response: status=${response.statusCode}, body=${responseBody}`)
683
- }
684
- catch (callbackErr) {
685
- // 接口调用失败不影响主流程,只记录错误
686
- log?.error?.(`[AgentCreated] Callback API failed: ${String(callbackErr)}`)
687
- }
688
- }