@openclaw/slack 2026.10.1 → 2026.10.5-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 (195) hide show
  1. package/dist/.setup/account-configured-zcR9TJJN.mjs +35 -0
  2. package/dist/.setup/{account-inspect-Cs-7DXXW.mjs → account-inspect-D58VVDjk.mjs} +15 -35
  3. package/dist/.setup/{accounts-CDgkV7Cm.mjs → accounts-BMg9YLIv.mjs} +44 -53
  4. package/dist/.setup/{action-runtime-DJ1daRAZ.mjs → action-runtime-BiRZNsIG.mjs} +20 -22
  5. package/dist/.setup/action-runtime.runtime-C5xceJoS.mjs +2 -0
  6. package/dist/.setup/{actions-DDoAJnrH.mjs → actions-KGKwTAKO.mjs} +34 -43
  7. package/dist/.setup/{approval-handler.runtime-BcE_shWc.mjs → approval-handler.runtime-DYrsG2Ox.mjs} +44 -70
  8. package/dist/.setup/{approval-message-updates-EgKGmFXx.mjs → approval-message-updates-CwdDew9i.mjs} +1 -1
  9. package/dist/.setup/{channel-DgKSu8Iv.mjs → channel-C7MY-Hhg.mjs} +138 -97
  10. package/dist/.setup/{channel-type-B9zYYzBU.mjs → channel-type-NjX2SwvS.mjs} +3 -3
  11. package/dist/.setup/{channel.setup-BYIlwbQ7.mjs → channel.setup-BFpQowO3.mjs} +7 -14
  12. package/dist/.setup/{directory-config-B_by7zrc.mjs → directory-config-BEDZPfDn.mjs} +1 -1
  13. package/dist/.setup/{directory-live-C48wazJt.mjs → directory-live-FipfeCwt.mjs} +33 -36
  14. package/dist/.setup/{message-tool-api-CcjLPN3v.mjs → message-tool-api-C7im5ETh.mjs} +2 -2
  15. package/dist/.setup/{monitor-BuYBDmm7.mjs → monitor-BnN2px0N.mjs} +609 -801
  16. package/dist/.setup/{outbound-adapter-BZFkK-mw.mjs → outbound-adapter-4HdGq-8r.mjs} +4 -4
  17. package/dist/.setup/{pipeline.runtime-CIepKmZt.mjs → pipeline.runtime-ByPbC6MN.mjs} +287 -365
  18. package/dist/.setup/{policy-KKTqEiDv.mjs → policy-BaY9_eh1.mjs} +2 -2
  19. package/dist/.setup/{probe-BVlJ3dp0.mjs → probe-CyX52GtD.mjs} +54 -61
  20. package/dist/.setup/{relay-source-CC3h6M7y.mjs → relay-source-CVfH-fBO.mjs} +28 -45
  21. package/dist/.setup/{replies-DHbuthIR.mjs → replies-WmfwvQxc.mjs} +38 -49
  22. package/dist/.setup/{reply-blocks-CKnO4BSG.mjs → reply-blocks-rqHQ_3pr.mjs} +87 -138
  23. package/dist/.setup/{resolve-channels-HR0TgArR.mjs → resolve-channels-B96cgprw.mjs} +17 -41
  24. package/dist/.setup/{resolve-users-BNYBhF0q.mjs → resolve-users-Xz9aPdns.mjs} +22 -58
  25. package/dist/.setup/{scopes-DrDbyUH2.mjs → scopes-aMcMHhXk.mjs} +1 -1
  26. package/dist/.setup/{send-CgPI3Zj8.mjs → send-CLmsR42r.mjs} +157 -284
  27. package/dist/.setup/{session-status-D46GHwOV.mjs → session-status-CcXe10zN.mjs} +181 -238
  28. package/dist/.setup/{setup-plugin-api-ZrHs0N4U.mjs → setup-plugin-api-D92P5p51.mjs} +1 -1
  29. package/dist/.setup/{setup-surface-83lxvE2y.mjs → setup-surface-368jx6Uc.mjs} +6 -6
  30. package/dist/.setup/{shared-VtmYNj-v.mjs → shared-CtprVh_G.mjs} +5 -5
  31. package/dist/.setup/{slash-dispatch.runtime-gBj_uaLM.mjs → slash-dispatch.runtime-Dzwj6TPI.mjs} +1 -1
  32. package/dist/account-inspect-api.js +1 -1
  33. package/dist/api.js +12 -12
  34. package/dist/channel-plugin-api.js +1 -1
  35. package/dist/configured-state.js +6 -13
  36. package/dist/directory-contract-api.js +1 -1
  37. package/dist/message-tool-api.js +1 -1
  38. package/dist/runtime-api.js +10 -10
  39. package/dist/setup-entry.js +1 -1
  40. package/dist/setup-plugin-api.js +1 -1
  41. package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts +1 -1
  42. package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts.map +1 -1
  43. package/node_modules/@slack/types/dist/block-kit/blocks.d.ts +79 -4
  44. package/node_modules/@slack/types/dist/block-kit/blocks.d.ts.map +1 -1
  45. package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts +17 -0
  46. package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts.map +1 -1
  47. package/node_modules/@slack/types/package.json +1 -1
  48. package/node_modules/@slack/web-api/dist/methods.d.ts +49 -2
  49. package/node_modules/@slack/web-api/dist/methods.d.ts.map +1 -1
  50. package/node_modules/@slack/web-api/dist/methods.js +47 -0
  51. package/node_modules/@slack/web-api/dist/methods.js.map +1 -1
  52. package/node_modules/@slack/web-api/dist/types/request/agents.d.ts +186 -0
  53. package/node_modules/@slack/web-api/dist/types/request/agents.d.ts.map +1 -1
  54. package/node_modules/@slack/web-api/dist/types/request/index.d.ts +1 -1
  55. package/node_modules/@slack/web-api/dist/types/request/index.d.ts.map +1 -1
  56. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.d.ts +9 -0
  57. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.d.ts.map +1 -0
  58. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.js +11 -0
  59. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.js.map +1 -0
  60. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.d.ts +10 -0
  61. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.d.ts.map +1 -0
  62. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.js +11 -0
  63. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.js.map +1 -0
  64. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.d.ts +29 -0
  65. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.d.ts.map +1 -0
  66. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.js +11 -0
  67. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.js.map +1 -0
  68. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.d.ts +18 -0
  69. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.d.ts.map +1 -0
  70. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.js +11 -0
  71. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.js.map +1 -0
  72. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.d.ts +11 -0
  73. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.d.ts.map +1 -0
  74. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.js +11 -0
  75. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.js.map +1 -0
  76. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.d.ts +11 -0
  77. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.d.ts.map +1 -0
  78. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.js +11 -0
  79. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.js.map +1 -0
  80. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.d.ts +11 -0
  81. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.d.ts.map +1 -0
  82. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.js +11 -0
  83. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.js.map +1 -0
  84. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.d.ts +10 -0
  85. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.d.ts.map +1 -0
  86. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.js +11 -0
  87. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.js.map +1 -0
  88. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.d.ts +15 -0
  89. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.d.ts.map +1 -0
  90. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.js +11 -0
  91. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.js.map +1 -0
  92. package/node_modules/@slack/web-api/dist/types/response/ConversationsInfoResponse.d.ts +31 -0
  93. package/node_modules/@slack/web-api/dist/types/response/ConversationsInfoResponse.d.ts.map +1 -1
  94. package/node_modules/@slack/web-api/dist/types/response/index.d.ts +9 -0
  95. package/node_modules/@slack/web-api/dist/types/response/index.d.ts.map +1 -1
  96. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/LICENSE +21 -0
  97. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/README.md +15 -0
  98. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/assert/strict.d.ts +68 -0
  99. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/assert.d.ts +1077 -0
  100. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/async_hooks.d.ts +711 -0
  101. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/buffer.buffer.d.ts +471 -0
  102. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/buffer.d.ts +1800 -0
  103. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/child_process.d.ts +1361 -0
  104. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/cluster.d.ts +432 -0
  105. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/console.d.ts +93 -0
  106. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/constants.d.ts +14 -0
  107. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/crypto.d.ts +3964 -0
  108. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/dgram.d.ts +652 -0
  109. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/diagnostics_channel.d.ts +794 -0
  110. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/dns/promises.d.ts +497 -0
  111. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/dns.d.ts +876 -0
  112. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/domain.d.ts +150 -0
  113. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/events.d.ts +1008 -0
  114. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ffi.d.ts +500 -0
  115. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/fs/promises.d.ts +1477 -0
  116. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/fs.d.ts +4803 -0
  117. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/globals.d.ts +150 -0
  118. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/globals.typedarray.d.ts +101 -0
  119. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/http.d.ts +2218 -0
  120. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/http2.d.ts +2498 -0
  121. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/https.d.ts +400 -0
  122. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/index.d.ts +116 -0
  123. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/inspector/promises.d.ts +35 -0
  124. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/inspector.d.ts +265 -0
  125. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/inspector.generated.d.ts +4406 -0
  126. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/module.d.ts +726 -0
  127. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/net.d.ts +1074 -0
  128. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/os.d.ts +498 -0
  129. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/package.json +155 -0
  130. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/path/posix.d.ts +8 -0
  131. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/path/win32.d.ts +8 -0
  132. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/path.d.ts +178 -0
  133. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/perf_hooks.d.ts +617 -0
  134. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/process.d.ts +2269 -0
  135. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/punycode.d.ts +89 -0
  136. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/querystring.d.ts +139 -0
  137. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/quic.d.ts +2191 -0
  138. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/readline/promises.d.ts +158 -0
  139. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/readline.d.ts +508 -0
  140. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/repl.d.ts +420 -0
  141. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/sea.d.ts +47 -0
  142. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/sqlite.d.ts +1140 -0
  143. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/consumers.d.ts +114 -0
  144. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/iter.d.ts +449 -0
  145. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/promises.d.ts +211 -0
  146. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/web.d.ts +320 -0
  147. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream.d.ts +1806 -0
  148. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/string_decoder.d.ts +27 -0
  149. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/test/reporters.d.ts +60 -0
  150. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/test.d.ts +2558 -0
  151. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/timers/promises.d.ts +93 -0
  152. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/timers.d.ts +149 -0
  153. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/tls.d.ts +1232 -0
  154. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/trace_events.d.ts +103 -0
  155. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +467 -0
  156. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  157. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  158. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/index.d.ts +118 -0
  159. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  160. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.7/index.d.ts +118 -0
  161. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/tty.d.ts +226 -0
  162. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/url.d.ts +556 -0
  163. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/util/types.d.ts +558 -0
  164. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/util.d.ts +1677 -0
  165. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/v8.d.ts +1059 -0
  166. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/vfs.d.ts +211 -0
  167. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/vm.d.ts +1137 -0
  168. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/wasi.d.ts +131 -0
  169. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
  170. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/blob.d.ts +23 -0
  171. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/console.d.ts +9 -0
  172. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
  173. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/domexception.d.ts +83 -0
  174. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
  175. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/events.d.ts +106 -0
  176. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
  177. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
  178. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
  179. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  180. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/performance.d.ts +45 -0
  181. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  182. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/streams.d.ts +119 -0
  183. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/timers.d.ts +44 -0
  184. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/url.d.ts +24 -0
  185. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/worker_threads.d.ts +672 -0
  186. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/zlib/iter.d.ts +131 -0
  187. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/zlib.d.ts +606 -0
  188. package/node_modules/@slack/web-api/node_modules/@types/node/README.md +2 -2
  189. package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -17
  190. package/node_modules/@slack/web-api/package.json +2 -2
  191. package/openclaw.plugin.json +0 -3
  192. package/package.json +6 -14
  193. package/dist/.setup/account-configured-sUohAxZr.mjs +0 -33
  194. package/dist/.setup/action-runtime.runtime-CdWL2mLC.mjs +0 -2
  195. package/dist/control-ui/2f4b1e827be6b68ced2ea0d8b7da8529a4eafbe72be27ee37e1064bdd530ec10/index.js +0 -1
@@ -1,15 +1,15 @@
1
1
  import { n as __reExport, t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { f as resolveSlackReplyToMode } from "./accounts-CDgkV7Cm.mjs";
2
+ import { f as resolveSlackReplyToMode } from "./accounts-BMg9YLIv.mjs";
3
3
  import { n as formatSlackTarget } from "./target-parsing-FFE26kOV.mjs";
4
- import { A as countSlackTextUtf8Bytes, C as buildSlackBlocksFallbackText, E as SLACK_EDIT_TEXT_MAX_BYTES, M as truncateSlackTextByUtf8Bytes, Y as normalizeSlackOutboundText, c as qualifySlackRoutePeerId, j as truncateSlackText, k as SLACK_TEXT_LIMIT, ot as escapeSlackMrkdwn, v as hasSlackNativeDataBlock, w as buildSlackCompleteBlocksFallbackText, z as SLACK_SESSION_LINK_ACTION_ID } from "./session-status-D46GHwOV.mjs";
5
- import { D as normalizeSlackAllowOwnerEntry, j as resolveSlackUserAllowed, o as formatSlackError, v as readLruMapEntry, y as writeLruMapEntry } from "./probe-BVlJ3dp0.mjs";
6
- import { a as prepareSlackReply, l as resolveSlackReplyRenderPlan, s as resolveSlackReplyBlocks } from "./reply-blocks-CKnO4BSG.mjs";
4
+ import { A as SLACK_TEXT_LIMIT, B as SLACK_SESSION_LINK_ACTION_ID, D as SLACK_EDIT_TEXT_MAX_BYTES, M as truncateSlackText, N as truncateSlackTextByUtf8Bytes, T as buildSlackCompleteBlocksFallbackText, X as normalizeSlackOutboundText, at as escapeSlackMrkdwn, c as qualifySlackRoutePeerId, j as countSlackTextUtf8Bytes, v as hasSlackNativeDataBlock, w as buildSlackBlocksFallbackText } from "./session-status-CcXe10zN.mjs";
5
+ import { M as resolveSlackUserAllowed, O as normalizeSlackAllowOwnerEntry, b as writeLruMapEntry, o as formatSlackError, v as pruneExpiredMapEntries, y as readLruMapEntry } from "./probe-CyX52GtD.mjs";
6
+ import { a as prepareSlackReply, l as resolveSlackReplyRenderPlan, s as resolveSlackReplyBlocks } from "./reply-blocks-rqHQ_3pr.mjs";
7
7
  import { n as resolveSlackReplyThreadTs } from "./thread-ts-Cvt7WD6B.mjs";
8
- import { C as hasSlackTableBlock, D as buildSlackEditTextPayload, E as resolveSlackMessageText$1, T as resolveSlackBlocksText, a as editSlackRenderedMessage, b as formatSlackFileReference, d as reactSlackMessage, i as editSlackMessage, m as removeSlackReaction, n as deleteSlackMessage, w as isSlackUnfurlAttachment, x as formatSlackFileReferenceList } from "./actions-DDoAJnrH.mjs";
9
- import { c as hasSlackThreadParticipationWithPersistence, i as clearSlackThreadFailureNotice, l as recordSlackThreadFailureNotice, m as buildSlackNativeDataDeliveryPlan, o as hasSlackThreadFailureNotice, p as hasSlackMessageIdentity, s as hasSlackThreadParticipation, t as sendMessageSlack, u as recordSlackThreadParticipation } from "./send-CgPI3Zj8.mjs";
10
- import { n as resolveSlackChannelConfig } from "./policy-KKTqEiDv.mjs";
11
- import { C as resolveSlackChatType, E as stripSlackMentionsForCommandDetection, S as normalizeSlackChannelType, T as readSlackAssistantThreadContext, _ as appendSlackStream, b as stopSlackStream, c as resolveSlackRoutingContext, g as SlackStreamNotDeliveredError, h as resolveSlackEffectiveAllowFrom, i as resolveSlackRoomContextHints, l as registerSlackSessionRun, m as resolveSlackCommandIngress, p as authorizeSlackBotRoomMessage, r as trackSlackDraftMessage, s as authorizeSlackDirectMessage, u as resolveSlackThreadContext, v as markSlackStreamFallbackDelivered, w as buildSlackAssistantThreadMetadata, y as startSlackStream } from "./monitor-BuYBDmm7.mjs";
12
- import { a as emitSlackMessageSentHooks, i as sanitizeSlackMonitorReplyPayload, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-DHbuthIR.mjs";
8
+ import { C as hasSlackTableBlock, D as buildSlackEditTextPayload, E as resolveSlackMessageText$1, T as resolveSlackBlocksText, a as editSlackRenderedMessage, b as formatSlackFileReference, d as reactSlackMessage, i as editSlackMessage, m as removeSlackReaction, n as deleteSlackMessage, w as isSlackUnfurlAttachment, x as formatSlackFileReferenceList } from "./actions-KGKwTAKO.mjs";
9
+ import { c as hasSlackThreadParticipationWithPersistence, i as clearSlackThreadFailureNotice, l as recordSlackThreadFailureNotice, m as buildSlackNativeDataDeliveryPlan, o as hasSlackThreadFailureNotice, p as hasSlackMessageIdentity, s as hasSlackThreadParticipation, t as sendMessageSlack, u as recordSlackThreadParticipation } from "./send-CLmsR42r.mjs";
10
+ import { n as resolveSlackChannelConfig } from "./policy-BaY9_eh1.mjs";
11
+ import { C as resolveSlackChatType, E as stripSlackMentionsForCommandDetection, S as normalizeSlackChannelType, T as readSlackAssistantThreadContext, _ as appendSlackStream, b as stopSlackStream, c as resolveSlackRoutingContext, g as SlackStreamNotDeliveredError, h as resolveSlackEffectiveAllowFrom, i as resolveSlackRoomContextHints, l as registerSlackSessionRun, m as resolveSlackCommandIngress, p as authorizeSlackBotRoomMessage, r as trackSlackDraftMessage, s as authorizeSlackDirectMessage, u as resolveSlackThreadContext, v as markSlackStreamFallbackDelivered, w as buildSlackAssistantThreadMetadata, y as startSlackStream } from "./monitor-BnN2px0N.mjs";
12
+ import { a as emitSlackMessageSentHooks, i as sanitizeSlackMonitorReplyPayload, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-WmfwvQxc.mjs";
13
13
  import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readNonBlankString } from "openclaw/plugin-sdk/string-coerce-runtime";
14
14
  import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
15
15
  import { buildChannelProgressDraftLine, compactChannelProgressDraftLine, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createChannelProgressWorkCounter, createDraftStreamLoop, createFinalizableDraftLifecycle, createLivePreviewLifecycle, createMessageReceiptFromOutboundResults, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages, selectPlanChecklistSteps } from "openclaw/plugin-sdk/channel-outbound";
@@ -31,7 +31,7 @@ import { formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-run
31
31
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/security-runtime";
32
32
  import { mimeTypeFromFilePath, normalizeMimeType } from "openclaw/plugin-sdk/media-mime";
33
33
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
34
- import { getSessionEntry, readSessionUpdatedAt, resolveChannelResetConfig, resolveStorePath, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
34
+ import { getSessionEntry, readSessionUpdatedAtAsync, resolveChannelResetConfig, resolveStorePath, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
35
35
  import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
36
36
  import { enqueueRoutedSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
37
37
  import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
@@ -120,17 +120,6 @@ function buildSlackEventDeliveryKey(params, preparedReply = prepareSlackReply(pa
120
120
  blocks: slackBlocks ?? null
121
121
  });
122
122
  }
123
- function createSlackEventDeliveryTracker() {
124
- const deliveredKeys = /* @__PURE__ */ new Set();
125
- return {
126
- hasDelivered(key) {
127
- return key ? deliveredKeys.has(key) : false;
128
- },
129
- markDelivered(key) {
130
- if (key) deliveredKeys.add(key);
131
- }
132
- };
133
- }
134
123
  async function resolveSlackStreamRecipientTeamId(params) {
135
124
  const cacheKey = params.fallbackTeamId && params.userId ? `${params.fallbackTeamId}:${params.userId}` : void 0;
136
125
  const cache = cacheKey ? getSlackStreamRecipientTeamCache(params.client) : void 0;
@@ -176,6 +165,13 @@ function createSlackDraftStream(params) {
176
165
  lastVisibleUpdate = void 0;
177
166
  lastSentKey = "";
178
167
  };
168
+ const editPreview = (message, text, blocks) => edit(message.channelId, message.messageId, text, {
169
+ cfg: params.cfg,
170
+ token: params.token,
171
+ accountId: params.accountId,
172
+ ...params.eventScope ? { client: params.eventScope.client } : {},
173
+ ...blocks ? { blocks } : {}
174
+ });
179
175
  const sendOrEditStreamMessage = async (pending) => {
180
176
  const update = normalizeUpdate(pending);
181
177
  const trimmed = update.text.trimEnd();
@@ -194,13 +190,7 @@ function createSlackDraftStream(params) {
194
190
  try {
195
191
  if (streamMessage) {
196
192
  const message = streamMessage;
197
- await edit(streamMessage.channelId, streamMessage.messageId, trimmed, {
198
- cfg: params.cfg,
199
- token: params.token,
200
- accountId: params.accountId,
201
- ...params.eventScope ? { client: params.eventScope.client } : {},
202
- ...blocks ? { blocks } : {}
203
- });
193
+ await editPreview(message, trimmed, blocks);
204
194
  if (streamMessage === message) lastVisibleUpdate = {
205
195
  text: trimmed,
206
196
  ...blocks ? { blocks } : {}
@@ -345,13 +335,7 @@ function createSlackDraftStream(params) {
345
335
  return true;
346
336
  }
347
337
  try {
348
- await edit(channelId, messageId, previousUpdate.text, {
349
- cfg: params.cfg,
350
- token: params.token,
351
- accountId: params.accountId,
352
- ...params.eventScope ? { client: params.eventScope.client } : {},
353
- ...previousUpdate.blocks ? { blocks: previousUpdate.blocks } : {}
354
- });
338
+ await editPreview(currentMessage, previousUpdate.text, previousUpdate.blocks);
355
339
  } catch (err) {
356
340
  params.warn?.(`slack stream preview restore failed: ${formatSlackError(err)}`);
357
341
  }
@@ -477,11 +461,8 @@ function compactDetail(value, maxChars) {
477
461
  const keepEnd = Math.max(1, maxChars - keepStart - 1);
478
462
  return `${chars.slice(0, keepStart).join("").trimEnd()}…${chars.slice(-keepEnd).join("").trimStart()}`;
479
463
  }
480
- function compactTitle(value) {
481
- return truncateSlackText(value.replace(/\s+/g, " ").trim(), SLACK_PROGRESS_TASK_TITLE_MAX);
482
- }
483
- function compactChunkText(value) {
484
- return truncateSlackText(value.replace(/\s+/g, " ").trim(), SLACK_PROGRESS_CHUNK_TEXT_MAX);
464
+ function compactTitle(value, maxChars = SLACK_PROGRESS_TASK_TITLE_MAX) {
465
+ return truncateSlackText(value.replace(/\s+/g, " ").trim(), maxChars);
485
466
  }
486
467
  function renderProgressCardText(text, enclosingStyle) {
487
468
  return normalizeSlackOutboundText(text, {
@@ -587,7 +568,7 @@ function buildSlackProgressStreamChunks(params) {
587
568
  const headline = params.title?.trim() || params.label?.trim();
588
569
  const summaryTitle = params.finalInProgressStatus === "error" ? "Failed" : params.finalInProgressStatus === "complete" || !params.summaryRow ? "Completed" : "Working";
589
570
  const newest = tasks.at(-1);
590
- const title = compactChunkText(headline || (newest?.details ? `${newest.title} — ${newest.details}` : newest?.title) || (params.summaryRow ? summaryTitle : attention.at(-1)?.title) || SLACK_PROGRESS_PLAN_FALLBACK_TITLE);
571
+ const title = compactTitle(headline || (newest?.details ? `${newest.title} — ${newest.details}` : newest?.title) || (params.summaryRow ? summaryTitle : attention.at(-1)?.title) || SLACK_PROGRESS_PLAN_FALLBACK_TITLE, SLACK_PROGRESS_CHUNK_TEXT_MAX);
591
572
  const diffOutput = formatTaskDiffOutput(params.diffStat);
592
573
  if (tasks.length === 0 && (params.summaryRow || params.sessionLinks?.length || diffOutput)) tasks.push({
593
574
  id: "openclaw_summary",
@@ -604,14 +585,9 @@ function buildSlackProgressStreamChunks(params) {
604
585
  const finalTaskIndex = tasks.length - 1;
605
586
  const taskChunks = tasks.map((task, index) => {
606
587
  const recovered = params.finalInProgressStatus === "complete" && task.status === "error";
607
- const chunk = {
608
- type: "task_update",
609
- id: task.id,
610
- title: recovered ? compactTitle(`Recovered: ${task.title}`) : task.title,
611
- status: recovered ? "complete" : task.status === "in_progress" ? params.finalInProgressStatus ?? task.status : task.status
612
- };
613
- if (task.details) chunk.details = task.details;
614
- if (task.output) chunk.output = task.output;
588
+ const chunk = Object.assign({ type: "task_update" }, task);
589
+ chunk.title = recovered ? compactTitle(`Recovered: ${task.title}`) : task.title;
590
+ chunk.status = recovered ? "complete" : task.status === "in_progress" ? params.finalInProgressStatus ?? task.status : task.status;
615
591
  if (index === finalTaskIndex && diffOutput) chunk.output = [task.output, diffOutput].filter(Boolean).join(" · ");
616
592
  if (index === finalTaskIndex && params.sessionLinks?.length) chunk.sources = buildSessionSources(params.sessionLinks);
617
593
  return chunk;
@@ -761,26 +737,29 @@ function reconcileSlackNativeTaskChunks(params) {
761
737
  continue;
762
738
  }
763
739
  const previousRow = params.previous.tasks.get(chunk.id);
764
- const details = resolveTaskFieldDelta(previousRow?.details, chunk.details);
765
- const output = resolveTaskFieldDelta(previousRow?.output, chunk.output);
766
- const sourcesChanged = Boolean(chunk.sources) && !previousRow?.sourcesSent;
767
740
  const row = {
768
741
  title: chunk.title,
769
742
  status: chunk.status
770
743
  };
771
- if (details.field) row.details = details.field;
772
- if (output.field) row.output = output.field;
773
- if (sourcesChanged || previousRow?.sourcesSent) row.sourcesSent = true;
774
- nextTasks.set(chunk.id, row);
775
- if (!(!previousRow || previousRow.title !== chunk.title || previousRow.status !== chunk.status || Boolean(details.delta) || Boolean(output.delta) || sourcesChanged)) continue;
776
744
  const update = {
777
745
  type: "task_update",
778
746
  id: chunk.id,
779
747
  title: chunk.title,
780
748
  status: chunk.status
781
749
  };
782
- if (details.delta) update.details = details.delta;
783
- if (output.delta) update.output = output.delta;
750
+ let fieldsChanged = false;
751
+ for (const key of ["details", "output"]) {
752
+ const { field: nextField, delta } = resolveTaskFieldDelta(previousRow?.[key], chunk[key]);
753
+ if (nextField) row[key] = nextField;
754
+ if (delta) {
755
+ update[key] = delta;
756
+ fieldsChanged = true;
757
+ }
758
+ }
759
+ const sourcesChanged = Boolean(chunk.sources) && !previousRow?.sourcesSent;
760
+ if (sourcesChanged || previousRow?.sourcesSent) row.sourcesSent = true;
761
+ nextTasks.set(chunk.id, row);
762
+ if (!(!previousRow || previousRow.title !== chunk.title || previousRow.status !== chunk.status || fieldsChanged || sourcesChanged)) continue;
784
763
  if (sourcesChanged) update.sources = chunk.sources;
785
764
  emitted.push(update);
786
765
  }
@@ -845,6 +824,15 @@ function resolveNativeProgressNarration(snapshot) {
845
824
  function combineProgressHeadlineAndExplanation(headline, explanation) {
846
825
  return headline && explanation && headline !== explanation ? `${headline} — ${explanation}` : headline ?? explanation;
847
826
  }
827
+ function normalizeProgressText(text) {
828
+ return text?.replace(/\s+/gu, " ").trim() ?? "";
829
+ }
830
+ function isSlackProgressTitleText(text, snapshot, explicitTitle) {
831
+ const candidate = normalizeProgressText(text);
832
+ if (!candidate) return false;
833
+ const title = normalizeProgressText(combineProgressHeadlineAndExplanation(explicitTitle ?? (snapshot.statusHeadlineFormat === "plain" ? void 0 : snapshot.statusHeadline), snapshot.planExplanationFormat === "plain" ? void 0 : snapshot.planExplanation));
834
+ return title.length > 0 && title.includes(candidate);
835
+ }
848
836
  //#endregion
849
837
  //#region extensions/slack/src/monitor/message-handler/preview-finalize.ts
850
838
  function buildExpectedSlackEditText(params) {
@@ -853,22 +841,6 @@ function buildExpectedSlackEditText(params) {
853
841
  if (params.blocks?.length) return normalizeSlackOutboundText(buildSlackBlocksFallbackText(params.blocks));
854
842
  return " ";
855
843
  }
856
- function buildAcceptedSlackEditTexts(params) {
857
- const expected = buildExpectedSlackEditText(params);
858
- const texts = /* @__PURE__ */ new Set([
859
- expected,
860
- normalizeSlackOutboundText(truncateSlackTextByUtf8Bytes(expected, SLACK_EDIT_TEXT_MAX_BYTES)),
861
- normalizeSlackOutboundText(buildSlackEditTextPayload(params.text, params.blocks))
862
- ]);
863
- if (params.blocks?.length && hasSlackNativeDataBlock(params.blocks)) {
864
- const fallbackPlan = buildSlackNativeDataDeliveryPlan({
865
- baseText: params.text,
866
- blocks: params.blocks
867
- });
868
- for (const message of fallbackPlan.fallbackMessages) texts.add(normalizeSlackOutboundText(message.text));
869
- }
870
- return texts;
871
- }
872
844
  function blocksMatch(expected, actual) {
873
845
  if (!expected?.length) return !actual?.length;
874
846
  if (!actual?.length) {
@@ -911,10 +883,18 @@ async function didSlackPreviewEditApplyAfterError(params) {
911
883
  text: params.text,
912
884
  blocks: params.blocks
913
885
  });
914
- const acceptedTexts = buildAcceptedSlackEditTexts({
915
- text: params.text,
916
- blocks: params.blocks
917
- });
886
+ const acceptedTexts = /* @__PURE__ */ new Set([
887
+ expectedText,
888
+ normalizeSlackOutboundText(truncateSlackTextByUtf8Bytes(expectedText, SLACK_EDIT_TEXT_MAX_BYTES)),
889
+ normalizeSlackOutboundText(buildSlackEditTextPayload(params.text, params.blocks))
890
+ ]);
891
+ if (params.blocks?.length && hasSlackNativeDataBlock(params.blocks)) {
892
+ const fallbackPlan = buildSlackNativeDataDeliveryPlan({
893
+ baseText: params.text,
894
+ blocks: params.blocks
895
+ });
896
+ for (const message of fallbackPlan.fallbackMessages) acceptedTexts.add(normalizeSlackOutboundText(message.text));
897
+ }
918
898
  const actualText = normalizeSlackOutboundText((readback.text ?? "").trim());
919
899
  if (params.blocks?.length) return acceptedTexts.has(actualText) && blocksMatch(params.blocks, readback.blocks);
920
900
  return actualText === expectedText;
@@ -943,7 +923,8 @@ async function finalizeSlackPreviewEdit(params) {
943
923
  //#region extensions/slack/src/monitor/message-handler/dispatch-progress-card.ts
944
924
  const MAX_VISIBLE_WORK_LINKS = 5;
945
925
  function createSlackDraftProgressCardRuntime(params) {
946
- const { account, cfg, ctx, prepared, slackClient } = params.setup;
926
+ const { cfg, prepared, slackClient } = params.setup;
927
+ const { account, ctx } = prepared;
947
928
  let finalStatus;
948
929
  const visibleWorkSessions = /* @__PURE__ */ new Map();
949
930
  const resolveSessionLinks = () => {
@@ -1088,8 +1069,8 @@ function createSlackNativeProgressTransport(params) {
1088
1069
  }
1089
1070
  return !delivery.streamFailed;
1090
1071
  };
1091
- const start = async (update) => {
1092
- const streamThreadTs = replyPlan.nextThreadTs();
1072
+ const start = async (update, retainedThreadTs) => {
1073
+ const streamThreadTs = retainedThreadTs ?? replyPlan.nextThreadTs();
1093
1074
  if (!streamThreadTs) {
1094
1075
  logVerbose("slack-stream: no reply thread target for native progress stream start, falling back");
1095
1076
  delivery.streamFailed = true;
@@ -1112,6 +1093,7 @@ function createSlackNativeProgressTransport(params) {
1112
1093
  }
1113
1094
  };
1114
1095
  const append = async (update) => {
1096
+ if (await delivery.rotateInterruptedStream()) return "rotated";
1115
1097
  const session = delivery.streamSession;
1116
1098
  if (!session) return false;
1117
1099
  await appendSlackStream({
@@ -1132,7 +1114,8 @@ function createSlackNativeProgressTransport(params) {
1132
1114
  //#region extensions/slack/src/monitor/message-handler/dispatch-progress.ts
1133
1115
  function createSlackProgressRuntime(runtimeParams) {
1134
1116
  const { setup, delivery } = runtimeParams;
1135
- const { account, cfg, ctx, hasSlackCustomIdentity, message, prepared, replyPlan, runtime, slackClient, slackIdentity, slackMessageMetadata, slackStreaming, slackProgressStyle, quietProgress, shouldUseDraftStream, useStreaming, previewStreamingEnabled } = setup;
1117
+ const { cfg, hasSlackCustomIdentity, prepared, replyPlan, runtime, slackIdentity, slackStreaming, slackProgressStyle, quietProgress, shouldUseDraftStream, useStreaming, previewStreamingEnabled } = setup;
1118
+ const { account, ctx, message, slackMessageMetadata } = prepared;
1136
1119
  const draftStream = shouldUseDraftStream ? createSlackDraftStream({
1137
1120
  target: prepared.replyTarget,
1138
1121
  cfg,
@@ -1155,7 +1138,6 @@ function createSlackProgressRuntime(runtimeParams) {
1155
1138
  const useNativeProgressStreaming = useStreaming && slackStreaming.mode === "progress";
1156
1139
  const progressDraftActive = Boolean(draftStream) || useNativeProgressStreaming;
1157
1140
  const previewToolProgressEnabled = progressDraftActive && resolveChannelStreamingPreviewToolProgress(account.config, slackStreaming.mode !== "progress", slackStreaming.mode);
1158
- let shouldYieldDraftProgress = () => false;
1159
1141
  const suppressDefaultToolProgressMessages = quietProgress || resolveChannelStreamingSuppressDefaultToolProgressMessages(account.config, {
1160
1142
  draftStreamActive: Boolean(draftStream) || useNativeProgressStreaming,
1161
1143
  mode: slackStreaming.mode,
@@ -1163,13 +1145,18 @@ function createSlackProgressRuntime(runtimeParams) {
1163
1145
  previewStreamingEnabled
1164
1146
  });
1165
1147
  let nativeStreamSnapshot = EMPTY_SLACK_NATIVE_STREAM_SNAPSHOT;
1166
- let appendRenderedText = "";
1167
- let appendSourceText = "";
1148
+ let nativeSnapshotSession = delivery.streamSession;
1149
+ let appendState = {
1150
+ rendered: "",
1151
+ source: ""
1152
+ };
1168
1153
  let nativeProgressCompletionSent = false;
1169
1154
  let cardPostRequested = false;
1170
1155
  let nativeProgressTerminalStatus = "complete";
1171
- let nativeNarrationRenderedText = "";
1172
- let nativeNarrationSourceText = "";
1156
+ let nativeNarration = {
1157
+ rendered: "",
1158
+ source: ""
1159
+ };
1173
1160
  let nativeStreamOrder = Promise.resolve();
1174
1161
  const withNativeStreamOrder = (task) => {
1175
1162
  const run = nativeStreamOrder.then(task, task);
@@ -1183,13 +1170,7 @@ function createSlackProgressRuntime(runtimeParams) {
1183
1170
  const explicitProgressTitle = resolveExplicitSlackProgressTitle(account.config);
1184
1171
  const progressDraftMaxLineChars = resolveChannelProgressDraftMaxLineChars(account.config);
1185
1172
  const progressCard = createSlackDraftProgressCardRuntime({
1186
- setup: {
1187
- account,
1188
- cfg,
1189
- ctx,
1190
- prepared,
1191
- slackClient
1192
- },
1173
+ setup,
1193
1174
  draftStream,
1194
1175
  enabled: useDraftProgressCard,
1195
1176
  detailed: previewToolProgressEnabled,
@@ -1219,10 +1200,7 @@ function createSlackProgressRuntime(runtimeParams) {
1219
1200
  session,
1220
1201
  chunks
1221
1202
  });
1222
- if (narrationUpdate.next.changed) {
1223
- nativeNarrationRenderedText = narrationUpdate.next.rendered;
1224
- nativeNarrationSourceText = narrationUpdate.next.source;
1225
- }
1203
+ if (narrationUpdate.next.changed) nativeNarration = narrationUpdate.next;
1226
1204
  nativeProgressCompletionSent = true;
1227
1205
  delivery.observedReplyDelivery ||= session.delivered;
1228
1206
  } catch (err) {
@@ -1231,30 +1209,23 @@ function createSlackProgressRuntime(runtimeParams) {
1231
1209
  }
1232
1210
  };
1233
1211
  const resolveNativeProgressTitle = (snapshot) => combineProgressHeadlineAndExplanation(explicitProgressTitle ?? snapshot.statusHeadline, snapshot.planExplanation);
1234
- const normalizeProgressText = (text) => text?.replace(/\s+/gu, " ").trim() ?? "";
1235
- const isRenderedAsProgressTitle = (text) => {
1236
- const candidate = normalizeProgressText(text);
1237
- if (!candidate) return false;
1238
- const snapshot = progressDraft.getSnapshot();
1239
- const title = normalizeProgressText(combineProgressHeadlineAndExplanation(explicitProgressTitle ?? (snapshot.statusHeadlineFormat === "plain" ? void 0 : snapshot.statusHeadline), snapshot.planExplanationFormat === "plain" ? void 0 : snapshot.planExplanation));
1240
- return title.length > 0 && title.includes(candidate);
1241
- };
1242
1212
  const resolveNarrationUpdate = (incoming) => {
1243
1213
  const next = applyAppendOnlyStreamUpdate({
1244
1214
  incoming: incoming ?? "",
1245
- rendered: nativeNarrationRenderedText,
1246
- source: nativeNarrationSourceText
1215
+ ...nativeNarration
1247
1216
  });
1248
1217
  return {
1249
1218
  next,
1250
- delta: next.changed ? next.rendered.slice(nativeNarrationRenderedText.length) : ""
1219
+ delta: next.changed ? next.rendered.slice(nativeNarration.rendered.length) : ""
1251
1220
  };
1252
1221
  };
1253
1222
  const updateNativeProgressStreamNow = async () => {
1254
- const snapshot = progressDraft.getSnapshot();
1255
- const narrationUpdate = resolveNarrationUpdate(resolveNativeProgressNarration(snapshot));
1256
1223
  if (!useNativeProgressStreaming || delivery.streamFailed || nativeUpdatesStopped) return false;
1257
1224
  if (!await nativeTransport.waitForStart()) return false;
1225
+ await delivery.rotateInterruptedStream();
1226
+ if (nativeSnapshotSession !== delivery.streamSession) nativeStreamSnapshot = EMPTY_SLACK_NATIVE_STREAM_SNAPSHOT;
1227
+ const snapshot = progressDraft.getSnapshot();
1228
+ const narrationUpdate = resolveNarrationUpdate(resolveNativeProgressNarration(snapshot));
1258
1229
  const reconciled = reconcileSlackNativeTaskChunks({
1259
1230
  previous: nativeStreamSnapshot,
1260
1231
  chunks: buildSlackProgressStreamChunks({
@@ -1269,16 +1240,17 @@ function createSlackProgressRuntime(runtimeParams) {
1269
1240
  if (!chunks?.length && !narrationUpdate.delta) return false;
1270
1241
  try {
1271
1242
  const hadSession = Boolean(delivery.streamSession);
1243
+ const retainedThreadTs = delivery.interruptedThreadTs;
1272
1244
  const streamUpdate = {
1273
1245
  ...narrationUpdate.delta ? { text: narrationUpdate.delta } : {},
1274
1246
  ...chunks?.length ? { chunks } : {}
1275
1247
  };
1276
- if (!(hadSession ? await nativeTransport.append(streamUpdate) : await nativeTransport.start(streamUpdate))) return false;
1277
- if (!hadSession) replyPlan.markSent();
1278
- if (narrationUpdate.next.changed) {
1279
- nativeNarrationRenderedText = narrationUpdate.next.rendered;
1280
- nativeNarrationSourceText = narrationUpdate.next.source;
1281
- }
1248
+ const accepted = hadSession ? await nativeTransport.append(streamUpdate) : await nativeTransport.start(streamUpdate, retainedThreadTs);
1249
+ if (accepted === "rotated") return await updateNativeProgressStreamNow();
1250
+ if (!accepted) return false;
1251
+ if (!hadSession && !retainedThreadTs) replyPlan.markSent();
1252
+ nativeSnapshotSession = delivery.streamSession;
1253
+ if (narrationUpdate.next.changed) nativeNarration = narrationUpdate.next;
1282
1254
  if (chunks?.length) nativeStreamSnapshot = reconciled.snapshot;
1283
1255
  return true;
1284
1256
  } catch (err) {
@@ -1303,7 +1275,7 @@ function createSlackProgressRuntime(runtimeParams) {
1303
1275
  await nativeUpdates.waitForInFlight();
1304
1276
  };
1305
1277
  const appendNativeNarration = (payload, kind) => withNativeStreamOrder(async () => {
1306
- if (isRenderedAsProgressTitle(payload.text)) return { visibleReplySent: false };
1278
+ if (isSlackProgressTitleText(payload.text, progressDraft.getSnapshot(), explicitProgressTitle)) return { visibleReplySent: false };
1307
1279
  const narrationUpdate = resolveNarrationUpdate(payload.text?.trimEnd());
1308
1280
  if (!narrationUpdate.delta) return { visibleReplySent: false };
1309
1281
  const result = await delivery.deliverWithStreaming({
@@ -1313,17 +1285,16 @@ function createSlackProgressRuntime(runtimeParams) {
1313
1285
  appendSeparator: false,
1314
1286
  taskDisplayMode: "plan"
1315
1287
  });
1316
- if (result.visibleReplySent && !delivery.streamFailed) {
1317
- nativeNarrationRenderedText = narrationUpdate.next.rendered;
1318
- nativeNarrationSourceText = narrationUpdate.next.source;
1319
- }
1288
+ if (result.visibleReplySent && !delivery.streamFailed) nativeNarration = narrationUpdate.next;
1320
1289
  return result;
1321
1290
  });
1322
1291
  const resetProgressTurnState = () => {
1323
1292
  progressWorkCounter.reset();
1324
1293
  cardPostRequested = false;
1325
- nativeNarrationRenderedText = "";
1326
- nativeNarrationSourceText = "";
1294
+ nativeNarration = {
1295
+ rendered: "",
1296
+ source: ""
1297
+ };
1327
1298
  };
1328
1299
  const progressDraft = createChannelProgressDraftCompositor({
1329
1300
  preparedItems: true,
@@ -1338,11 +1309,11 @@ function createSlackProgressRuntime(runtimeParams) {
1338
1309
  update: async (previewText, options) => {
1339
1310
  if (useNativeProgressStreaming) {
1340
1311
  const priorSnapshot = nativeStreamSnapshot;
1341
- const priorNarration = nativeNarrationRenderedText;
1312
+ const priorNarration = nativeNarration.rendered;
1342
1313
  nativeUpdates.update(true);
1343
1314
  if (options?.flush) await nativeUpdates.flush();
1344
1315
  else await nativeUpdates.waitForInFlight();
1345
- return priorSnapshot !== nativeStreamSnapshot || priorNarration !== nativeNarrationRenderedText;
1316
+ return priorSnapshot !== nativeStreamSnapshot || priorNarration !== nativeNarration.rendered;
1346
1317
  }
1347
1318
  if (!draftStream) return false;
1348
1319
  const snapshot = options.snapshot;
@@ -1412,8 +1383,9 @@ function createSlackProgressRuntime(runtimeParams) {
1412
1383
  };
1413
1384
  const deliverNativeFinalNow = async (payload, kind) => {
1414
1385
  const streamReady = await nativeTransport.waitForStart();
1415
- const finalThreadTs = delivery.streamSession?.threadTs ?? delivery.nativeProgressStreamThreadTs;
1416
- if (payload.isError !== true && streamReady && Boolean(delivery.streamSession) && delivery.isStreamingEligible(payload, { maxTextBytes: 4e3 })) {
1386
+ await delivery.rotateInterruptedStream();
1387
+ const finalThreadTs = delivery.nativeFinalThreadTs();
1388
+ if (delivery.canFinishNativeFinal(payload, streamReady)) {
1417
1389
  await appendNativeProgressCompletion(false);
1418
1390
  return await delivery.deliverWithStreaming({
1419
1391
  payload,
@@ -1477,11 +1449,9 @@ function createSlackProgressRuntime(runtimeParams) {
1477
1449
  progressDraft.resetActivity({ suppressed: true });
1478
1450
  const next = applyAppendOnlyStreamUpdate({
1479
1451
  incoming: trimmed,
1480
- rendered: appendRenderedText,
1481
- source: appendSourceText
1452
+ ...appendState
1482
1453
  });
1483
- appendRenderedText = next.rendered;
1484
- appendSourceText = next.source;
1454
+ appendState = next;
1485
1455
  if (!next.changed) return false;
1486
1456
  draftStream?.update(next.rendered);
1487
1457
  return false;
@@ -1508,8 +1478,10 @@ function createSlackProgressRuntime(runtimeParams) {
1508
1478
  return await progressDraft.pushReasoningProgress(payload.text, { snapshot: payload.isReasoningSnapshot === true });
1509
1479
  };
1510
1480
  const resetDraftDeliveryState = () => {
1511
- appendRenderedText = "";
1512
- appendSourceText = "";
1481
+ appendState = {
1482
+ rendered: "",
1483
+ source: ""
1484
+ };
1513
1485
  };
1514
1486
  const beginNewProgressTurn = async (options) => {
1515
1487
  if (useNativeProgressStreaming) {
@@ -1609,11 +1581,7 @@ function createSlackProgressRuntime(runtimeParams) {
1609
1581
  onQueuedFollowupSettled,
1610
1582
  pushPlanProgress,
1611
1583
  pushReasoningProgress,
1612
- updateDraftFromPartial,
1613
- setShouldYieldDraftProgress: (value) => {
1614
- shouldYieldDraftProgress = value;
1615
- },
1616
- shouldYieldDraftProgress: () => shouldYieldDraftProgress()
1584
+ updateDraftFromPartial
1617
1585
  };
1618
1586
  }
1619
1587
  //#endregion
@@ -1665,7 +1633,6 @@ async function createSlackDispatchSetup(prepared) {
1665
1633
  replyToMode: prepared.replyToMode
1666
1634
  });
1667
1635
  const forcedReplyThreadTs = prepared.forcedReplyThreadTs;
1668
- const slackMessageMetadata = prepared.slackMessageMetadata;
1669
1636
  const statusThreadTs = forcedReplyThreadTs ?? threadContext.messageThreadId;
1670
1637
  const isThreadReply = threadContext.isThreadReply;
1671
1638
  const replyDeliveryMode = forcedReplyThreadTs ? "off" : prepared.replyToMode;
@@ -1681,10 +1648,6 @@ async function createSlackDispatchSetup(prepared) {
1681
1648
  isGroup: prepared.isRoomish,
1682
1649
  groupId: prepared.isRoomish ? message.channel : void 0
1683
1650
  };
1684
- const messageSentDeliveryHookContext = {
1685
- ...messageSentHookContext,
1686
- messageSentHookTarget
1687
- };
1688
1651
  const reactionMessageTs = prepared.ackReactionMessageTs;
1689
1652
  const messageTs = message.ts ?? message.event_ts;
1690
1653
  const incomingThreadTs = message.thread_ts;
@@ -1692,20 +1655,18 @@ async function createSlackDispatchSetup(prepared) {
1692
1655
  let statusWasSet = false;
1693
1656
  let didAddTypingReaction = false;
1694
1657
  const statusReactionsEnabled = prepared.ctxPayload.InboundEventKind !== "room_event" && Boolean(prepared.ackReactionPromise) && Boolean(reactionMessageTs) && cfg.messages?.statusReactions?.enabled === true;
1658
+ const updateReaction = (send, targetTs, emoji) => send(message.channel, targetTs, emoji, {
1659
+ token: ctx.botToken,
1660
+ client: slackClient
1661
+ });
1695
1662
  const statusReactions = createStatusReactionController({
1696
1663
  enabled: statusReactionsEnabled,
1697
1664
  adapter: {
1698
1665
  setReaction: async (emoji) => {
1699
- await reactSlackMessage(message.channel, reactionMessageTs ?? "", emoji, {
1700
- token: ctx.botToken,
1701
- client: slackClient
1702
- });
1666
+ await updateReaction(reactSlackMessage, reactionMessageTs ?? "", emoji);
1703
1667
  },
1704
1668
  removeReaction: async (emoji) => {
1705
- await removeSlackReaction(message.channel, reactionMessageTs ?? "", emoji, {
1706
- token: ctx.botToken,
1707
- client: slackClient
1708
- });
1669
+ await updateReaction(removeSlackReaction, reactionMessageTs ?? "", emoji);
1709
1670
  }
1710
1671
  },
1711
1672
  initialEmoji: prepared.ackReactionValue || "eyes",
@@ -1735,6 +1696,15 @@ async function createSlackDispatchSetup(prepared) {
1735
1696
  const typingTarget = statusThreadTs ? `${message.channel}/${statusThreadTs}` : message.channel;
1736
1697
  const typingReaction = quietProgress && account.config.typingReaction === void 0 ? "hourglass_flowing_sand" : ctx.typingReaction;
1737
1698
  const threadStatusGate = { hasVisibleOutput: () => false };
1699
+ const onTypingError = (action, error) => {
1700
+ logTypingFailure({
1701
+ log: (messageValue) => runtime.error?.(danger(messageValue)),
1702
+ channel: "slack",
1703
+ action,
1704
+ target: typingTarget,
1705
+ error
1706
+ });
1707
+ };
1738
1708
  const { onModelSelected, ...replyPipeline } = createChannelMessageReplyPipeline({
1739
1709
  cfg,
1740
1710
  agentId: route.agentId,
@@ -1755,10 +1725,7 @@ async function createSlackDispatchSetup(prepared) {
1755
1725
  }
1756
1726
  if (typingReaction && message.ts) {
1757
1727
  didAddTypingReaction = true;
1758
- await reactSlackMessage(message.channel, message.ts, typingReaction, {
1759
- token: ctx.botToken,
1760
- client: slackClient
1761
- }).catch((err) => {
1728
+ await updateReaction(reactSlackMessage, message.ts, typingReaction).catch((err) => {
1762
1729
  logVerbose(`slack send: typing reaction failed: ${formatSlackError(err)}`);
1763
1730
  });
1764
1731
  }
@@ -1780,32 +1747,13 @@ async function createSlackDispatchSetup(prepared) {
1780
1747
  }
1781
1748
  if (didAddTypingReaction && typingReaction && message.ts) {
1782
1749
  didAddTypingReaction = false;
1783
- await removeSlackReaction(message.channel, message.ts, typingReaction, {
1784
- token: ctx.botToken,
1785
- client: slackClient
1786
- }).catch((err) => {
1750
+ await updateReaction(removeSlackReaction, message.ts, typingReaction).catch((err) => {
1787
1751
  logVerbose(`slack send: typing reaction removal failed: ${formatSlackError(err)}`);
1788
1752
  });
1789
1753
  }
1790
1754
  },
1791
- onStartError: (err) => {
1792
- logTypingFailure({
1793
- log: (messageValue) => runtime.error?.(danger(messageValue)),
1794
- channel: "slack",
1795
- action: "start",
1796
- target: typingTarget,
1797
- error: err
1798
- });
1799
- },
1800
- onStopError: (err) => {
1801
- logTypingFailure({
1802
- log: (messageLocal) => runtime.error?.(danger(messageLocal)),
1803
- channel: "slack",
1804
- action: "stop",
1805
- target: typingTarget,
1806
- error: err
1807
- });
1808
- }
1755
+ onStartError: (err) => onTypingError("start", err),
1756
+ onStopError: (err) => onTypingError("stop", err)
1809
1757
  }
1810
1758
  });
1811
1759
  const hookRunner = getGlobalHookRunner();
@@ -1824,18 +1772,12 @@ async function createSlackDispatchSetup(prepared) {
1824
1772
  const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(account.config);
1825
1773
  return {
1826
1774
  prepared,
1827
- ctx,
1828
- account,
1829
- message,
1830
- route,
1831
1775
  slackClient,
1832
1776
  slackClientOptions,
1833
1777
  slackStreamFallbackTeamId,
1834
1778
  cfg,
1835
1779
  runtime,
1836
1780
  slackIdentity,
1837
- forcedReplyThreadTs,
1838
- slackMessageMetadata,
1839
1781
  statusThreadTs,
1840
1782
  isThreadReply,
1841
1783
  replyDeliveryMode,
@@ -1843,7 +1785,6 @@ async function createSlackDispatchSetup(prepared) {
1843
1785
  suppressRoomEventTyping,
1844
1786
  messageSentHookTarget,
1845
1787
  messageSentHookContext,
1846
- messageSentDeliveryHookContext,
1847
1788
  statusReactionsEnabled,
1848
1789
  statusReactions,
1849
1790
  hasRepliedRef,
@@ -1865,9 +1806,13 @@ async function createSlackDispatchSetup(prepared) {
1865
1806
  //#endregion
1866
1807
  //#region extensions/slack/src/monitor/message-handler/dispatch-streaming.ts
1867
1808
  function createSlackStreamingDeliveryRuntime(setup) {
1868
- const { account, ctx, forcedReplyThreadTs, isThreadReply, message, messageSentDeliveryHookContext, messageSentHookContext, messageSentHookTarget, prepared, replyDeliveryMode, replyPlan, runtime, slackClient, slackClientOptions, slackIdentity, slackMessageMetadata, slackStreamFallbackTeamId } = setup;
1809
+ const { isThreadReply, messageSentHookContext, messageSentHookTarget, prepared, replyDeliveryMode, replyPlan, runtime, slackClient, slackClientOptions, slackIdentity, slackStreamFallbackTeamId } = setup;
1810
+ const { account, ctx, forcedReplyThreadTs, message, slackMessageMetadata } = prepared;
1869
1811
  const state = {
1870
1812
  streamSession: null,
1813
+ streamBoundary: null,
1814
+ interruptedThreadTs: void 0,
1815
+ streamInterrupted: false,
1871
1816
  nativeProgressStreamStartPromise: null,
1872
1817
  nativeProgressStreamThreadTs: void 0,
1873
1818
  streamFailed: false,
@@ -1876,22 +1821,40 @@ function createSlackStreamingDeliveryRuntime(setup) {
1876
1821
  observedReplyDelivery: false
1877
1822
  };
1878
1823
  const startStream = async (params) => {
1879
- const session = await startSlackStream({
1880
- client: slackClient,
1881
- clientOptions: slackClientOptions,
1882
- channel: message.channel,
1883
- ...params,
1884
- ...slackIdentity ? { identity: slackIdentity } : {},
1885
- teamId: await resolveSlackStreamRecipientTeamId({
1886
- client: slackClient,
1887
- token: ctx.botToken,
1888
- userId: message.user,
1889
- fallbackTeamId: slackStreamFallbackTeamId
1890
- }),
1891
- userId: message.user
1824
+ const boundary = trackSlackDraftMessage({
1825
+ accountId: account.accountId,
1826
+ teamId: prepared.eventScope?.teamId,
1827
+ channelId: message.channel,
1828
+ threadTs: message.thread_ts,
1829
+ onInterveningMessage: () => {
1830
+ state.streamInterrupted = true;
1831
+ }
1892
1832
  });
1893
- state.streamSession = session;
1894
- return session;
1833
+ state.streamBoundary = boundary;
1834
+ try {
1835
+ const session = await startSlackStream({
1836
+ client: slackClient,
1837
+ clientOptions: slackClientOptions,
1838
+ channel: message.channel,
1839
+ ...params,
1840
+ ...slackIdentity ? { identity: slackIdentity } : {},
1841
+ teamId: await resolveSlackStreamRecipientTeamId({
1842
+ client: slackClient,
1843
+ token: ctx.botToken,
1844
+ userId: message.user,
1845
+ fallbackTeamId: slackStreamFallbackTeamId
1846
+ }),
1847
+ userId: message.user
1848
+ });
1849
+ state.streamSession = session;
1850
+ state.interruptedThreadTs = void 0;
1851
+ if (session.streamer.ts) boundary.setMessageTs(session.streamer.ts);
1852
+ return session;
1853
+ } catch (error) {
1854
+ boundary.stop();
1855
+ if (state.streamBoundary === boundary) state.streamBoundary = null;
1856
+ throw error;
1857
+ }
1895
1858
  };
1896
1859
  const deliverPreparedReply = (reply, replyThreadTs, deferMessageSentHooks = false) => deliverReplies({
1897
1860
  cfg: ctx.cfg,
@@ -1906,7 +1869,8 @@ function createSlackStreamingDeliveryRuntime(setup) {
1906
1869
  replyToMode: replyDeliveryMode,
1907
1870
  ...slackIdentity ? { identity: slackIdentity } : {},
1908
1871
  ...slackMessageMetadata ? { metadata: slackMessageMetadata } : {},
1909
- ...messageSentDeliveryHookContext,
1872
+ ...messageSentHookContext,
1873
+ messageSentHookTarget,
1910
1874
  ...deferMessageSentHooks ? { deferMessageSentHooks: true } : {},
1911
1875
  eventScope: prepared.eventScope
1912
1876
  });
@@ -1919,12 +1883,15 @@ function createSlackStreamingDeliveryRuntime(setup) {
1919
1883
  ...result
1920
1884
  });
1921
1885
  };
1922
- let deliveryTracker = createSlackEventDeliveryTracker();
1886
+ const deliveredKeys = /* @__PURE__ */ new Set();
1887
+ const markDelivered = (key) => {
1888
+ if (key) deliveredKeys.add(key);
1889
+ };
1923
1890
  const markPreviewPayloadDelivered = (params) => {
1924
1891
  const preparedReply = prepareSlackReply(params.payload);
1925
- deliveryTracker.markDelivered(buildSlackEventDeliveryKey(params, preparedReply));
1892
+ markDelivered(buildSlackEventDeliveryKey(params, preparedReply));
1926
1893
  const nextThreadTs = replyPlan.peekThreadTs();
1927
- if (nextThreadTs !== params.threadTs) deliveryTracker.markDelivered(buildSlackEventDeliveryKey({
1894
+ if (nextThreadTs !== params.threadTs) markDelivered(buildSlackEventDeliveryKey({
1928
1895
  ...params,
1929
1896
  threadTs: nextThreadTs
1930
1897
  }, preparedReply));
@@ -1938,14 +1905,16 @@ function createSlackStreamingDeliveryRuntime(setup) {
1938
1905
  state.usedReplyThreadTs ??= deliveredThreadTs;
1939
1906
  if (kind === "block") state.usedBlockReplyThreadTs = deliveredThreadTs;
1940
1907
  };
1908
+ const stopStream = (session, chunks) => stopSlackStream({
1909
+ session,
1910
+ ...chunks?.length ? { chunks } : {},
1911
+ ...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
1912
+ });
1941
1913
  const deliverPendingStreamFallback = async (session, err) => {
1942
1914
  if (session.stoppedBySlack) return;
1943
1915
  let fallbackError = err;
1944
1916
  if (!session.stopped) try {
1945
- const stopResult = await stopSlackStream({
1946
- session,
1947
- ...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
1948
- });
1917
+ const stopResult = await stopStream(session);
1949
1918
  if (session.stoppedBySlack) return;
1950
1919
  state.observedReplyDelivery = true;
1951
1920
  state.usedReplyThreadTs ??= session.threadTs;
@@ -1964,10 +1933,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
1964
1933
  if (!sent?.receipt.platformMessageIds.length) return;
1965
1934
  markSlackStreamFallbackDelivered(session);
1966
1935
  if (!session.stopped) try {
1967
- await stopSlackStream({
1968
- session,
1969
- ...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
1970
- });
1936
+ await stopStream(session);
1971
1937
  } catch (finalizeErr) {
1972
1938
  runtime.error?.(danger(`slack-stream: failed to finalize native stream after fallback delivery: ${formatSlackError(finalizeErr)}`));
1973
1939
  }
@@ -1982,14 +1948,12 @@ function createSlackStreamingDeliveryRuntime(setup) {
1982
1948
  };
1983
1949
  };
1984
1950
  const finishStream = async (chunks) => {
1951
+ state.streamBoundary?.stop();
1952
+ state.streamBoundary = null;
1985
1953
  const session = state.streamSession;
1986
1954
  if (session && !session.stopped) try {
1987
1955
  try {
1988
- await stopSlackStream({
1989
- session,
1990
- ...chunks?.length ? { chunks } : {},
1991
- ...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
1992
- });
1956
+ await stopStream(session, chunks);
1993
1957
  state.observedReplyDelivery ||= session.delivered;
1994
1958
  } catch (error) {
1995
1959
  if (!(error instanceof SlackStreamNotDeliveredError)) throw error;
@@ -2000,9 +1964,28 @@ function createSlackStreamingDeliveryRuntime(setup) {
2000
1964
  runtime.error?.(danger(`slack-stream: failed to stop stream: ${formatSlackError(error)}`));
2001
1965
  }
2002
1966
  };
1967
+ const rotateInterruptedStream = async () => {
1968
+ if (!state.streamInterrupted) return;
1969
+ await state.nativeProgressStreamStartPromise?.catch(() => null);
1970
+ if (!state.streamInterrupted) return;
1971
+ state.streamInterrupted = false;
1972
+ if (state.streamSession?.stoppedBySlack) {
1973
+ state.streamBoundary?.stop();
1974
+ state.streamBoundary = null;
1975
+ return;
1976
+ }
1977
+ const threadTs = state.streamSession?.threadTs ?? state.nativeProgressStreamThreadTs;
1978
+ await finishStream();
1979
+ if (state.streamSession?.stoppedBySlack) return;
1980
+ state.streamSession = null;
1981
+ state.interruptedThreadTs = threadTs;
1982
+ return threadTs;
1983
+ };
2003
1984
  const deliverNormally = async (params) => {
2004
1985
  if (state.streamSession?.stoppedBySlack) return { visibleReplySent: false };
2005
- const replyThreadTs = resolveDeliveryThreadTs(params);
1986
+ await rotateInterruptedStream();
1987
+ if (state.streamSession?.stoppedBySlack) return { visibleReplySent: false };
1988
+ const replyThreadTs = params.forcedThreadTs ?? state.interruptedThreadTs ?? resolveDeliveryThreadTs(params);
2006
1989
  const deliveryReplyThreadTs = replyDeliveryMode === "off" && !forcedReplyThreadTs && !isThreadReply ? void 0 : replyThreadTs;
2007
1990
  const preparedReply = prepareSlackReply(params.payload);
2008
1991
  const deliveryKey = buildSlackEventDeliveryKey({
@@ -2010,7 +1993,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
2010
1993
  payload: params.payload,
2011
1994
  threadTs: deliveryReplyThreadTs
2012
1995
  }, preparedReply);
2013
- if (deliveryTracker.hasDelivered(deliveryKey)) {
1996
+ if (deliveryKey && deliveredKeys.has(deliveryKey)) {
2014
1997
  logVerbose("slack: suppressed duplicate normal delivery within the same turn");
2015
1998
  return { visibleReplySent: false };
2016
1999
  }
@@ -2025,7 +2008,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
2025
2008
  });
2026
2009
  rememberDeliveredThreadTs(params.kind, deliveredThreadTs);
2027
2010
  replyPlan.markSent();
2028
- deliveryTracker.markDelivered(deliveryKey);
2011
+ markDelivered(deliveryKey);
2029
2012
  return {
2030
2013
  visibleReplySent: true,
2031
2014
  messageIds: sent.receipt.platformMessageIds,
@@ -2047,9 +2030,10 @@ function createSlackStreamingDeliveryRuntime(setup) {
2047
2030
  forcedThreadTs: state.streamSession?.threadTs ?? state.nativeProgressStreamThreadTs
2048
2031
  });
2049
2032
  if (!state.streamSession && state.nativeProgressStreamStartPromise) await state.nativeProgressStreamStartPromise;
2033
+ await rotateInterruptedStream();
2050
2034
  if (state.streamSession?.stoppedBySlack) return { visibleReplySent: false };
2051
2035
  let session = state.streamSession;
2052
- const threadTs = session?.threadTs ?? replyPlan.nextThreadTs();
2036
+ const threadTs = session?.threadTs ?? state.interruptedThreadTs ?? replyPlan.nextThreadTs();
2053
2037
  if (state.streamFailed || !threadTs) {
2054
2038
  state.streamFailed = true;
2055
2039
  return await deliverNormally({
@@ -2065,7 +2049,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
2065
2049
  threadTs,
2066
2050
  textOverride: text
2067
2051
  });
2068
- if (deliveryTracker.hasDelivered(deliveryKey)) {
2052
+ if (deliveryKey && deliveredKeys.has(deliveryKey)) {
2069
2053
  logVerbose("slack-stream: suppressed duplicate reply payload");
2070
2054
  return { visibleReplySent: false };
2071
2055
  }
@@ -2122,7 +2106,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
2122
2106
  state.observedReplyDelivery = true;
2123
2107
  rememberDeliveredThreadTs(params.kind, threadTs);
2124
2108
  replyPlan.markSent();
2125
- deliveryTracker.markDelivered(deliveryKey);
2109
+ markDelivered(deliveryKey);
2126
2110
  emitStreamedDelivery(hookContent, {
2127
2111
  success: true,
2128
2112
  ...messageId ? { messageId } : {}
@@ -2133,17 +2117,20 @@ function createSlackStreamingDeliveryRuntime(setup) {
2133
2117
  threadId: threadTs
2134
2118
  };
2135
2119
  };
2120
+ const nativeFinalThreadTs = () => state.streamSession?.threadTs ?? state.interruptedThreadTs ?? state.nativeProgressStreamThreadTs;
2121
+ const canFinishNativeFinal = (payload, streamReady) => payload.isError !== true && streamReady && Boolean(state.streamSession || state.interruptedThreadTs) && isStreamingEligible(payload, { maxTextBytes: 4e3 });
2136
2122
  return Object.assign(state, {
2123
+ canFinishNativeFinal,
2137
2124
  deliverNormally,
2138
2125
  deliverWithStreaming,
2139
2126
  finishStream,
2140
2127
  isStreamingEligible,
2141
2128
  markPreviewPayloadDelivered,
2129
+ nativeFinalThreadTs,
2142
2130
  rememberDeliveredThreadTs,
2131
+ rotateInterruptedStream,
2143
2132
  startStream,
2144
- resetDeliveryTracker: () => {
2145
- deliveryTracker = createSlackEventDeliveryTracker();
2146
- }
2133
+ resetDeliveryTracker: () => deliveredKeys.clear()
2147
2134
  });
2148
2135
  }
2149
2136
  //#endregion
@@ -2180,13 +2167,16 @@ async function dispatchPreparedSlackMessage(prepared) {
2180
2167
  }
2181
2168
  async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptionLifecycle) {
2182
2169
  const { prepared } = setup;
2183
- const { account, cfg, ctx, disableBlockStreaming, hasSlackCustomIdentity, hasRepliedRef, message, messageSentHookContext, messageSentHookTarget, onModelSelected, previewStreamingEnabled, replyPipeline, replyPlan, route, runtime, slackClient, slackStreaming, sourceReplyDeliveryMode, statusReactions, statusReactionsEnabled, statusThreadTs, suppressRoomEventTyping, useStreaming } = setup;
2170
+ const { account, ctx, message, route } = prepared;
2171
+ const { cfg, disableBlockStreaming, hasSlackCustomIdentity, hasRepliedRef, messageSentHookContext, messageSentHookTarget, onModelSelected, previewStreamingEnabled, replyPipeline, replyPlan, runtime, slackClient, slackStreaming, sourceReplyDeliveryMode, statusReactions, statusReactionsEnabled, statusThreadTs, suppressRoomEventTyping, useStreaming } = setup;
2184
2172
  let dispatchError;
2185
2173
  const delivery = createSlackStreamingDeliveryRuntime(setup);
2186
2174
  const progress = createSlackProgressRuntime({
2187
2175
  setup,
2188
2176
  delivery
2189
2177
  });
2178
+ let shouldYieldDraftProgress = async () => false;
2179
+ let turnCommentaryVisible = false;
2190
2180
  const { draftStream, previewLifecycle } = progress;
2191
2181
  setup.threadStatusGate.hasVisibleOutput = () => delivery.observedReplyDelivery || previewLifecycle.previewFinalized || Boolean(draftStream?.messageId());
2192
2182
  const failureNoticeThreadTs = message.thread_ts;
@@ -2409,9 +2399,10 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
2409
2399
  commentaryProgressEnabled: progress.commentaryProgressEnabled ? true : void 0,
2410
2400
  progressPreambleEnabled: progress.progressDraftActive && slackStreaming.mode === "progress" ? true : void 0,
2411
2401
  commentaryPayloadsEnabled: progress.commentaryProgressEnabled ? true : void 0,
2412
- shouldDeliverCommentaryPayloads: progress.commentaryProgressEnabled ? progress.shouldYieldDraftProgress : void 0,
2413
- onVerboseProgressVisibility: progress.commentaryProgressEnabled ? (isActive) => {
2414
- progress.setShouldYieldDraftProgress(isActive);
2402
+ shouldDeliverCommentaryPayloads: progress.commentaryProgressEnabled ? () => turnCommentaryVisible : void 0,
2403
+ onVerboseProgressVisibilityAsync: progress.commentaryProgressEnabled ? async (isActive) => {
2404
+ shouldYieldDraftProgress = isActive;
2405
+ turnCommentaryVisible = await isActive();
2415
2406
  } : void 0,
2416
2407
  allowProgressCallbacksWhenSourceDeliverySuppressed: sourceReplyDeliveryMode === "message_tool_only" && statusReactionsEnabled ? true : void 0,
2417
2408
  allowToolLifecycleWhenProgressHidden: statusReactionsEnabled ? true : void 0,
@@ -2437,7 +2428,8 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
2437
2428
  },
2438
2429
  onItemEvent: async (payload) => {
2439
2430
  if (payload.hideFromChannelProgress || payload.suppressChannelProgress) return progress.preambleOnlyProgress ? false : progress.progressDraft.pushItemEvent(payload);
2440
- if (payload.kind === "preamble" && progress.shouldYieldDraftProgress()) return false;
2431
+ if (payload.kind === "preamble" && await shouldYieldDraftProgress()) return false;
2432
+ if (prepared.turnAdoptionLifecycle?.abortSignal?.aborted) return false;
2441
2433
  progress.progressWorkCounter.noteItem(payload);
2442
2434
  return progress.preambleOnlyProgress && payload.kind !== "preamble" ? await progress.progressDraft.noteActivity() : await progress.progressDraft.pushItemEvent(payload);
2443
2435
  },
@@ -2546,12 +2538,7 @@ const THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
2546
2538
  const THREAD_STARTER_CACHE_TTL_MS = 216e5;
2547
2539
  const THREAD_STARTER_CACHE_MAX = 2e3;
2548
2540
  function evictThreadStarterCache() {
2549
- const now = asDateTimestampMs(Date.now());
2550
- if (now === void 0) {
2551
- THREAD_STARTER_CACHE.clear();
2552
- return;
2553
- }
2554
- for (const [cacheKey, entry] of THREAD_STARTER_CACHE.entries()) if (asDateTimestampMs(entry.expiresAt) === void 0 || entry.expiresAt <= now) THREAD_STARTER_CACHE.delete(cacheKey);
2541
+ pruneExpiredMapEntries(THREAD_STARTER_CACHE, Date.now());
2555
2542
  pruneMapToMaxSize(THREAD_STARTER_CACHE, THREAD_STARTER_CACHE_MAX);
2556
2543
  }
2557
2544
  function formatSlackFilePlaceholder(files) {
@@ -2635,6 +2622,16 @@ async function resolveSlackThreadStarter(params) {
2635
2622
  }
2636
2623
  }
2637
2624
  const SLACK_THREAD_HISTORY_MAX_PAGES = 3;
2625
+ function toSlackHistoryMessage(message, text) {
2626
+ return {
2627
+ text: text ?? formatSlackFilePlaceholder(message.files),
2628
+ userId: message.user,
2629
+ botId: message.bot_id,
2630
+ ts: message.ts,
2631
+ files: message.files,
2632
+ attachments: message.attachments
2633
+ };
2634
+ }
2638
2635
  /**
2639
2636
  * Fetches the most recent messages in a Slack thread (excluding the current message).
2640
2637
  * Used to populate thread context when a new thread session starts.
@@ -2684,14 +2681,7 @@ async function resolveSlackThreadHistory(params) {
2684
2681
  params.onOmission?.("Slack thread exceeds the three-page automatic history budget");
2685
2682
  return [];
2686
2683
  }
2687
- return retained.map(([message, text]) => ({
2688
- text: text ?? formatSlackFilePlaceholder(message.files),
2689
- userId: message.user,
2690
- botId: message.bot_id,
2691
- ts: message.ts,
2692
- files: message.files,
2693
- attachments: message.attachments
2694
- }));
2684
+ return retained.map(([message, text]) => toSlackHistoryMessage(message, text));
2695
2685
  } catch (err) {
2696
2686
  params.assertCurrent?.();
2697
2687
  params.onOmission?.(formatErrorMessage(err));
@@ -2724,14 +2714,7 @@ async function resolveSlackChannelHistory(params) {
2724
2714
  seen.add(message.ts);
2725
2715
  const text = resolveSlackMessageText(message);
2726
2716
  if (!text && !message.files?.length) continue;
2727
- messages.push({
2728
- text: text ?? formatSlackFilePlaceholder(message.files),
2729
- userId: message.user,
2730
- botId: message.bot_id,
2731
- ts: message.ts,
2732
- files: message.files,
2733
- attachments: message.attachments
2734
- });
2717
+ messages.push(toSlackHistoryMessage(message, text));
2735
2718
  }
2736
2719
  cursor = response.response_metadata?.next_cursor?.trim() || void 0;
2737
2720
  if (!cursor || scanned >= params.limit) break;
@@ -2788,7 +2771,7 @@ const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
2788
2771
  const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
2789
2772
  const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
2790
2773
  const MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS = 2e3;
2791
- const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-DDoAJnrH.mjs").then((n) => n._));
2774
+ const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-KGKwTAKO.mjs").then((n) => n._));
2792
2775
  function formatSlackUnavailableMedia(params) {
2793
2776
  let fileReferences = params.files?.map((file) => `${formatSlackFileReference(file)} unavailable (${file.reason})`).join(", ");
2794
2777
  if (fileReferences && fileReferences.length > MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS) fileReferences = `${truncateUtf16Safe(fileReferences, MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS)}; … (file references truncated)`;
@@ -2805,7 +2788,7 @@ function formatSlackUnavailableMedia(params) {
2805
2788
  notice
2806
2789
  });
2807
2790
  }
2808
- function collectUniqueSlackMentionIds$1(texts) {
2791
+ function collectUniqueSlackMentionIds(texts) {
2809
2792
  const seen = /* @__PURE__ */ new Set();
2810
2793
  for (const text of texts) {
2811
2794
  if (!text) continue;
@@ -2862,7 +2845,7 @@ async function resolveSlackMessageContent(params) {
2862
2845
  const renderedMentions = /* @__PURE__ */ new Map();
2863
2846
  const resolveUserName = params.resolveUserName;
2864
2847
  if (resolveUserName) {
2865
- const mentionIds = collectUniqueSlackMentionIds$1(textParts);
2848
+ const mentionIds = collectUniqueSlackMentionIds(textParts);
2866
2849
  const lookupIds = mentionIds.slice(0, SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE);
2867
2850
  const skippedLookups = mentionIds.length - lookupIds.length;
2868
2851
  if (skippedLookups > 0) logVerbose(`slack: skipping ${skippedLookups} mention lookup(s) beyond per-message cap (${SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE})`);
@@ -3142,52 +3125,13 @@ function resolveSlackGroupSessionSubject(params) {
3142
3125
  if (channelName && workspaceName) return `${workspaceName} #${channelName}`;
3143
3126
  return `Slack Channel (Workspace ID: ${params.workspaceId}, Channel ID: ${params.channelId})`;
3144
3127
  }
3145
- function resolveSlackConversationLink(params) {
3146
- if (params.existingLink) return params.existingLink;
3147
- const teamId = normalizeOptionalString(params.teamId);
3148
- let apiHost = "";
3149
- try {
3150
- apiHost = params.slackApiUrl ? new URL(params.slackApiUrl).hostname.toLowerCase() : "";
3151
- } catch {}
3152
- const url = new URL(`https://${apiHost === "slack-gov.com" ? "slack-gov.com" : "slack.com"}/app_redirect`);
3153
- url.searchParams.set("channel", params.channelId);
3154
- if (teamId) url.searchParams.set("team", teamId);
3155
- return {
3156
- url: url.href,
3157
- label: "Slack"
3158
- };
3159
- }
3160
3128
  //#endregion
3161
3129
  //#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
3162
- const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-DDoAJnrH.mjs").then((n) => n._));
3130
+ const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-KGKwTAKO.mjs").then((n) => n._));
3163
3131
  const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
3164
3132
  function formatSlackThreadLabelSnippet(text) {
3165
3133
  return truncateUtf16Safe(text.replace(/\s+/g, " "), 80);
3166
3134
  }
3167
- function resolveSlackThreadSessionFreshness(params) {
3168
- return params.ctx.channelRuntime?.session?.resolveEntryResetFreshness?.({
3169
- agentId: params.agentId,
3170
- storePath: params.storePath,
3171
- sessionKey: params.sessionKey,
3172
- sessionCfg: params.ctx.cfg.session,
3173
- resetType: "thread",
3174
- resetOverride: resolveChannelResetConfig({
3175
- sessionCfg: params.ctx.cfg.session,
3176
- channel: "slack"
3177
- })
3178
- });
3179
- }
3180
- async function resolveSlackThreadUserMap(params) {
3181
- const uniqueUserIds = [...new Set(params.messages.map((item) => item.userId).filter((id) => Boolean(id)))];
3182
- const { results } = await runTasksWithConcurrency({
3183
- tasks: uniqueUserIds.map((id) => async () => {
3184
- const user = await params.ctx.resolveUserName(id, params.eventScope);
3185
- return user ? [id, user] : null;
3186
- }),
3187
- limit: SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY
3188
- });
3189
- return new Map(results.flatMap((result) => result ? [result] : []));
3190
- }
3191
3135
  async function resolveSlackThreadContextData(params) {
3192
3136
  const botIdentity = {
3193
3137
  botUserId: params.ctx.botUserId,
@@ -3197,17 +3141,34 @@ async function resolveSlackThreadContextData(params) {
3197
3141
  identity: botIdentity,
3198
3142
  author
3199
3143
  });
3144
+ const resolveThreadUserMap = async (messages) => {
3145
+ const uniqueUserIds = [...new Set(messages.map((item) => item.userId).filter((id) => Boolean(id)))];
3146
+ const { results } = await runTasksWithConcurrency({
3147
+ tasks: uniqueUserIds.map((id) => async () => {
3148
+ const user = await params.ctx.resolveUserName(id, params.eventScope);
3149
+ return user ? [id, user] : null;
3150
+ }),
3151
+ limit: SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY
3152
+ });
3153
+ return new Map(results.flatMap((result) => result ? [result] : []));
3154
+ };
3200
3155
  let threadStarterBody;
3201
3156
  let threadHistoryBody;
3202
3157
  let threadLabel;
3203
3158
  let threadStarterMedia = null;
3204
- const threadSessionFreshness = params.isThreadReply && params.threadTs ? resolveSlackThreadSessionFreshness({
3205
- ctx: params.ctx,
3159
+ const threadSessionFreshness = params.isThreadReply && params.threadTs ? await params.ctx.channelRuntime?.session?.resolveEntryResetFreshnessAsync?.({
3206
3160
  agentId: params.agentId,
3207
3161
  storePath: params.storePath,
3208
- sessionKey: params.sessionKey
3162
+ sessionKey: params.sessionKey,
3163
+ sessionCfg: params.ctx.cfg.session,
3164
+ resetType: "thread",
3165
+ resetOverride: resolveChannelResetConfig({
3166
+ sessionCfg: params.ctx.cfg.session,
3167
+ channel: "slack"
3168
+ })
3209
3169
  }) : void 0;
3210
- const threadSessionPreviousTimestamp = params.isThreadReply && params.threadTs && !threadSessionFreshness ? readSessionUpdatedAt({
3170
+ params.assertHistoryCurrent?.();
3171
+ const threadSessionPreviousTimestamp = params.isThreadReply && params.threadTs && !threadSessionFreshness ? await readSessionUpdatedAtAsync({
3211
3172
  storePath: params.storePath,
3212
3173
  sessionKey: params.sessionKey
3213
3174
  }) : void 0;
@@ -3319,11 +3280,7 @@ async function resolveSlackThreadContextData(params) {
3319
3280
  const retainCurrentBotHistory = params.isGroupDm && (isMissingThreadSession || isOutboundOnlyThreadSession);
3320
3281
  const threadHistoryWithoutCurrentBot = threadHistoryWithBotRoot.filter((entry) => !isCurrentBotAuthor(entry) || retainCurrentBotHistory || includeBotStarterAsRootContext && entry.ts === currentBotRootTs);
3321
3282
  const omittedCurrentBotHistoryCount = threadHistoryWithBotRoot.length - threadHistoryWithoutCurrentBot.length;
3322
- const userMapForFilter = params.contextVisibilityMode !== "all" && params.allowNameMatching && params.allowFromLower.length > 0 ? await resolveSlackThreadUserMap({
3323
- ctx: params.ctx,
3324
- messages: threadHistoryWithoutCurrentBot,
3325
- eventScope: params.eventScope
3326
- }) : /* @__PURE__ */ new Map();
3283
+ const userMapForFilter = params.contextVisibilityMode !== "all" && params.allowNameMatching && params.allowFromLower.length > 0 ? await resolveThreadUserMap(threadHistoryWithoutCurrentBot) : /* @__PURE__ */ new Map();
3327
3284
  params.assertHistoryCurrent?.();
3328
3285
  const { items: filteredThreadHistory, omitted: omittedHistoryCount } = params.contextVisibilityMode === "all" ? {
3329
3286
  items: threadHistoryWithoutCurrentBot,
@@ -3344,11 +3301,7 @@ async function resolveSlackThreadContextData(params) {
3344
3301
  });
3345
3302
  }
3346
3303
  });
3347
- const userMap = await resolveSlackThreadUserMap({
3348
- ctx: params.ctx,
3349
- messages: filteredThreadHistory,
3350
- eventScope: params.eventScope
3351
- });
3304
+ const userMap = await resolveThreadUserMap(filteredThreadHistory);
3352
3305
  params.assertHistoryCurrent?.();
3353
3306
  if (omittedHistoryCount > 0 || omittedCurrentBotHistoryCount > 0) logVerbose(`slack: omitted ${omittedHistoryCount + omittedCurrentBotHistoryCount} thread message(s) from context (mode=${params.contextVisibilityMode})`);
3354
3307
  const historyParts = [];
@@ -3441,10 +3394,10 @@ const subteamMemberCache = /* @__PURE__ */ new WeakMap();
3441
3394
  function normalizeSlackId(value) {
3442
3395
  return normalizeOptionalString(value)?.toUpperCase();
3443
3396
  }
3444
- function extractSlackSubteamMentionIds(text) {
3445
- if (!text) return [];
3397
+ function collectSlackMentionIds(text, regex) {
3446
3398
  const ids = /* @__PURE__ */ new Set();
3447
- for (const match of text.matchAll(SUBTEAM_MENTION_RE)) {
3399
+ regex.lastIndex = 0;
3400
+ for (const match of (text ?? "").matchAll(regex)) {
3448
3401
  const id = normalizeSlackId(match[1]);
3449
3402
  if (id) ids.add(id);
3450
3403
  }
@@ -3487,7 +3440,7 @@ async function readSlackSubteamUsers(params) {
3487
3440
  async function isSlackSubteamMentionForBot(params) {
3488
3441
  const botUserId = normalizeSlackId(params.botUserId);
3489
3442
  if (!botUserId) return false;
3490
- const subteamIds = extractSlackSubteamMentionIds(params.text);
3443
+ const subteamIds = collectSlackMentionIds(params.text, SUBTEAM_MENTION_RE);
3491
3444
  if (subteamIds.length === 0) return false;
3492
3445
  const now = params.now ?? Date.now();
3493
3446
  for (const subteamId of subteamIds) if ((await readSlackSubteamUsers({
@@ -3571,39 +3524,14 @@ function resolveCachedMentionRegexes(ctx, agentId, options) {
3571
3524
  byAgent.set(key, built);
3572
3525
  return built;
3573
3526
  }
3574
- function collectUniqueSlackMentionIds(text, regex) {
3575
- const ids = [];
3576
- regex.lastIndex = 0;
3577
- for (const match of text.matchAll(regex)) {
3578
- const id = normalizeSlackId(match[1]);
3579
- if (id && !ids.includes(id)) ids.push(id);
3580
- }
3581
- return ids;
3582
- }
3583
3527
  function collectSlackMentionMetadata(text) {
3584
3528
  return {
3585
- mentionedUserIds: collectUniqueSlackMentionIds(text, SLACK_USER_MENTION_RE),
3586
- mentionedSubteamIds: collectUniqueSlackMentionIds(text, SLACK_SUBTEAM_MENTION_RE),
3529
+ mentionedUserIds: collectSlackMentionIds(text, SLACK_USER_MENTION_RE),
3530
+ mentionedSubteamIds: collectSlackMentionIds(text, SLACK_SUBTEAM_MENTION_RE),
3587
3531
  hasAnyMention: SLACK_ANY_MENTION_RE.test(text),
3588
3532
  hasSubteamMention: text.includes(SLACK_SUBTEAM_MENTION_MARKER)
3589
3533
  };
3590
3534
  }
3591
- async function resolveSlackExplicitMentionState(params) {
3592
- const normalizedBotUserId = normalizeSlackId(params.ctx.botUserId);
3593
- const explicitlyMentionedBotUser = Boolean(normalizedBotUserId && params.mentionedUserIds.includes(normalizedBotUserId));
3594
- const explicitlyMentionedBotSubteam = Boolean(params.ctx.botUserId && params.hasSubteamMention) && await isSlackSubteamMentionForBot({
3595
- client: params.eventScope?.client ?? params.ctx.app.client,
3596
- text: params.messageText,
3597
- botUserId: params.ctx.botUserId,
3598
- teamId: params.eventScope?.teamId ?? params.ctx.teamId,
3599
- log: logVerbose
3600
- });
3601
- return {
3602
- explicitlyMentionedBotUser,
3603
- explicitlyMentionedBotSubteam,
3604
- explicitlyMentioned: explicitlyMentionedBotUser || explicitlyMentionedBotSubteam || params.source === "app_mention"
3605
- };
3606
- }
3607
3535
  function resolveSlackMentionSource(params) {
3608
3536
  if (params.explicitBotMention) return "explicit_bot";
3609
3537
  if (params.explicitSubteamMention) return "subteam";
@@ -3794,14 +3722,16 @@ async function prepareSlackMessage(params) {
3794
3722
  message,
3795
3723
  eventScope: opts.eventScope
3796
3724
  }) : Promise.resolve(void 0);
3797
- const { explicitlyMentionedBotUser, explicitlyMentionedBotSubteam, explicitlyMentioned } = await resolveSlackExplicitMentionState({
3798
- ctx,
3799
- messageText,
3800
- mentionedUserIds,
3801
- hasSubteamMention: mentionMetadata.hasSubteamMention,
3802
- source: opts.source,
3803
- eventScope: opts.eventScope
3725
+ const currentBotUserId = normalizeSlackId(ctx.botUserId);
3726
+ const explicitlyMentionedBotUser = Boolean(currentBotUserId && mentionedUserIds.includes(currentBotUserId));
3727
+ const explicitlyMentionedBotSubteam = Boolean(ctx.botUserId && mentionMetadata.hasSubteamMention) && await isSlackSubteamMentionForBot({
3728
+ client: opts.eventScope?.client ?? ctx.app.client,
3729
+ text: messageText,
3730
+ botUserId: ctx.botUserId,
3731
+ teamId: opts.eventScope?.teamId ?? ctx.teamId,
3732
+ log: logVerbose
3804
3733
  });
3734
+ const explicitlyMentioned = explicitlyMentionedBotUser || explicitlyMentionedBotSubteam || opts.source === "app_mention";
3805
3735
  const channelRequireMention = channelConfig?.requireMention ?? ctx.defaultRequireMention ?? true;
3806
3736
  const chatType = resolveSlackChatType(conversation.resolvedChannelType);
3807
3737
  const restoredAssistantThreadContext = await restoredAssistantThreadContextPromise;
@@ -3869,12 +3799,11 @@ async function prepareSlackMessage(params) {
3869
3799
  let mentionRegexes = buildPolicyMentionRegexes(routing.route.agentId);
3870
3800
  let wasMentioned = resolveWasMentioned(mentionRegexes);
3871
3801
  const hasBoundSession = Boolean(routing.runtimeBoundSessionKey || routing.configuredBindingSessionKey);
3872
- let { route, runtimeBinding, replyToMode, threadContext, threadTs, isThreadReply, threadKeys, sessionKey } = routing;
3873
3802
  const { configuredBinding, configuredBindingSessionKey } = routing;
3874
3803
  const isAssistantThreadMessage = Boolean(isDirectMessage && messageAssistantThreadContext);
3875
- const forcedAssistantReplyThreadTs = Boolean(assistantThreadContext?.threadTs && (isThreadReply || isAssistantThreadMessage || replyToMode !== "off")) ? assistantThreadContext?.threadTs : void 0;
3804
+ const forcedAssistantReplyThreadTs = Boolean(assistantThreadContext?.threadTs && (routing.isThreadReply || isAssistantThreadMessage || routing.replyToMode !== "off")) ? assistantThreadContext?.threadTs : void 0;
3876
3805
  const forcedReplyThreadTs = agentViewThreadTs ?? forcedAssistantReplyThreadTs;
3877
- if (runtimeBinding && shouldLogVerbose()) logVerbose(`slack: routed via bound conversation ${runtimeBinding.conversation.conversationId} -> ${runtimeBinding.targetSessionKey}`);
3806
+ if (routing.runtimeBinding && shouldLogVerbose()) logVerbose(`slack: routed via bound conversation ${routing.runtimeBinding.conversation.conversationId} -> ${routing.runtimeBinding.targetSessionKey}`);
3878
3807
  if (configuredBinding) {
3879
3808
  const ensured = await ensureConfiguredBindingRouteReady({
3880
3809
  cfg,
@@ -3890,9 +3819,9 @@ async function prepareSlackMessage(params) {
3890
3819
  const senderNameForAuthPromise = ctx.allowNameMatching ? resolveSenderName() : void 0;
3891
3820
  let threadStarterPromise;
3892
3821
  const getThreadStarter = () => {
3893
- threadStarterPromise ??= isThreadReply && threadTs ? resolveSlackThreadStarter({
3822
+ threadStarterPromise ??= routing.isThreadReply && routing.threadTs ? resolveSlackThreadStarter({
3894
3823
  channelId: message.channel,
3895
- threadTs,
3824
+ threadTs: routing.threadTs,
3896
3825
  client: slackClient,
3897
3826
  workspaceScope: threadStarterWorkspaceScope,
3898
3827
  refresh: isRoomish && ctx.historyLimit > 0
@@ -3901,7 +3830,7 @@ async function prepareSlackMessage(params) {
3901
3830
  };
3902
3831
  const resolveMessageContent = (contentMessage, preloadedMedia) => getThreadStarter().then((threadStarter) => resolveSlackMessageContent({
3903
3832
  message: contentMessage,
3904
- isThreadReply,
3833
+ isThreadReply: routing.isThreadReply,
3905
3834
  threadStarter,
3906
3835
  isBotMessage,
3907
3836
  botToken: ctx.botToken,
@@ -4051,7 +3980,6 @@ async function prepareSlackMessage(params) {
4051
3980
  })) groupThread = void 0;
4052
3981
  mentionRegexes = buildPolicyMentionRegexes(routing.route.agentId);
4053
3982
  wasMentioned = resolveWasMentioned(mentionRegexes);
4054
- ({route, runtimeBinding, replyToMode, threadContext, threadTs, isThreadReply, threadKeys, sessionKey} = routing);
4055
3983
  canDetectMention = Boolean(groupThread) || Boolean(ctx.botUserId) || mentionRegexes.length > 0;
4056
3984
  }
4057
3985
  if (preflightAudioTranscript && !wasMentioned) {
@@ -4060,6 +3988,7 @@ async function prepareSlackMessage(params) {
4060
3988
  preflightAudioTranscript = void 0;
4061
3989
  preflightAudioMedia = void 0;
4062
3990
  }
3991
+ const { route, runtimeBinding, replyToMode, threadContext, threadTs, isThreadReply, threadKeys, sessionKey } = routing;
4063
3992
  const directThreadRoutedToDmSession = !assistantThreadContext && !agentViewThreadTs && isDirectMessage && isThreadReply && threadTs && runtimeBinding?.conversation.conversationId !== threadTs;
4064
3993
  const mentionDecision = resolveInboundMentionDecision({
4065
3994
  facts: {
@@ -4188,12 +4117,6 @@ async function prepareSlackMessage(params) {
4188
4117
  storePath,
4189
4118
  sessionKey
4190
4119
  });
4191
- const conversationLink = resolveSlackConversationLink({
4192
- channelId: message.channel,
4193
- teamId: opts.eventScope?.teamId ?? ctx.teamId,
4194
- slackApiUrl: slackClient.slackApiUrl,
4195
- existingLink: sessionEntry?.conversationLink
4196
- });
4197
4120
  const previousTimestamp = sessionEntry?.updatedAt;
4198
4121
  const excludedMessageIds = new Set(opts.sourceMessageIds);
4199
4122
  if (message.ts) excludedMessageIds.add(message.ts);
@@ -4348,8 +4271,7 @@ async function prepareSlackMessage(params) {
4348
4271
  spaceId: opts.eventScope?.teamId || ctx.teamId || void 0,
4349
4272
  threadId: boundMessageThreadId,
4350
4273
  nativeChannelId: message.channel,
4351
- avatar: conversationAvatar,
4352
- link: conversationLink
4274
+ avatar: conversationAvatar
4353
4275
  },
4354
4276
  route: {
4355
4277
  ...route,