@workclaw/openclaw-workclaw 1.0.25 → 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 (161) hide show
  1. package/dist/api.d.ts +4 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +379 -0
  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 +12 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +2088 -0
  9. package/dist/jiti-4i2h0FGP.js +4814 -0
  10. package/dist/setup-entry.d.ts +3 -0
  11. package/dist/setup-entry.d.ts.map +1 -0
  12. package/dist/setup-entry.js +182 -0
  13. package/dist/src/accounts.d.ts +67 -0
  14. package/dist/src/accounts.d.ts.map +1 -0
  15. package/dist/src/api/accounts-api.d.ts +3 -0
  16. package/dist/src/api/accounts-api.d.ts.map +1 -0
  17. package/dist/src/api/prompts-api.d.ts +3 -0
  18. package/dist/src/api/prompts-api.d.ts.map +1 -0
  19. package/dist/src/api/session-api.d.ts +3 -0
  20. package/dist/src/api/session-api.d.ts.map +1 -0
  21. package/dist/src/api/skills-api.d.ts +3 -0
  22. package/dist/src/api/skills-api.d.ts.map +1 -0
  23. package/dist/src/api/workspace.d.ts +4 -0
  24. package/dist/src/api/workspace.d.ts.map +1 -0
  25. package/dist/src/channel.d.ts +12 -0
  26. package/dist/src/channel.d.ts.map +1 -0
  27. package/dist/src/config-schema.d.ts +88 -0
  28. package/dist/src/config-schema.d.ts.map +1 -0
  29. package/dist/src/connection/workclaw-client.d.ts +149 -0
  30. package/dist/src/connection/workclaw-client.d.ts.map +1 -0
  31. package/dist/src/gateway/agent-handlers.d.ts +13 -0
  32. package/dist/src/gateway/agent-handlers.d.ts.map +1 -0
  33. package/dist/src/gateway/config-writer.d.ts +72 -0
  34. package/dist/src/gateway/config-writer.d.ts.map +1 -0
  35. package/dist/src/gateway/cron-tasks-handler.d.ts +20 -0
  36. package/dist/src/gateway/cron-tasks-handler.d.ts.map +1 -0
  37. package/dist/src/gateway/message-context.d.ts +81 -0
  38. package/dist/src/gateway/message-context.d.ts.map +1 -0
  39. package/dist/src/gateway/message-dispatcher.d.ts +17 -0
  40. package/dist/src/gateway/message-dispatcher.d.ts.map +1 -0
  41. package/dist/src/gateway/reconnect.d.ts +25 -0
  42. package/dist/src/gateway/reconnect.d.ts.map +1 -0
  43. package/dist/src/gateway/skills-handler.d.ts +30 -0
  44. package/dist/src/gateway/skills-handler.d.ts.map +1 -0
  45. package/dist/src/gateway/skills-list-handler.d.ts +28 -0
  46. package/dist/src/gateway/skills-list-handler.d.ts.map +1 -0
  47. package/dist/src/gateway/tools-list-handler.d.ts +31 -0
  48. package/dist/src/gateway/tools-list-handler.d.ts.map +1 -0
  49. package/dist/src/gateway/workclaw-gateway.d.ts +11 -0
  50. package/dist/src/gateway/workclaw-gateway.d.ts.map +1 -0
  51. package/dist/src/media/upload.d.ts +14 -0
  52. package/dist/src/media/upload.d.ts.map +1 -0
  53. package/dist/src/outbound/index.d.ts +39 -0
  54. package/dist/src/outbound/index.d.ts.map +1 -0
  55. package/dist/src/outbound/workclaw-sender.d.ts +38 -0
  56. package/dist/src/outbound/workclaw-sender.d.ts.map +1 -0
  57. package/dist/src/runtime.d.ts +118 -0
  58. package/dist/src/runtime.d.ts.map +1 -0
  59. package/dist/src/secret-contract-api.d.ts +5 -0
  60. package/dist/src/secret-contract-api.d.ts.map +1 -0
  61. package/{src/send.ts → 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 -0
  64. package/dist/src/setup-api.d.ts.map +1 -0
  65. package/dist/src/setup-core.d.ts +4 -0
  66. package/dist/src/setup-core.d.ts.map +1 -0
  67. package/dist/src/setup-surface.d.ts +8 -0
  68. package/dist/src/setup-surface.d.ts.map +1 -0
  69. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts +91 -0
  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 +11 -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 +14 -0
  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 +16 -0
  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 +12 -0
  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 +12 -0
  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 +12 -0
  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 +12 -0
  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 +13 -0
  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 +12 -0
  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 +12 -0
  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 +15 -0
  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 +16 -0
  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 +53 -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 +41 -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 +11 -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 +6 -0
  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 +6 -0
  104. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts.map +1 -0
  105. package/dist/src/types.d.ts +39 -0
  106. package/dist/src/types.d.ts.map +1 -0
  107. package/dist/src/utils/content.d.ts +16 -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/index.ts +0 -325
  113. package/setup-entry.ts +0 -13
  114. package/src/accounts.ts +0 -360
  115. package/src/api/accounts-api.ts +0 -156
  116. package/src/api/prompts-api.ts +0 -122
  117. package/src/api/session-api.ts +0 -246
  118. package/src/api/skills-api.ts +0 -74
  119. package/src/api/workspace.ts +0 -45
  120. package/src/channel.ts +0 -226
  121. package/src/config-schema.ts +0 -60
  122. package/src/connection/workclaw-client.ts +0 -618
  123. package/src/gateway/agent-handlers.ts +0 -551
  124. package/src/gateway/config-writer.ts +0 -378
  125. package/src/gateway/cron-tasks-handler.ts +0 -230
  126. package/src/gateway/message-context.ts +0 -645
  127. package/src/gateway/message-dispatcher.ts +0 -688
  128. package/src/gateway/reconnect.ts +0 -260
  129. package/src/gateway/skills-handler.ts +0 -805
  130. package/src/gateway/skills-list-handler.ts +0 -332
  131. package/src/gateway/tools-list-handler.ts +0 -161
  132. package/src/gateway/workclaw-gateway.ts +0 -304
  133. package/src/media/upload.ts +0 -168
  134. package/src/outbound/index.ts +0 -191
  135. package/src/outbound/workclaw-sender.ts +0 -161
  136. package/src/runtime.ts +0 -520
  137. package/src/secret-contract-api.ts +0 -4
  138. package/src/setup-api.ts +0 -3
  139. package/src/setup-core.ts +0 -25
  140. package/src/setup-surface.ts +0 -498
  141. package/src/tools/openclaw-workclaw-cron/api/index.ts +0 -326
  142. package/src/tools/openclaw-workclaw-cron/index.ts +0 -39
  143. package/src/tools/openclaw-workclaw-cron/src/add/params.ts +0 -177
  144. package/src/tools/openclaw-workclaw-cron/src/add/sync.ts +0 -188
  145. package/src/tools/openclaw-workclaw-cron/src/disable/params.ts +0 -100
  146. package/src/tools/openclaw-workclaw-cron/src/disable/sync.ts +0 -127
  147. package/src/tools/openclaw-workclaw-cron/src/enable/params.ts +0 -100
  148. package/src/tools/openclaw-workclaw-cron/src/enable/sync.ts +0 -127
  149. package/src/tools/openclaw-workclaw-cron/src/notify/sync.ts +0 -148
  150. package/src/tools/openclaw-workclaw-cron/src/remove/params.ts +0 -109
  151. package/src/tools/openclaw-workclaw-cron/src/remove/sync.ts +0 -127
  152. package/src/tools/openclaw-workclaw-cron/src/update/params.ts +0 -195
  153. package/src/tools/openclaw-workclaw-cron/src/update/sync.ts +0 -161
  154. package/src/tools/openclaw-workclaw-cron/types/index.ts +0 -55
  155. package/src/tools/openclaw-workclaw-cron/utils/index.ts +0 -141
  156. package/src/tools/openclaw-workclaw-system/index.ts +0 -17
  157. package/src/tools/openclaw-workclaw-system/src/get/index.ts +0 -77
  158. package/src/tools/openclaw-workclaw-system/src/token/index.ts +0 -93
  159. package/src/types.ts +0 -50
  160. package/src/utils/content.ts +0 -40
  161. package/tsconfig.json +0 -34
@@ -1,332 +0,0 @@
1
- import { execSync } from 'node:child_process'
2
-
3
- /**
4
- * Skills list handler - 处理 SKILLS_LIST 事件
5
- * 从 OpenClaw 获取 skills 列表并通过回调返回
6
- */
7
- import { readFileSync } from 'node:fs'
8
- import { existsSync, readdirSync, statSync } from 'node:fs'
9
- import { homedir } from 'node:os'
10
- import { join } from 'node:path'
11
-
12
- export interface SkillsListEvent {
13
- agentId: string | number
14
- userId: string | number
15
- }
16
-
17
- export interface SkillItem {
18
- typeStr: string
19
- name: string
20
- description: string
21
- }
22
-
23
- export interface SkillsListCallbackPayload {
24
- userId: number
25
- agentId: number
26
- dataList: SkillItem[]
27
- }
28
-
29
- /**
30
- * 处理 SKILLS_LIST 事件
31
- * @param event - 事件数据
32
- * @param baseUrl - 回调基础 URL
33
- * @param token - 鉴权 token
34
- * @param log 日志对象(可选)
35
- * @param {Function} [log.info] - 信息日志函数
36
- * @param {Function} [log.error] - 错误日志函数
37
- */
38
- export async function handleSkillsListEvent(
39
- event: SkillsListEvent,
40
- baseUrl: string,
41
- token: string,
42
- log?: {
43
- info?: (msg: string) => void
44
- error?: (msg: string) => void
45
- },
46
- ): Promise<void> {
47
- const agentId = Number(event.agentId)
48
- const userId = Number(event.userId)
49
-
50
- log?.info?.(`SkillsList: Handling SKILLS_LIST event for agentId: ${agentId}, userId: ${userId}`)
51
-
52
- try {
53
- // 从 OpenClaw 获取 skills 列表
54
- const skills = await fetchSkillsFromOpenClaw(agentId, userId, log)
55
-
56
- // 构建回调 payload
57
- const callbackPayload: SkillsListCallbackPayload = {
58
- userId,
59
- agentId,
60
- dataList: skills,
61
- }
62
-
63
- // 发送回调
64
- const callbackUrl = `${baseUrl.replace(/\/$/, '')}/open-apis/v1/claw/push/skills`
65
- await sendSkillsListCallback(callbackUrl, callbackPayload, token, log)
66
-
67
- log?.info?.(`SkillsList: Successfully processed SKILLS_LIST event, sent ${skills.length} skills`)
68
- }
69
- catch (error) {
70
- log?.error?.(`SkillsList: Failed to handle SKILLS_LIST event: ${String(error)}`)
71
- throw error
72
- }
73
- }
74
-
75
- /**
76
- * 从 OpenClaw 获取 skills 列表
77
- * 包括全局技能和智能体工作区的专有技能
78
- */
79
- async function fetchSkillsFromOpenClaw(
80
- agentId: number,
81
- _userId: number,
82
- log?: {
83
- info?: (msg: string) => void
84
- error?: (msg: string) => void
85
- },
86
- ): Promise<SkillItem[]> {
87
- log?.info?.(`SkillsList: Fetching skills from OpenClaw for agentId: ${agentId}`)
88
-
89
- try {
90
- // 使用 OpenClaw CLI 获取 skills 列表(全局技能)
91
- const result = execSync('openclaw skills list', {
92
- encoding: 'utf-8',
93
- timeout: 30000, // 30秒超时
94
- })
95
-
96
- // 解析输出
97
- const globalSkills = parseSkillsListOutput(result)
98
-
99
- // 检查智能体工作区中的专有技能
100
- const agentWorkspaceSkills = await fetchAgentWorkspaceSkills(agentId, log)
101
-
102
- // 合并技能列表,去重
103
- const allSkills = mergeSkills(globalSkills, agentWorkspaceSkills)
104
-
105
- log?.info?.(`SkillsList: Found ${allSkills.length} skills (${globalSkills.length} global, ${agentWorkspaceSkills.length} agent-specific)`)
106
- return allSkills
107
- }
108
- catch (error) {
109
- log?.error?.(`SkillsList: Error fetching skills: ${String(error)}`)
110
- // 如果获取失败,返回空列表
111
- return []
112
- }
113
- }
114
-
115
- /**
116
- * 获取智能体工作区中的专有技能
117
- */
118
- async function fetchAgentWorkspaceSkills(
119
- agentId: number,
120
- log?: {
121
- info?: (msg: string) => void
122
- error?: (msg: string) => void
123
- },
124
- ): Promise<SkillItem[]> {
125
- const skills: SkillItem[] = []
126
-
127
- try {
128
- // 智能体工作区路径
129
- const agentWorkspace = join(homedir(), '.openclaw', 'agents', `openclaw-workclaw-${agentId}`)
130
- const skillsDir = join(agentWorkspace, 'skills')
131
-
132
- // 检查技能目录是否存在
133
- if (!existsSync(skillsDir)) {
134
- log?.info?.(`SkillsList: No skills directory found in agent workspace: ${skillsDir}`)
135
- return skills
136
- }
137
-
138
- // 读取技能目录中的子目录(每个子目录是一个技能)
139
- const items = readdirSync(skillsDir)
140
- for (const item of items) {
141
- const itemPath = join(skillsDir, item)
142
- const stat = statSync(itemPath)
143
-
144
- // 如果是目录,检查里面的技能文件
145
- if (stat.isDirectory()) {
146
- const skillFiles = readdirSync(itemPath)
147
- for (const skillFile of skillFiles) {
148
- if (skillFile.endsWith('.md') || skillFile.endsWith('.prose')) {
149
- const skillFilePath = join(itemPath, skillFile)
150
- const skill = parseSkillFile(skillFilePath, item, log)
151
- if (skill) {
152
- skills.push(skill)
153
- }
154
- }
155
- }
156
- }
157
- }
158
-
159
- log?.info?.(`SkillsList: Found ${skills.length} agent-specific skills in ${skillsDir}`)
160
- }
161
- catch (error) {
162
- log?.error?.(`SkillsList: Error reading agent workspace skills: ${String(error)}`)
163
- }
164
-
165
- return skills
166
- }
167
-
168
- /**
169
- * 解析技能文件
170
- */
171
- function parseSkillFile(
172
- filePath: string,
173
- skillName: string,
174
- log?: {
175
- info?: (msg: string) => void
176
- error?: (msg: string) => void
177
- },
178
- ): SkillItem | null {
179
- try {
180
- const content = readFileSync(filePath, 'utf-8')
181
-
182
- // 提取描述(从文件内容中)
183
- let description = 'Agent-specific skill'
184
- const lines = content.split('\n')
185
- for (const line of lines) {
186
- if (line.startsWith('# ')) {
187
- description = line.substring(2).trim()
188
- break
189
- }
190
- else if (line.startsWith('summary:') || line.startsWith('Summary:')) {
191
- description = line.substring(line.indexOf(':') + 1).trim()
192
- break
193
- }
194
- }
195
-
196
- return {
197
- typeStr: 'skill',
198
- name: skillName,
199
- description,
200
- }
201
- }
202
- catch (error) {
203
- log?.error?.(`SkillsList: Error parsing skill file ${filePath}: ${String(error)}`)
204
- return null
205
- }
206
- }
207
-
208
- /**
209
- * 合并技能列表,去重
210
- */
211
- function mergeSkills(globalSkills: SkillItem[], agentSkills: SkillItem[]): SkillItem[] {
212
- const skillMap = new Map<string, SkillItem>()
213
-
214
- // 先添加全局技能
215
- for (const skill of globalSkills) {
216
- skillMap.set(skill.name, skill)
217
- }
218
-
219
- // 再添加智能体专有技能(会覆盖同名的全局技能)
220
- for (const skill of agentSkills) {
221
- skillMap.set(skill.name, skill)
222
- }
223
-
224
- return Array.from(skillMap.values())
225
- }
226
-
227
- /**
228
- * 解析 openclaw skills list 的输出
229
- */
230
- function parseSkillsListOutput(output: string): SkillItem[] {
231
- const skills: SkillItem[] = []
232
- const lines = output.split('\n')
233
-
234
- // 查找表格内容(从表头后开始)
235
- let inTable = false
236
- let headerLine = -1
237
-
238
- for (let i = 0; i < lines.length; i++) {
239
- const line = lines[i]
240
-
241
- // 找到表头行(包含 Status | Skill | Description | Source)
242
- if (line.includes('Status') && line.includes('Skill') && line.includes('Description')) {
243
- headerLine = i
244
- inTable = true
245
- continue
246
- }
247
-
248
- // 跳过分隔线
249
- if (inTable && (line.startsWith('├') || line.startsWith('┌') || line.startsWith('└'))) {
250
- continue
251
- }
252
-
253
- // 解析表格行
254
- if (inTable && line.startsWith('│') && i > headerLine + 1) {
255
- const parsed = parseSkillsTableRow(line)
256
- if (parsed) {
257
- skills.push(parsed)
258
- }
259
- }
260
-
261
- // 表格结束
262
- if (inTable && line.startsWith('└')) {
263
- break
264
- }
265
- }
266
-
267
- return skills
268
- }
269
-
270
- /**
271
- * 解析单行表格数据
272
- */
273
- function parseSkillsTableRow(line: string): SkillItem | null {
274
- // 移除开头的 │ 和结尾的 │
275
- const content = line.replace(/^│\s*/, '').replace(/\s*│$/, '')
276
-
277
- // 按 │ 分割列
278
- const columns = content.split('│').map(col => col.trim())
279
-
280
- if (columns.length < 4) {
281
- return null
282
- }
283
-
284
- const status = columns[0]
285
- const skillName = columns[1]
286
- const description = columns[2]
287
-
288
- // 只返回 ready 状态的 skills
289
- if (!status.includes('✓') && !status.includes('ready')) {
290
- return null
291
- }
292
-
293
- // 提取 skill 名称(移除 emoji)
294
- const cleanName = skillName.replace(/[\u{1F300}-\u{1F9FF}]/gu, '').trim()
295
-
296
- return {
297
- typeStr: 'skill',
298
- name: cleanName,
299
- description,
300
- }
301
- }
302
-
303
- /**
304
- * 发送 skills 列表回调
305
- */
306
- async function sendSkillsListCallback(
307
- callbackUrl: string,
308
- payload: SkillsListCallbackPayload,
309
- token: string,
310
- log?: {
311
- info?: (msg: string) => void
312
- error?: (msg: string) => void
313
- },
314
- ): Promise<void> {
315
- log?.info?.(`SkillsList: Sending callback to ${callbackUrl}`)
316
-
317
- const response = await fetch(callbackUrl, {
318
- method: 'POST',
319
- headers: {
320
- 'Content-Type': 'application/json',
321
- 'Authorization': `Bearer ${token}`,
322
- },
323
- body: JSON.stringify(payload),
324
- })
325
-
326
- if (!response.ok) {
327
- const errorText = await response.text().catch(() => 'Unknown error')
328
- throw new Error(`Callback failed: ${response.status} ${errorText}`)
329
- }
330
-
331
- log?.info?.(`SkillsList: Callback sent successfully`)
332
- }
@@ -1,161 +0,0 @@
1
- /**
2
- * Tools List 事件处理器
3
- * 处理云端下发的 TOOLS_LIST EVENT 消息
4
- * 从 OpenClaw 获取 tools 列表并通过 HTTP 回调返回
5
- */
6
-
7
- import { readFile } from 'node:fs/promises'
8
- import { homedir } from 'node:os'
9
- import path from 'node:path'
10
- import { fetch } from 'undici'
11
-
12
- export interface ToolsListEvent {
13
- agentId: string | number
14
- userId: string | number
15
- }
16
-
17
- export interface ToolItem {
18
- typeStr: string
19
- name: string
20
- description: string
21
- }
22
-
23
- export interface ToolsListCallbackPayload {
24
- userId: number
25
- agentId: number
26
- dataList: ToolItem[]
27
- }
28
-
29
- /**
30
- * 处理 TOOLS_LIST 事件
31
- * @param event 事件数据
32
- * @param baseUrl 回调基础 URL
33
- * @param token 鉴权 token
34
- * @param log 日志函数
35
- */
36
- export async function handleToolsListEvent(
37
- event: ToolsListEvent,
38
- baseUrl: string,
39
- token: string,
40
- log?: {
41
- info?: (msg: string) => void
42
- error?: (msg: string) => void
43
- },
44
- ): Promise<void> {
45
- const agentId = Number(event.agentId)
46
- const userId = Number(event.userId)
47
-
48
- log?.info?.(`ToolsList: Handling TOOLS_LIST event for agentId: ${agentId}, userId: ${userId}`)
49
-
50
- try {
51
- // 从 OpenClaw 获取 tools 列表
52
- const tools = await fetchToolsFromOpenClaw(agentId, userId, log)
53
-
54
- // 构建回调 payload
55
- const callbackPayload: ToolsListCallbackPayload = {
56
- userId,
57
- agentId,
58
- dataList: tools,
59
- }
60
-
61
- // 发送回调
62
- const callbackUrl = `${baseUrl.replace(/\/$/, '')}/open-apis/v1/claw/push/tools`
63
- await sendToolsListCallback(callbackUrl, callbackPayload, token, log)
64
-
65
- log?.info?.(`ToolsList: Successfully processed TOOLS_LIST event, sent ${tools.length} tools`)
66
- }
67
- catch (error) {
68
- log?.error?.(`ToolsList: Failed to handle TOOLS_LIST event: ${String(error)}`)
69
- throw error
70
- }
71
- }
72
-
73
- /**
74
- * 从 OpenClaw 获取 tools 列表
75
- * 根据 agent 的 tools.allow 配置决定返回哪些工具
76
- */
77
- async function fetchToolsFromOpenClaw(
78
- agentId: number,
79
- userId: number,
80
- log?: {
81
- info?: (msg: string) => void
82
- error?: (msg: string) => void
83
- },
84
- ): Promise<ToolItem[]> {
85
- log?.info?.(`ToolsList: Fetching tools from OpenClaw for agentId: ${agentId}`)
86
-
87
- // OpenClaw 所有内置工具列表
88
- const allTools: ToolItem[] = [
89
- { typeStr: 'function', name: 'web_search', description: 'Search the web for information using Brave Search API.' },
90
- { typeStr: 'function', name: 'web_fetch', description: 'Fetch and read content from a URL.' },
91
- { typeStr: 'function', name: 'sessions_list', description: 'List all active agent sessions.' },
92
- { typeStr: 'function', name: 'sessions_history', description: 'Get the history of a specific session.' },
93
- { typeStr: 'function', name: 'memory_search', description: 'Search memory for past conversations and information.' },
94
- { typeStr: 'function', name: 'memory_get', description: 'Get specific memory by ID.' },
95
- { typeStr: 'function', name: 'gateway', description: 'Gateway control operations.' },
96
- { typeStr: 'function', name: 'exec', description: 'Execute shell commands.' },
97
- ]
98
-
99
- try {
100
- // 读取 OpenClaw 配置文件
101
- const configPath = path.join(homedir(), '.openclaw', 'openclaw.json')
102
- const configContent = await readFile(configPath, 'utf-8')
103
- const config = JSON.parse(configContent)
104
-
105
- // 查找对应的 agent 配置
106
- const agentConfig = config.agents?.list?.find((agent: any) =>
107
- String(agent.id) === String(agentId)
108
- || agent.id === `openclaw-workclaw-${agentId}`,
109
- )
110
-
111
- // 获取 tools.allow 配置
112
- const allowTools = agentConfig?.tools?.allow
113
-
114
- // 如果没有 allow 配置,或者 allow 是 ["*"],返回所有工具
115
- if (!allowTools || allowTools.length === 0 || allowTools.includes('*')) {
116
- log?.info?.(`ToolsList: Agent has no allow restriction or allow=[*], returning all ${allTools.length} tools`)
117
- return allTools
118
- }
119
-
120
- // 如果有具体的 allow 列表,只返回列表中的工具
121
- const filteredTools = allTools.filter(tool => allowTools.includes(tool.name))
122
- log?.info?.(`ToolsList: Agent allow=${JSON.stringify(allowTools)}, returning ${filteredTools.length} tools`)
123
- return filteredTools
124
- }
125
- catch (error) {
126
- log?.error?.(`ToolsList: Error reading agent config: ${String(error)}, returning all tools`)
127
- // 如果读取配置失败,返回所有工具
128
- return allTools
129
- }
130
- }
131
-
132
- /**
133
- * 发送 tools 列表回调
134
- */
135
- async function sendToolsListCallback(
136
- callbackUrl: string,
137
- payload: ToolsListCallbackPayload,
138
- token: string,
139
- log?: {
140
- info?: (msg: string) => void
141
- error?: (msg: string) => void
142
- },
143
- ): Promise<void> {
144
- log?.info?.(`ToolsList: Sending callback to ${callbackUrl}`)
145
-
146
- const response = await fetch(callbackUrl, {
147
- method: 'POST',
148
- headers: {
149
- 'Content-Type': 'application/json',
150
- 'Authorization': `Bearer ${token}`,
151
- },
152
- body: JSON.stringify(payload),
153
- })
154
-
155
- if (!response.ok) {
156
- const errorText = await response.text()
157
- throw new Error(`Callback failed: ${response.status} ${response.statusText} - ${errorText}`)
158
- }
159
-
160
- log?.info?.(`ToolsList: Callback sent successfully: ${response.status}`)
161
- }