@openclaw/discord 2026.10.2 → 2026.10.5-beta.2

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 (246) hide show
  1. package/dist/.setup/account-inspect-8cCu6uPG.mjs +31 -0
  2. package/dist/.setup/{accounts-HE9-mj1L.mjs → accounts-ljrzXBJi.mjs} +47 -45
  3. package/dist/.setup/{allow-list-vxkG9_JD.mjs → allow-list-B_ToXtew.mjs} +34 -101
  4. package/dist/.setup/{api-DlNUkDqj.mjs → api-CtmE1OUN.mjs} +25 -31
  5. package/dist/.setup/{approval-handler.runtime-DmnEa54W.mjs → approval-handler.runtime-D7FoZSn0.mjs} +30 -53
  6. package/dist/.setup/{approval-message-updates-B0jdSqOj.mjs → approval-message-updates-CIGByUcE.mjs} +2 -2
  7. package/dist/.setup/{audit-BpikUwN_.mjs → audit-zSawfbsN.mjs} +5 -8
  8. package/dist/.setup/{channel-Dr-AUnGt.mjs → channel-DI7DMzu0.mjs} +136 -215
  9. package/dist/.setup/{channel-access-BRp3Y-rF.mjs → channel-access-DasWY_OV.mjs} +6 -7
  10. package/dist/.setup/{channel.setup-BmNvkidb.mjs → channel.setup-DdFVN1mr.mjs} +35 -64
  11. package/dist/.setup/{components-DLJR0xU-.mjs → components-HN9052L1.mjs} +123 -146
  12. package/dist/.setup/{config-schema-BQWfnSCx.mjs → config-schema-_uBILpQf.mjs} +7 -3
  13. package/dist/.setup/{conversation-binding-route-DicJC1Lj.mjs → conversation-binding-route-DTjCBx-O.mjs} +1 -1
  14. package/dist/.setup/{directory-config-gqsdcplU.mjs → directory-config-3iVub-3m.mjs} +1 -1
  15. package/dist/.setup/{directory-live-Bipr0eUJ.mjs → directory-live-DLygQVtW.mjs} +18 -22
  16. package/dist/.setup/{discord-9gysrhzp.mjs → discord-BGqgx-yd.mjs} +686 -854
  17. package/dist/.setup/{doctor-B2bskDcF.mjs → doctor-DSrNJ7m2.mjs} +36 -47
  18. package/dist/.setup/{doctor-contract-Bg3NPAMw.mjs → doctor-contract-Bwv8EuQ_.mjs} +7 -16
  19. package/dist/.setup/{handle-action-UmkjXBfo.mjs → handle-action-CXH1h1tq.mjs} +25 -38
  20. package/dist/.setup/{handle-action.guild-admin-CB4sc9VV.mjs → handle-action.guild-admin-CHKW6PIs.mjs} +25 -31
  21. package/dist/.setup/{live-policy-config-VxexfRKo.mjs → live-policy-config-BPoB3eQi.mjs} +1 -1
  22. package/dist/.setup/{message-handler-BK69A-NB.mjs → message-handler-Ii_etru1.mjs} +9 -14
  23. package/dist/.setup/{message-handler.preflight-DFpsh90H.mjs → message-handler.preflight-C7YuSRl_.mjs} +79 -128
  24. package/dist/.setup/{message-handler.preflight-pluralkit-BXGGVmpe.mjs → message-handler.preflight-pluralkit-C3iAG--b.mjs} +6 -6
  25. package/dist/.setup/{message-handler.process-TKoqcqIP.mjs → message-handler.process-ClgWYH6o.mjs} +234 -206
  26. package/dist/.setup/{outbound-adapter-D4wRAb5S.mjs → outbound-adapter-D8OOIuKn.mjs} +73 -112
  27. package/dist/.setup/{outbound-session-route-BvBH4LC6.mjs → outbound-session-route-B0Hpwn3Q.mjs} +57 -115
  28. package/dist/.setup/output-activity-uBpMSX75.mjs +11 -0
  29. package/dist/.setup/{pluralkit-a6_NLfH9.mjs → pluralkit-B64dfq_j.mjs} +3 -1
  30. package/dist/.setup/{preflight-audio-DHGIHEpv.mjs → preflight-audio-wWgsZG5F.mjs} +1 -5
  31. package/dist/.setup/{presence-cache-Dg3_dADn.mjs → presence-cache-DCeTsL73.mjs} +3 -6
  32. package/dist/.setup/{probe-BwSKpnZf.mjs → probe-D3P1x4aN.mjs} +10 -18
  33. package/dist/.setup/{provider-YP8gN9_o.mjs → provider-D9EzOfG8.mjs} +2990 -3903
  34. package/dist/.setup/{provider-session.runtime-D1gkPxHT.mjs → provider-session.runtime-CsnRvddI.mjs} +5 -5
  35. package/dist/.setup/provider.runtime-BQVcM7Pg.mjs +2 -0
  36. package/dist/.setup/{realtime-session.runtime-BKUQBy1u.mjs → realtime-session.runtime-CxGBk8H-.mjs} +69 -98
  37. package/dist/.setup/{receive-recovery-DgkX7Qvi.mjs → receive-recovery-eVmK2_hl.mjs} +2 -12
  38. package/dist/.setup/resolve-allowlist-common-DNSsUQRF.mjs +66 -0
  39. package/dist/.setup/resolve-channels-UdT38DzU.mjs +173 -0
  40. package/dist/.setup/{resolve-users-DNrwvunm.mjs → resolve-users-DnCsrXZ_.mjs} +12 -41
  41. package/dist/.setup/{runtime-CESTexGn.mjs → runtime-CRTkKU1G.mjs} +202 -313
  42. package/dist/.setup/{runtime-DPcmPST9.mjs → runtime-DPm3gZXk.mjs} +2 -2
  43. package/dist/.setup/{secret-config-contract-uOE2J7yM.mjs → secret-config-contract-CIsH7R3B.mjs} +9 -18
  44. package/dist/.setup/{security-audit-D42cp5N7.mjs → security-audit-BFT84Uny.mjs} +1 -2
  45. package/dist/.setup/security-contract-DNyyjTZZ.mjs +19 -0
  46. package/dist/.setup/{send-CJk3VP5q.mjs → send-DbILKgcm.mjs} +184 -241
  47. package/dist/.setup/{send.components-dPljuV24.mjs → send.components-FxOS3CeP.mjs} +47 -63
  48. package/dist/.setup/{send.outbound-rOboMO_6.mjs → send.outbound-_jx4Xpd3.mjs} +178 -202
  49. package/dist/.setup/{send.receipt-DVOg2Oaw.mjs → send.receipt-BAlzXd8e.mjs} +33 -109
  50. package/dist/.setup/{send.shared-C4CN24D9.mjs → send.shared-CjQ4jbMA.mjs} +97 -153
  51. package/dist/.setup/{sender-identity-AHpUNr72.mjs → sender-identity-BNBvGt1l.mjs} +1 -1
  52. package/dist/.setup/setup-plugin-api-xfOFmxHP.mjs +3 -0
  53. package/dist/.setup/{shared-BoBnM5kM.mjs → shared-CestGDpq.mjs} +30 -20
  54. package/dist/.setup/{subagent-hooks-HH8Uy9cx.mjs → subagent-hooks-CME7dSGf.mjs} +5 -10
  55. package/dist/.setup/{system-events-Cwxaww8i.mjs → system-events-BwwSDCw4.mjs} +2 -2
  56. package/dist/.setup/target-parsing-C-HyNxcE.mjs +48 -0
  57. package/dist/.setup/{target-resolver-CSFoPQ12.mjs → target-resolver-Bse8fuTi.mjs} +11 -27
  58. package/dist/.setup/targets-DZJjkzwv.mjs +3 -0
  59. package/dist/.setup/{thread-bindings-DjQCkmsd.mjs → thread-bindings-0hPTSK14.mjs} +61 -52
  60. package/dist/.setup/{thread-bindings.manager-D2-GYZ5s.mjs → thread-bindings.manager-CdNa6UIs.mjs} +138 -211
  61. package/dist/.setup/{thread-bindings.session-updates-Bu_CGr_O.mjs → thread-bindings.session-updates-DGSljVf6.mjs} +60 -99
  62. package/dist/.setup/threading-BKe3E3tp.mjs +246 -0
  63. package/dist/.setup/{timeouts-pun7VJ02.mjs → timeouts-CuNARfyw.mjs} +10 -18
  64. package/dist/.setup/{transcripts-source-CaZQnGRH.mjs → transcripts-source-0qQYVu2H.mjs} +50 -368
  65. package/dist/.setup/{voice-runtime-DDymtIw8.mjs → voice-runtime-QlZJ4sHv.mjs} +166 -322
  66. package/dist/account-inspect-api.js +1 -1
  67. package/dist/action-runtime-api.js +1 -1
  68. package/dist/activities-api.js +77 -120
  69. package/dist/api.js +19 -18
  70. package/dist/channel-config-api.js +1 -1
  71. package/dist/channel-plugin-api.js +1 -1
  72. package/dist/directory-contract-api.js +1 -1
  73. package/dist/doctor-contract-api.js +1 -1
  74. package/dist/runtime-api.js +21 -20
  75. package/dist/secret-contract-api.js +1 -1
  76. package/dist/security-audit-contract-api.js +1 -1
  77. package/dist/security-contract-api.js +1 -1
  78. package/dist/setup-entry.js +1 -1
  79. package/dist/setup-plugin-api.js +1 -1
  80. package/dist/src/voice/audio-worker.runtime.js +38 -57
  81. package/dist/subagent-hooks-api.js +1 -1
  82. package/dist/transcripts-source-api.js +1 -1
  83. package/node_modules/@types/node/README.md +1 -1
  84. package/node_modules/@types/node/crypto.d.ts +2 -2
  85. package/node_modules/@types/node/dgram.d.ts +1 -1
  86. package/node_modules/@types/node/package.json +2 -2
  87. package/node_modules/@types/node/zlib.d.ts +6 -0
  88. package/node_modules/@types/ws/README.md +1 -1
  89. package/node_modules/@types/ws/index.d.mts +4 -0
  90. package/node_modules/@types/ws/index.d.ts +4 -0
  91. package/node_modules/@types/ws/package.json +3 -3
  92. package/node_modules/discord-api-types/_generated_/rest/v10/interfaces.d.ts +21 -0
  93. package/node_modules/discord-api-types/_generated_/rest/v10/interfaces.d.ts.map +1 -1
  94. package/node_modules/discord-api-types/_generated_/rest/v9/interfaces.d.ts +21 -0
  95. package/node_modules/discord-api-types/_generated_/rest/v9/interfaces.d.ts.map +1 -1
  96. package/node_modules/discord-api-types/globals.d.ts +6 -0
  97. package/node_modules/discord-api-types/globals.d.ts.map +1 -1
  98. package/node_modules/discord-api-types/globals.js +6 -0
  99. package/node_modules/discord-api-types/globals.js.map +1 -1
  100. package/node_modules/discord-api-types/package.json +3 -3
  101. package/node_modules/discord-api-types/payloads/index.mjs +1 -0
  102. package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.d.ts +207 -0
  103. package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.d.ts.map +1 -0
  104. package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.js +25 -0
  105. package/node_modules/discord-api-types/payloads/v10/applicationIdentityProfile.js.map +1 -0
  106. package/node_modules/discord-api-types/payloads/v10/autoModeration.d.ts +1 -1
  107. package/node_modules/discord-api-types/payloads/v10/autoModeration.d.ts.map +1 -1
  108. package/node_modules/discord-api-types/payloads/v10/guild.d.ts +27 -23
  109. package/node_modules/discord-api-types/payloads/v10/guild.d.ts.map +1 -1
  110. package/node_modules/discord-api-types/payloads/v10/guild.js +26 -22
  111. package/node_modules/discord-api-types/payloads/v10/guild.js.map +1 -1
  112. package/node_modules/discord-api-types/payloads/v10/index.d.ts +1 -0
  113. package/node_modules/discord-api-types/payloads/v10/index.d.ts.map +1 -1
  114. package/node_modules/discord-api-types/payloads/v10/index.js +1 -0
  115. package/node_modules/discord-api-types/payloads/v10/index.js.map +1 -1
  116. package/node_modules/discord-api-types/payloads/v10/index.mjs +1 -0
  117. package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.d.ts +207 -0
  118. package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.d.ts.map +1 -0
  119. package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.js +25 -0
  120. package/node_modules/discord-api-types/payloads/v9/applicationIdentityProfile.js.map +1 -0
  121. package/node_modules/discord-api-types/payloads/v9/autoModeration.d.ts +1 -1
  122. package/node_modules/discord-api-types/payloads/v9/autoModeration.d.ts.map +1 -1
  123. package/node_modules/discord-api-types/payloads/v9/guild.d.ts +27 -23
  124. package/node_modules/discord-api-types/payloads/v9/guild.d.ts.map +1 -1
  125. package/node_modules/discord-api-types/payloads/v9/guild.js +26 -22
  126. package/node_modules/discord-api-types/payloads/v9/guild.js.map +1 -1
  127. package/node_modules/discord-api-types/payloads/v9/index.d.ts +1 -0
  128. package/node_modules/discord-api-types/payloads/v9/index.d.ts.map +1 -1
  129. package/node_modules/discord-api-types/payloads/v9/index.js +1 -0
  130. package/node_modules/discord-api-types/payloads/v9/index.js.map +1 -1
  131. package/node_modules/discord-api-types/payloads/v9/index.mjs +1 -0
  132. package/node_modules/discord-api-types/rest/common.d.ts +2 -0
  133. package/node_modules/discord-api-types/rest/common.d.ts.map +1 -1
  134. package/node_modules/discord-api-types/rest/common.js +2 -0
  135. package/node_modules/discord-api-types/rest/common.js.map +1 -1
  136. package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.d.ts +70 -0
  137. package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.d.ts.map +1 -0
  138. package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.js +3 -0
  139. package/node_modules/discord-api-types/rest/v10/applicationIdentityProfile.js.map +1 -0
  140. package/node_modules/discord-api-types/rest/v10/index.d.ts +1 -0
  141. package/node_modules/discord-api-types/rest/v10/index.d.ts.map +1 -1
  142. package/node_modules/discord-api-types/rest/v10/index.js +29 -0
  143. package/node_modules/discord-api-types/rest/v10/index.js.map +1 -1
  144. package/node_modules/discord-api-types/rest/v10/interactions.d.ts +4 -2
  145. package/node_modules/discord-api-types/rest/v10/interactions.d.ts.map +1 -1
  146. package/node_modules/discord-api-types/rest/v10/user.d.ts +2 -2
  147. package/node_modules/discord-api-types/rest/v10/user.d.ts.map +1 -1
  148. package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.d.ts +70 -0
  149. package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.d.ts.map +1 -0
  150. package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.js +3 -0
  151. package/node_modules/discord-api-types/rest/v9/applicationIdentityProfile.js.map +1 -0
  152. package/node_modules/discord-api-types/rest/v9/index.d.ts +1 -0
  153. package/node_modules/discord-api-types/rest/v9/index.d.ts.map +1 -1
  154. package/node_modules/discord-api-types/rest/v9/index.js +29 -0
  155. package/node_modules/discord-api-types/rest/v9/index.js.map +1 -1
  156. package/node_modules/discord-api-types/rest/v9/interactions.d.ts +4 -2
  157. package/node_modules/discord-api-types/rest/v9/interactions.d.ts.map +1 -1
  158. package/node_modules/discord-api-types/rest/v9/user.d.ts +2 -2
  159. package/node_modules/discord-api-types/rest/v9/user.d.ts.map +1 -1
  160. package/node_modules/discord-api-types/v10.mjs +1 -0
  161. package/node_modules/discord-api-types/v9.mjs +1 -0
  162. package/node_modules/micromark/dev/lib/compile.d.ts.map +1 -1
  163. package/node_modules/micromark/dev/lib/compile.js +14 -4
  164. package/node_modules/micromark/dev/lib/create-tokenizer.d.ts.map +1 -1
  165. package/node_modules/micromark/dev/lib/create-tokenizer.js +7 -6
  166. package/node_modules/micromark/dev/lib/initialize/document.js +25 -21
  167. package/node_modules/micromark/dev/lib/initialize/text.d.ts.map +1 -1
  168. package/node_modules/micromark/dev/lib/initialize/text.js +10 -6
  169. package/node_modules/micromark/dev/lib/preprocess.d.ts.map +1 -1
  170. package/node_modules/micromark/dev/lib/preprocess.js +19 -21
  171. package/node_modules/micromark/lib/compile.d.ts.map +1 -1
  172. package/node_modules/micromark/lib/compile.js +37 -29
  173. package/node_modules/micromark/lib/create-tokenizer.d.ts.map +1 -1
  174. package/node_modules/micromark/lib/create-tokenizer.js +37 -35
  175. package/node_modules/micromark/lib/initialize/document.js +21 -13
  176. package/node_modules/micromark/lib/initialize/text.d.ts.map +1 -1
  177. package/node_modules/micromark/lib/initialize/text.js +7 -3
  178. package/node_modules/micromark/lib/preprocess.d.ts.map +1 -1
  179. package/node_modules/micromark/lib/preprocess.js +16 -19
  180. package/node_modules/micromark/package.json +2 -15
  181. package/node_modules/micromark-core-commonmark/dev/lib/attention.js +18 -24
  182. package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.d.ts.map +1 -1
  183. package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.js +1 -43
  184. package/node_modules/micromark-core-commonmark/dev/lib/code-indented.js +19 -43
  185. package/node_modules/micromark-core-commonmark/dev/lib/heading-atx.js +2 -6
  186. package/node_modules/micromark-core-commonmark/dev/lib/html-flow.d.ts.map +1 -1
  187. package/node_modules/micromark-core-commonmark/dev/lib/html-flow.js +2 -53
  188. package/node_modules/micromark-core-commonmark/dev/lib/label-end.js +14 -12
  189. package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.d.ts.map +1 -1
  190. package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.js +14 -5
  191. package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.d.ts.map +1 -1
  192. package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.js +14 -5
  193. package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.d.ts +4 -0
  194. package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.d.ts.map +1 -0
  195. package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.js +67 -0
  196. package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.d.ts.map +1 -1
  197. package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.js +8 -5
  198. package/node_modules/micromark-core-commonmark/lib/attention.js +14 -24
  199. package/node_modules/micromark-core-commonmark/lib/code-fenced.d.ts.map +1 -1
  200. package/node_modules/micromark-core-commonmark/lib/code-fenced.js +1 -39
  201. package/node_modules/micromark-core-commonmark/lib/code-indented.js +11 -29
  202. package/node_modules/micromark-core-commonmark/lib/heading-atx.js +2 -6
  203. package/node_modules/micromark-core-commonmark/lib/html-flow.d.ts.map +1 -1
  204. package/node_modules/micromark-core-commonmark/lib/html-flow.js +2 -51
  205. package/node_modules/micromark-core-commonmark/lib/label-end.js +11 -10
  206. package/node_modules/micromark-core-commonmark/lib/label-start-image.d.ts.map +1 -1
  207. package/node_modules/micromark-core-commonmark/lib/label-start-image.js +11 -3
  208. package/node_modules/micromark-core-commonmark/lib/label-start-link.d.ts.map +1 -1
  209. package/node_modules/micromark-core-commonmark/lib/label-start-link.js +11 -3
  210. package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.d.ts +4 -0
  211. package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.d.ts.map +1 -0
  212. package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.js +61 -0
  213. package/node_modules/micromark-core-commonmark/lib/setext-underline.d.ts.map +1 -1
  214. package/node_modules/micromark-core-commonmark/lib/setext-underline.js +7 -5
  215. package/node_modules/micromark-core-commonmark/package.json +4 -16
  216. package/node_modules/micromark-factory-space/dev/index.d.ts +24 -1
  217. package/node_modules/micromark-factory-space/dev/index.d.ts.map +1 -1
  218. package/node_modules/micromark-factory-space/dev/index.js +58 -3
  219. package/node_modules/micromark-factory-space/index.d.ts +24 -1
  220. package/node_modules/micromark-factory-space/index.d.ts.map +1 -1
  221. package/node_modules/micromark-factory-space/index.js +55 -3
  222. package/node_modules/micromark-factory-space/package.json +1 -10
  223. package/node_modules/micromark-factory-space/readme.md +25 -25
  224. package/node_modules/micromark-util-edit-map/dev/index.d.ts +78 -0
  225. package/node_modules/micromark-util-edit-map/dev/index.d.ts.map +1 -0
  226. package/node_modules/micromark-util-edit-map/dev/index.js +237 -0
  227. package/node_modules/micromark-util-edit-map/index.d.ts +78 -0
  228. package/node_modules/micromark-util-edit-map/index.d.ts.map +1 -0
  229. package/node_modules/micromark-util-edit-map/index.js +225 -0
  230. package/node_modules/micromark-util-edit-map/license +22 -0
  231. package/node_modules/micromark-util-edit-map/package.json +48 -0
  232. package/node_modules/micromark-util-edit-map/readme.md +234 -0
  233. package/node_modules/micromark-util-types/index.d.ts +6 -3
  234. package/node_modules/micromark-util-types/package.json +2 -36
  235. package/node_modules/ws/lib/websocket.js +17 -3
  236. package/node_modules/ws/package.json +1 -1
  237. package/openclaw.plugin.json +3 -6
  238. package/package.json +7 -12
  239. package/dist/.setup/account-inspect-DsER5ILV.mjs +0 -45
  240. package/dist/.setup/provider.runtime-CZ51OIgD.mjs +0 -2
  241. package/dist/.setup/resolve-allowlist-common-BUyU3C-T.mjs +0 -27
  242. package/dist/.setup/resolve-channels-DA6QlhZN.mjs +0 -246
  243. package/dist/.setup/security-contract-DSHk7I2w.mjs +0 -26
  244. package/dist/.setup/setup-plugin-api-BVlCz3fm.mjs +0 -3
  245. package/dist/.setup/targets-bqXQENmX.mjs +0 -3
  246. package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +0 -1
@@ -1,7 +1,7 @@
1
1
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.mjs";
2
2
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
3
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
4
3
  import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
4
+ import { asOptionalObjectRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { resolveNonNegativeIntegerOption, resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
6
6
  import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
7
7
  import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
@@ -58,6 +58,12 @@ function openThreadBindingsStore() {
58
58
  maxEntries: THREAD_BINDINGS_MAX_ENTRIES
59
59
  });
60
60
  }
61
+ function openThreadBindingsStoreAsync() {
62
+ return getDiscordRuntime().state.openKeyedStore({
63
+ namespace: THREAD_BINDINGS_NAMESPACE,
64
+ maxEntries: THREAD_BINDINGS_MAX_ENTRIES
65
+ });
66
+ }
61
67
  function normalizeTargetKind(raw, targetSessionKey) {
62
68
  if (raw === "subagent" || raw === "acp") return raw;
63
69
  return targetSessionKey.includes(":subagent:") ? "subagent" : "acp";
@@ -69,7 +75,7 @@ function resolveBindingRecordKey(params) {
69
75
  const threadId = normalizeOptionalStringifiedId(params.threadId);
70
76
  if (!threadId) return;
71
77
  return toBindingRecordKey({
72
- accountId: normalizeAccountId(params.accountId),
78
+ accountId: params.accountId,
73
79
  threadId
74
80
  });
75
81
  }
@@ -92,7 +98,7 @@ function normalizePersistedBinding(threadIdKey, raw) {
92
98
  const idleTimeoutMs = resolveOptionalIntegerOption(value.idleTimeoutMs, { min: 0 });
93
99
  const maxAgeMs = resolveOptionalIntegerOption(value.maxAgeMs, { min: 0 });
94
100
  const metadata = value.metadata && typeof value.metadata === "object" ? { ...value.metadata } : void 0;
95
- const record = {
101
+ return {
96
102
  accountId,
97
103
  channelId,
98
104
  threadId,
@@ -101,15 +107,14 @@ function normalizePersistedBinding(threadIdKey, raw) {
101
107
  agentId,
102
108
  boundBy,
103
109
  boundAt,
104
- lastActivityAt
110
+ lastActivityAt,
111
+ ...label !== void 0 ? { label } : {},
112
+ ...webhookId !== void 0 ? { webhookId } : {},
113
+ ...webhookToken !== void 0 ? { webhookToken } : {},
114
+ ...idleTimeoutMs !== void 0 ? { idleTimeoutMs } : {},
115
+ ...maxAgeMs !== void 0 ? { maxAgeMs } : {},
116
+ ...metadata !== void 0 ? { metadata } : {}
105
117
  };
106
- if (label !== void 0) record.label = label;
107
- if (webhookId !== void 0) record.webhookId = webhookId;
108
- if (webhookToken !== void 0) record.webhookToken = webhookToken;
109
- if (idleTimeoutMs !== void 0) record.idleTimeoutMs = idleTimeoutMs;
110
- if (maxAgeMs !== void 0) record.maxAgeMs = maxAgeMs;
111
- if (metadata !== void 0) record.metadata = metadata;
112
- return record;
113
118
  }
114
119
  function normalizeThreadBindingDurationMs(raw, defaultsTo) {
115
120
  const durationMs = resolveOptionalIntegerOption(raw);
@@ -145,17 +150,11 @@ function resolvePreparedThreadBindingLifecycle(params) {
145
150
  };
146
151
  }
147
152
  function resolveThreadBindingInactivityExpiresAt(params) {
148
- const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs({
149
- record: params.record,
150
- defaultIdleTimeoutMs: params.defaultIdleTimeoutMs
151
- });
153
+ const idleTimeoutMs = resolveThreadBindingIdleTimeoutMs(params);
152
154
  return resolveTimestampExpiry(params.record.lastActivityAt, idleTimeoutMs);
153
155
  }
154
156
  function resolveThreadBindingMaxAgeExpiresAt(params) {
155
- const maxAgeMs = resolveThreadBindingMaxAgeMs({
156
- record: params.record,
157
- defaultMaxAgeMs: params.defaultMaxAgeMs
158
- });
157
+ const maxAgeMs = resolveThreadBindingMaxAgeMs(params);
159
158
  return resolveTimestampExpiry(params.record.boundAt, maxAgeMs);
160
159
  }
161
160
  function linkSessionBinding(targetSessionKey, bindingKey) {
@@ -180,10 +179,7 @@ function rememberReusableWebhook(record) {
180
179
  const webhookId = record.webhookId?.trim();
181
180
  const webhookToken = record.webhookToken?.trim();
182
181
  if (!webhookId || !webhookToken) return;
183
- const key = toReusableWebhookKey({
184
- accountId: record.accountId,
185
- channelId: record.channelId
186
- });
182
+ const key = toReusableWebhookKey(record);
187
183
  REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL.set(key, {
188
184
  webhookId,
189
185
  webhookToken
@@ -200,10 +196,7 @@ function refreshUnboundThreadWebhookIdentity(record) {
200
196
  });
201
197
  }
202
198
  function setBindingRecord(record) {
203
- const bindingKey = toBindingRecordKey({
204
- accountId: record.accountId,
205
- threadId: record.threadId
206
- });
199
+ const bindingKey = toBindingRecordKey(record);
207
200
  const existing = BINDINGS_BY_THREAD_ID.get(bindingKey);
208
201
  if (existing) unlinkSessionBinding(existing.targetSessionKey, bindingKey);
209
202
  BINDINGS_BY_THREAD_ID.set(bindingKey, record);
@@ -234,8 +227,7 @@ function restoreBindings(entries) {
234
227
  THREAD_BINDINGS_STATE.loadedPersistentBindings = entries.length > 0;
235
228
  for (const entry of entries) {
236
229
  const normalized = normalizePersistedBinding(entry.key, entry.value);
237
- if (!normalized) continue;
238
- setBindingRecord(normalized);
230
+ if (normalized) setBindingRecord(normalized);
239
231
  }
240
232
  }
241
233
  function ensureBindingsLoaded() {
@@ -253,10 +245,7 @@ function ensureBindingsLoaded() {
253
245
  async function loadBindingsAsync() {
254
246
  let entries;
255
247
  try {
256
- entries = await getDiscordRuntime().state.openKeyedStore({
257
- namespace: THREAD_BINDINGS_NAMESPACE,
258
- maxEntries: THREAD_BINDINGS_MAX_ENTRIES
259
- }).entries();
248
+ entries = await openThreadBindingsStoreAsync().entries();
260
249
  } catch {
261
250
  if (!THREAD_BINDINGS_STATE.loadedBindings) {
262
251
  beginBindingsLoad();
@@ -279,34 +268,28 @@ async function ensureBindingsLoadedAsync() {
279
268
  }
280
269
  }
281
270
  function resolveBindingIdsForSession(params) {
282
- const key = params.targetSessionKey.trim();
283
- if (!key) return [];
284
- const ids = BINDINGS_BY_SESSION_KEY.get(key);
285
- if (!ids) return [];
286
271
  const out = [];
287
- for (const bindingKey of ids.values()) {
272
+ for (const bindingKey of BINDINGS_BY_SESSION_KEY.get(params.targetSessionKey.trim()) ?? []) {
288
273
  const record = BINDINGS_BY_THREAD_ID.get(bindingKey);
289
- if (!record) continue;
290
- if (params.accountId && record.accountId !== params.accountId) continue;
291
- if (params.targetKind && record.targetKind !== params.targetKind) continue;
292
- out.push(bindingKey);
274
+ if (record && (!params.accountId || record.accountId === params.accountId) && (!params.targetKind || record.targetKind === params.targetKind)) out.push(bindingKey);
293
275
  }
294
276
  return out;
295
277
  }
296
278
  //#endregion
297
279
  //#region extensions/discord/src/monitor/thread-bindings.persistence.ts
298
280
  function shouldPersistAnyBindingState() {
299
- for (const value of PERSIST_BY_ACCOUNT_ID.values()) if (value) return true;
300
- return false;
281
+ return [...PERSIST_BY_ACCOUNT_ID.values()].some(Boolean);
301
282
  }
302
283
  function shouldPersistBindingMutations() {
303
- if (shouldPersistAnyBindingState()) return true;
304
- return THREAD_BINDINGS_STATE.loadedPersistentBindings;
284
+ return shouldPersistAnyBindingState() || THREAD_BINDINGS_STATE.loadedPersistentBindings;
305
285
  }
306
286
  function snapshotThreadBindingJson(value) {
307
287
  const serialized = JSON.stringify(value);
308
288
  return serialized ? JSON.parse(serialized) : void 0;
309
289
  }
290
+ function snapshotThreadBindingMetadata(input) {
291
+ return asOptionalObjectRecord(snapshotThreadBindingJson(input.metadata ? { ...input.metadata } : void 0));
292
+ }
310
293
  function toPersistedBindingRecord(record) {
311
294
  return normalizePersistedBinding(record.threadId, snapshotThreadBindingJson(record)) ?? { ...record };
312
295
  }
@@ -337,7 +320,6 @@ async function commitBindingRecord(params) {
337
320
  const revision = THREAD_BINDINGS_STATE.revision;
338
321
  let authorityRefused = false;
339
322
  let targetCommitted = false;
340
- let committedWrites = 0;
341
323
  const assertCurrent = () => {
342
324
  try {
343
325
  params.assertCurrent?.();
@@ -362,10 +344,7 @@ async function commitBindingRecord(params) {
362
344
  };
363
345
  THREAD_BINDINGS_STATE.activePersistence = active;
364
346
  try {
365
- const store = getDiscordRuntime().state.openKeyedStore({
366
- namespace: THREAD_BINDINGS_NAMESPACE,
367
- maxEntries: THREAD_BINDINGS_MAX_ENTRIES
368
- });
347
+ const store = openThreadBindingsStoreAsync();
369
348
  for (const [key, record] of records) {
370
349
  assertCurrent();
371
350
  const persisted = toPersistedBindingRecord(record);
@@ -374,7 +353,6 @@ async function commitBindingRecord(params) {
374
353
  await store.register(key, persisted, { assertCurrent });
375
354
  active.writingKey = void 0;
376
355
  active.committedKeys.add(key);
377
- committedWrites += 1;
378
356
  targetCommitted ||= key === params.bindingKey;
379
357
  }
380
358
  assertCurrent();
@@ -385,7 +363,6 @@ async function commitBindingRecord(params) {
385
363
  await store.delete(entry.key, { assertCurrent });
386
364
  active.writingKey = void 0;
387
365
  active.committedKeys.add(entry.key);
388
- committedWrites += 1;
389
366
  targetCommitted ||= entry.key === params.bindingKey;
390
367
  }
391
368
  if (!params.next) targetCommitted = true;
@@ -393,6 +370,7 @@ async function commitBindingRecord(params) {
393
370
  THREAD_BINDINGS_STATE.loadedPersistentBindings = records.size > 0;
394
371
  THREAD_BINDINGS_STATE.lastPersistedAtMs = now;
395
372
  } catch (error) {
373
+ const committedWrites = active.committedKeys.size;
396
374
  let failure = error;
397
375
  if (!authorityRefused) try {
398
376
  assertCurrent();
@@ -530,26 +508,21 @@ function removeBindingRecordSync(bindingKey) {
530
508
  }
531
509
  //#endregion
532
510
  //#region extensions/discord/src/monitor/thread-bindings.session-shared.ts
533
- function normalizeNonNegativeMs(raw) {
534
- if (!Number.isFinite(raw)) return 0;
535
- return Math.max(0, Math.floor(raw));
536
- }
537
511
  function resolveBindingIdsForTargetSession(params) {
538
512
  ensureBindingsLoaded();
539
- const targetSessionKey = params.targetSessionKey.trim();
540
- if (!targetSessionKey) return [];
541
513
  return resolveBindingIdsForSession({
542
- targetSessionKey,
543
- accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0,
544
- targetKind: params.targetKind
514
+ ...params,
515
+ accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0
545
516
  });
546
517
  }
547
518
  function mutateBindingsForTargetSession(params, update, onRemoved) {
548
519
  const accountId = params.accountId ? normalizeAccountId(params.accountId) : void 0;
549
- const admittedOwners = new Map([...MANAGERS_BY_ACCOUNT_ID].filter(([ownerAccountId]) => accountId === void 0 || ownerAccountId === accountId).map(([ownerAccountId, manager]) => [ownerAccountId, {
520
+ const admittedOwners = /* @__PURE__ */ new Map();
521
+ const ownerSnapshot = [...MANAGERS_BY_ACCOUNT_ID];
522
+ for (const [ownerAccountId, manager] of ownerSnapshot) if (accountId === void 0 || ownerAccountId === accountId) admittedOwners.set(ownerAccountId, {
550
523
  manager,
551
524
  stopping: manager.isStopping()
552
- }]));
525
+ });
553
526
  return runThreadBindingAccountOperation([...admittedOwners.values()].map(({ manager }) => manager), () => runThreadBindingMutation(async () => {
554
527
  await ensureBindingsLoadedAsync();
555
528
  const ids = resolveBindingIdsForTargetSession(params);
@@ -605,45 +578,33 @@ function updateBindingsForTargetSessionSync(ids, update) {
605
578
  }
606
579
  //#endregion
607
580
  //#region extensions/discord/src/monitor/thread-bindings.session-updates.ts
608
- async function setThreadBindingIdleTimeoutBySessionKeyAsync(input) {
609
- const params = { ...input };
610
- const idleTimeoutMs = normalizeNonNegativeMs(params.idleTimeoutMs);
611
- return mutateBindingsForTargetSession(params, (existing, now) => ({
581
+ function createDurationUpdate(field, raw) {
582
+ const duration = resolveNonNegativeIntegerOption(raw, 0);
583
+ return (existing, now) => ({
612
584
  ...existing,
613
- idleTimeoutMs,
585
+ [field]: duration,
586
+ ...field === "maxAgeMs" ? { boundAt: now } : {},
614
587
  lastActivityAt: now
615
- }));
588
+ });
616
589
  }
617
- async function setThreadBindingMaxAgeBySessionKeyAsync(input) {
618
- const params = { ...input };
619
- const maxAgeMs = normalizeNonNegativeMs(params.maxAgeMs);
620
- return mutateBindingsForTargetSession(params, (existing, now) => ({
621
- ...existing,
622
- maxAgeMs,
623
- boundAt: now,
624
- lastActivityAt: now
625
- }));
590
+ function createDurationSetters(field) {
591
+ return {
592
+ setAsync: async (input) => {
593
+ const params = { ...input };
594
+ return mutateBindingsForTargetSession(params, createDurationUpdate(field, params[field]));
595
+ },
596
+ set: (params) => {
597
+ return updateBindingsForTargetSessionSync(resolveBindingIdsForTargetSession(params), createDurationUpdate(field, params[field]));
598
+ }
599
+ };
626
600
  }
601
+ const idleSetters = createDurationSetters("idleTimeoutMs");
602
+ const maxAgeSetters = createDurationSetters("maxAgeMs");
603
+ const setThreadBindingIdleTimeoutBySessionKeyAsync = idleSetters.setAsync;
604
+ const setThreadBindingMaxAgeBySessionKeyAsync = maxAgeSetters.setAsync;
627
605
  /** @deprecated Use the awaited lifecycle setter; retained for the generic SDK contract. */
628
- function setThreadBindingIdleTimeoutBySessionKey(params) {
629
- const ids = resolveBindingIdsForTargetSession(params);
630
- const idleTimeoutMs = normalizeNonNegativeMs(params.idleTimeoutMs);
631
- return updateBindingsForTargetSessionSync(ids, (existing, now) => ({
632
- ...existing,
633
- idleTimeoutMs,
634
- lastActivityAt: now
635
- }));
636
- }
606
+ const setThreadBindingIdleTimeoutBySessionKey = idleSetters.set;
637
607
  /** @deprecated Use the awaited lifecycle setter; retained for the generic SDK contract. */
638
- function setThreadBindingMaxAgeBySessionKey(params) {
639
- const ids = resolveBindingIdsForTargetSession(params);
640
- const maxAgeMs = normalizeNonNegativeMs(params.maxAgeMs);
641
- return updateBindingsForTargetSessionSync(ids, (existing, now) => ({
642
- ...existing,
643
- maxAgeMs,
644
- boundAt: now,
645
- lastActivityAt: now
646
- }));
647
- }
608
+ const setThreadBindingMaxAgeBySessionKey = maxAgeSetters.set;
648
609
  //#endregion
649
- export { resolveBindingRecordKey as A, getThreadBindingToken as C, rememberReusableWebhook as D, refreshUnboundThreadWebhookIdentity as E, resolveThreadBindingMaxAgeMs as F, shouldDefaultPersist as I, toBindingRecordKey as L, resolveThreadBindingIdleTimeoutMs as M, resolveThreadBindingInactivityExpiresAt as N, rememberThreadBindingToken as O, resolveThreadBindingMaxAgeExpiresAt as P, toReusableWebhookKey as R, forgetThreadBindingToken as S, normalizeThreadBindingDurationMs as T, MANAGERS_BY_ACCOUNT_ID as _, mutateBindingsForTargetSession as a, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as b, drainThreadBindingAccountOperations as c, runThreadBindingAccountOperation as d, runThreadBindingMutation as f, BINDINGS_BY_THREAD_ID as g, updateBindingRecordSync as h, setThreadBindingMaxAgeBySessionKeyAsync as i, resolvePreparedThreadBindingLifecycle as j, resolveBindingIdsForSession as k, drainThreadBindingMutations as l, snapshotThreadBindingJson as m, setThreadBindingIdleTimeoutBySessionKeyAsync as n, resolveBindingIdsForTargetSession as o, shouldPersistAnyBindingState as p, setThreadBindingMaxAgeBySessionKey as r, commitBindingRecord as s, setThreadBindingIdleTimeoutBySessionKey as t, removeBindingRecordSync as u, PERSIST_BY_ACCOUNT_ID as v, normalizeTargetKind as w, ensureBindingsLoadedAsync as x, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as y };
610
+ export { resolveBindingRecordKey as A, getThreadBindingToken as C, rememberReusableWebhook as D, refreshUnboundThreadWebhookIdentity as E, resolveThreadBindingMaxAgeMs as F, shouldDefaultPersist as I, toBindingRecordKey as L, resolveThreadBindingIdleTimeoutMs as M, resolveThreadBindingInactivityExpiresAt as N, rememberThreadBindingToken as O, resolveThreadBindingMaxAgeExpiresAt as P, toReusableWebhookKey as R, forgetThreadBindingToken as S, normalizeThreadBindingDurationMs as T, MANAGERS_BY_ACCOUNT_ID as _, mutateBindingsForTargetSession as a, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as b, drainThreadBindingAccountOperations as c, runThreadBindingAccountOperation as d, runThreadBindingMutation as f, BINDINGS_BY_THREAD_ID as g, updateBindingRecordSync as h, setThreadBindingMaxAgeBySessionKeyAsync as i, resolvePreparedThreadBindingLifecycle as j, resolveBindingIdsForSession as k, drainThreadBindingMutations as l, snapshotThreadBindingMetadata as m, setThreadBindingIdleTimeoutBySessionKeyAsync as n, resolveBindingIdsForTargetSession as o, shouldPersistAnyBindingState as p, setThreadBindingMaxAgeBySessionKey as r, commitBindingRecord as s, setThreadBindingIdleTimeoutBySessionKey as t, removeBindingRecordSync as u, PERSIST_BY_ACCOUNT_ID as v, normalizeTargetKind as w, ensureBindingsLoadedAsync as x, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as y };
@@ -0,0 +1,246 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
+ import { ct as createThread, ft as getChannelMessage, t as discord_exports } from "./discord-BGqgx-yd.mjs";
3
+ import { d as resolveDiscordReplyDeliveryPlan, f as resolveDiscordReplyTarget, g as sanitizeDiscordThreadName, h as resolveDiscordThreadStarter, j as resolveDiscordMessageChannelId, m as resolveDiscordThreadParentInfo, p as resolveDiscordThreadChannel } from "./transcripts-source-0qQYVu2H.mjs";
4
+ import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
5
+ import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
6
+ import { normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
7
+ import { Routes } from "discord-api-types/v10";
8
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
9
+ import { resolveChannelModelOverride } from "openclaw/plugin-sdk/model-session-runtime";
10
+ import { generateConversationLabel } from "openclaw/plugin-sdk/reply-dispatch-runtime";
11
+ //#region extensions/discord/src/monitor/thread-title.ts
12
+ const DEFAULT_THREAD_TITLE_TIMEOUT_MS = 6e4;
13
+ const MAX_THREAD_TITLE_SOURCE_CHARS = 600;
14
+ const MAX_THREAD_TITLE_CHANNEL_NAME_CHARS = 120;
15
+ const MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS = 320;
16
+ const DISCORD_THREAD_TITLE_SYSTEM_PROMPT = "Generate a concise Discord thread title (3-6 words) in sentence case: capitalize only the first word and words that are always capitalized. Return only the title. Use channel context when provided and avoid redundant channel-name words unless needed for clarity.";
17
+ async function generateThreadTitle(params) {
18
+ const sourceText = params.messageText.trim();
19
+ if (!sourceText) return null;
20
+ try {
21
+ const userMessage = buildThreadTitleCompletionUserMessage({
22
+ sourceText,
23
+ channelName: params.channelName,
24
+ channelDescription: params.channelDescription
25
+ });
26
+ const generated = await generateConversationLabel({
27
+ cfg: params.cfg,
28
+ agentId: params.agentId,
29
+ userMessage,
30
+ prompt: DISCORD_THREAD_TITLE_SYSTEM_PROMPT,
31
+ ...params.modelRef ? { modelRef: params.modelRef } : {},
32
+ timeoutMs: Math.max(100, Math.floor(params.timeoutMs ?? DEFAULT_THREAD_TITLE_TIMEOUT_MS)),
33
+ maxLength: MAX_THREAD_TITLE_SOURCE_CHARS
34
+ });
35
+ return generated ? normalizeGeneratedThreadTitle(generated) : null;
36
+ } catch (err) {
37
+ logVerbose(`thread-title: title generation failed for agent ${params.agentId}: ${String(err)}`);
38
+ return null;
39
+ }
40
+ }
41
+ function buildThreadTitleCompletionUserMessage(params) {
42
+ const sourceText = truncateThreadTitleText(params.sourceText, MAX_THREAD_TITLE_SOURCE_CHARS);
43
+ const channelName = normalizeTitleContextField(params.channelName, MAX_THREAD_TITLE_CHANNEL_NAME_CHARS);
44
+ const channelDescription = normalizeTitleContextField(params.channelDescription, MAX_THREAD_TITLE_CHANNEL_DESCRIPTION_CHARS);
45
+ return [
46
+ channelName ? `Channel: ${channelName}` : void 0,
47
+ channelDescription ? `Channel description: ${channelDescription}` : void 0,
48
+ `Message:\n${sourceText}`
49
+ ].filter(Boolean).join("\n\n");
50
+ }
51
+ function truncateThreadTitleText(text, maxChars) {
52
+ if (text.length <= maxChars) return text;
53
+ return `${truncateUtf16Safe(text, maxChars)}...`;
54
+ }
55
+ function normalizeGeneratedThreadTitle(raw) {
56
+ return stripThreadTitleWrappers(raw.replace(/\r/g, "").split("\n").find((line) => line.trim() && !line.trim().startsWith("```")) ?? "");
57
+ }
58
+ function stripThreadTitleWrappers(raw) {
59
+ let current = raw.trim();
60
+ let previous = "";
61
+ while (current && current !== previous) {
62
+ previous = current;
63
+ current = current.replace(/^["'`]+|["'`]+$/g, "").trim();
64
+ for (const marker of [
65
+ "**",
66
+ "__",
67
+ "*",
68
+ "_",
69
+ "~~"
70
+ ]) current = stripBalancedWrapper(current, marker);
71
+ }
72
+ return current;
73
+ }
74
+ function stripBalancedWrapper(text, marker) {
75
+ if (text.length < marker.length * 2 + 1 || !text.startsWith(marker) || !text.endsWith(marker)) return text;
76
+ const inner = text.slice(marker.length, text.length - marker.length);
77
+ return inner.includes(marker) ? text : inner;
78
+ }
79
+ function normalizeTitleContextField(raw, maxChars) {
80
+ const value = raw?.trim();
81
+ if (!value) return;
82
+ return truncateThreadTitleText(value.replace(/\s+/g, " "), maxChars);
83
+ }
84
+ //#endregion
85
+ //#region extensions/discord/src/monitor/threading.auto-thread.ts
86
+ function resolveTrimmedDiscordMessageChannelId(params) {
87
+ return (params.messageChannelId || resolveDiscordMessageChannelId({ message: params.message })).trim();
88
+ }
89
+ function resolveDiscordAutoThreadContext(params) {
90
+ const createdThreadId = normalizeOptionalStringifiedId(params.createdThreadId) ?? "";
91
+ if (!createdThreadId) return null;
92
+ const parentSessionKey = normalizeOptionalString(params.parentSessionKey) ?? "";
93
+ if (!parentSessionKey) return null;
94
+ const threadSessionKey = params.groupScope === "main" ? parentSessionKey : buildAgentSessionKey({
95
+ agentId: params.agentId,
96
+ channel: params.channel,
97
+ peer: {
98
+ kind: "channel",
99
+ id: createdThreadId
100
+ }
101
+ });
102
+ const inheritsDistinctParent = threadSessionKey !== parentSessionKey;
103
+ return {
104
+ createdThreadId,
105
+ From: `${params.channel}:channel:${createdThreadId}`,
106
+ To: `channel:${createdThreadId}`,
107
+ OriginatingTo: `channel:${createdThreadId}`,
108
+ SessionKey: threadSessionKey,
109
+ ...inheritsDistinctParent ? { ModelParentSessionKey: parentSessionKey } : {},
110
+ ...inheritsDistinctParent && params.parentInheritanceEnabled === true ? { ParentSessionKey: parentSessionKey } : {}
111
+ };
112
+ }
113
+ async function resolveDiscordAutoThreadReplyPlan(params) {
114
+ const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
115
+ const originalReplyTarget = `channel:${params.threadChannel?.id ?? (messageChannelId || "unknown")}`;
116
+ const createdThreadId = await maybeCreateDiscordAutoThread({
117
+ ...params,
118
+ messageChannelId: messageChannelId || void 0
119
+ });
120
+ const deliveryPlan = resolveDiscordReplyDeliveryPlan({
121
+ replyTarget: originalReplyTarget,
122
+ replyToMode: params.replyToMode,
123
+ messageId: params.message.id,
124
+ threadChannel: params.threadChannel,
125
+ createdThreadId
126
+ });
127
+ const autoThreadContext = params.isGuildMessage ? resolveDiscordAutoThreadContext({
128
+ ...params,
129
+ createdThreadId,
130
+ parentInheritanceEnabled: params.threadParentInheritanceEnabled
131
+ }) : null;
132
+ return {
133
+ ...deliveryPlan,
134
+ createdThreadId,
135
+ autoThreadContext
136
+ };
137
+ }
138
+ async function maybeCreateDiscordAutoThread(params) {
139
+ if (!params.isGuildMessage || !params.channelConfig?.autoThread || params.threadChannel) return;
140
+ if (params.channelType === discord_exports.ChannelType.GuildForum || params.channelType === discord_exports.ChannelType.GuildMedia || params.channelType === discord_exports.ChannelType.GuildVoice || params.channelType === discord_exports.ChannelType.GuildStageVoice) return;
141
+ const messageChannelId = resolveTrimmedDiscordMessageChannelId(params);
142
+ if (!messageChannelId) return;
143
+ const findExistingThread = async () => {
144
+ try {
145
+ const existingThreadId = (await getChannelMessage(params.client.rest, messageChannelId, params.message.id))?.thread?.id;
146
+ if (existingThreadId) {
147
+ logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`);
148
+ return existingThreadId;
149
+ }
150
+ } catch {}
151
+ };
152
+ try {
153
+ const existingThreadId = await findExistingThread();
154
+ if (existingThreadId) return existingThreadId;
155
+ if (params.message.author?.bot) {
156
+ logVerbose(`discord: autoThread skipped for bot-authored message ${messageChannelId}/${params.message.id}`);
157
+ return;
158
+ }
159
+ const rawThreadSource = params.baseText || params.combinedBody || "Thread";
160
+ const threadName = sanitizeDiscordThreadName(rawThreadSource, params.message.id);
161
+ const archiveDuration = params.channelConfig?.autoArchiveDuration ? Number(params.channelConfig.autoArchiveDuration) : 60;
162
+ const createdId = (await createThread(params.client.rest, messageChannelId, { body: {
163
+ name: threadName,
164
+ auto_archive_duration: archiveDuration
165
+ } }, params.message.id))?.id || "";
166
+ if (createdId && params.channelConfig?.autoThreadName === "generated" && params.cfg && params.agentId) {
167
+ const modelRef = resolveDiscordThreadTitleModelRef({
168
+ cfg: params.cfg,
169
+ channel: params.channel,
170
+ agentId: params.agentId,
171
+ threadId: createdId,
172
+ messageChannelId,
173
+ channelName: params.channelName
174
+ });
175
+ maybeRenameDiscordAutoThread({
176
+ client: params.client,
177
+ threadId: createdId,
178
+ currentName: threadName,
179
+ fallbackId: params.message.id,
180
+ sourceText: rawThreadSource,
181
+ modelRef,
182
+ channelName: params.channelName,
183
+ channelDescription: params.channelDescription,
184
+ cfg: params.cfg,
185
+ agentId: params.agentId
186
+ });
187
+ }
188
+ return createdId || void 0;
189
+ } catch (err) {
190
+ logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);
191
+ return findExistingThread();
192
+ }
193
+ }
194
+ function resolveDiscordThreadTitleModelRef(params) {
195
+ const channel = params.channel?.trim();
196
+ if (!channel) return;
197
+ const parentSessionKey = buildAgentSessionKey({
198
+ agentId: params.agentId,
199
+ channel,
200
+ peer: {
201
+ kind: "channel",
202
+ id: params.messageChannelId
203
+ }
204
+ });
205
+ const channelLabel = params.channelName?.trim();
206
+ const groupChannel = channelLabel ? `#${channelLabel}` : void 0;
207
+ return resolveChannelModelOverride({
208
+ cfg: params.cfg,
209
+ channel,
210
+ groupId: params.threadId,
211
+ groupChatType: "channel",
212
+ groupChannel,
213
+ groupSubject: groupChannel,
214
+ parentSessionKey
215
+ })?.model;
216
+ }
217
+ async function maybeRenameDiscordAutoThread(params) {
218
+ try {
219
+ const fallbackName = sanitizeDiscordThreadName("", params.fallbackId);
220
+ const generated = await generateThreadTitle({
221
+ ...params,
222
+ messageText: params.sourceText
223
+ });
224
+ if (!generated) return;
225
+ const nextName = sanitizeDiscordThreadName(generated, params.fallbackId);
226
+ if (!nextName || nextName === params.currentName || nextName === fallbackName) return;
227
+ await params.client.rest.patch(Routes.channel(params.threadId), { body: { name: nextName } });
228
+ } catch (err) {
229
+ logVerbose(`discord: autoThread rename failed for ${params.threadId}: ${String(err)}`);
230
+ }
231
+ }
232
+ //#endregion
233
+ //#region extensions/discord/src/monitor/threading.ts
234
+ var threading_exports = /* @__PURE__ */ __exportAll({
235
+ maybeCreateDiscordAutoThread: () => maybeCreateDiscordAutoThread,
236
+ resolveDiscordAutoThreadContext: () => resolveDiscordAutoThreadContext,
237
+ resolveDiscordAutoThreadReplyPlan: () => resolveDiscordAutoThreadReplyPlan,
238
+ resolveDiscordReplyDeliveryPlan: () => resolveDiscordReplyDeliveryPlan,
239
+ resolveDiscordReplyTarget: () => resolveDiscordReplyTarget,
240
+ resolveDiscordThreadChannel: () => resolveDiscordThreadChannel,
241
+ resolveDiscordThreadParentInfo: () => resolveDiscordThreadParentInfo,
242
+ resolveDiscordThreadStarter: () => resolveDiscordThreadStarter,
243
+ sanitizeDiscordThreadName: () => sanitizeDiscordThreadName
244
+ });
245
+ //#endregion
246
+ export { resolveDiscordAutoThreadReplyPlan as n, threading_exports as t };
@@ -1,4 +1,5 @@
1
1
  import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
2
+ import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
2
3
  //#region extensions/discord/src/monitor/timeouts.ts
3
4
  const DISCORD_DEFAULT_LISTENER_TIMEOUT_MS = 12e4;
4
5
  const DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS = 18e5;
@@ -27,7 +28,6 @@ async function runDiscordTaskWithTimeout(params) {
27
28
  const abortSignals = [...params.abortSignals ?? [], timeoutAbortController?.signal].filter((signal) => Boolean(signal));
28
29
  const mergedAbortSignal = abortSignals.length > 1 ? AbortSignal.any(abortSignals) : abortSignals[0];
29
30
  let timedOut = false;
30
- let timeoutHandle = null;
31
31
  const runPromise = params.run(mergedAbortSignal).catch((error) => {
32
32
  if (!timedOut) throw error;
33
33
  if (timeoutAbortController?.signal.aborted && isAbortError(error)) {
@@ -36,25 +36,17 @@ async function runDiscordTaskWithTimeout(params) {
36
36
  }
37
37
  params.onErrorAfterTimeout?.(error);
38
38
  });
39
- try {
40
- if (!timeoutMs) {
41
- await runPromise;
42
- return false;
43
- }
44
- const timeoutPromise = new Promise((resolve) => {
45
- timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
46
- timeoutHandle.unref?.();
47
- });
48
- if (await Promise.race([runPromise.then(() => "completed"), timeoutPromise]) === "timeout") {
49
- timedOut = true;
50
- timeoutAbortController?.abort();
51
- await params.onTimeout(timeoutMs);
52
- return true;
53
- }
39
+ if (!timeoutMs) {
40
+ await runPromise;
54
41
  return false;
55
- } finally {
56
- if (timeoutHandle) clearTimeout(timeoutHandle);
57
42
  }
43
+ if (await raceWithTimeout(runPromise.then(() => "completed"), timeoutMs, () => "timeout", { ref: false }) === "timeout") {
44
+ timedOut = true;
45
+ timeoutAbortController?.abort();
46
+ await params.onTimeout(timeoutMs);
47
+ return true;
48
+ }
49
+ return false;
58
50
  }
59
51
  async function withAbortTimeout(params) {
60
52
  const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, 1);