@workclaw/openclaw-workclaw 1.0.20 → 1.0.25

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 (153) hide show
  1. package/README.md +0 -1
  2. package/api.ts +3 -0
  3. package/index.ts +325 -0
  4. package/package.json +3 -11
  5. package/setup-entry.ts +13 -0
  6. package/src/accounts.ts +360 -0
  7. package/src/api/accounts-api.ts +156 -0
  8. package/src/api/prompts-api.ts +122 -0
  9. package/src/api/session-api.ts +246 -0
  10. package/src/api/skills-api.ts +74 -0
  11. package/src/api/workspace.ts +45 -0
  12. package/src/channel.ts +226 -0
  13. package/{dist/src/config-schema.js → src/config-schema.ts} +60 -56
  14. package/src/connection/workclaw-client.ts +618 -0
  15. package/src/gateway/agent-handlers.ts +551 -0
  16. package/src/gateway/config-writer.ts +378 -0
  17. package/src/gateway/cron-tasks-handler.ts +230 -0
  18. package/src/gateway/message-context.ts +645 -0
  19. package/src/gateway/message-dispatcher.ts +688 -0
  20. package/src/gateway/reconnect.ts +260 -0
  21. package/src/gateway/skills-handler.ts +805 -0
  22. package/src/gateway/skills-list-handler.ts +332 -0
  23. package/src/gateway/tools-list-handler.ts +161 -0
  24. package/src/gateway/workclaw-gateway.ts +304 -0
  25. package/src/media/upload.ts +168 -0
  26. package/src/outbound/index.ts +191 -0
  27. package/src/outbound/workclaw-sender.ts +161 -0
  28. package/src/runtime.ts +520 -0
  29. package/src/secret-contract-api.ts +4 -0
  30. package/src/send.ts +1 -0
  31. package/src/setup-api.ts +3 -0
  32. package/src/setup-core.ts +25 -0
  33. package/src/setup-surface.ts +498 -0
  34. package/src/tools/openclaw-workclaw-cron/api/index.ts +326 -0
  35. package/{dist/src/tools/openclaw-workclaw-cron/index.js → src/tools/openclaw-workclaw-cron/index.ts} +39 -33
  36. package/src/tools/openclaw-workclaw-cron/src/add/params.ts +177 -0
  37. package/src/tools/openclaw-workclaw-cron/src/add/sync.ts +188 -0
  38. package/src/tools/openclaw-workclaw-cron/src/disable/params.ts +100 -0
  39. package/src/tools/openclaw-workclaw-cron/src/disable/sync.ts +127 -0
  40. package/src/tools/openclaw-workclaw-cron/src/enable/params.ts +100 -0
  41. package/src/tools/openclaw-workclaw-cron/src/enable/sync.ts +127 -0
  42. package/src/tools/openclaw-workclaw-cron/src/notify/sync.ts +148 -0
  43. package/src/tools/openclaw-workclaw-cron/src/remove/params.ts +109 -0
  44. package/src/tools/openclaw-workclaw-cron/src/remove/sync.ts +127 -0
  45. package/src/tools/openclaw-workclaw-cron/src/update/params.ts +195 -0
  46. package/src/tools/openclaw-workclaw-cron/src/update/sync.ts +161 -0
  47. package/src/tools/openclaw-workclaw-cron/types/index.ts +55 -0
  48. package/src/tools/openclaw-workclaw-cron/utils/index.ts +141 -0
  49. package/{dist/src/tools/openclaw-workclaw-system/index.js → src/tools/openclaw-workclaw-system/index.ts} +17 -15
  50. package/src/tools/openclaw-workclaw-system/src/get/index.ts +77 -0
  51. package/src/tools/openclaw-workclaw-system/src/token/index.ts +93 -0
  52. package/src/types.ts +50 -0
  53. package/src/utils/content.ts +40 -0
  54. package/tsconfig.json +34 -0
  55. package/dist/api.d.ts +0 -3
  56. package/dist/api.js +0 -3
  57. package/dist/index.d.ts +0 -11
  58. package/dist/index.js +0 -264
  59. package/dist/setup-entry.d.ts +0 -2
  60. package/dist/setup-entry.js +0 -12
  61. package/dist/src/accounts.d.ts +0 -66
  62. package/dist/src/accounts.js +0 -279
  63. package/dist/src/api/accounts-api.d.ts +0 -2
  64. package/dist/src/api/accounts-api.js +0 -130
  65. package/dist/src/api/prompts-api.d.ts +0 -2
  66. package/dist/src/api/prompts-api.js +0 -103
  67. package/dist/src/api/session-api.d.ts +0 -2
  68. package/dist/src/api/session-api.js +0 -207
  69. package/dist/src/api/skills-api.d.ts +0 -2
  70. package/dist/src/api/skills-api.js +0 -64
  71. package/dist/src/api/workspace.d.ts +0 -3
  72. package/dist/src/api/workspace.js +0 -30
  73. package/dist/src/channel.d.ts +0 -11
  74. package/dist/src/channel.js +0 -199
  75. package/dist/src/config-schema.d.ts +0 -93
  76. package/dist/src/connection/workclaw-client.d.ts +0 -147
  77. package/dist/src/connection/workclaw-client.js +0 -351
  78. package/dist/src/gateway/agent-handlers.d.ts +0 -12
  79. package/dist/src/gateway/agent-handlers.js +0 -433
  80. package/dist/src/gateway/config-writer.d.ts +0 -71
  81. package/dist/src/gateway/config-writer.js +0 -302
  82. package/dist/src/gateway/cron-tasks-handler.d.ts +0 -19
  83. package/dist/src/gateway/cron-tasks-handler.js +0 -188
  84. package/dist/src/gateway/message-context.d.ts +0 -80
  85. package/dist/src/gateway/message-context.js +0 -509
  86. package/dist/src/gateway/message-dispatcher.d.ts +0 -18
  87. package/dist/src/gateway/message-dispatcher.js +0 -572
  88. package/dist/src/gateway/reconnect.d.ts +0 -27
  89. package/dist/src/gateway/reconnect.js +0 -210
  90. package/dist/src/gateway/skills-handler.d.ts +0 -29
  91. package/dist/src/gateway/skills-handler.js +0 -615
  92. package/dist/src/gateway/skills-list-handler.d.ts +0 -27
  93. package/dist/src/gateway/skills-list-handler.js +0 -233
  94. package/dist/src/gateway/tools-list-handler.d.ts +0 -30
  95. package/dist/src/gateway/tools-list-handler.js +0 -101
  96. package/dist/src/gateway/workclaw-gateway.d.ts +0 -14
  97. package/dist/src/gateway/workclaw-gateway.js +0 -237
  98. package/dist/src/media/upload.d.ts +0 -13
  99. package/dist/src/media/upload.js +0 -125
  100. package/dist/src/outbound/index.d.ts +0 -36
  101. package/dist/src/outbound/index.js +0 -123
  102. package/dist/src/outbound/workclaw-sender.d.ts +0 -36
  103. package/dist/src/outbound/workclaw-sender.js +0 -95
  104. package/dist/src/runtime.d.ts +0 -116
  105. package/dist/src/runtime.js +0 -374
  106. package/dist/src/secret-contract-api.d.ts +0 -4
  107. package/dist/src/secret-contract-api.js +0 -4
  108. package/dist/src/send.d.ts +0 -1
  109. package/dist/src/send.js +0 -1
  110. package/dist/src/setup-api.d.ts +0 -3
  111. package/dist/src/setup-api.js +0 -3
  112. package/dist/src/setup-core.d.ts +0 -3
  113. package/dist/src/setup-core.js +0 -13
  114. package/dist/src/setup-surface.d.ts +0 -7
  115. package/dist/src/setup-surface.js +0 -363
  116. package/dist/src/tools/openclaw-workclaw-cron/api/index.d.ts +0 -93
  117. package/dist/src/tools/openclaw-workclaw-cron/api/index.js +0 -209
  118. package/dist/src/tools/openclaw-workclaw-cron/index.d.ts +0 -10
  119. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.d.ts +0 -16
  120. package/dist/src/tools/openclaw-workclaw-cron/src/add/params.js +0 -152
  121. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.d.ts +0 -18
  122. package/dist/src/tools/openclaw-workclaw-cron/src/add/sync.js +0 -162
  123. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.d.ts +0 -14
  124. package/dist/src/tools/openclaw-workclaw-cron/src/disable/params.js +0 -80
  125. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.d.ts +0 -14
  126. package/dist/src/tools/openclaw-workclaw-cron/src/disable/sync.js +0 -107
  127. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.d.ts +0 -14
  128. package/dist/src/tools/openclaw-workclaw-cron/src/enable/params.js +0 -80
  129. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.d.ts +0 -14
  130. package/dist/src/tools/openclaw-workclaw-cron/src/enable/sync.js +0 -107
  131. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.d.ts +0 -17
  132. package/dist/src/tools/openclaw-workclaw-cron/src/notify/sync.js +0 -127
  133. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.d.ts +0 -14
  134. package/dist/src/tools/openclaw-workclaw-cron/src/remove/params.js +0 -87
  135. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.d.ts +0 -14
  136. package/dist/src/tools/openclaw-workclaw-cron/src/remove/sync.js +0 -107
  137. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.d.ts +0 -17
  138. package/dist/src/tools/openclaw-workclaw-cron/src/update/params.js +0 -164
  139. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.d.ts +0 -18
  140. package/dist/src/tools/openclaw-workclaw-cron/src/update/sync.js +0 -135
  141. package/dist/src/tools/openclaw-workclaw-cron/types/index.d.ts +0 -52
  142. package/dist/src/tools/openclaw-workclaw-cron/types/index.js +0 -4
  143. package/dist/src/tools/openclaw-workclaw-cron/utils/index.d.ts +0 -40
  144. package/dist/src/tools/openclaw-workclaw-cron/utils/index.js +0 -122
  145. package/dist/src/tools/openclaw-workclaw-system/index.d.ts +0 -10
  146. package/dist/src/tools/openclaw-workclaw-system/src/get/index.d.ts +0 -8
  147. package/dist/src/tools/openclaw-workclaw-system/src/get/index.js +0 -64
  148. package/dist/src/tools/openclaw-workclaw-system/src/token/index.d.ts +0 -8
  149. package/dist/src/tools/openclaw-workclaw-system/src/token/index.js +0 -78
  150. package/dist/src/types.d.ts +0 -39
  151. package/dist/src/types.js +0 -1
  152. package/dist/src/utils/content.d.ts +0 -15
  153. package/dist/src/utils/content.js +0 -38
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Reconnect Scheduler - manages WebSocket reconnection with exponential backoff
3
+ */
4
+
5
+ import type { WorkClawBaseConfig } from '../types.js'
6
+ import { Agent, WebSocket } from 'undici'
7
+ import { clearWorkclawTokenCache, openWorkclawConnection } from '../connection/workclaw-client.js'
8
+
9
+ import { clearWorkclawWsConnection, setWorkclawWsConnection } from '../runtime.js'
10
+
11
+ export interface ReconnectSchedulerOptions {
12
+ /** Key for WebSocket storage (appKey) */
13
+ key: string
14
+ config: WorkClawBaseConfig
15
+ log?: {
16
+ info?: (msg: string) => void
17
+ warn?: (msg: string) => void
18
+ error?: (msg: string) => void
19
+ debug?: (msg: string) => void
20
+ }
21
+ onMessage: (data: string) => void
22
+ onReconnectSuccess?: () => void
23
+ /** Called when connection closes (after initial connect), to trigger reconnect */
24
+ onClose?: () => void
25
+ /** Called after WebSocket is registered (before onopen), useful for lock release */
26
+ onConnectingStarted?: (ws: WebSocket) => void
27
+ }
28
+
29
+ export function createReconnectScheduler(options: ReconnectSchedulerOptions): {
30
+ connect: () => Promise<void>
31
+ scheduleReconnect: () => void
32
+ stopReconnect: () => void
33
+ } {
34
+ const { key, config, log, onMessage, onReconnectSuccess, onClose, onConnectingStarted } = options
35
+
36
+ let reconnectBackoff = 5000
37
+ let shouldStopReconnect = false
38
+ let pendingReconnectTimer: NodeJS.Timeout | null = null
39
+ /** 正在进行的 doConnect() 的 promise,所有 caller 共享同一个结果 */
40
+ let pendingDoConnectPromise: Promise<void> | null = null
41
+
42
+ /**
43
+ * 核心建连逻辑,首次连接和重连复用同一套代码
44
+ * 返回 Promise,连接建立后 resolve,失败后决定是否重连
45
+ * 关键:重试时复用 pendingDoConnectPromise,所有 caller 共享同一个结果
46
+ * - 失败时:不删除 promise,让后续 connect() 调用者等待重试结果
47
+ * - 重试定时器触发时:复用同一 promise,不创建新的
48
+ */
49
+ async function doConnect(): Promise<void> {
50
+ // 如果已有进行中的 doConnect(失败后重试期间),复用同一 promise
51
+ if (pendingDoConnectPromise !== null) {
52
+ return pendingDoConnectPromise
53
+ }
54
+
55
+ let resolveThis: (() => void) | undefined
56
+ let rejectThis: ((err: unknown) => void) | undefined
57
+ const p = new Promise<void>((resolve, reject) => {
58
+ resolveThis = resolve
59
+ rejectThis = reject
60
+ })
61
+ // 设置后再调用 connection,后续 connect() 调用能立即看到它
62
+ pendingDoConnectPromise = p
63
+
64
+ const tokenCacheKey = config.appKey || key
65
+ clearWorkclawTokenCache(tokenCacheKey)
66
+
67
+ const connConfig = {
68
+ baseUrl: config.baseUrl || '',
69
+ websocketUrl: config.websocketUrl,
70
+ appKey: config.appKey,
71
+ appSecret: config.appSecret,
72
+ localIp: config.localIp,
73
+ allowInsecureTls: config.allowInsecureTls,
74
+ requestTimeout: config.requestTimeout,
75
+ }
76
+
77
+ let endpoint: string
78
+ let ticket: string
79
+ try {
80
+ const result = await openWorkclawConnection(tokenCacheKey, connConfig)
81
+ endpoint = result.endpoint
82
+ ticket = result.ticket
83
+ }
84
+ catch (err) {
85
+ // openWorkclawConnection 失败时(如 AbortError),由 handleConnectError 决定是否重试
86
+ // 如果不重试则 reject promise;如果重试则保持 pending(后续 timer 会触发重试)
87
+ const willRetry = handleConnectError(String(err))
88
+ if (!willRetry) {
89
+ pendingDoConnectPromise = null
90
+ rejectThis!(err)
91
+ }
92
+ throw err
93
+ }
94
+ const url = `${endpoint}?ticket=${encodeURIComponent(ticket)}`
95
+
96
+ const dispatcher = connConfig.allowInsecureTls
97
+ ? new Agent({ connect: { rejectUnauthorized: false } })
98
+ : undefined
99
+ const wsOptions = dispatcher ? { dispatcher } : undefined
100
+
101
+ const ws = new WebSocket(url, wsOptions)
102
+ setWorkclawWsConnection(key, ws)
103
+
104
+ // 在 onopen 之前调用,让 waitForConnect() 释放锁
105
+ onConnectingStarted?.(ws)
106
+
107
+ // 统一用 resolveThis/rejectThis,ws.onopen 调用 resolveThis 让 await Promise 完成
108
+ ws.onopen = () => {
109
+ log?.info?.(`Gateway WebSocket connected endpoint=${endpoint}`)
110
+ reconnectBackoff = 5000
111
+ onReconnectSuccess?.()
112
+ resolveThis!()
113
+ }
114
+
115
+ ws.onerror = (event: any) => {
116
+ log?.error?.(`Gateway WebSocket error: ${String(event?.message ?? event)}`)
117
+ rejectThis!(new Error(String(event?.message ?? event)))
118
+ }
119
+
120
+ ws.onclose = (event: any) => {
121
+ const code = String(event?.code ?? '')
122
+ const reason = String(event?.reason ?? '')
123
+ log?.warn?.(`Gateway WebSocket closed code=${code} reason=${reason}`)
124
+ clearWorkclawWsConnection(key)
125
+ if (onClose) {
126
+ onClose()
127
+ }
128
+ else {
129
+ scheduleReconnect()
130
+ }
131
+ rejectThis!(new Error(`WebSocket closed code=${code} reason=${reason}`))
132
+ }
133
+
134
+ ws.onmessage = (event: any) => {
135
+ const data = typeof event.data === 'string' ? event.data : String(event.data ?? '')
136
+ log?.debug?.(`Gateway WebSocket message received bytes=${data.length}`)
137
+ onMessage(data)
138
+ }
139
+
140
+ // 等待 ws.onopen 完成(resolveThis)或 ws.onerror/ws.onclose 失败(rejectThis)
141
+ await new Promise<void>((resolve, reject) => {
142
+ const timeout = setTimeout(() => reject(new Error('websocket connection timeout')), 30000)
143
+ ws.addEventListener('open', () => { clearTimeout(timeout); resolve() }, { once: true })
144
+ ws.addEventListener('error', (event: any) => { clearTimeout(timeout); reject(new Error(String(event?.message ?? event))) }, { once: true })
145
+ ws.addEventListener('close', (event: any) => { clearTimeout(timeout); reject(new Error(`websocket closed before ready code=${event?.code ?? ''} reason=${event?.reason ?? ''}`)) }, { once: true })
146
+ })
147
+ }
148
+
149
+ const scheduleReconnect = () => {
150
+ if (shouldStopReconnect) {
151
+ log?.info?.(`Reconnect: Stopped due to previous auth failure`)
152
+ return
153
+ }
154
+ if (pendingReconnectTimer !== null) {
155
+ log?.info?.(`Reconnect: Already scheduled, skipping duplicate`)
156
+ return
157
+ }
158
+
159
+ const jitter = Math.floor(Math.random() * 3000)
160
+ const delayMs = reconnectBackoff + jitter
161
+ log?.info?.(`Reconnect: Scheduling in ${delayMs}ms (base=${reconnectBackoff} + jitter=${jitter}) key=${key}`)
162
+
163
+ pendingReconnectTimer = setTimeout(async () => {
164
+ pendingReconnectTimer = null
165
+ // 清除旧的 pendingDoConnectPromise,确保 doConnect() 真正建立新连接
166
+ // 否则 doConnect() 会直接返回已 resolved 的旧 promise(第一次失败后 promise 没被清除)
167
+ pendingDoConnectPromise = null
168
+ try {
169
+ log?.info?.(`Reconnect: Attempting... key=${key}`)
170
+ await doConnect()
171
+ log?.info?.(`Reconnect: Success`)
172
+ }
173
+ catch (err) {
174
+ const errorStr = String(err)
175
+ log?.error?.(`Reconnect: Failed: ${errorStr}`)
176
+ const willRetry = handleConnectError(errorStr)
177
+ if (!willRetry) {
178
+ // 永久失败,清除 pending promise
179
+ pendingDoConnectPromise = null
180
+ }
181
+ else {
182
+ // 错误不代表永久失败,调度下一次重连
183
+ scheduleReconnect()
184
+ }
185
+ }
186
+ }, delayMs)
187
+ }
188
+
189
+ /** 返回 true=会重试(promise 保持 pending),false=不重试(promise 应被 reject) */
190
+ function handleConnectError(errorStr: string): boolean {
191
+ if (errorStr.includes('访问过于频繁')) {
192
+ log?.warn?.(`Reconnect: Rate limited, retrying with minimal backoff`)
193
+ if (pendingReconnectTimer !== null) {
194
+ clearTimeout(pendingReconnectTimer)
195
+ pendingReconnectTimer = null
196
+ }
197
+ reconnectBackoff = 1000
198
+ scheduleReconnect()
199
+ return true // 会重试
200
+ }
201
+
202
+ const isAuthError
203
+ = errorStr.includes('"errCode":2001')
204
+ || errorStr.includes('"code":2001')
205
+ || errorStr.includes('鉴权失败')
206
+ || errorStr.includes('invalid credentials')
207
+ || errorStr.includes('unauthorized')
208
+
209
+ if (isAuthError) {
210
+ log?.error?.(`Reconnect: Authentication failed, stopping`)
211
+ shouldStopReconnect = true
212
+ if (pendingReconnectTimer !== null) {
213
+ clearTimeout(pendingReconnectTimer)
214
+ pendingReconnectTimer = null
215
+ }
216
+ return false // 不重试
217
+ }
218
+
219
+ // 其他错误:重试
220
+ return true
221
+ }
222
+
223
+ /**
224
+ * 首次连接或重连:调用 doConnect(),返回其 promise
225
+ * 如果 doConnect() 因失败正在重试(promise 仍 pending),返回同一 promise
226
+ * 调用方 await 此方法,连接建立后 resolve,失败且不重试时 reject
227
+ */
228
+ async function connect(): Promise<void> {
229
+ // 如果 doConnect() 正在进行中(失败后重试期间),返回同一 promise 让 caller 等待
230
+ if (pendingDoConnectPromise !== null) {
231
+ return pendingDoConnectPromise
232
+ }
233
+ try {
234
+ return await doConnect()
235
+ }
236
+ catch (err) {
237
+ const errorStr = String(err)
238
+ log?.error?.(`Gateway connect failed: ${errorStr}`)
239
+ const willRetry = handleConnectError(errorStr)
240
+ if (!willRetry) {
241
+ // 不重试时,清除 pending promise,后续 connect() 可创建新的
242
+ pendingDoConnectPromise = null
243
+ throw err
244
+ }
245
+ // handleConnectError 返回 true 时,安排后续重试
246
+ // 注意:pendingDoConnectPromise 仍 pending,下次定时器触发时会清除它再真正重连
247
+ scheduleReconnect()
248
+ }
249
+ }
250
+
251
+ const stopReconnect = () => {
252
+ shouldStopReconnect = true
253
+ if (pendingReconnectTimer !== null) {
254
+ clearTimeout(pendingReconnectTimer)
255
+ pendingReconnectTimer = null
256
+ }
257
+ }
258
+
259
+ return { connect, scheduleReconnect, stopReconnect }
260
+ }