@openclaw/discord 2026.6.8 → 2026.6.9-beta.1

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 (110) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/api.js +13 -13
  3. package/dist/{approval-handler.runtime-B3gyUd-L.js → approval-handler.runtime-BprBDUQG.js} +3 -3
  4. package/dist/{audit-BlfewK04.js → audit-DuZUxGjM.js} +3 -3
  5. package/dist/{channel-b0hY1EJw.js → channel--3YhTUOb.js} +27 -19
  6. package/dist/{channel-actions-BnPHwCZ_.js → channel-actions-CoudAyAB.js} +12 -6
  7. package/dist/{channel-actions.runtime-DX5iW6ut.js → channel-actions.runtime-DdOfD3fi.js} +5 -5
  8. package/dist/channel-plugin-api.js +1 -1
  9. package/dist/{channel.setup-By5cfELZ.js → channel.setup-C-y6Jifd.js} +2 -2
  10. package/dist/{components-D-CYw0-b.js → components-CUmrNvv-.js} +1 -1
  11. package/dist/{conversation-identity-CKzQAqFF.js → conversation-identity-CN-HPn11.js} +2 -2
  12. package/dist/{directory-config-Bu7FYOsl.js → directory-config-BCt5KxcX.js} +1 -1
  13. package/dist/directory-contract-api.js +1 -1
  14. package/dist/{directory-live-LjENjK6L.js → directory-live-CE7IDmwo.js} +1 -1
  15. package/dist/{handle-action.guild-admin-BS2qnhXF.js → handle-action.guild-admin-B7SnVS0m.js} +14 -9
  16. package/dist/index.js +1 -1
  17. package/dist/{manager.runtime-BU1vkOeO.js → manager.runtime-zMVwNPAT.js} +12 -4
  18. package/dist/{message-handler-CQVkXHMN.js → message-handler-DE413Oj4.js} +6 -6
  19. package/dist/{message-handler.preflight-DAnLOeDA.js → message-handler.preflight-BuF-DsE2.js} +10 -10
  20. package/dist/{message-handler.process-Dp5NQT05.js → message-handler.process-BX8HsMfV.js} +37 -23
  21. package/dist/{message-utils-Bx993JLN.js → message-utils-s_8KDqAQ.js} +1 -1
  22. package/dist/{outbound-adapter-CmN7ao1t.js → outbound-adapter-CNievjXH.js} +6 -6
  23. package/dist/{pluralkit-SYmlmerw.js → pluralkit-BXkU9XmC.js} +1 -1
  24. package/dist/{provider-DrScDA1p.js → provider-ByZ6xxgi.js} +85 -56
  25. package/dist/{provider-session.runtime-DXTzSYOJ.js → provider-session.runtime-DMfaQ9Z6.js} +3 -3
  26. package/dist/provider.runtime-EW-G8l_U.js +2 -0
  27. package/dist/{resolve-channels-Rautpk8n.js → resolve-channels-t1URw0Qz.js} +1 -1
  28. package/dist/{resolve-users-Bw7vvtsi.js → resolve-users-Bapkb237.js} +1 -1
  29. package/dist/{runtime-C80YEJ7Z.js → runtime-C6jV3hf4.js} +24 -10
  30. package/dist/runtime-api.actions.js +2 -2
  31. package/dist/runtime-api.js +19 -19
  32. package/dist/runtime-api.lookup.js +4 -4
  33. package/dist/runtime-api.monitor-5BSxmucu.js +6 -0
  34. package/dist/runtime-api.monitor.js +4 -4
  35. package/dist/runtime-api.send.js +5 -5
  36. package/dist/runtime-api.threads.js +3 -3
  37. package/dist/{send-zGsXF-up.js → send-o-Y1DiAT.js} +3 -3
  38. package/dist/{send.components-ktzrUTkt.js → send.components-B4_oNcOh.js} +4 -4
  39. package/dist/{send.outbound-C8oC51um.js → send.outbound-DhiXV3UJ.js} +53 -10
  40. package/dist/{send.receipt-DsQWEQ2O.js → send.receipt-HXIwVvXy.js} +2 -1
  41. package/dist/{send.shared-Dvo2ZCVG.js → send.shared-DYdjs_Zh.js} +13 -5
  42. package/dist/session-binding-contract-api.js +1 -1
  43. package/dist/setup-plugin-api.js +1 -1
  44. package/dist/{subagent-hooks-kjrWDeDg.js → subagent-hooks-CbF_Z5F0.js} +2 -2
  45. package/dist/subagent-hooks-api.js +1 -1
  46. package/dist/{system-events-CvU3Aduf.js → system-events-BxTHlBbM.js} +1 -1
  47. package/dist/{target-resolver-DMPTzuo7.js → target-resolver-DpC8iueE.js} +2 -2
  48. package/dist/targets-BEIgHBHc.js +3 -0
  49. package/dist/{thread-bindings-DO32M2kW.js → thread-bindings-CEVvN75T.js} +4 -4
  50. package/dist/{thread-bindings.discord-api-304M1PMr.js → thread-bindings.discord-api-B8NfbxEB.js} +4 -4
  51. package/dist/{thread-bindings.manager-C9YT7wF2.js → thread-bindings.manager-BKfUaXGt.js} +3 -3
  52. package/dist/{transcripts-source-Chy2OrO_.js → transcripts-source-W6n_8J8g.js} +1 -1
  53. package/dist/transcripts-source-api.js +1 -1
  54. package/dist/{typing-BaivbXIG.js → typing-0-pUmlY9.js} +1 -1
  55. package/node_modules/undici/README.md +59 -18
  56. package/node_modules/undici/docs/docs/GettingStarted.md +278 -0
  57. package/node_modules/undici/docs/docs/api/Agent.md +3 -0
  58. package/node_modules/undici/docs/docs/api/BalancedPool.md +1 -1
  59. package/node_modules/undici/docs/docs/api/Client.md +44 -5
  60. package/node_modules/undici/docs/docs/api/Connector.md +1 -0
  61. package/node_modules/undici/docs/docs/api/Cookies.md +28 -1
  62. package/node_modules/undici/docs/docs/api/Dispatcher.md +22 -5
  63. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +6 -9
  64. package/node_modules/undici/docs/docs/api/Errors.md +12 -0
  65. package/node_modules/undici/docs/docs/api/EventSource.md +50 -3
  66. package/node_modules/undici/docs/docs/api/Fetch.md +5 -3
  67. package/node_modules/undici/docs/docs/api/H2CClient.md +3 -3
  68. package/node_modules/undici/docs/docs/api/MockAgent.md +1 -1
  69. package/node_modules/undici/docs/docs/api/MockCallHistory.md +1 -1
  70. package/node_modules/undici/docs/docs/api/Pool.md +4 -1
  71. package/node_modules/undici/docs/docs/api/RedirectHandler.md +4 -1
  72. package/node_modules/undici/docs/docs/api/RetryAgent.md +3 -3
  73. package/node_modules/undici/docs/docs/api/RetryHandler.md +6 -6
  74. package/node_modules/undici/docs/docs/api/RoundRobinPool.md +1 -1
  75. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +3 -3
  76. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +1 -0
  77. package/node_modules/undici/docs/docs/api/api-lifecycle.md +4 -4
  78. package/node_modules/undici/lib/core/connect.js +29 -4
  79. package/node_modules/undici/lib/core/util.js +8 -6
  80. package/node_modules/undici/lib/dispatcher/client-h1.js +69 -2
  81. package/node_modules/undici/lib/dispatcher/client-h2.js +160 -37
  82. package/node_modules/undici/lib/dispatcher/client.js +36 -7
  83. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +1 -0
  84. package/node_modules/undici/lib/dispatcher/proxy-agent.js +2 -1
  85. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +4 -2
  86. package/node_modules/undici/lib/handler/redirect-handler.js +36 -11
  87. package/node_modules/undici/lib/interceptor/dns.js +4 -0
  88. package/node_modules/undici/lib/interceptor/redirect.js +3 -3
  89. package/node_modules/undici/lib/mock/mock-call-history.js +1 -1
  90. package/node_modules/undici/lib/mock/snapshot-agent.js +9 -1
  91. package/node_modules/undici/lib/util/cache.js +8 -2
  92. package/node_modules/undici/lib/web/cookies/parse.js +17 -25
  93. package/node_modules/undici/lib/web/eventsource/eventsource.js +7 -18
  94. package/node_modules/undici/lib/web/eventsource/util.js +32 -1
  95. package/node_modules/undici/lib/web/fetch/body.js +43 -0
  96. package/node_modules/undici/lib/web/fetch/index.js +17 -3
  97. package/node_modules/undici/lib/web/fetch/request.js +33 -3
  98. package/node_modules/undici/lib/web/websocket/receiver.js +20 -3
  99. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -1
  100. package/node_modules/undici/lib/web/websocket/websocket.js +3 -1
  101. package/node_modules/undici/package.json +1 -1
  102. package/node_modules/undici/types/client.d.ts +5 -0
  103. package/node_modules/undici/types/connector.d.ts +1 -0
  104. package/node_modules/undici/types/fetch.d.ts +5 -1
  105. package/node_modules/undici/types/interceptors.d.ts +1 -1
  106. package/npm-shrinkwrap.json +7 -7
  107. package/package.json +5 -5
  108. package/dist/provider.runtime-nb-6cRoy.js +0 -2
  109. package/dist/runtime-api.monitor-D8KNDAd5.js +0 -6
  110. package/dist/targets-CKaNidbk.js +0 -3
@@ -228,6 +228,10 @@ function parseCacheControlHeader (header) {
228
228
  headers[headers.length - 1] = lastHeader
229
229
  }
230
230
 
231
+ for (let j = 0; j < headers.length; j++) {
232
+ headers[j] = headers[j].trim()
233
+ }
234
+
231
235
  if (key in output) {
232
236
  output[key] = output[key].concat(headers)
233
237
  } else {
@@ -236,10 +240,12 @@ function parseCacheControlHeader (header) {
236
240
  }
237
241
  } else {
238
242
  // Something like `no-cache="some-header"`
243
+ const fieldName = value.trim()
244
+
239
245
  if (key in output) {
240
- output[key] = output[key].concat(value)
246
+ output[key] = output[key].concat(fieldName)
241
247
  } else {
242
- output[key] = [value]
248
+ output[key] = [fieldName]
243
249
  }
244
250
  }
245
251
 
@@ -4,7 +4,6 @@ const { collectASequenceOfCodePointsFast } = require('../infra')
4
4
  const { maxNameValuePairSize, maxAttributeValueSize } = require('./constants')
5
5
  const { isCTLExcludingHtab } = require('./util')
6
6
  const assert = require('node:assert')
7
- const { unescape: qsUnescape } = require('node:querystring')
8
7
 
9
8
  /**
10
9
  * @description Parses the field-value attributes of a set-cookie header string.
@@ -82,7 +81,7 @@ function parseSetCookie (header) {
82
81
  // store arbitrary data in a cookie-value SHOULD encode that data, for
83
82
  // example, using Base64 [RFC4648].
84
83
  return {
85
- name, value: qsUnescape(value), ...parseUnparsedAttributes(unparsedAttributes)
84
+ name, value, ...parseUnparsedAttributes(unparsedAttributes)
86
85
  }
87
86
  }
88
87
 
@@ -280,32 +279,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
280
279
  // If the attribute-name case-insensitively matches the string
281
280
  // "SameSite", the user agent MUST process the cookie-av as follows:
282
281
 
283
- // 1. Let enforcement be "Default".
284
- let enforcement = 'Default'
285
-
286
282
  const attributeValueLowercase = attributeValue.toLowerCase()
287
- // 2. If cookie-av's attribute-value is a case-insensitive match for
288
- // "None", set enforcement to "None".
289
- if (attributeValueLowercase.includes('none')) {
290
- enforcement = 'None'
291
- }
292
283
 
293
- // 3. If cookie-av's attribute-value is a case-insensitive match for
294
- // "Strict", set enforcement to "Strict".
295
- if (attributeValueLowercase.includes('strict')) {
296
- enforcement = 'Strict'
284
+ // 1. If cookie-av's attribute-value is a case-insensitive match for
285
+ // "None", append an attribute to the cookie-attribute-list with an
286
+ // attribute-name of "SameSite" and an attribute-value of "None".
287
+ if (attributeValueLowercase === 'none') {
288
+ cookieAttributeList.sameSite = 'None'
289
+ } else if (attributeValueLowercase === 'strict') {
290
+ // 2. If cookie-av's attribute-value is a case-insensitive match for
291
+ // "Strict", append an attribute to the cookie-attribute-list with
292
+ // an attribute-name of "SameSite" and an attribute-value of
293
+ // "Strict".
294
+ cookieAttributeList.sameSite = 'Strict'
295
+ } else if (attributeValueLowercase === 'lax') {
296
+ // 3. If cookie-av's attribute-value is a case-insensitive match for
297
+ // "Lax", append an attribute to the cookie-attribute-list with an
298
+ // attribute-name of "SameSite" and an attribute-value of "Lax".
299
+ cookieAttributeList.sameSite = 'Lax'
297
300
  }
298
-
299
- // 4. If cookie-av's attribute-value is a case-insensitive match for
300
- // "Lax", set enforcement to "Lax".
301
- if (attributeValueLowercase.includes('lax')) {
302
- enforcement = 'Lax'
303
- }
304
-
305
- // 5. Append an attribute to the cookie-attribute-list with an
306
- // attribute-name of "SameSite" and an attribute-value of
307
- // enforcement.
308
- cookieAttributeList.sameSite = enforcement
309
301
  } else {
310
302
  cookieAttributeList.unparsed ??= []
311
303
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  const { pipeline } = require('node:stream')
4
4
  const { fetching } = require('../fetch')
5
- const { makeRequest } = require('../fetch/request')
6
5
  const { webidl } = require('../webidl')
7
6
  const { EventSourceStream } = require('./eventsource-stream')
8
7
  const { parseMIMEType } = require('../fetch/data-url')
@@ -10,6 +9,7 @@ const { createFastMessageEvent } = require('../websocket/events')
10
9
  const { isNetworkError } = require('../fetch/response')
11
10
  const { kEnumerableProperty } = require('../../core/util')
12
11
  const { environmentSettingsObject } = require('../fetch/util')
12
+ const { createPotentialCORSRequest } = require('./util')
13
13
 
14
14
  let experimentalWarned = false
15
15
 
@@ -160,33 +160,22 @@ class EventSource extends EventTarget {
160
160
 
161
161
  // 8. Let request be the result of creating a potential-CORS request given
162
162
  // urlRecord, the empty string, and corsAttributeState.
163
- const initRequest = {
164
- redirect: 'follow',
165
- keepalive: true,
166
- // @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
167
- mode: 'cors',
168
- credentials: corsAttributeState === 'anonymous'
169
- ? 'same-origin'
170
- : 'omit',
171
- referrer: 'no-referrer'
172
- }
163
+ const request = createPotentialCORSRequest(urlRecord, '', corsAttributeState)
173
164
 
174
165
  // 9. Set request's client to settings.
175
- initRequest.client = environmentSettingsObject.settingsObject
166
+ request.client = environmentSettingsObject.settingsObject
176
167
 
177
168
  // 10. User agents may set (`Accept`, `text/event-stream`) in request's header list.
178
- initRequest.headersList = [['accept', { name: 'accept', value: 'text/event-stream' }]]
169
+ request.headersList.set('Accept', 'text/event-stream')
179
170
 
180
171
  // 11. Set request's cache mode to "no-store".
181
- initRequest.cache = 'no-store'
172
+ request.cache = 'no-store'
182
173
 
183
174
  // 12. Set request's initiator type to "other".
184
- initRequest.initiator = 'other'
185
-
186
- initRequest.urlList = [new URL(this.#url)]
175
+ request.initiator = 'other'
187
176
 
188
177
  // 13. Set ev's request to request.
189
- this.#request = makeRequest(initRequest)
178
+ this.#request = request
190
179
 
191
180
  this.#connect()
192
181
  }
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const { makeRequest } = require('../fetch/request')
4
+
3
5
  /**
4
6
  * Checks if the given value is a valid LastEventId.
5
7
  * @param {string} value
@@ -23,7 +25,36 @@ function isASCIINumber (value) {
23
25
  return true
24
26
  }
25
27
 
28
+ function createPotentialCORSRequest (url, destination, corsAttributeState, sameOriginFallback) {
29
+ // 1. Let mode be "no-cors" if corsAttributeState is No CORS, and "cors" otherwise.
30
+ let mode = corsAttributeState === 'no cors' ? 'no-cors' : 'cors'
31
+
32
+ // 2. If same-origin fallback flag is set and mode is "no-cors", set mode to "same-origin".
33
+ if (sameOriginFallback && mode === 'no-cors') {
34
+ mode = 'same-origin'
35
+ }
36
+
37
+ // 3. Let credentialsMode be "include".
38
+ let credentialsMode = 'include'
39
+
40
+ // 4. If corsAttributeState is Anonymous, set credentialsMode to "same-origin".
41
+ if (corsAttributeState === 'anonymous') {
42
+ credentialsMode = 'same-origin'
43
+ }
44
+
45
+ // 5. Return a new request whose URL is url, destination is destination, mode is mode,
46
+ // credentials mode is credentialsMode, and whose use-URL-credentials flag is set.
47
+ return makeRequest({
48
+ urlList: [url],
49
+ destination,
50
+ mode,
51
+ credentials: credentialsMode,
52
+ useCredentials: true
53
+ })
54
+ }
55
+
26
56
  module.exports = {
27
57
  isValidLastEventId,
28
- isASCIINumber
58
+ isASCIINumber,
59
+ createPotentialCORSRequest
29
60
  }
@@ -392,6 +392,49 @@ function bodyMixinMethods (instance, getInternalState) {
392
392
  return consumeBody(this, (bytes) => {
393
393
  return new Uint8Array(bytes)
394
394
  }, instance, getInternalState)
395
+ },
396
+
397
+ textStream () {
398
+ const this_ = getInternalState(this)
399
+
400
+ // 1. If this is unusable, then throw a TypeError.
401
+ if (bodyUnusable(this_)) {
402
+ throw new TypeError('Body is unusable: Body has already been read')
403
+ }
404
+
405
+ // 2. If this’s body is null:
406
+ if (this_.body == null) {
407
+ // 2.1. Let emptyStream be a new ReadableStream in this’s relevant realm.
408
+ // 2.2. Set up emptyStream.
409
+ /** @type {ReadableStreamDefaultController<any>} */
410
+ let controller
411
+ const emptyStream = new ReadableStream({
412
+ start: (c) => {
413
+ controller = c
414
+ },
415
+ pull: () => Promise.resolve(),
416
+ cancel: () => Promise.resolve()
417
+ }, {
418
+ size: () => 1
419
+ })
420
+
421
+ // 2.3. Close emptyStream.
422
+ controller.close()
423
+
424
+ // 2.4. Return emptyStream.
425
+ return emptyStream
426
+ }
427
+
428
+ // 3. Let stream be this’s body’s stream.
429
+ /** @type {ReadableStream} */
430
+ const stream = this_.body.stream
431
+
432
+ // 4. Let decoder be a new TextDecoderStream object in this’s relevant realm.
433
+ // 5. Set up decoder with UTF-8.
434
+ const decoder = new TextDecoderStream('UTF-8')
435
+
436
+ // 6. Return the result of stream, piped through decoder.
437
+ return stream.pipeThrough(decoder)
395
438
  }
396
439
  }
397
440
 
@@ -11,7 +11,7 @@ const {
11
11
  getResponseState
12
12
  } = require('./response')
13
13
  const { HeadersList } = require('./headers')
14
- const { Request, cloneRequest, getRequestDispatcher, getRequestState } = require('./request')
14
+ const { Request, cloneRequest, getRequestDispatcher, getRequestState, removeRequestAbortListener } = require('./request')
15
15
  const zlib = require('node:zlib')
16
16
  const {
17
17
  makePolicyContainer,
@@ -208,7 +208,7 @@ function fetch (input, init = undefined) {
208
208
  let controller = null
209
209
 
210
210
  // 11. Add the following abort steps to requestObject’s signal:
211
- addAbortListener(
211
+ const removeAbortListener = addAbortListener(
212
212
  requestObject.signal,
213
213
  () => {
214
214
  // 1. Set locallyAborted to true.
@@ -228,6 +228,15 @@ function fetch (input, init = undefined) {
228
228
  }
229
229
  )
230
230
 
231
+ // Remove the `abort` listeners registered above and in the Request
232
+ // constructor once the fetch has settled. Without this, reusing a single
233
+ // signal across many requests leaks listeners and Node.js emits a
234
+ // MaxListenersExceededWarning. See https://github.com/nodejs/undici/issues/5285
235
+ const cleanupAbortListeners = () => {
236
+ removeAbortListener()
237
+ removeRequestAbortListener(requestObject)
238
+ }
239
+
231
240
  // 12. Let handleFetchDone given response response be to finalize and
232
241
  // report timing with response, globalObject, and "fetch".
233
242
  // see function handleFetchDone
@@ -252,6 +261,7 @@ function fetch (input, init = undefined) {
252
261
  // deserializedError.
253
262
 
254
263
  abortFetch(p, request, responseObject, controller.serializedAbortReason, controller.controller)
264
+ cleanupAbortListeners()
255
265
  return
256
266
  }
257
267
 
@@ -259,6 +269,7 @@ function fetch (input, init = undefined) {
259
269
  // and terminate these substeps.
260
270
  if (response.type === 'error') {
261
271
  p.reject(new TypeError('fetch failed', { cause: response.error }))
272
+ cleanupAbortListeners()
262
273
  return
263
274
  }
264
275
 
@@ -273,7 +284,10 @@ function fetch (input, init = undefined) {
273
284
 
274
285
  controller = fetching({
275
286
  request,
276
- processResponseEndOfBody: handleFetchDone,
287
+ processResponseEndOfBody: (response) => {
288
+ handleFetchDone(response)
289
+ cleanupAbortListeners()
290
+ },
277
291
  processResponse,
278
292
  dispatcher: getRequestDispatcher(requestObject), // undici
279
293
  // Keep requestObject alive to prevent its AbortController from being GC'd
@@ -97,6 +97,13 @@ class Request {
97
97
 
98
98
  #state
99
99
 
100
+ /**
101
+ * Removes the `abort` listener that makes this request's signal follow the
102
+ * passed signal. `null` when no such listener was registered.
103
+ * @type {(() => void) | null}
104
+ */
105
+ #abortCleanup = null
106
+
100
107
  // https://fetch.spec.whatwg.org/#dom-request
101
108
  constructor (input, init = undefined) {
102
109
  webidl.util.markAsUncloneable(this)
@@ -436,12 +443,23 @@ class Request {
436
443
  setMaxListeners(1500, signal)
437
444
  }
438
445
 
439
- util.addAbortListener(signal, abort)
446
+ const removeAbortListener = util.addAbortListener(signal, abort)
440
447
  // The third argument must be a registry key to be unregistered.
441
448
  // Without it, you cannot unregister.
442
449
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry
443
450
  // abort is used as the unregister key. (because it is unique)
444
451
  requestFinalizer.register(ac, { signal, abort }, abort)
452
+
453
+ // Allow the listener to be removed deterministically once the fetch
454
+ // that owns this request has settled, instead of relying solely on the
455
+ // FinalizationRegistry (i.e. garbage collection). Reusing a single
456
+ // signal across many requests would otherwise leak listeners.
457
+ // See https://github.com/nodejs/undici/issues/5285
458
+ this.#abortCleanup = () => {
459
+ requestFinalizer.unregister(abort)
460
+ removeAbortListener()
461
+ this.#abortCleanup = null
462
+ }
445
463
  }
446
464
  }
447
465
 
@@ -868,15 +886,25 @@ class Request {
868
886
  static setRequestState (request, newState) {
869
887
  request.#state = newState
870
888
  }
889
+
890
+ /**
891
+ * Removes the `abort` listener that makes this request's signal follow the
892
+ * signal passed to its constructor, if any. Idempotent.
893
+ * @param {Request} request
894
+ */
895
+ static removeRequestAbortListener (request) {
896
+ request.#abortCleanup?.()
897
+ }
871
898
  }
872
899
 
873
- const { setRequestSignal, getRequestDispatcher, setRequestDispatcher, setRequestHeaders, getRequestState, setRequestState } = Request
900
+ const { setRequestSignal, getRequestDispatcher, setRequestDispatcher, setRequestHeaders, getRequestState, setRequestState, removeRequestAbortListener } = Request
874
901
  Reflect.deleteProperty(Request, 'setRequestSignal')
875
902
  Reflect.deleteProperty(Request, 'getRequestDispatcher')
876
903
  Reflect.deleteProperty(Request, 'setRequestDispatcher')
877
904
  Reflect.deleteProperty(Request, 'setRequestHeaders')
878
905
  Reflect.deleteProperty(Request, 'getRequestState')
879
906
  Reflect.deleteProperty(Request, 'setRequestState')
907
+ Reflect.deleteProperty(Request, 'removeRequestAbortListener')
880
908
 
881
909
  mixinBody(Request, getRequestState)
882
910
 
@@ -902,6 +930,7 @@ function makeRequest (init) {
902
930
  referrerPolicy: init.referrerPolicy ?? '',
903
931
  mode: init.mode ?? 'no-cors',
904
932
  useCORSPreflightFlag: init.useCORSPreflightFlag ?? false,
933
+ // TODO: is this credentials mode? https://fetch.spec.whatwg.org/#concept-request-credentials-mode
905
934
  credentials: init.credentials ?? 'same-origin',
906
935
  useCredentials: init.useCredentials ?? false,
907
936
  cache: init.cache ?? 'default',
@@ -1111,5 +1140,6 @@ module.exports = {
1111
1140
  fromInnerRequest,
1112
1141
  cloneRequest,
1113
1142
  getRequestDispatcher,
1114
- getRequestState
1143
+ getRequestState,
1144
+ removeRequestAbortListener
1115
1145
  }
@@ -39,6 +39,9 @@ class ByteParser extends Writable {
39
39
  /** @type {import('./websocket').Handler} */
40
40
  #handler
41
41
 
42
+ /** @type {number} */
43
+ #maxFragments
44
+
42
45
  /** @type {number} */
43
46
  #maxPayloadSize
44
47
 
@@ -52,6 +55,7 @@ class ByteParser extends Writable {
52
55
 
53
56
  this.#handler = handler
54
57
  this.#extensions = extensions == null ? new Map() : extensions
58
+ this.#maxFragments = options.maxFragments ?? 0
55
59
  this.#maxPayloadSize = options.maxPayloadSize ?? 0
56
60
 
57
61
  if (this.#extensions.has('permessage-deflate')) {
@@ -75,7 +79,7 @@ class ByteParser extends Writable {
75
79
  if (
76
80
  this.#maxPayloadSize > 0 &&
77
81
  !isControlFrame(this.#info.opcode) &&
78
- this.#info.payloadLength > this.#maxPayloadSize
82
+ this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
79
83
  ) {
80
84
  failWebsocketConnection(this.#handler, 1009, 'Payload size exceeds maximum allowed size')
81
85
  return false
@@ -242,7 +246,9 @@ class ByteParser extends Writable {
242
246
  this.#state = parserStates.INFO
243
247
  } else {
244
248
  if (!this.#info.compressed) {
245
- this.writeFragments(body)
249
+ if (!this.writeFragments(body)) {
250
+ return
251
+ }
246
252
 
247
253
  // If the frame is not fragmented, a message has been received.
248
254
  // If the frame is fragmented, it will terminate with a fin bit set
@@ -264,7 +270,9 @@ class ByteParser extends Writable {
264
270
  return
265
271
  }
266
272
 
267
- this.writeFragments(data)
273
+ if (!this.writeFragments(data)) {
274
+ return
275
+ }
268
276
 
269
277
  // Check cumulative fragment size
270
278
  if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
@@ -345,8 +353,17 @@ class ByteParser extends Writable {
345
353
  }
346
354
 
347
355
  writeFragments (fragment) {
356
+ if (
357
+ this.#maxFragments > 0 &&
358
+ this.#fragments.length === this.#maxFragments
359
+ ) {
360
+ failWebsocketConnection(this.#handler, 1008, 'Too many message fragments')
361
+ return false
362
+ }
363
+
348
364
  this.#fragmentsBytes += fragment.length
349
365
  this.#fragments.push(fragment)
366
+ return true
350
367
  }
351
368
 
352
369
  consumeFragments () {
@@ -258,7 +258,14 @@ class WebSocketStream {
258
258
  #onConnectionEstablished (response, parsedExtensions) {
259
259
  this.#handler.socket = response.socket
260
260
 
261
- const parser = new ByteParser(this.#handler, parsedExtensions)
261
+ // Get options from dispatcher options
262
+ const maxFragments = this.#handler.controller.dispatcher?.webSocketOptions?.maxFragments
263
+ const maxPayloadSize = this.#handler.controller.dispatcher?.webSocketOptions?.maxPayloadSize
264
+
265
+ const parser = new ByteParser(this.#handler, parsedExtensions, {
266
+ maxFragments,
267
+ maxPayloadSize
268
+ })
262
269
  parser.on('drain', () => this.#handler.onParserDrain())
263
270
  parser.on('error', (err) => this.#handler.onParserError(err))
264
271
 
@@ -468,10 +468,12 @@ class WebSocket extends EventTarget {
468
468
  // once this happens, the connection is open
469
469
  this.#handler.socket = response.socket
470
470
 
471
- // Get maxPayloadSize from dispatcher options
471
+ // Get options from dispatcher options
472
+ const maxFragments = this.#handler.controller.dispatcher?.webSocketOptions?.maxFragments
472
473
  const maxPayloadSize = this.#handler.controller.dispatcher?.webSocketOptions?.maxPayloadSize
473
474
 
474
475
  const parser = new ByteParser(this.#handler, parsedExtensions, {
476
+ maxFragments,
475
477
  maxPayloadSize
476
478
  })
477
479
  parser.on('drain', () => this.#handler.onParserDrain())
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "undici",
3
- "version": "8.3.0",
3
+ "version": "8.5.0",
4
4
  "description": "An HTTP/1.1 client, written from scratch for Node.js",
5
5
  "homepage": "https://undici.nodejs.org",
6
6
  "bugs": {
@@ -116,6 +116,11 @@ export declare namespace Client {
116
116
  bytesRead?: number
117
117
  }
118
118
  export interface WebSocketOptions {
119
+ /**
120
+ * Maximum number of fragments in a message. Set to 0 to disable the limit.
121
+ * @default 131072
122
+ */
123
+ maxFragments?: number;
119
124
  /**
120
125
  * Maximum allowed payload size in bytes for WebSocket messages.
121
126
  * Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages.
@@ -7,6 +7,7 @@ declare function buildConnector (options?: buildConnector.BuildOptions): buildCo
7
7
  declare namespace buildConnector {
8
8
  export type BuildOptions = (ConnectionOptions | TcpNetConnectOpts | IpcNetConnectOpts) & {
9
9
  allowH2?: boolean;
10
+ preferH2?: boolean;
10
11
  maxCachedSessions?: number | null;
11
12
  socketPath?: string | null;
12
13
  timeout?: number | null;
@@ -36,7 +36,10 @@ export class BodyMixin {
36
36
  readonly bytes: () => Promise<Uint8Array>
37
37
  /**
38
38
  * @deprecated This method is not recommended for parsing multipart/form-data bodies in server environments.
39
- * It is recommended to use a library such as [@fastify/busboy](https://www.npmjs.com/package/@fastify/busboy) as follows:
39
+ * Calling body.formData() buffers and parses the entire body. Since this is dictated by the spec,
40
+ * this method must only be called on responses from trusted servers.
41
+ * For responses from untrusted or user-controlled servers, use a dedicated streaming parser such as
42
+ * [@fastify/busboy](https://www.npmjs.com/package/@fastify/busboy) and apply application-specific limits as follows:
40
43
  *
41
44
  * @example
42
45
  * ```js
@@ -54,6 +57,7 @@ export class BodyMixin {
54
57
  readonly formData: () => Promise<FormData>
55
58
  readonly json: () => Promise<unknown>
56
59
  readonly text: () => Promise<string>
60
+ readonly textStream: () => ReadableStream<string>
57
61
  }
58
62
 
59
63
  export interface SpecIterator<T, TReturn = any, TNext = undefined> {
@@ -8,7 +8,7 @@ export default Interceptors
8
8
  declare namespace Interceptors {
9
9
  export type DumpInterceptorOpts = { maxSize?: number }
10
10
  export type RetryInterceptorOpts = RetryHandler.RetryOptions
11
- export type RedirectInterceptorOpts = { maxRedirections?: number, throwOnMaxRedirect?: boolean }
11
+ export type RedirectInterceptorOpts = { maxRedirections?: number, throwOnMaxRedirect?: boolean, stripHeadersOnRedirect?: string[], stripHeadersOnCrossOriginRedirect?: string[] }
12
12
  export type DecompressInterceptorOpts = {
13
13
  skipErrorResponses?: boolean
14
14
  skipStatusCodes?: number[]
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@openclaw/discord",
3
- "version": "2026.6.8",
3
+ "version": "2026.6.9-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/discord",
9
- "version": "2026.6.8",
9
+ "version": "2026.6.9-beta.1",
10
10
  "dependencies": {
11
11
  "@discordjs/voice": "0.19.2",
12
12
  "discord-api-types": "0.38.48",
13
13
  "libopus-wasm": "0.2.0",
14
14
  "typebox": "1.1.39",
15
- "undici": "8.3.0",
15
+ "undici": "8.5.0",
16
16
  "ws": "8.21.0"
17
17
  },
18
18
  "peerDependencies": {
19
- "openclaw": ">=2026.6.8"
19
+ "openclaw": ">=2026.6.9-beta.1"
20
20
  },
21
21
  "peerDependenciesMeta": {
22
22
  "openclaw": {
@@ -399,9 +399,9 @@
399
399
  "license": "MIT"
400
400
  },
401
401
  "node_modules/undici": {
402
- "version": "8.3.0",
403
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.3.0.tgz",
404
- "integrity": "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==",
402
+ "version": "8.5.0",
403
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
404
+ "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
405
405
  "license": "MIT",
406
406
  "engines": {
407
407
  "node": ">=22.19.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/discord",
3
- "version": "2026.6.8",
3
+ "version": "2026.6.9-beta.1",
4
4
  "description": "OpenClaw Discord channel plugin for channels, DMs, commands, and app events.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,11 +12,11 @@
12
12
  "discord-api-types": "0.38.48",
13
13
  "libopus-wasm": "0.2.0",
14
14
  "typebox": "1.1.39",
15
- "undici": "8.3.0",
15
+ "undici": "8.5.0",
16
16
  "ws": "8.21.0"
17
17
  },
18
18
  "peerDependencies": {
19
- "openclaw": ">=2026.6.8"
19
+ "openclaw": ">=2026.6.9-beta.1"
20
20
  },
21
21
  "peerDependenciesMeta": {
22
22
  "openclaw": {
@@ -63,10 +63,10 @@
63
63
  "allowInvalidConfigRecovery": true
64
64
  },
65
65
  "compat": {
66
- "pluginApi": ">=2026.6.8"
66
+ "pluginApi": ">=2026.6.9-beta.1"
67
67
  },
68
68
  "build": {
69
- "openclawVersion": "2026.6.8"
69
+ "openclawVersion": "2026.6.9-beta.1"
70
70
  },
71
71
  "release": {
72
72
  "publishToClawHub": true,
@@ -1,2 +0,0 @@
1
- import { t as monitorDiscordProvider } from "./provider-DrScDA1p.js";
2
- export { monitorDiscordProvider };
@@ -1,6 +0,0 @@
1
- import "./allow-list-C-MqM-B_.js";
2
- import "./timeouts-C5TBc_9x.js";
3
- import "./provider-DrScDA1p.js";
4
- import "./message-utils-Bx993JLN.js";
5
- import "./message-handler-CQVkXHMN.js";
6
- export {};
@@ -1,3 +0,0 @@
1
- import "./send.receipt-DsQWEQ2O.js";
2
- import "./target-resolver-DMPTzuo7.js";
3
- export {};