@archipelagolab/lobi 1.0.6 → 1.0.7

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 (1533) hide show
  1. package/CHANGELOG.md +164 -0
  2. package/SPEC-SUPPORT.md +116 -0
  3. package/api.ts +18 -0
  4. package/auth-presence.ts +56 -0
  5. package/channel-plugin-api.ts +3 -0
  6. package/cli-metadata.ts +11 -0
  7. package/contract-api.ts +17 -0
  8. package/helper-api.ts +3 -0
  9. package/index.test.ts +61 -0
  10. package/index.ts +51 -0
  11. package/openclaw.plugin.json +10 -10
  12. package/package.json +13 -19
  13. package/plugin-entry.handlers.runtime.ts +1 -0
  14. package/runtime-api.ts +54 -0
  15. package/runtime-heavy-api.ts +1 -0
  16. package/secret-contract-api.ts +5 -0
  17. package/setup-entry.ts +13 -0
  18. package/src/account-selection.test.ts +124 -0
  19. package/src/account-selection.ts +220 -0
  20. package/src/actions.account-propagation.test.ts +251 -0
  21. package/src/actions.test.ts +251 -0
  22. package/src/actions.ts +336 -0
  23. package/src/approval-auth.test.ts +23 -0
  24. package/src/approval-auth.ts +25 -0
  25. package/src/approval-handler.runtime.test.ts +46 -0
  26. package/src/approval-handler.runtime.ts +400 -0
  27. package/src/approval-ids.ts +6 -0
  28. package/src/approval-native.test.ts +329 -0
  29. package/src/approval-native.ts +336 -0
  30. package/src/approval-reactions.test.ts +107 -0
  31. package/src/approval-reactions.ts +158 -0
  32. package/src/auth-precedence.ts +61 -0
  33. package/src/channel-account-paths.ts +92 -0
  34. package/src/channel.account-paths.test.ts +102 -0
  35. package/src/channel.directory.test.ts +601 -0
  36. package/src/channel.resolve.test.ts +38 -0
  37. package/src/channel.runtime.ts +16 -0
  38. package/src/channel.setup.test.ts +269 -0
  39. package/src/channel.ts +570 -0
  40. package/src/cli-metadata.ts +19 -0
  41. package/src/cli.test.ts +1015 -0
  42. package/src/cli.ts +1198 -0
  43. package/src/config-adapter.ts +41 -0
  44. package/src/config-schema.test.ts +90 -0
  45. package/src/config-schema.ts +114 -0
  46. package/src/directory-live.test.ts +200 -0
  47. package/src/directory-live.ts +238 -0
  48. package/src/doctor-contract.ts +287 -0
  49. package/src/doctor.test.ts +440 -0
  50. package/src/doctor.ts +262 -0
  51. package/src/env-vars.ts +92 -0
  52. package/src/exec-approval-resolver.test.ts +68 -0
  53. package/src/exec-approval-resolver.ts +23 -0
  54. package/src/exec-approvals.test.ts +483 -0
  55. package/src/exec-approvals.ts +290 -0
  56. package/src/group-mentions.ts +41 -0
  57. package/src/legacy-crypto-inspector-availability.test.ts +81 -0
  58. package/src/legacy-crypto-inspector-availability.ts +60 -0
  59. package/src/legacy-crypto.test.ts +234 -0
  60. package/src/legacy-crypto.ts +549 -0
  61. package/src/legacy-state.test.ts +86 -0
  62. package/src/legacy-state.ts +156 -0
  63. package/src/matrix/account-config.ts +150 -0
  64. package/src/matrix/accounts.readiness.test.ts +27 -0
  65. package/src/matrix/accounts.test.ts +757 -0
  66. package/src/matrix/accounts.ts +194 -0
  67. package/src/matrix/actions/client.test.ts +215 -0
  68. package/src/matrix/actions/client.ts +31 -0
  69. package/src/matrix/actions/devices.test.ts +114 -0
  70. package/src/matrix/actions/devices.ts +34 -0
  71. package/src/matrix/actions/limits.test.ts +15 -0
  72. package/src/matrix/actions/limits.ts +6 -0
  73. package/src/matrix/actions/messages.test.ts +289 -0
  74. package/src/matrix/actions/messages.ts +123 -0
  75. package/src/matrix/actions/pins.test.ts +74 -0
  76. package/src/matrix/actions/pins.ts +64 -0
  77. package/src/matrix/actions/polls.test.ts +71 -0
  78. package/src/matrix/actions/polls.ts +109 -0
  79. package/src/matrix/actions/profile.test.ts +109 -0
  80. package/src/matrix/actions/profile.ts +37 -0
  81. package/src/matrix/actions/reactions.test.ts +135 -0
  82. package/src/matrix/actions/reactions.ts +59 -0
  83. package/src/matrix/actions/room.test.ts +79 -0
  84. package/src/matrix/actions/room.ts +71 -0
  85. package/src/matrix/actions/summary.test.ts +87 -0
  86. package/src/matrix/actions/summary.ts +88 -0
  87. package/src/matrix/actions/types.ts +82 -0
  88. package/src/matrix/actions/verification.test.ts +105 -0
  89. package/src/matrix/actions/verification.ts +237 -0
  90. package/src/matrix/actions.ts +37 -0
  91. package/src/matrix/active-client.ts +26 -0
  92. package/src/matrix/async-lock.ts +18 -0
  93. package/src/matrix/backup-health.ts +115 -0
  94. package/src/matrix/client/config-runtime-api.ts +14 -0
  95. package/src/matrix/client/config-secret-input.runtime.ts +1 -0
  96. package/src/matrix/client/config.ts +979 -0
  97. package/src/matrix/client/create-client.test.ts +115 -0
  98. package/src/matrix/client/create-client.ts +101 -0
  99. package/src/matrix/client/env-auth.ts +6 -0
  100. package/src/matrix/client/file-sync-store.test.ts +265 -0
  101. package/src/matrix/client/file-sync-store.ts +289 -0
  102. package/src/matrix/client/logging.ts +123 -0
  103. package/src/matrix/client/migration-snapshot.runtime.ts +1 -0
  104. package/src/matrix/client/private-network-host.ts +56 -0
  105. package/src/matrix/client/runtime.ts +4 -0
  106. package/src/matrix/client/shared.test.ts +344 -0
  107. package/src/matrix/client/shared.ts +306 -0
  108. package/src/matrix/client/storage.test.ts +634 -0
  109. package/src/matrix/client/storage.ts +544 -0
  110. package/src/matrix/client/types.ts +50 -0
  111. package/src/matrix/client-bootstrap.test.ts +84 -0
  112. package/src/matrix/client-bootstrap.ts +164 -0
  113. package/src/matrix/client-resolver.test-helpers.ts +147 -0
  114. package/src/matrix/client.test.ts +1521 -0
  115. package/src/matrix/client.ts +23 -0
  116. package/src/matrix/config-paths.ts +31 -0
  117. package/src/matrix/config-update.test.ts +237 -0
  118. package/src/matrix/config-update.ts +291 -0
  119. package/src/matrix/credentials-read.ts +206 -0
  120. package/src/matrix/credentials-write.runtime.ts +26 -0
  121. package/src/matrix/credentials.test.ts +501 -0
  122. package/src/matrix/credentials.ts +95 -0
  123. package/src/matrix/deps.test.ts +74 -0
  124. package/src/matrix/deps.ts +225 -0
  125. package/src/matrix/device-health.test.ts +45 -0
  126. package/src/matrix/device-health.ts +31 -0
  127. package/src/matrix/direct-management.test.ts +350 -0
  128. package/src/matrix/direct-management.ts +347 -0
  129. package/src/matrix/direct-room.test.ts +61 -0
  130. package/src/matrix/direct-room.ts +128 -0
  131. package/src/matrix/draft-stream.test.ts +406 -0
  132. package/src/matrix/draft-stream.ts +216 -0
  133. package/src/matrix/encryption-guidance.ts +27 -0
  134. package/src/matrix/errors.ts +21 -0
  135. package/src/matrix/format.test.ts +340 -0
  136. package/src/matrix/format.ts +428 -0
  137. package/src/matrix/legacy-crypto-inspector.ts +95 -0
  138. package/src/matrix/media-errors.ts +20 -0
  139. package/src/matrix/media-text.ts +169 -0
  140. package/src/matrix/monitor/access-state.test.ts +45 -0
  141. package/src/matrix/monitor/access-state.ts +77 -0
  142. package/src/matrix/monitor/ack-config.test.ts +57 -0
  143. package/src/matrix/monitor/ack-config.ts +26 -0
  144. package/src/matrix/monitor/allowlist.test.ts +45 -0
  145. package/src/matrix/monitor/allowlist.ts +94 -0
  146. package/src/matrix/monitor/auto-join.test.ts +203 -0
  147. package/src/matrix/monitor/auto-join.ts +86 -0
  148. package/src/matrix/monitor/config.test.ts +197 -0
  149. package/src/matrix/monitor/config.ts +303 -0
  150. package/src/matrix/monitor/context-summary.ts +43 -0
  151. package/src/matrix/monitor/direct.test.ts +529 -0
  152. package/src/matrix/monitor/direct.ts +270 -0
  153. package/src/matrix/monitor/events.test.ts +1524 -0
  154. package/src/matrix/monitor/events.ts +213 -0
  155. package/src/matrix/monitor/handler.body-for-agent.test.ts +396 -0
  156. package/src/matrix/monitor/handler.group-history.test.ts +648 -0
  157. package/src/matrix/monitor/handler.media-failure.test.ts +267 -0
  158. package/src/matrix/monitor/handler.test-helpers.ts +308 -0
  159. package/src/matrix/monitor/handler.test.ts +2952 -0
  160. package/src/matrix/monitor/handler.thread-root-media.test.ts +82 -0
  161. package/src/matrix/monitor/handler.ts +1679 -0
  162. package/src/matrix/monitor/inbound-dedupe.test.ts +146 -0
  163. package/src/matrix/monitor/inbound-dedupe.ts +267 -0
  164. package/src/matrix/monitor/index.test.ts +920 -0
  165. package/src/matrix/monitor/index.ts +434 -0
  166. package/src/matrix/monitor/legacy-crypto-restore.test.ts +206 -0
  167. package/src/matrix/monitor/legacy-crypto-restore.ts +139 -0
  168. package/src/matrix/monitor/location.ts +100 -0
  169. package/src/matrix/monitor/media.test.ts +159 -0
  170. package/src/matrix/monitor/media.ts +119 -0
  171. package/src/matrix/monitor/mentions.test.ts +289 -0
  172. package/src/matrix/monitor/mentions.ts +177 -0
  173. package/src/matrix/monitor/reaction-events.test.ts +326 -0
  174. package/src/matrix/monitor/reaction-events.ts +187 -0
  175. package/src/matrix/monitor/recent-invite.test.ts +92 -0
  176. package/src/matrix/monitor/recent-invite.ts +30 -0
  177. package/src/matrix/monitor/replies.test.ts +265 -0
  178. package/src/matrix/monitor/replies.ts +136 -0
  179. package/src/matrix/monitor/reply-context.test.ts +276 -0
  180. package/src/matrix/monitor/reply-context.ts +92 -0
  181. package/src/matrix/monitor/room-history.test.ts +258 -0
  182. package/src/matrix/monitor/room-history.ts +301 -0
  183. package/src/matrix/monitor/room-info.test.ts +201 -0
  184. package/src/matrix/monitor/room-info.ts +126 -0
  185. package/src/matrix/monitor/rooms.test.ts +121 -0
  186. package/src/matrix/monitor/rooms.ts +52 -0
  187. package/src/matrix/monitor/route.test.ts +255 -0
  188. package/src/matrix/monitor/route.ts +178 -0
  189. package/src/matrix/monitor/runtime-api.ts +31 -0
  190. package/src/matrix/monitor/startup-verification.test.ts +294 -0
  191. package/src/matrix/monitor/startup-verification.ts +237 -0
  192. package/src/matrix/monitor/startup.test.ts +257 -0
  193. package/src/matrix/monitor/startup.ts +218 -0
  194. package/src/matrix/monitor/status.ts +111 -0
  195. package/src/matrix/monitor/sync-lifecycle.test.ts +224 -0
  196. package/src/matrix/monitor/sync-lifecycle.ts +91 -0
  197. package/src/matrix/monitor/task-runner.ts +38 -0
  198. package/src/matrix/monitor/thread-context.test.ts +149 -0
  199. package/src/matrix/monitor/thread-context.ts +108 -0
  200. package/src/matrix/monitor/threads.test.ts +68 -0
  201. package/src/matrix/monitor/threads.ts +85 -0
  202. package/src/matrix/monitor/types.ts +30 -0
  203. package/src/matrix/monitor/verification-events.ts +627 -0
  204. package/src/matrix/monitor/verification-utils.test.ts +47 -0
  205. package/src/matrix/monitor/verification-utils.ts +46 -0
  206. package/src/matrix/outbound-media-runtime.ts +1 -0
  207. package/src/matrix/poll-summary.ts +110 -0
  208. package/src/matrix/poll-types.test.ts +205 -0
  209. package/src/matrix/poll-types.ts +433 -0
  210. package/src/matrix/probe.runtime.ts +4 -0
  211. package/src/matrix/probe.test.ts +154 -0
  212. package/src/matrix/probe.ts +96 -0
  213. package/src/matrix/profile.test.ts +154 -0
  214. package/src/matrix/profile.ts +184 -0
  215. package/src/matrix/reaction-common.test.ts +96 -0
  216. package/src/matrix/reaction-common.ts +147 -0
  217. package/src/matrix/sdk/crypto-bootstrap.test.ts +505 -0
  218. package/src/matrix/sdk/crypto-bootstrap.ts +341 -0
  219. package/src/matrix/sdk/crypto-facade.test.ts +197 -0
  220. package/src/matrix/sdk/crypto-facade.ts +207 -0
  221. package/src/matrix/sdk/crypto-node.runtime.test.ts +27 -0
  222. package/src/matrix/sdk/crypto-node.runtime.ts +9 -0
  223. package/src/matrix/sdk/crypto-runtime.ts +11 -0
  224. package/src/matrix/sdk/decrypt-bridge.ts +356 -0
  225. package/src/matrix/sdk/event-helpers.test.ts +60 -0
  226. package/src/matrix/sdk/event-helpers.ts +71 -0
  227. package/src/matrix/sdk/http-client.test.ts +134 -0
  228. package/src/matrix/sdk/http-client.ts +87 -0
  229. package/src/matrix/sdk/idb-persistence-lock.ts +51 -0
  230. package/src/matrix/sdk/idb-persistence.lock-order.test.ts +108 -0
  231. package/src/matrix/sdk/idb-persistence.test-helpers.ts +88 -0
  232. package/src/matrix/sdk/idb-persistence.test.ts +149 -0
  233. package/src/matrix/sdk/idb-persistence.ts +283 -0
  234. package/src/matrix/sdk/logger.test.ts +25 -0
  235. package/src/matrix/sdk/logger.ts +108 -0
  236. package/src/matrix/sdk/read-response-with-limit.ts +19 -0
  237. package/src/matrix/sdk/recovery-key-store.test.ts +385 -0
  238. package/src/matrix/sdk/recovery-key-store.ts +430 -0
  239. package/src/matrix/sdk/transport.test.ts +161 -0
  240. package/src/matrix/sdk/transport.ts +344 -0
  241. package/src/matrix/sdk/types.ts +236 -0
  242. package/src/matrix/sdk/verification-manager.test.ts +509 -0
  243. package/src/matrix/sdk/verification-manager.ts +694 -0
  244. package/src/matrix/sdk/verification-status.ts +23 -0
  245. package/src/matrix/sdk.test.ts +2568 -0
  246. package/src/matrix/sdk.ts +1789 -0
  247. package/src/matrix/send/client.test.ts +174 -0
  248. package/src/matrix/send/client.ts +90 -0
  249. package/src/matrix/send/formatting.ts +189 -0
  250. package/src/matrix/send/media.ts +244 -0
  251. package/src/matrix/send/targets.test.ts +254 -0
  252. package/src/matrix/send/targets.ts +104 -0
  253. package/src/matrix/send/types.ts +134 -0
  254. package/src/matrix/send.test.ts +958 -0
  255. package/src/matrix/send.ts +609 -0
  256. package/src/matrix/session-store-metadata.ts +108 -0
  257. package/src/matrix/startup-abort.ts +44 -0
  258. package/src/matrix/sync-state.ts +27 -0
  259. package/src/matrix/target-ids.ts +102 -0
  260. package/src/matrix/thread-bindings-shared.ts +201 -0
  261. package/src/matrix/thread-bindings.test.ts +673 -0
  262. package/src/matrix/thread-bindings.ts +577 -0
  263. package/src/matrix-migration.runtime.ts +9 -0
  264. package/src/migration-config.test.ts +228 -0
  265. package/src/migration-config.ts +243 -0
  266. package/src/migration-snapshot-backup.ts +117 -0
  267. package/src/migration-snapshot.test.ts +184 -0
  268. package/src/migration-snapshot.ts +55 -0
  269. package/src/onboarding.resolve.test.ts +55 -0
  270. package/src/onboarding.test-harness.ts +158 -0
  271. package/src/onboarding.test.ts +665 -0
  272. package/src/onboarding.ts +773 -0
  273. package/src/outbound.test.ts +173 -0
  274. package/src/outbound.ts +78 -0
  275. package/src/plugin-entry.runtime.js +159 -0
  276. package/src/plugin-entry.runtime.test.ts +108 -0
  277. package/src/plugin-entry.runtime.ts +68 -0
  278. package/src/profile-update.ts +68 -0
  279. package/src/record-shared.ts +3 -0
  280. package/src/resolve-targets.test.ts +178 -0
  281. package/src/resolve-targets.ts +175 -0
  282. package/src/resolver.ts +21 -0
  283. package/src/runtime-api.ts +144 -0
  284. package/src/runtime.ts +7 -0
  285. package/src/secret-contract.ts +174 -0
  286. package/src/session-route.test.ts +315 -0
  287. package/src/session-route.ts +113 -0
  288. package/src/setup-bootstrap.ts +94 -0
  289. package/src/setup-config.ts +222 -0
  290. package/src/setup-contract.ts +89 -0
  291. package/src/setup-core.test.ts +326 -0
  292. package/src/setup-core.ts +50 -0
  293. package/src/setup-surface.ts +4 -0
  294. package/src/startup-maintenance.test.ts +227 -0
  295. package/src/startup-maintenance.ts +114 -0
  296. package/src/storage-paths.ts +92 -0
  297. package/src/test-helpers.ts +42 -0
  298. package/src/test-mocks.ts +55 -0
  299. package/src/test-runtime.ts +72 -0
  300. package/src/test-support/monitor-route-test-support.ts +8 -0
  301. package/src/tool-actions.runtime.ts +1 -0
  302. package/src/tool-actions.test.ts +422 -0
  303. package/src/tool-actions.ts +498 -0
  304. package/src/types.ts +230 -0
  305. package/test-api.ts +2 -0
  306. package/thread-bindings-runtime.ts +4 -0
  307. package/tsconfig.json +16 -0
  308. package/LICENSE +0 -17
  309. package/README.md +0 -136
  310. package/dist/APEv2Parser-6EMKXRZS.js +0 -15
  311. package/dist/APEv2Parser-6EMKXRZS.js.map +0 -7
  312. package/dist/APEv2Parser-FYYGMFPI.js +0 -15
  313. package/dist/APEv2Parser-FYYGMFPI.js.map +0 -7
  314. package/dist/AiffParser-E6XWRTXM.js +0 -194
  315. package/dist/AiffParser-E6XWRTXM.js.map +0 -7
  316. package/dist/AiffParser-JHSDQA7T.js +0 -194
  317. package/dist/AiffParser-JHSDQA7T.js.map +0 -7
  318. package/dist/AsfParser-TPCQDEJB.js +0 -620
  319. package/dist/AsfParser-TPCQDEJB.js.map +0 -7
  320. package/dist/AsfParser-WSOH2JQY.js +0 -620
  321. package/dist/AsfParser-WSOH2JQY.js.map +0 -7
  322. package/dist/DsdiffParser-CGD3C3TL.js +0 -192
  323. package/dist/DsdiffParser-CGD3C3TL.js.map +0 -7
  324. package/dist/DsdiffParser-EUWJ4YAR.js +0 -192
  325. package/dist/DsdiffParser-EUWJ4YAR.js.map +0 -7
  326. package/dist/DsfParser-3UTIJVNF.js +0 -114
  327. package/dist/DsfParser-3UTIJVNF.js.map +0 -7
  328. package/dist/DsfParser-R6TPBJIY.js +0 -114
  329. package/dist/DsfParser-R6TPBJIY.js.map +0 -7
  330. package/dist/FlacParser-HLLYPJ76.js +0 -16
  331. package/dist/FlacParser-HLLYPJ76.js.map +0 -7
  332. package/dist/FlacParser-VDASGZ3E.js +0 -16
  333. package/dist/FlacParser-VDASGZ3E.js.map +0 -7
  334. package/dist/MP4Parser-64RGJLUM.js +0 -1145
  335. package/dist/MP4Parser-64RGJLUM.js.map +0 -7
  336. package/dist/MP4Parser-SM7HYL3Z.js +0 -1145
  337. package/dist/MP4Parser-SM7HYL3Z.js.map +0 -7
  338. package/dist/MatroskaParser-O6RXAKYA.js +0 -662
  339. package/dist/MatroskaParser-O6RXAKYA.js.map +0 -7
  340. package/dist/MatroskaParser-X7WRZ6D4.js +0 -662
  341. package/dist/MatroskaParser-X7WRZ6D4.js.map +0 -7
  342. package/dist/MpegParser-B6NX6DS3.js +0 -652
  343. package/dist/MpegParser-B6NX6DS3.js.map +0 -7
  344. package/dist/MpegParser-KXQEC6KD.js +0 -652
  345. package/dist/MpegParser-KXQEC6KD.js.map +0 -7
  346. package/dist/MusepackParser-NURI46TG.js +0 -331
  347. package/dist/MusepackParser-NURI46TG.js.map +0 -7
  348. package/dist/MusepackParser-WUBT63DS.js +0 -331
  349. package/dist/MusepackParser-WUBT63DS.js.map +0 -7
  350. package/dist/OggParser-5IYVBXPS.js +0 -448
  351. package/dist/OggParser-5IYVBXPS.js.map +0 -7
  352. package/dist/OggParser-ZY6E5C2P.js +0 -448
  353. package/dist/OggParser-ZY6E5C2P.js.map +0 -7
  354. package/dist/WavPackParser-5KTCSQEU.js +0 -209
  355. package/dist/WavPackParser-5KTCSQEU.js.map +0 -7
  356. package/dist/WavPackParser-RTEHKSJH.js +0 -209
  357. package/dist/WavPackParser-RTEHKSJH.js.map +0 -7
  358. package/dist/WaveParser-3R2NLXGP.js +0 -300
  359. package/dist/WaveParser-3R2NLXGP.js.map +0 -7
  360. package/dist/WaveParser-RZSHVQPZ.js +0 -300
  361. package/dist/WaveParser-RZSHVQPZ.js.map +0 -7
  362. package/dist/auth-presence.js +0 -46
  363. package/dist/auth-presence.js.map +0 -7
  364. package/dist/channel-plugin-api.js +0 -79
  365. package/dist/channel-plugin-api.js.map +0 -7
  366. package/dist/chunk-22WAAZ6I.js +0 -114
  367. package/dist/chunk-22WAAZ6I.js.map +0 -7
  368. package/dist/chunk-2A6HEFSO.js +0 -676
  369. package/dist/chunk-2A6HEFSO.js.map +0 -7
  370. package/dist/chunk-2GFROLI2.js +0 -261
  371. package/dist/chunk-2GFROLI2.js.map +0 -7
  372. package/dist/chunk-2IQWKATM.js +0 -127
  373. package/dist/chunk-2IQWKATM.js.map +0 -7
  374. package/dist/chunk-2KGHUHKU.js +0 -169
  375. package/dist/chunk-2KGHUHKU.js.map +0 -7
  376. package/dist/chunk-2NEQI4K6.js +0 -171
  377. package/dist/chunk-2NEQI4K6.js.map +0 -7
  378. package/dist/chunk-2OSJ3MTW.js +0 -175
  379. package/dist/chunk-2OSJ3MTW.js.map +0 -7
  380. package/dist/chunk-2Q626TDO.js +0 -27
  381. package/dist/chunk-2Q626TDO.js.map +0 -7
  382. package/dist/chunk-2U6OZ7N2.js +0 -155
  383. package/dist/chunk-2U6OZ7N2.js.map +0 -7
  384. package/dist/chunk-2V6Y4CAN.js +0 -25
  385. package/dist/chunk-2V6Y4CAN.js.map +0 -7
  386. package/dist/chunk-2WHRUMOM.js +0 -321
  387. package/dist/chunk-2WHRUMOM.js.map +0 -7
  388. package/dist/chunk-2Z4IOUDZ.js +0 -129
  389. package/dist/chunk-2Z4IOUDZ.js.map +0 -7
  390. package/dist/chunk-2ZEPAW7U.js +0 -154
  391. package/dist/chunk-2ZEPAW7U.js.map +0 -7
  392. package/dist/chunk-2ZI6JK5O.js +0 -63
  393. package/dist/chunk-2ZI6JK5O.js.map +0 -7
  394. package/dist/chunk-34UY6D6X.js +0 -36
  395. package/dist/chunk-34UY6D6X.js.map +0 -7
  396. package/dist/chunk-3GIK7SAA.js +0 -109
  397. package/dist/chunk-3GIK7SAA.js.map +0 -7
  398. package/dist/chunk-3JD6JSJD.js +0 -111
  399. package/dist/chunk-3JD6JSJD.js.map +0 -7
  400. package/dist/chunk-3OXOEMBS.js +0 -123
  401. package/dist/chunk-3OXOEMBS.js.map +0 -7
  402. package/dist/chunk-3R4ATE4Q.js +0 -176
  403. package/dist/chunk-3R4ATE4Q.js.map +0 -7
  404. package/dist/chunk-3TOEIHG5.js +0 -314
  405. package/dist/chunk-3TOEIHG5.js.map +0 -7
  406. package/dist/chunk-3TRKKAVT.js +0 -130
  407. package/dist/chunk-3TRKKAVT.js.map +0 -7
  408. package/dist/chunk-3UFTTK7C.js +0 -418
  409. package/dist/chunk-3UFTTK7C.js.map +0 -7
  410. package/dist/chunk-3XO6AAIC.js +0 -25
  411. package/dist/chunk-3XO6AAIC.js.map +0 -7
  412. package/dist/chunk-427SAQME.js +0 -321
  413. package/dist/chunk-427SAQME.js.map +0 -7
  414. package/dist/chunk-4CFQNJ7F.js +0 -7
  415. package/dist/chunk-4CFQNJ7F.js.map +0 -7
  416. package/dist/chunk-4COI4L2Y.js +0 -31
  417. package/dist/chunk-4COI4L2Y.js.map +0 -7
  418. package/dist/chunk-4EKKDVG3.js +0 -1662
  419. package/dist/chunk-4EKKDVG3.js.map +0 -7
  420. package/dist/chunk-4JVNTZAI.js +0 -80
  421. package/dist/chunk-4JVNTZAI.js.map +0 -7
  422. package/dist/chunk-4L2QI6AY.js +0 -71
  423. package/dist/chunk-4L2QI6AY.js.map +0 -7
  424. package/dist/chunk-4O3BEYYM.js +0 -187
  425. package/dist/chunk-4O3BEYYM.js.map +0 -7
  426. package/dist/chunk-4OXPPDV6.js +0 -676
  427. package/dist/chunk-4OXPPDV6.js.map +0 -7
  428. package/dist/chunk-4QTZHELX.js +0 -51
  429. package/dist/chunk-4QTZHELX.js.map +0 -7
  430. package/dist/chunk-4U42OJMK.js +0 -217
  431. package/dist/chunk-4U42OJMK.js.map +0 -7
  432. package/dist/chunk-4WCKVGQ5.js +0 -193
  433. package/dist/chunk-4WCKVGQ5.js.map +0 -7
  434. package/dist/chunk-4XXERLFH.js +0 -95
  435. package/dist/chunk-4XXERLFH.js.map +0 -7
  436. package/dist/chunk-4Z2N4GW6.js +0 -247
  437. package/dist/chunk-4Z2N4GW6.js.map +0 -7
  438. package/dist/chunk-4ZY2BOQ4.js +0 -123
  439. package/dist/chunk-4ZY2BOQ4.js.map +0 -7
  440. package/dist/chunk-56HN4SH6.js +0 -46
  441. package/dist/chunk-56HN4SH6.js.map +0 -7
  442. package/dist/chunk-57ROEOHB.js +0 -183
  443. package/dist/chunk-57ROEOHB.js.map +0 -7
  444. package/dist/chunk-5APBBTGW.js +0 -7
  445. package/dist/chunk-5APBBTGW.js.map +0 -7
  446. package/dist/chunk-5BQ6LLNU.js +0 -39
  447. package/dist/chunk-5BQ6LLNU.js.map +0 -7
  448. package/dist/chunk-5LNGMBWW.js +0 -93
  449. package/dist/chunk-5LNGMBWW.js.map +0 -7
  450. package/dist/chunk-5XFQSYZ4.js +0 -52
  451. package/dist/chunk-5XFQSYZ4.js.map +0 -7
  452. package/dist/chunk-62N5N4AC.js +0 -241
  453. package/dist/chunk-62N5N4AC.js.map +0 -7
  454. package/dist/chunk-63QTHDJL.js +0 -52
  455. package/dist/chunk-63QTHDJL.js.map +0 -7
  456. package/dist/chunk-65UUVZ6B.js +0 -151
  457. package/dist/chunk-65UUVZ6B.js.map +0 -7
  458. package/dist/chunk-6COVTMAO.js +0 -3586
  459. package/dist/chunk-6COVTMAO.js.map +0 -7
  460. package/dist/chunk-6EYPDJUD.js +0 -34
  461. package/dist/chunk-6EYPDJUD.js.map +0 -7
  462. package/dist/chunk-6HDYPVA4.js +0 -15
  463. package/dist/chunk-6HDYPVA4.js.map +0 -7
  464. package/dist/chunk-6HX3DEXK.js +0 -178
  465. package/dist/chunk-6HX3DEXK.js.map +0 -7
  466. package/dist/chunk-6NO5VEVV.js +0 -18
  467. package/dist/chunk-6NO5VEVV.js.map +0 -7
  468. package/dist/chunk-6OP3FK5F.js +0 -266
  469. package/dist/chunk-6OP3FK5F.js.map +0 -7
  470. package/dist/chunk-6PZGDVLR.js +0 -465
  471. package/dist/chunk-6PZGDVLR.js.map +0 -7
  472. package/dist/chunk-6RBDFNSX.js +0 -88
  473. package/dist/chunk-6RBDFNSX.js.map +0 -7
  474. package/dist/chunk-6SOGH3TW.js +0 -163
  475. package/dist/chunk-6SOGH3TW.js.map +0 -7
  476. package/dist/chunk-6TWWCETB.js +0 -70
  477. package/dist/chunk-6TWWCETB.js.map +0 -7
  478. package/dist/chunk-6WFHPMUF.js +0 -17
  479. package/dist/chunk-6WFHPMUF.js.map +0 -7
  480. package/dist/chunk-72TGY3LX.js +0 -104
  481. package/dist/chunk-72TGY3LX.js.map +0 -7
  482. package/dist/chunk-76IE55K7.js +0 -392
  483. package/dist/chunk-76IE55K7.js.map +0 -7
  484. package/dist/chunk-77BEEAPD.js +0 -86
  485. package/dist/chunk-77BEEAPD.js.map +0 -7
  486. package/dist/chunk-77JJ6QJK.js +0 -50
  487. package/dist/chunk-77JJ6QJK.js.map +0 -7
  488. package/dist/chunk-7BIUNV33.js +0 -62
  489. package/dist/chunk-7BIUNV33.js.map +0 -7
  490. package/dist/chunk-7F3242AO.js +0 -86
  491. package/dist/chunk-7F3242AO.js.map +0 -7
  492. package/dist/chunk-7FLQSTPG.js +0 -57
  493. package/dist/chunk-7FLQSTPG.js.map +0 -7
  494. package/dist/chunk-7L37R42D.js +0 -52
  495. package/dist/chunk-7L37R42D.js.map +0 -7
  496. package/dist/chunk-7MP46JBP.js +0 -177
  497. package/dist/chunk-7MP46JBP.js.map +0 -7
  498. package/dist/chunk-7MVZYR2T.js +0 -87
  499. package/dist/chunk-7MVZYR2T.js.map +0 -7
  500. package/dist/chunk-7N7ISMPG.js +0 -50
  501. package/dist/chunk-7N7ISMPG.js.map +0 -7
  502. package/dist/chunk-7S7LQQPX.js +0 -127
  503. package/dist/chunk-7S7LQQPX.js.map +0 -7
  504. package/dist/chunk-7TTNY5FK.js +0 -21
  505. package/dist/chunk-7TTNY5FK.js.map +0 -7
  506. package/dist/chunk-7W73QCTR.js +0 -244
  507. package/dist/chunk-7W73QCTR.js.map +0 -7
  508. package/dist/chunk-7XXLU33Y.js +0 -76
  509. package/dist/chunk-7XXLU33Y.js.map +0 -7
  510. package/dist/chunk-7ZP3KYVO.js +0 -104
  511. package/dist/chunk-7ZP3KYVO.js.map +0 -7
  512. package/dist/chunk-AAO7BQEV.js +0 -258
  513. package/dist/chunk-AAO7BQEV.js.map +0 -7
  514. package/dist/chunk-AH4MLRYT.js +0 -91
  515. package/dist/chunk-AH4MLRYT.js.map +0 -7
  516. package/dist/chunk-AHKR32FH.js +0 -7
  517. package/dist/chunk-AHKR32FH.js.map +0 -7
  518. package/dist/chunk-ALKRFDAW.js +0 -94
  519. package/dist/chunk-ALKRFDAW.js.map +0 -7
  520. package/dist/chunk-AQQGAE7N.js +0 -12
  521. package/dist/chunk-AQQGAE7N.js.map +0 -7
  522. package/dist/chunk-ARGF232V.js +0 -32
  523. package/dist/chunk-ARGF232V.js.map +0 -7
  524. package/dist/chunk-ATCJOK3K.js +0 -24
  525. package/dist/chunk-ATCJOK3K.js.map +0 -7
  526. package/dist/chunk-AUUABFHL.js +0 -124
  527. package/dist/chunk-AUUABFHL.js.map +0 -7
  528. package/dist/chunk-AWW3YUGJ.js +0 -193
  529. package/dist/chunk-AWW3YUGJ.js.map +0 -7
  530. package/dist/chunk-AX7VEEWJ.js +0 -158
  531. package/dist/chunk-AX7VEEWJ.js.map +0 -7
  532. package/dist/chunk-B3NTODO7.js +0 -57
  533. package/dist/chunk-B3NTODO7.js.map +0 -7
  534. package/dist/chunk-BAX7Q6GR.js +0 -55
  535. package/dist/chunk-BAX7Q6GR.js.map +0 -7
  536. package/dist/chunk-BBM6BR3Z.js +0 -28
  537. package/dist/chunk-BBM6BR3Z.js.map +0 -7
  538. package/dist/chunk-BHXZMHSX.js +0 -109
  539. package/dist/chunk-BHXZMHSX.js.map +0 -7
  540. package/dist/chunk-BIUXDLVY.js +0 -62
  541. package/dist/chunk-BIUXDLVY.js.map +0 -7
  542. package/dist/chunk-BM7J2W36.js +0 -86
  543. package/dist/chunk-BM7J2W36.js.map +0 -7
  544. package/dist/chunk-BMFZL2P4.js +0 -97
  545. package/dist/chunk-BMFZL2P4.js.map +0 -7
  546. package/dist/chunk-BQXEXK4H.js +0 -114
  547. package/dist/chunk-BQXEXK4H.js.map +0 -7
  548. package/dist/chunk-BU2CTWBG.js +0 -30
  549. package/dist/chunk-BU2CTWBG.js.map +0 -7
  550. package/dist/chunk-BVKSCLF7.js +0 -195
  551. package/dist/chunk-BVKSCLF7.js.map +0 -7
  552. package/dist/chunk-BWA3D22L.js +0 -88
  553. package/dist/chunk-BWA3D22L.js.map +0 -7
  554. package/dist/chunk-CE24RSPL.js +0 -506
  555. package/dist/chunk-CE24RSPL.js.map +0 -7
  556. package/dist/chunk-CEB5S2Z5.js +0 -127
  557. package/dist/chunk-CEB5S2Z5.js.map +0 -7
  558. package/dist/chunk-CEKNTCJD.js +0 -177
  559. package/dist/chunk-CEKNTCJD.js.map +0 -7
  560. package/dist/chunk-CETZGSCP.js +0 -71
  561. package/dist/chunk-CETZGSCP.js.map +0 -7
  562. package/dist/chunk-CGBWMONK.js +0 -412
  563. package/dist/chunk-CGBWMONK.js.map +0 -7
  564. package/dist/chunk-CGFDIH77.js +0 -94
  565. package/dist/chunk-CGFDIH77.js.map +0 -7
  566. package/dist/chunk-CPLEC5LJ.js +0 -26
  567. package/dist/chunk-CPLEC5LJ.js.map +0 -7
  568. package/dist/chunk-CPNIXMGX.js +0 -127
  569. package/dist/chunk-CPNIXMGX.js.map +0 -7
  570. package/dist/chunk-CSJO73LD.js +0 -84
  571. package/dist/chunk-CSJO73LD.js.map +0 -7
  572. package/dist/chunk-CTKBDSL6.js +0 -81
  573. package/dist/chunk-CTKBDSL6.js.map +0 -7
  574. package/dist/chunk-CY6WHUCW.js +0 -54
  575. package/dist/chunk-CY6WHUCW.js.map +0 -7
  576. package/dist/chunk-D4GYYYMW.js +0 -155
  577. package/dist/chunk-D4GYYYMW.js.map +0 -7
  578. package/dist/chunk-D64CZG54.js +0 -78
  579. package/dist/chunk-D64CZG54.js.map +0 -7
  580. package/dist/chunk-D7Q6Z74D.js +0 -123
  581. package/dist/chunk-D7Q6Z74D.js.map +0 -7
  582. package/dist/chunk-DSGPDHF2.js +0 -737
  583. package/dist/chunk-DSGPDHF2.js.map +0 -7
  584. package/dist/chunk-DZIM4OWK.js +0 -17
  585. package/dist/chunk-DZIM4OWK.js.map +0 -7
  586. package/dist/chunk-E3GC4V5V.js +0 -30
  587. package/dist/chunk-E3GC4V5V.js.map +0 -7
  588. package/dist/chunk-E5HPDHCW.js +0 -34
  589. package/dist/chunk-E5HPDHCW.js.map +0 -7
  590. package/dist/chunk-E75BJJZ2.js +0 -635
  591. package/dist/chunk-E75BJJZ2.js.map +0 -7
  592. package/dist/chunk-EBXHW7ZO.js +0 -108
  593. package/dist/chunk-EBXHW7ZO.js.map +0 -7
  594. package/dist/chunk-EE4DHUUZ.js +0 -472
  595. package/dist/chunk-EE4DHUUZ.js.map +0 -7
  596. package/dist/chunk-EHELTAAD.js +0 -198
  597. package/dist/chunk-EHELTAAD.js.map +0 -7
  598. package/dist/chunk-EKXPSI7Z.js +0 -135
  599. package/dist/chunk-EKXPSI7Z.js.map +0 -7
  600. package/dist/chunk-EO35SCFP.js +0 -7
  601. package/dist/chunk-EO35SCFP.js.map +0 -7
  602. package/dist/chunk-ER2XTD2S.js +0 -271
  603. package/dist/chunk-ER2XTD2S.js.map +0 -7
  604. package/dist/chunk-ERCH75SH.js +0 -292
  605. package/dist/chunk-ERCH75SH.js.map +0 -7
  606. package/dist/chunk-ERXO3674.js +0 -54
  607. package/dist/chunk-ERXO3674.js.map +0 -7
  608. package/dist/chunk-EVFWZGFL.js +0 -235
  609. package/dist/chunk-EVFWZGFL.js.map +0 -7
  610. package/dist/chunk-EVPBRKMZ.js +0 -45
  611. package/dist/chunk-EVPBRKMZ.js.map +0 -7
  612. package/dist/chunk-F43CC2X2.js +0 -49
  613. package/dist/chunk-F43CC2X2.js.map +0 -7
  614. package/dist/chunk-F64TXVJJ.js +0 -158
  615. package/dist/chunk-F64TXVJJ.js.map +0 -7
  616. package/dist/chunk-F6AFJHWV.js +0 -45
  617. package/dist/chunk-F6AFJHWV.js.map +0 -7
  618. package/dist/chunk-F6APWSAA.js +0 -51
  619. package/dist/chunk-F6APWSAA.js.map +0 -7
  620. package/dist/chunk-F7LNS7G3.js +0 -235
  621. package/dist/chunk-F7LNS7G3.js.map +0 -7
  622. package/dist/chunk-FCNWR7ZX.js +0 -16352
  623. package/dist/chunk-FCNWR7ZX.js.map +0 -7
  624. package/dist/chunk-FFCG5NRU.js +0 -87
  625. package/dist/chunk-FFCG5NRU.js.map +0 -7
  626. package/dist/chunk-FG4NVFKM.js +0 -455
  627. package/dist/chunk-FG4NVFKM.js.map +0 -7
  628. package/dist/chunk-FHNEN6IR.js +0 -14
  629. package/dist/chunk-FHNEN6IR.js.map +0 -7
  630. package/dist/chunk-FJFC6CRR.js +0 -446
  631. package/dist/chunk-FJFC6CRR.js.map +0 -7
  632. package/dist/chunk-FK6RGYBB.js +0 -46
  633. package/dist/chunk-FK6RGYBB.js.map +0 -7
  634. package/dist/chunk-FMY6KXK6.js +0 -251
  635. package/dist/chunk-FMY6KXK6.js.map +0 -7
  636. package/dist/chunk-FPH56SCM.js +0 -21
  637. package/dist/chunk-FPH56SCM.js.map +0 -7
  638. package/dist/chunk-FQ4R7IOX.js +0 -32
  639. package/dist/chunk-FQ4R7IOX.js.map +0 -7
  640. package/dist/chunk-FQPYAPJJ.js +0 -124
  641. package/dist/chunk-FQPYAPJJ.js.map +0 -7
  642. package/dist/chunk-FQTLJO4W.js +0 -335
  643. package/dist/chunk-FQTLJO4W.js.map +0 -7
  644. package/dist/chunk-FVLJSB2W.js +0 -124
  645. package/dist/chunk-FVLJSB2W.js.map +0 -7
  646. package/dist/chunk-FVSH4Z6T.js +0 -173
  647. package/dist/chunk-FVSH4Z6T.js.map +0 -7
  648. package/dist/chunk-FVWBLEAD.js +0 -44
  649. package/dist/chunk-FVWBLEAD.js.map +0 -7
  650. package/dist/chunk-FYRKBNTI.js +0 -18
  651. package/dist/chunk-FYRKBNTI.js.map +0 -7
  652. package/dist/chunk-FYSARMGS.js +0 -93
  653. package/dist/chunk-FYSARMGS.js.map +0 -7
  654. package/dist/chunk-FZJOJ6P4.js +0 -28
  655. package/dist/chunk-FZJOJ6P4.js.map +0 -7
  656. package/dist/chunk-G46GHNDU.js +0 -4890
  657. package/dist/chunk-G46GHNDU.js.map +0 -7
  658. package/dist/chunk-G4TIS2SC.js +0 -56
  659. package/dist/chunk-G4TIS2SC.js.map +0 -7
  660. package/dist/chunk-GD6L3SLC.js +0 -30
  661. package/dist/chunk-GD6L3SLC.js.map +0 -7
  662. package/dist/chunk-GGWS7NQP.js +0 -247
  663. package/dist/chunk-GGWS7NQP.js.map +0 -7
  664. package/dist/chunk-GI2ZANRY.js +0 -24
  665. package/dist/chunk-GI2ZANRY.js.map +0 -7
  666. package/dist/chunk-GK3XVKXT.js +0 -737
  667. package/dist/chunk-GK3XVKXT.js.map +0 -7
  668. package/dist/chunk-GKOWCDQV.js +0 -699
  669. package/dist/chunk-GKOWCDQV.js.map +0 -7
  670. package/dist/chunk-GLLRCKKE.js +0 -26
  671. package/dist/chunk-GLLRCKKE.js.map +0 -7
  672. package/dist/chunk-GNYG6I36.js +0 -175
  673. package/dist/chunk-GNYG6I36.js.map +0 -7
  674. package/dist/chunk-GRBJYAYF.js +0 -129
  675. package/dist/chunk-GRBJYAYF.js.map +0 -7
  676. package/dist/chunk-GVYGUH2V.js +0 -7
  677. package/dist/chunk-GVYGUH2V.js.map +0 -7
  678. package/dist/chunk-GXDQGBA2.js +0 -106
  679. package/dist/chunk-GXDQGBA2.js.map +0 -7
  680. package/dist/chunk-GZAGAWSU.js +0 -28
  681. package/dist/chunk-GZAGAWSU.js.map +0 -7
  682. package/dist/chunk-H23E72SB.js +0 -163
  683. package/dist/chunk-H23E72SB.js.map +0 -7
  684. package/dist/chunk-H2HY73I6.js +0 -122
  685. package/dist/chunk-H2HY73I6.js.map +0 -7
  686. package/dist/chunk-H5MLA6PA.js +0 -29
  687. package/dist/chunk-H5MLA6PA.js.map +0 -7
  688. package/dist/chunk-H6YVV7GE.js +0 -22
  689. package/dist/chunk-H6YVV7GE.js.map +0 -7
  690. package/dist/chunk-H7KAUMBC.js +0 -635
  691. package/dist/chunk-H7KAUMBC.js.map +0 -7
  692. package/dist/chunk-HDPICD3P.js +0 -4890
  693. package/dist/chunk-HDPICD3P.js.map +0 -7
  694. package/dist/chunk-HGHU3TVL.js +0 -174
  695. package/dist/chunk-HGHU3TVL.js.map +0 -7
  696. package/dist/chunk-HJ5E2JRL.js +0 -88
  697. package/dist/chunk-HJ5E2JRL.js.map +0 -7
  698. package/dist/chunk-HJW3CKZL.js +0 -94
  699. package/dist/chunk-HJW3CKZL.js.map +0 -7
  700. package/dist/chunk-HKF5EBER.js +0 -418
  701. package/dist/chunk-HKF5EBER.js.map +0 -7
  702. package/dist/chunk-HLUR35G5.js +0 -30
  703. package/dist/chunk-HLUR35G5.js.map +0 -7
  704. package/dist/chunk-HNIW2NZU.js +0 -120
  705. package/dist/chunk-HNIW2NZU.js.map +0 -7
  706. package/dist/chunk-HP5HMWOM.js +0 -123
  707. package/dist/chunk-HP5HMWOM.js.map +0 -7
  708. package/dist/chunk-HQSHS6IB.js +0 -88
  709. package/dist/chunk-HQSHS6IB.js.map +0 -7
  710. package/dist/chunk-HSXRCP25.js +0 -171
  711. package/dist/chunk-HSXRCP25.js.map +0 -7
  712. package/dist/chunk-HTV3R73W.js +0 -51
  713. package/dist/chunk-HTV3R73W.js.map +0 -7
  714. package/dist/chunk-I26OPZLO.js +0 -28
  715. package/dist/chunk-I26OPZLO.js.map +0 -7
  716. package/dist/chunk-I7JJQ4BQ.js +0 -30
  717. package/dist/chunk-I7JJQ4BQ.js.map +0 -7
  718. package/dist/chunk-IJ6Y4W7F.js +0 -392
  719. package/dist/chunk-IJ6Y4W7F.js.map +0 -7
  720. package/dist/chunk-IJCMYMZB.js +0 -239
  721. package/dist/chunk-IJCMYMZB.js.map +0 -7
  722. package/dist/chunk-IJH4NOQ4.js +0 -18
  723. package/dist/chunk-IJH4NOQ4.js.map +0 -7
  724. package/dist/chunk-IMHRZQRH.js +0 -76
  725. package/dist/chunk-IMHRZQRH.js.map +0 -7
  726. package/dist/chunk-INNENDEE.js +0 -472
  727. package/dist/chunk-INNENDEE.js.map +0 -7
  728. package/dist/chunk-IOTLSMEQ.js +0 -177
  729. package/dist/chunk-IOTLSMEQ.js.map +0 -7
  730. package/dist/chunk-IQYYEHSM.js +0 -300
  731. package/dist/chunk-IQYYEHSM.js.map +0 -7
  732. package/dist/chunk-IRA5NJ4Q.js +0 -21
  733. package/dist/chunk-IRA5NJ4Q.js.map +0 -7
  734. package/dist/chunk-IU7EXXK7.js +0 -1662
  735. package/dist/chunk-IU7EXXK7.js.map +0 -7
  736. package/dist/chunk-IUXAKDAY.js +0 -102
  737. package/dist/chunk-IUXAKDAY.js.map +0 -7
  738. package/dist/chunk-JB6ZQEVR.js +0 -465
  739. package/dist/chunk-JB6ZQEVR.js.map +0 -7
  740. package/dist/chunk-JCWNMWNY.js +0 -102
  741. package/dist/chunk-JCWNMWNY.js.map +0 -7
  742. package/dist/chunk-JGIZPU2Y.js +0 -39
  743. package/dist/chunk-JGIZPU2Y.js.map +0 -7
  744. package/dist/chunk-JIU4FXA7.js +0 -485
  745. package/dist/chunk-JIU4FXA7.js.map +0 -7
  746. package/dist/chunk-JMYIFYY5.js +0 -233
  747. package/dist/chunk-JMYIFYY5.js.map +0 -7
  748. package/dist/chunk-JSZBX2TA.js +0 -5853
  749. package/dist/chunk-JSZBX2TA.js.map +0 -7
  750. package/dist/chunk-JU2Y33DB.js +0 -60
  751. package/dist/chunk-JU2Y33DB.js.map +0 -7
  752. package/dist/chunk-JVLRI4RU.js +0 -62
  753. package/dist/chunk-JVLRI4RU.js.map +0 -7
  754. package/dist/chunk-JZ3AVNZC.js +0 -44117
  755. package/dist/chunk-JZ3AVNZC.js.map +0 -7
  756. package/dist/chunk-K3HEWOHN.js +0 -30
  757. package/dist/chunk-K3HEWOHN.js.map +0 -7
  758. package/dist/chunk-K5EK4WZV.js +0 -7
  759. package/dist/chunk-K5EK4WZV.js.map +0 -7
  760. package/dist/chunk-KAWXMSYC.js +0 -58
  761. package/dist/chunk-KAWXMSYC.js.map +0 -7
  762. package/dist/chunk-KEGPHS4C.js +0 -80
  763. package/dist/chunk-KEGPHS4C.js.map +0 -7
  764. package/dist/chunk-KHFWQ334.js +0 -138
  765. package/dist/chunk-KHFWQ334.js.map +0 -7
  766. package/dist/chunk-KJW6JLM6.js +0 -95
  767. package/dist/chunk-KJW6JLM6.js.map +0 -7
  768. package/dist/chunk-KSEANSJE.js +0 -40
  769. package/dist/chunk-KSEANSJE.js.map +0 -7
  770. package/dist/chunk-KVU54E6W.js +0 -63
  771. package/dist/chunk-KVU54E6W.js.map +0 -7
  772. package/dist/chunk-KXXVR3DC.js +0 -244
  773. package/dist/chunk-KXXVR3DC.js.map +0 -7
  774. package/dist/chunk-L5OUVMHK.js +0 -174
  775. package/dist/chunk-L5OUVMHK.js.map +0 -7
  776. package/dist/chunk-L5T6XUDP.js +0 -412
  777. package/dist/chunk-L5T6XUDP.js.map +0 -7
  778. package/dist/chunk-LIFXTQ4U.js +0 -7287
  779. package/dist/chunk-LIFXTQ4U.js.map +0 -7
  780. package/dist/chunk-LIVQ7GIO.js +0 -86
  781. package/dist/chunk-LIVQ7GIO.js.map +0 -7
  782. package/dist/chunk-LMD5UTKM.js +0 -169
  783. package/dist/chunk-LMD5UTKM.js.map +0 -7
  784. package/dist/chunk-LO4F6E3N.js +0 -163
  785. package/dist/chunk-LO4F6E3N.js.map +0 -7
  786. package/dist/chunk-LSVKDUNM.js +0 -151
  787. package/dist/chunk-LSVKDUNM.js.map +0 -7
  788. package/dist/chunk-LTXNC6JX.js +0 -27
  789. package/dist/chunk-LTXNC6JX.js.map +0 -7
  790. package/dist/chunk-LUGTGPT6.js +0 -138
  791. package/dist/chunk-LUGTGPT6.js.map +0 -7
  792. package/dist/chunk-LVMK2GPM.js +0 -18
  793. package/dist/chunk-LVMK2GPM.js.map +0 -7
  794. package/dist/chunk-LXVPETLK.js +0 -1405
  795. package/dist/chunk-LXVPETLK.js.map +0 -7
  796. package/dist/chunk-LZNW24OB.js +0 -78
  797. package/dist/chunk-LZNW24OB.js.map +0 -7
  798. package/dist/chunk-LZQFDJNW.js +0 -300
  799. package/dist/chunk-LZQFDJNW.js.map +0 -7
  800. package/dist/chunk-M4VQPIF4.js +0 -5853
  801. package/dist/chunk-M4VQPIF4.js.map +0 -7
  802. package/dist/chunk-M64QE4QC.js +0 -64
  803. package/dist/chunk-M64QE4QC.js.map +0 -7
  804. package/dist/chunk-MAF6PSCJ.js +0 -44
  805. package/dist/chunk-MAF6PSCJ.js.map +0 -7
  806. package/dist/chunk-MBIX6Z7U.js +0 -80
  807. package/dist/chunk-MBIX6Z7U.js.map +0 -7
  808. package/dist/chunk-MDLLXMC3.js +0 -183
  809. package/dist/chunk-MDLLXMC3.js.map +0 -7
  810. package/dist/chunk-MEI5HTWV.js +0 -127
  811. package/dist/chunk-MEI5HTWV.js.map +0 -7
  812. package/dist/chunk-MH74AJ3A.js +0 -82
  813. package/dist/chunk-MH74AJ3A.js.map +0 -7
  814. package/dist/chunk-MIFIM4PI.js +0 -163
  815. package/dist/chunk-MIFIM4PI.js.map +0 -7
  816. package/dist/chunk-MISZB5QJ.js +0 -22
  817. package/dist/chunk-MISZB5QJ.js.map +0 -7
  818. package/dist/chunk-MJ27XQYG.js +0 -125
  819. package/dist/chunk-MJ27XQYG.js.map +0 -7
  820. package/dist/chunk-MJ2GW6SU.js +0 -163
  821. package/dist/chunk-MJ2GW6SU.js.map +0 -7
  822. package/dist/chunk-MLQY5SKR.js +0 -52
  823. package/dist/chunk-MLQY5SKR.js.map +0 -7
  824. package/dist/chunk-MTMHGC3G.js +0 -39
  825. package/dist/chunk-MTMHGC3G.js.map +0 -7
  826. package/dist/chunk-MWBAW3YV.js +0 -244
  827. package/dist/chunk-MWBAW3YV.js.map +0 -7
  828. package/dist/chunk-MYSK3SIM.js +0 -55
  829. package/dist/chunk-MYSK3SIM.js.map +0 -7
  830. package/dist/chunk-MZGGB2YT.js +0 -50
  831. package/dist/chunk-MZGGB2YT.js.map +0 -7
  832. package/dist/chunk-N46MIZXB.js +0 -154
  833. package/dist/chunk-N46MIZXB.js.map +0 -7
  834. package/dist/chunk-N53537P6.js +0 -31
  835. package/dist/chunk-N53537P6.js.map +0 -7
  836. package/dist/chunk-N5CTFOLX.js +0 -40
  837. package/dist/chunk-N5CTFOLX.js.map +0 -7
  838. package/dist/chunk-N5SNGZJV.js +0 -217
  839. package/dist/chunk-N5SNGZJV.js.map +0 -7
  840. package/dist/chunk-NGCTBYQ3.js +0 -181
  841. package/dist/chunk-NGCTBYQ3.js.map +0 -7
  842. package/dist/chunk-NIFG55CE.js +0 -52
  843. package/dist/chunk-NIFG55CE.js.map +0 -7
  844. package/dist/chunk-NJ63ALPX.js +0 -7
  845. package/dist/chunk-NJ63ALPX.js.map +0 -7
  846. package/dist/chunk-NMUX7SGU.js +0 -676
  847. package/dist/chunk-NMUX7SGU.js.map +0 -7
  848. package/dist/chunk-NO7GMLNU.js +0 -292
  849. package/dist/chunk-NO7GMLNU.js.map +0 -7
  850. package/dist/chunk-NTOGVX2Y.js +0 -92
  851. package/dist/chunk-NTOGVX2Y.js.map +0 -7
  852. package/dist/chunk-NZVHE4IT.js +0 -3101
  853. package/dist/chunk-NZVHE4IT.js.map +0 -7
  854. package/dist/chunk-O5IVKDX7.js +0 -30
  855. package/dist/chunk-O5IVKDX7.js.map +0 -7
  856. package/dist/chunk-O7ORICEC.js +0 -82
  857. package/dist/chunk-O7ORICEC.js.map +0 -7
  858. package/dist/chunk-OBMBAM3N.js +0 -73
  859. package/dist/chunk-OBMBAM3N.js.map +0 -7
  860. package/dist/chunk-OFWMLQMU.js +0 -7287
  861. package/dist/chunk-OFWMLQMU.js.map +0 -7
  862. package/dist/chunk-OJ3ZUKBI.js +0 -73
  863. package/dist/chunk-OJ3ZUKBI.js.map +0 -7
  864. package/dist/chunk-OJJBD5K3.js +0 -45
  865. package/dist/chunk-OJJBD5K3.js.map +0 -7
  866. package/dist/chunk-OJTHE4B7.js +0 -50
  867. package/dist/chunk-OJTHE4B7.js.map +0 -7
  868. package/dist/chunk-OKDOVX4B.js +0 -699
  869. package/dist/chunk-OKDOVX4B.js.map +0 -7
  870. package/dist/chunk-OOYPYBTA.js +0 -446
  871. package/dist/chunk-OOYPYBTA.js.map +0 -7
  872. package/dist/chunk-OQP4W4AR.js +0 -105
  873. package/dist/chunk-OQP4W4AR.js.map +0 -7
  874. package/dist/chunk-OVMDMCZ5.js +0 -241
  875. package/dist/chunk-OVMDMCZ5.js.map +0 -7
  876. package/dist/chunk-OVTT2EKA.js +0 -516
  877. package/dist/chunk-OVTT2EKA.js.map +0 -7
  878. package/dist/chunk-OVU43GJK.js +0 -63
  879. package/dist/chunk-OVU43GJK.js.map +0 -7
  880. package/dist/chunk-P3TMARA6.js +0 -18
  881. package/dist/chunk-P3TMARA6.js.map +0 -7
  882. package/dist/chunk-P5N63LBS.js +0 -94
  883. package/dist/chunk-P5N63LBS.js.map +0 -7
  884. package/dist/chunk-PARITZ7F.js +0 -28
  885. package/dist/chunk-PARITZ7F.js.map +0 -7
  886. package/dist/chunk-PBQK4KY4.js +0 -195
  887. package/dist/chunk-PBQK4KY4.js.map +0 -7
  888. package/dist/chunk-PLMOTQ42.js +0 -335
  889. package/dist/chunk-PLMOTQ42.js.map +0 -7
  890. package/dist/chunk-PSL2AHIA.js +0 -27
  891. package/dist/chunk-PSL2AHIA.js.map +0 -7
  892. package/dist/chunk-Q5QT7JBM.js +0 -92
  893. package/dist/chunk-Q5QT7JBM.js.map +0 -7
  894. package/dist/chunk-Q6H5OV2R.js +0 -180
  895. package/dist/chunk-Q6H5OV2R.js.map +0 -7
  896. package/dist/chunk-Q7WA5DCR.js +0 -62
  897. package/dist/chunk-Q7WA5DCR.js.map +0 -7
  898. package/dist/chunk-QAR5POXD.js +0 -472
  899. package/dist/chunk-QAR5POXD.js.map +0 -7
  900. package/dist/chunk-QATEENP2.js +0 -7
  901. package/dist/chunk-QATEENP2.js.map +0 -7
  902. package/dist/chunk-QDT24CIA.js +0 -485
  903. package/dist/chunk-QDT24CIA.js.map +0 -7
  904. package/dist/chunk-QI3NB7D5.js +0 -455
  905. package/dist/chunk-QI3NB7D5.js.map +0 -7
  906. package/dist/chunk-QIDAVXSX.js +0 -106
  907. package/dist/chunk-QIDAVXSX.js.map +0 -7
  908. package/dist/chunk-QKIGQVP2.js +0 -104
  909. package/dist/chunk-QKIGQVP2.js.map +0 -7
  910. package/dist/chunk-QNJENPK2.js +0 -81
  911. package/dist/chunk-QNJENPK2.js.map +0 -7
  912. package/dist/chunk-R5S76YR5.js +0 -12
  913. package/dist/chunk-R5S76YR5.js.map +0 -7
  914. package/dist/chunk-R7ZBOXPS.js +0 -163
  915. package/dist/chunk-R7ZBOXPS.js.map +0 -7
  916. package/dist/chunk-RAL3KX76.js +0 -239
  917. package/dist/chunk-RAL3KX76.js.map +0 -7
  918. package/dist/chunk-REVXXWAS.js +0 -31
  919. package/dist/chunk-REVXXWAS.js.map +0 -7
  920. package/dist/chunk-RFH4HRZP.js +0 -94
  921. package/dist/chunk-RFH4HRZP.js.map +0 -7
  922. package/dist/chunk-RHITG64O.js +0 -50
  923. package/dist/chunk-RHITG64O.js.map +0 -7
  924. package/dist/chunk-RK5HZFP6.js +0 -111
  925. package/dist/chunk-RK5HZFP6.js.map +0 -7
  926. package/dist/chunk-RNGAGYCL.js +0 -49
  927. package/dist/chunk-RNGAGYCL.js.map +0 -7
  928. package/dist/chunk-RPCVN3JA.js +0 -261
  929. package/dist/chunk-RPCVN3JA.js.map +0 -7
  930. package/dist/chunk-RQ26XXFS.js +0 -45
  931. package/dist/chunk-RQ26XXFS.js.map +0 -7
  932. package/dist/chunk-RQQE5DDT.js +0 -193
  933. package/dist/chunk-RQQE5DDT.js.map +0 -7
  934. package/dist/chunk-RSA7PKZH.js +0 -187
  935. package/dist/chunk-RSA7PKZH.js.map +0 -7
  936. package/dist/chunk-RTSINQ4T.js +0 -78
  937. package/dist/chunk-RTSINQ4T.js.map +0 -7
  938. package/dist/chunk-RVOD3ESA.js +0 -38
  939. package/dist/chunk-RVOD3ESA.js.map +0 -7
  940. package/dist/chunk-SAOUP24A.js +0 -70
  941. package/dist/chunk-SAOUP24A.js.map +0 -7
  942. package/dist/chunk-SFZL2TCV.js +0 -55
  943. package/dist/chunk-SFZL2TCV.js.map +0 -7
  944. package/dist/chunk-SH6Y4CGQ.js +0 -175
  945. package/dist/chunk-SH6Y4CGQ.js.map +0 -7
  946. package/dist/chunk-SHBAAFFH.js +0 -74
  947. package/dist/chunk-SHBAAFFH.js.map +0 -7
  948. package/dist/chunk-SJPFUXBV.js +0 -45
  949. package/dist/chunk-SJPFUXBV.js.map +0 -7
  950. package/dist/chunk-SLIUQWAR.js +0 -58
  951. package/dist/chunk-SLIUQWAR.js.map +0 -7
  952. package/dist/chunk-SPNSM6SB.js +0 -36
  953. package/dist/chunk-SPNSM6SB.js.map +0 -7
  954. package/dist/chunk-SQUHLLK5.js +0 -125
  955. package/dist/chunk-SQUHLLK5.js.map +0 -7
  956. package/dist/chunk-SSEX66OL.js +0 -39
  957. package/dist/chunk-SSEX66OL.js.map +0 -7
  958. package/dist/chunk-SWWK35VQ.js +0 -84
  959. package/dist/chunk-SWWK35VQ.js.map +0 -7
  960. package/dist/chunk-SX2LOHOX.js +0 -251
  961. package/dist/chunk-SX2LOHOX.js.map +0 -7
  962. package/dist/chunk-T72EMFTX.js +0 -74
  963. package/dist/chunk-T72EMFTX.js.map +0 -7
  964. package/dist/chunk-TA2QJPPG.js +0 -169
  965. package/dist/chunk-TA2QJPPG.js.map +0 -7
  966. package/dist/chunk-TC5ZVFV6.js +0 -292
  967. package/dist/chunk-TC5ZVFV6.js.map +0 -7
  968. package/dist/chunk-TFD7ZIYD.js +0 -105
  969. package/dist/chunk-TFD7ZIYD.js.map +0 -7
  970. package/dist/chunk-TFEETDNY.js +0 -78
  971. package/dist/chunk-TFEETDNY.js.map +0 -7
  972. package/dist/chunk-TH6ONRWT.js +0 -516
  973. package/dist/chunk-TH6ONRWT.js.map +0 -7
  974. package/dist/chunk-THM2QV25.js +0 -108
  975. package/dist/chunk-THM2QV25.js.map +0 -7
  976. package/dist/chunk-TMQMQ67T.js +0 -81
  977. package/dist/chunk-TMQMQ67T.js.map +0 -7
  978. package/dist/chunk-TPYWUZOR.js +0 -178
  979. package/dist/chunk-TPYWUZOR.js.map +0 -7
  980. package/dist/chunk-TRWT2N6Z.js +0 -15
  981. package/dist/chunk-TRWT2N6Z.js.map +0 -7
  982. package/dist/chunk-TTXEM54Y.js +0 -76
  983. package/dist/chunk-TTXEM54Y.js.map +0 -7
  984. package/dist/chunk-U2O4LE6S.js +0 -22
  985. package/dist/chunk-U2O4LE6S.js.map +0 -7
  986. package/dist/chunk-U44IVNP2.js +0 -91
  987. package/dist/chunk-U44IVNP2.js.map +0 -7
  988. package/dist/chunk-U4LVIY5F.js +0 -1405
  989. package/dist/chunk-U4LVIY5F.js.map +0 -7
  990. package/dist/chunk-U767LCSG.js +0 -78
  991. package/dist/chunk-U767LCSG.js.map +0 -7
  992. package/dist/chunk-U7GKLHU6.js +0 -120
  993. package/dist/chunk-U7GKLHU6.js.map +0 -7
  994. package/dist/chunk-UAB5P5QO.js +0 -60
  995. package/dist/chunk-UAB5P5QO.js.map +0 -7
  996. package/dist/chunk-UDDWLWKZ.js +0 -82
  997. package/dist/chunk-UDDWLWKZ.js.map +0 -7
  998. package/dist/chunk-UEHPJQBL.js +0 -38
  999. package/dist/chunk-UEHPJQBL.js.map +0 -7
  1000. package/dist/chunk-UIBV6IGR.js +0 -31
  1001. package/dist/chunk-UIBV6IGR.js.map +0 -7
  1002. package/dist/chunk-UIYFRUET.js +0 -16352
  1003. package/dist/chunk-UIYFRUET.js.map +0 -7
  1004. package/dist/chunk-UJS3TIVS.js +0 -52
  1005. package/dist/chunk-UJS3TIVS.js.map +0 -7
  1006. package/dist/chunk-UMMPB6FL.js +0 -506
  1007. package/dist/chunk-UMMPB6FL.js.map +0 -7
  1008. package/dist/chunk-UP42ACP7.js +0 -27
  1009. package/dist/chunk-UP42ACP7.js.map +0 -7
  1010. package/dist/chunk-UPEF7ETP.js +0 -92
  1011. package/dist/chunk-UPEF7ETP.js.map +0 -7
  1012. package/dist/chunk-UU5PSBSI.js +0 -176
  1013. package/dist/chunk-UU5PSBSI.js.map +0 -7
  1014. package/dist/chunk-UV63XYFU.js +0 -173
  1015. package/dist/chunk-UV63XYFU.js.map +0 -7
  1016. package/dist/chunk-UWPHOAOC.js +0 -29
  1017. package/dist/chunk-UWPHOAOC.js.map +0 -7
  1018. package/dist/chunk-UXDDOSJC.js +0 -52
  1019. package/dist/chunk-UXDDOSJC.js.map +0 -7
  1020. package/dist/chunk-V3VAOMCO.js +0 -465
  1021. package/dist/chunk-V3VAOMCO.js.map +0 -7
  1022. package/dist/chunk-VA7ENH2S.js +0 -38
  1023. package/dist/chunk-VA7ENH2S.js.map +0 -7
  1024. package/dist/chunk-VBDLTKI2.js +0 -130
  1025. package/dist/chunk-VBDLTKI2.js.map +0 -7
  1026. package/dist/chunk-VCWIKEJ7.js +0 -7
  1027. package/dist/chunk-VCWIKEJ7.js.map +0 -7
  1028. package/dist/chunk-VFPDFLVE.js +0 -516
  1029. package/dist/chunk-VFPDFLVE.js.map +0 -7
  1030. package/dist/chunk-VHG4FNIJ.js +0 -93
  1031. package/dist/chunk-VHG4FNIJ.js.map +0 -7
  1032. package/dist/chunk-VKOO6MIZ.js +0 -51
  1033. package/dist/chunk-VKOO6MIZ.js.map +0 -7
  1034. package/dist/chunk-VKXKRZG7.js +0 -62
  1035. package/dist/chunk-VKXKRZG7.js.map +0 -7
  1036. package/dist/chunk-VPQICZQR.js +0 -93
  1037. package/dist/chunk-VPQICZQR.js.map +0 -7
  1038. package/dist/chunk-VRBJNFPL.js +0 -114
  1039. package/dist/chunk-VRBJNFPL.js.map +0 -7
  1040. package/dist/chunk-VUOLPEUZ.js +0 -7
  1041. package/dist/chunk-VUOLPEUZ.js.map +0 -7
  1042. package/dist/chunk-VUU5KFH3.js +0 -38
  1043. package/dist/chunk-VUU5KFH3.js.map +0 -7
  1044. package/dist/chunk-VVBL5CFF.js +0 -7
  1045. package/dist/chunk-VVBL5CFF.js.map +0 -7
  1046. package/dist/chunk-VYZEQ6KY.js +0 -22
  1047. package/dist/chunk-VYZEQ6KY.js.map +0 -7
  1048. package/dist/chunk-W6SOBS7M.js +0 -138
  1049. package/dist/chunk-W6SOBS7M.js.map +0 -7
  1050. package/dist/chunk-WBPQVWSU.js +0 -198
  1051. package/dist/chunk-WBPQVWSU.js.map +0 -7
  1052. package/dist/chunk-WDOKKRTE.js +0 -7
  1053. package/dist/chunk-WDOKKRTE.js.map +0 -7
  1054. package/dist/chunk-WGXXKFN5.js +0 -7
  1055. package/dist/chunk-WGXXKFN5.js.map +0 -7
  1056. package/dist/chunk-WHPUUP3J.js +0 -25
  1057. package/dist/chunk-WHPUUP3J.js.map +0 -7
  1058. package/dist/chunk-WS6HWBKT.js +0 -30
  1059. package/dist/chunk-WS6HWBKT.js.map +0 -7
  1060. package/dist/chunk-XF7LD6VV.js +0 -122
  1061. package/dist/chunk-XF7LD6VV.js.map +0 -7
  1062. package/dist/chunk-XFTXM3RE.js +0 -64
  1063. package/dist/chunk-XFTXM3RE.js.map +0 -7
  1064. package/dist/chunk-XJABPO2T.js +0 -235
  1065. package/dist/chunk-XJABPO2T.js.map +0 -7
  1066. package/dist/chunk-XK6VF3H7.js +0 -3586
  1067. package/dist/chunk-XK6VF3H7.js.map +0 -7
  1068. package/dist/chunk-XOZPOHLG.js +0 -233
  1069. package/dist/chunk-XOZPOHLG.js.map +0 -7
  1070. package/dist/chunk-XQYIIPOJ.js +0 -266
  1071. package/dist/chunk-XQYIIPOJ.js.map +0 -7
  1072. package/dist/chunk-XR7DPSNX.js +0 -195
  1073. package/dist/chunk-XR7DPSNX.js.map +0 -7
  1074. package/dist/chunk-XYH4JC3U.js +0 -7
  1075. package/dist/chunk-XYH4JC3U.js.map +0 -7
  1076. package/dist/chunk-XZSAN55E.js +0 -58
  1077. package/dist/chunk-XZSAN55E.js.map +0 -7
  1078. package/dist/chunk-Y3KJR4OG.js +0 -64
  1079. package/dist/chunk-Y3KJR4OG.js.map +0 -7
  1080. package/dist/chunk-Y4JKH7FF.js +0 -45
  1081. package/dist/chunk-Y4JKH7FF.js.map +0 -7
  1082. package/dist/chunk-Y6CJN4ID.js +0 -31
  1083. package/dist/chunk-Y6CJN4ID.js.map +0 -7
  1084. package/dist/chunk-YABGJU5M.js +0 -271
  1085. package/dist/chunk-YABGJU5M.js.map +0 -7
  1086. package/dist/chunk-YB5UCHLN.js +0 -314
  1087. package/dist/chunk-YB5UCHLN.js.map +0 -7
  1088. package/dist/chunk-YEJH7ZC2.js +0 -34
  1089. package/dist/chunk-YEJH7ZC2.js.map +0 -7
  1090. package/dist/chunk-YF5DYD3X.js +0 -97
  1091. package/dist/chunk-YF5DYD3X.js.map +0 -7
  1092. package/dist/chunk-YFTE4H54.js +0 -44117
  1093. package/dist/chunk-YFTE4H54.js.map +0 -7
  1094. package/dist/chunk-YGVQZCE7.js +0 -30
  1095. package/dist/chunk-YGVQZCE7.js.map +0 -7
  1096. package/dist/chunk-YNHADHHS.js +0 -138
  1097. package/dist/chunk-YNHADHHS.js.map +0 -7
  1098. package/dist/chunk-YNJYMD43.js +0 -392
  1099. package/dist/chunk-YNJYMD43.js.map +0 -7
  1100. package/dist/chunk-YNYEQGVN.js +0 -251
  1101. package/dist/chunk-YNYEQGVN.js.map +0 -7
  1102. package/dist/chunk-YOAMBAM2.js +0 -70
  1103. package/dist/chunk-YOAMBAM2.js.map +0 -7
  1104. package/dist/chunk-YUPBD27Z.js +0 -70
  1105. package/dist/chunk-YUPBD27Z.js.map +0 -7
  1106. package/dist/chunk-YWE5AQPZ.js +0 -258
  1107. package/dist/chunk-YWE5AQPZ.js.map +0 -7
  1108. package/dist/chunk-YWHH3MB6.js +0 -1405
  1109. package/dist/chunk-YWHH3MB6.js.map +0 -7
  1110. package/dist/chunk-YXJ52FD5.js +0 -271
  1111. package/dist/chunk-YXJ52FD5.js.map +0 -7
  1112. package/dist/chunk-YZ6F5N7R.js +0 -455
  1113. package/dist/chunk-YZ6F5N7R.js.map +0 -7
  1114. package/dist/chunk-YZGORRQN.js +0 -3101
  1115. package/dist/chunk-YZGORRQN.js.map +0 -7
  1116. package/dist/chunk-Z6IVJ6ZW.js +0 -30
  1117. package/dist/chunk-Z6IVJ6ZW.js.map +0 -7
  1118. package/dist/chunk-ZFC44XJJ.js +0 -86
  1119. package/dist/chunk-ZFC44XJJ.js.map +0 -7
  1120. package/dist/chunk-ZFGRQIB6.js +0 -38
  1121. package/dist/chunk-ZFGRQIB6.js.map +0 -7
  1122. package/dist/chunk-ZGAUVPAB.js +0 -14
  1123. package/dist/chunk-ZGAUVPAB.js.map +0 -7
  1124. package/dist/chunk-ZGCATLM5.js +0 -18
  1125. package/dist/chunk-ZGCATLM5.js.map +0 -7
  1126. package/dist/chunk-ZJDJC5TP.js +0 -82
  1127. package/dist/chunk-ZJDJC5TP.js.map +0 -7
  1128. package/dist/chunk-ZJGZNPDK.js +0 -171
  1129. package/dist/chunk-ZJGZNPDK.js.map +0 -7
  1130. package/dist/chunk-ZJHBJWZX.js +0 -699
  1131. package/dist/chunk-ZJHBJWZX.js.map +0 -7
  1132. package/dist/chunk-ZNOTD65D.js +0 -95
  1133. package/dist/chunk-ZNOTD65D.js.map +0 -7
  1134. package/dist/chunk-ZQ2QIFXW.js +0 -122
  1135. package/dist/chunk-ZQ2QIFXW.js.map +0 -7
  1136. package/dist/chunk-ZRMXPQGY.js +0 -241
  1137. package/dist/chunk-ZRMXPQGY.js.map +0 -7
  1138. package/dist/chunk-ZSOPE7DO.js +0 -92
  1139. package/dist/chunk-ZSOPE7DO.js.map +0 -7
  1140. package/dist/chunk-ZVEE5IDC.js +0 -3101
  1141. package/dist/chunk-ZVEE5IDC.js.map +0 -7
  1142. package/dist/chunk-ZY247PXY.js +0 -135
  1143. package/dist/chunk-ZY247PXY.js.map +0 -7
  1144. package/dist/cli-metadata.js +0 -12
  1145. package/dist/cli-metadata.js.map +0 -7
  1146. package/dist/contract-api.js +0 -104
  1147. package/dist/contract-api.js.map +0 -7
  1148. package/dist/dist-DVBXHDB4.js +0 -549
  1149. package/dist/dist-DVBXHDB4.js.map +0 -7
  1150. package/dist/dist-F3K7S5SS.js +0 -549
  1151. package/dist/dist-F3K7S5SS.js.map +0 -7
  1152. package/dist/helper-api.js +0 -51
  1153. package/dist/helper-api.js.map +0 -7
  1154. package/dist/index.js +0 -70
  1155. package/dist/index.js.map +0 -7
  1156. package/dist/magic-string.es-ITIPPYGW.js +0 -1315
  1157. package/dist/magic-string.es-ITIPPYGW.js.map +0 -7
  1158. package/dist/magic-string.es-V5NOGTUV.js +0 -1315
  1159. package/dist/magic-string.es-V5NOGTUV.js.map +0 -7
  1160. package/dist/openclaw.plugin.json +0 -23
  1161. package/dist/package.json +0 -59
  1162. package/dist/plugin-entry.handlers.runtime-JLRK5XTV.js +0 -20
  1163. package/dist/plugin-entry.handlers.runtime-JLRK5XTV.js.map +0 -7
  1164. package/dist/plugin-entry.handlers.runtime-POD4CSHM.js +0 -20
  1165. package/dist/plugin-entry.handlers.runtime-POD4CSHM.js.map +0 -7
  1166. package/dist/plugin-entry.handlers.runtime-YOSG6V6U.js +0 -20
  1167. package/dist/plugin-entry.handlers.runtime-YOSG6V6U.js.map +0 -7
  1168. package/dist/runtime-api.js +0 -104
  1169. package/dist/runtime-api.js.map +0 -7
  1170. package/dist/rust-crypto-7KS7OJ3F.js +0 -5323
  1171. package/dist/rust-crypto-7KS7OJ3F.js.map +0 -7
  1172. package/dist/rust-crypto-H35BXWUU.js +0 -5323
  1173. package/dist/rust-crypto-H35BXWUU.js.map +0 -7
  1174. package/dist/secret-contract-api.js +0 -18
  1175. package/dist/secret-contract-api.js.map +0 -7
  1176. package/dist/setup-entry.js +0 -22
  1177. package/dist/setup-entry.js.map +0 -7
  1178. package/dist/src/account-selection.js +0 -19
  1179. package/dist/src/account-selection.js.map +0 -7
  1180. package/dist/src/actions.js +0 -24
  1181. package/dist/src/actions.js.map +0 -7
  1182. package/dist/src/approval-auth.js +0 -27
  1183. package/dist/src/approval-auth.js.map +0 -7
  1184. package/dist/src/approval-handler.runtime.js +0 -378
  1185. package/dist/src/approval-handler.runtime.js.map +0 -7
  1186. package/dist/src/approval-ids.js +0 -9
  1187. package/dist/src/approval-ids.js.map +0 -7
  1188. package/dist/src/approval-native.js +0 -28
  1189. package/dist/src/approval-native.js.map +0 -7
  1190. package/dist/src/approval-reactions.js +0 -20
  1191. package/dist/src/approval-reactions.js.map +0 -7
  1192. package/dist/src/auth-precedence.js +0 -8
  1193. package/dist/src/auth-precedence.js.map +0 -7
  1194. package/dist/src/channel-account-paths.js +0 -11
  1195. package/dist/src/channel-account-paths.js.map +0 -7
  1196. package/dist/src/channel.js +0 -74
  1197. package/dist/src/channel.js.map +0 -7
  1198. package/dist/src/channel.runtime.js +0 -82
  1199. package/dist/src/channel.runtime.js.map +0 -7
  1200. package/dist/src/cli-metadata.js +0 -8
  1201. package/dist/src/cli-metadata.js.map +0 -7
  1202. package/dist/src/cli.js +0 -936
  1203. package/dist/src/cli.js.map +0 -7
  1204. package/dist/src/config-adapter.js +0 -26
  1205. package/dist/src/config-adapter.js.map +0 -7
  1206. package/dist/src/config-schema.js +0 -8
  1207. package/dist/src/config-schema.js.map +0 -7
  1208. package/dist/src/directory-live.js +0 -35
  1209. package/dist/src/directory-live.js.map +0 -7
  1210. package/dist/src/doctor-contract.js +0 -11
  1211. package/dist/src/doctor-contract.js.map +0 -7
  1212. package/dist/src/doctor.js +0 -42
  1213. package/dist/src/doctor.js.map +0 -7
  1214. package/dist/src/env-vars.js +0 -12
  1215. package/dist/src/env-vars.js.map +0 -7
  1216. package/dist/src/exec-approval-resolver.js +0 -10
  1217. package/dist/src/exec-approval-resolver.js.map +0 -7
  1218. package/dist/src/exec-approvals.js +0 -51
  1219. package/dist/src/exec-approvals.js.map +0 -7
  1220. package/dist/src/group-mentions.js +0 -28
  1221. package/dist/src/group-mentions.js.map +0 -7
  1222. package/dist/src/legacy-crypto-inspector-availability.js +0 -8
  1223. package/dist/src/legacy-crypto-inspector-availability.js.map +0 -7
  1224. package/dist/src/legacy-crypto.js +0 -26
  1225. package/dist/src/legacy-crypto.js.map +0 -7
  1226. package/dist/src/legacy-state.js +0 -24
  1227. package/dist/src/legacy-state.js.map +0 -7
  1228. package/dist/src/matrix/account-config.js +0 -16
  1229. package/dist/src/matrix/account-config.js.map +0 -7
  1230. package/dist/src/matrix/accounts.js +0 -31
  1231. package/dist/src/matrix/accounts.js.map +0 -7
  1232. package/dist/src/matrix/actions/client.js +0 -40
  1233. package/dist/src/matrix/actions/client.js.map +0 -7
  1234. package/dist/src/matrix/actions/devices.js +0 -42
  1235. package/dist/src/matrix/actions/devices.js.map +0 -7
  1236. package/dist/src/matrix/actions/limits.js +0 -8
  1237. package/dist/src/matrix/actions/limits.js.map +0 -7
  1238. package/dist/src/matrix/actions/messages.js +0 -49
  1239. package/dist/src/matrix/actions/messages.js.map +0 -7
  1240. package/dist/src/matrix/actions/pins.js +0 -46
  1241. package/dist/src/matrix/actions/pins.js.map +0 -7
  1242. package/dist/src/matrix/actions/polls.js +0 -37
  1243. package/dist/src/matrix/actions/polls.js.map +0 -7
  1244. package/dist/src/matrix/actions/profile.js +0 -38
  1245. package/dist/src/matrix/actions/profile.js.map +0 -7
  1246. package/dist/src/matrix/actions/reactions.js +0 -40
  1247. package/dist/src/matrix/actions/reactions.js.map +0 -7
  1248. package/dist/src/matrix/actions/room.js +0 -40
  1249. package/dist/src/matrix/actions/room.js.map +0 -7
  1250. package/dist/src/matrix/actions/summary.js +0 -19
  1251. package/dist/src/matrix/actions/summary.js.map +0 -7
  1252. package/dist/src/matrix/actions/types.js +0 -13
  1253. package/dist/src/matrix/actions/types.js.map +0 -7
  1254. package/dist/src/matrix/actions/verification.js +0 -77
  1255. package/dist/src/matrix/actions/verification.js.map +0 -7
  1256. package/dist/src/matrix/actions.js +0 -126
  1257. package/dist/src/matrix/actions.js.map +0 -7
  1258. package/dist/src/matrix/active-client.js +0 -10
  1259. package/dist/src/matrix/active-client.js.map +0 -7
  1260. package/dist/src/matrix/async-lock.js +0 -8
  1261. package/dist/src/matrix/async-lock.js.map +0 -7
  1262. package/dist/src/matrix/backup-health.js +0 -10
  1263. package/dist/src/matrix/backup-health.js.map +0 -7
  1264. package/dist/src/matrix/client/config-runtime-api.js +0 -24
  1265. package/dist/src/matrix/client/config-runtime-api.js.map +0 -7
  1266. package/dist/src/matrix/client/config-secret-input.runtime.js +0 -11
  1267. package/dist/src/matrix/client/config-secret-input.runtime.js.map +0 -7
  1268. package/dist/src/matrix/client/config.js +0 -42
  1269. package/dist/src/matrix/client/config.js.map +0 -7
  1270. package/dist/src/matrix/client/create-client.js +0 -20
  1271. package/dist/src/matrix/client/create-client.js.map +0 -7
  1272. package/dist/src/matrix/client/env-auth.js +0 -26
  1273. package/dist/src/matrix/client/env-auth.js.map +0 -7
  1274. package/dist/src/matrix/client/file-sync-store.js +0 -23
  1275. package/dist/src/matrix/client/file-sync-store.js.map +0 -7
  1276. package/dist/src/matrix/client/logging.js +0 -17
  1277. package/dist/src/matrix/client/logging.js.map +0 -7
  1278. package/dist/src/matrix/client/migration-snapshot.runtime.js +0 -13
  1279. package/dist/src/matrix/client/migration-snapshot.runtime.js.map +0 -7
  1280. package/dist/src/matrix/client/private-network-host.js +0 -8
  1281. package/dist/src/matrix/client/private-network-host.js.map +0 -7
  1282. package/dist/src/matrix/client/runtime.js +0 -8
  1283. package/dist/src/matrix/client/runtime.js.map +0 -7
  1284. package/dist/src/matrix/client/shared.js +0 -34
  1285. package/dist/src/matrix/client/shared.js.map +0 -7
  1286. package/dist/src/matrix/client/storage.js +0 -26
  1287. package/dist/src/matrix/client/storage.js.map +0 -7
  1288. package/dist/src/matrix/client/types.js +0 -7
  1289. package/dist/src/matrix/client/types.js.map +0 -7
  1290. package/dist/src/matrix/client-bootstrap.js +0 -15
  1291. package/dist/src/matrix/client-bootstrap.js.map +0 -7
  1292. package/dist/src/matrix/client-resolver.test-helpers.js +0 -122
  1293. package/dist/src/matrix/client-resolver.test-helpers.js.map +0 -7
  1294. package/dist/src/matrix/client.js +0 -63
  1295. package/dist/src/matrix/client.js.map +0 -7
  1296. package/dist/src/matrix/config-paths.js +0 -12
  1297. package/dist/src/matrix/config-paths.js.map +0 -7
  1298. package/dist/src/matrix/config-update.js +0 -17
  1299. package/dist/src/matrix/config-update.js.map +0 -7
  1300. package/dist/src/matrix/credentials-read.js +0 -22
  1301. package/dist/src/matrix/credentials-read.js.map +0 -7
  1302. package/dist/src/matrix/credentials-write.runtime.js +0 -24
  1303. package/dist/src/matrix/credentials-write.runtime.js.map +0 -7
  1304. package/dist/src/matrix/credentials.js +0 -90
  1305. package/dist/src/matrix/credentials.js.map +0 -7
  1306. package/dist/src/matrix/deps.js +0 -12
  1307. package/dist/src/matrix/deps.js.map +0 -7
  1308. package/dist/src/matrix/device-health.js +0 -10
  1309. package/dist/src/matrix/device-health.js.map +0 -7
  1310. package/dist/src/matrix/direct-management.js +0 -18
  1311. package/dist/src/matrix/direct-management.js.map +0 -7
  1312. package/dist/src/matrix/direct-room.js +0 -18
  1313. package/dist/src/matrix/direct-room.js.map +0 -7
  1314. package/dist/src/matrix/draft-stream.js +0 -33
  1315. package/dist/src/matrix/draft-stream.js.map +0 -7
  1316. package/dist/src/matrix/encryption-guidance.js +0 -17
  1317. package/dist/src/matrix/encryption-guidance.js.map +0 -7
  1318. package/dist/src/matrix/errors.js +0 -12
  1319. package/dist/src/matrix/errors.js.map +0 -7
  1320. package/dist/src/matrix/format.js +0 -13
  1321. package/dist/src/matrix/format.js.map +0 -7
  1322. package/dist/src/matrix/legacy-crypto-inspector.js +0 -72
  1323. package/dist/src/matrix/legacy-crypto-inspector.js.map +0 -7
  1324. package/dist/src/matrix/media-errors.js +0 -12
  1325. package/dist/src/matrix/media-errors.js.map +0 -7
  1326. package/dist/src/matrix/media-text.js +0 -22
  1327. package/dist/src/matrix/media-text.js.map +0 -7
  1328. package/dist/src/matrix/monitor/access-state.js +0 -9
  1329. package/dist/src/matrix/monitor/access-state.js.map +0 -7
  1330. package/dist/src/matrix/monitor/ack-config.js +0 -10
  1331. package/dist/src/matrix/monitor/ack-config.js.map +0 -7
  1332. package/dist/src/matrix/monitor/allowlist.js +0 -12
  1333. package/dist/src/matrix/monitor/allowlist.js.map +0 -7
  1334. package/dist/src/matrix/monitor/auto-join.js +0 -9
  1335. package/dist/src/matrix/monitor/auto-join.js.map +0 -7
  1336. package/dist/src/matrix/monitor/config.js +0 -37
  1337. package/dist/src/matrix/monitor/config.js.map +0 -7
  1338. package/dist/src/matrix/monitor/context-summary.js +0 -13
  1339. package/dist/src/matrix/monitor/context-summary.js.map +0 -7
  1340. package/dist/src/matrix/monitor/direct.js +0 -13
  1341. package/dist/src/matrix/monitor/direct.js.map +0 -7
  1342. package/dist/src/matrix/monitor/events.js +0 -20
  1343. package/dist/src/matrix/monitor/events.js.map +0 -7
  1344. package/dist/src/matrix/monitor/handler.js +0 -76
  1345. package/dist/src/matrix/monitor/handler.js.map +0 -7
  1346. package/dist/src/matrix/monitor/handler.test-helpers.js +0 -268
  1347. package/dist/src/matrix/monitor/handler.test-helpers.js.map +0 -7
  1348. package/dist/src/matrix/monitor/inbound-dedupe.js +0 -17
  1349. package/dist/src/matrix/monitor/inbound-dedupe.js.map +0 -7
  1350. package/dist/src/matrix/monitor/index.js +0 -502
  1351. package/dist/src/matrix/monitor/index.js.map +0 -7
  1352. package/dist/src/matrix/monitor/legacy-crypto-restore.js +0 -99
  1353. package/dist/src/matrix/monitor/legacy-crypto-restore.js.map +0 -7
  1354. package/dist/src/matrix/monitor/location.js +0 -11
  1355. package/dist/src/matrix/monitor/location.js.map +0 -7
  1356. package/dist/src/matrix/monitor/media.js +0 -10
  1357. package/dist/src/matrix/monitor/media.js.map +0 -7
  1358. package/dist/src/matrix/monitor/mentions.js +0 -9
  1359. package/dist/src/matrix/monitor/mentions.js.map +0 -7
  1360. package/dist/src/matrix/monitor/reaction-events.js +0 -38
  1361. package/dist/src/matrix/monitor/reaction-events.js.map +0 -7
  1362. package/dist/src/matrix/monitor/recent-invite.js +0 -10
  1363. package/dist/src/matrix/monitor/recent-invite.js.map +0 -7
  1364. package/dist/src/matrix/monitor/replies.js +0 -33
  1365. package/dist/src/matrix/monitor/replies.js.map +0 -7
  1366. package/dist/src/matrix/monitor/reply-context.js +0 -14
  1367. package/dist/src/matrix/monitor/reply-context.js.map +0 -7
  1368. package/dist/src/matrix/monitor/room-history.js +0 -10
  1369. package/dist/src/matrix/monitor/room-history.js.map +0 -7
  1370. package/dist/src/matrix/monitor/room-info.js +0 -9
  1371. package/dist/src/matrix/monitor/room-info.js.map +0 -7
  1372. package/dist/src/matrix/monitor/rooms.js +0 -9
  1373. package/dist/src/matrix/monitor/rooms.js.map +0 -7
  1374. package/dist/src/matrix/monitor/route.js +0 -12
  1375. package/dist/src/matrix/monitor/route.js.map +0 -7
  1376. package/dist/src/matrix/monitor/runtime-api.js +0 -40
  1377. package/dist/src/matrix/monitor/runtime-api.js.map +0 -7
  1378. package/dist/src/matrix/monitor/startup-verification.js +0 -174
  1379. package/dist/src/matrix/monitor/startup-verification.js.map +0 -7
  1380. package/dist/src/matrix/monitor/startup.js +0 -9
  1381. package/dist/src/matrix/monitor/startup.js.map +0 -7
  1382. package/dist/src/matrix/monitor/status.js +0 -10
  1383. package/dist/src/matrix/monitor/status.js.map +0 -7
  1384. package/dist/src/matrix/monitor/sync-lifecycle.js +0 -9
  1385. package/dist/src/matrix/monitor/sync-lifecycle.js.map +0 -7
  1386. package/dist/src/matrix/monitor/task-runner.js +0 -8
  1387. package/dist/src/matrix/monitor/task-runner.js.map +0 -7
  1388. package/dist/src/matrix/monitor/thread-context.js +0 -14
  1389. package/dist/src/matrix/monitor/thread-context.js.map +0 -7
  1390. package/dist/src/matrix/monitor/threads.js +0 -16
  1391. package/dist/src/matrix/monitor/threads.js.map +0 -7
  1392. package/dist/src/matrix/monitor/types.js +0 -11
  1393. package/dist/src/matrix/monitor/types.js.map +0 -7
  1394. package/dist/src/matrix/monitor/verification-events.js +0 -13
  1395. package/dist/src/matrix/monitor/verification-events.js.map +0 -7
  1396. package/dist/src/matrix/monitor/verification-utils.js +0 -16
  1397. package/dist/src/matrix/monitor/verification-utils.js.map +0 -7
  1398. package/dist/src/matrix/outbound-media-runtime.js +0 -9
  1399. package/dist/src/matrix/outbound-media-runtime.js.map +0 -7
  1400. package/dist/src/matrix/poll-summary.js +0 -14
  1401. package/dist/src/matrix/poll-summary.js.map +0 -7
  1402. package/dist/src/matrix/poll-types.js +0 -55
  1403. package/dist/src/matrix/poll-types.js.map +0 -7
  1404. package/dist/src/matrix/probe.js +0 -9
  1405. package/dist/src/matrix/probe.js.map +0 -7
  1406. package/dist/src/matrix/probe.runtime.js +0 -30
  1407. package/dist/src/matrix/probe.runtime.js.map +0 -7
  1408. package/dist/src/matrix/profile.js +0 -16
  1409. package/dist/src/matrix/profile.js.map +0 -7
  1410. package/dist/src/matrix/reaction-common.js +0 -26
  1411. package/dist/src/matrix/reaction-common.js.map +0 -7
  1412. package/dist/src/matrix/sdk/crypto-bootstrap.js +0 -15
  1413. package/dist/src/matrix/sdk/crypto-bootstrap.js.map +0 -7
  1414. package/dist/src/matrix/sdk/crypto-facade.js +0 -8
  1415. package/dist/src/matrix/sdk/crypto-facade.js.map +0 -7
  1416. package/dist/src/matrix/sdk/crypto-node.runtime.js +0 -14
  1417. package/dist/src/matrix/sdk/crypto-node.runtime.js.map +0 -7
  1418. package/dist/src/matrix/sdk/crypto-runtime.js +0 -84
  1419. package/dist/src/matrix/sdk/crypto-runtime.js.map +0 -7
  1420. package/dist/src/matrix/sdk/decrypt-bridge.js +0 -11
  1421. package/dist/src/matrix/sdk/decrypt-bridge.js.map +0 -7
  1422. package/dist/src/matrix/sdk/event-helpers.js +0 -12
  1423. package/dist/src/matrix/sdk/event-helpers.js.map +0 -7
  1424. package/dist/src/matrix/sdk/http-client.js +0 -13
  1425. package/dist/src/matrix/sdk/http-client.js.map +0 -7
  1426. package/dist/src/matrix/sdk/idb-persistence-lock.js +0 -12
  1427. package/dist/src/matrix/sdk/idb-persistence-lock.js.map +0 -7
  1428. package/dist/src/matrix/sdk/idb-persistence.js +0 -13
  1429. package/dist/src/matrix/sdk/idb-persistence.js.map +0 -7
  1430. package/dist/src/matrix/sdk/idb-persistence.test-helpers.js +0 -83
  1431. package/dist/src/matrix/sdk/idb-persistence.test-helpers.js.map +0 -7
  1432. package/dist/src/matrix/sdk/logger.js +0 -15
  1433. package/dist/src/matrix/sdk/logger.js.map +0 -7
  1434. package/dist/src/matrix/sdk/read-response-with-limit.js +0 -8
  1435. package/dist/src/matrix/sdk/read-response-with-limit.js.map +0 -7
  1436. package/dist/src/matrix/sdk/recovery-key-store.js +0 -14
  1437. package/dist/src/matrix/sdk/recovery-key-store.js.map +0 -7
  1438. package/dist/src/matrix/sdk/transport.js +0 -13
  1439. package/dist/src/matrix/sdk/transport.js.map +0 -7
  1440. package/dist/src/matrix/sdk/types.js +0 -7
  1441. package/dist/src/matrix/sdk/types.js.map +0 -7
  1442. package/dist/src/matrix/sdk/verification-manager.js +0 -11
  1443. package/dist/src/matrix/sdk/verification-manager.js.map +0 -7
  1444. package/dist/src/matrix/sdk/verification-status.js +0 -12
  1445. package/dist/src/matrix/sdk/verification-status.js.map +0 -7
  1446. package/dist/src/matrix/sdk.js +0 -1375
  1447. package/dist/src/matrix/sdk.js.map +0 -7
  1448. package/dist/src/matrix/send/client.js +0 -14
  1449. package/dist/src/matrix/send/client.js.map +0 -7
  1450. package/dist/src/matrix/send/formatting.js +0 -29
  1451. package/dist/src/matrix/send/formatting.js.map +0 -7
  1452. package/dist/src/matrix/send/media.js +0 -26
  1453. package/dist/src/matrix/send/media.js.map +0 -7
  1454. package/dist/src/matrix/send/targets.js +0 -15
  1455. package/dist/src/matrix/send/targets.js.map +0 -7
  1456. package/dist/src/matrix/send/types.js +0 -17
  1457. package/dist/src/matrix/send/types.js.map +0 -7
  1458. package/dist/src/matrix/send.js +0 -51
  1459. package/dist/src/matrix/send.js.map +0 -7
  1460. package/dist/src/matrix/session-store-metadata.js +0 -15
  1461. package/dist/src/matrix/session-store-metadata.js.map +0 -7
  1462. package/dist/src/matrix/startup-abort.js +0 -14
  1463. package/dist/src/matrix/startup-abort.js.map +0 -7
  1464. package/dist/src/matrix/sync-state.js +0 -12
  1465. package/dist/src/matrix/sync-state.js.map +0 -7
  1466. package/dist/src/matrix/target-ids.js +0 -20
  1467. package/dist/src/matrix/target-ids.js.map +0 -7
  1468. package/dist/src/matrix/thread-bindings-shared.js +0 -34
  1469. package/dist/src/matrix/thread-bindings-shared.js.map +0 -7
  1470. package/dist/src/matrix/thread-bindings.js +0 -49
  1471. package/dist/src/matrix/thread-bindings.js.map +0 -7
  1472. package/dist/src/matrix-migration.runtime.js +0 -45
  1473. package/dist/src/matrix-migration.runtime.js.map +0 -7
  1474. package/dist/src/migration-config.js +0 -29
  1475. package/dist/src/migration-config.js.map +0 -7
  1476. package/dist/src/migration-snapshot-backup.js +0 -12
  1477. package/dist/src/migration-snapshot-backup.js.map +0 -7
  1478. package/dist/src/migration-snapshot.js +0 -38
  1479. package/dist/src/migration-snapshot.js.map +0 -7
  1480. package/dist/src/onboarding.js +0 -43
  1481. package/dist/src/onboarding.js.map +0 -7
  1482. package/dist/src/onboarding.test-harness.js +0 -124
  1483. package/dist/src/onboarding.test-harness.js.map +0 -7
  1484. package/dist/src/outbound.js +0 -33
  1485. package/dist/src/outbound.js.map +0 -7
  1486. package/dist/src/plugin-entry.runtime.js +0 -15
  1487. package/dist/src/plugin-entry.runtime.js.map +0 -7
  1488. package/dist/src/profile-update.js +0 -41
  1489. package/dist/src/profile-update.js.map +0 -7
  1490. package/dist/src/record-shared.js +0 -8
  1491. package/dist/src/record-shared.js.map +0 -7
  1492. package/dist/src/resolve-targets.js +0 -34
  1493. package/dist/src/resolve-targets.js.map +0 -7
  1494. package/dist/src/resolver.js +0 -8
  1495. package/dist/src/resolver.js.map +0 -7
  1496. package/dist/src/runtime-api.js +0 -120
  1497. package/dist/src/runtime-api.js.map +0 -7
  1498. package/dist/src/runtime.js +0 -10
  1499. package/dist/src/runtime.js.map +0 -7
  1500. package/dist/src/secret-contract.js +0 -13
  1501. package/dist/src/secret-contract.js.map +0 -7
  1502. package/dist/src/session-route.js +0 -25
  1503. package/dist/src/session-route.js.map +0 -7
  1504. package/dist/src/setup-bootstrap.js +0 -124
  1505. package/dist/src/setup-bootstrap.js.map +0 -7
  1506. package/dist/src/setup-config.js +0 -28
  1507. package/dist/src/setup-config.js.map +0 -7
  1508. package/dist/src/setup-contract.js +0 -16
  1509. package/dist/src/setup-contract.js.map +0 -7
  1510. package/dist/src/setup-core.js +0 -25
  1511. package/dist/src/setup-core.js.map +0 -7
  1512. package/dist/src/setup-surface.js +0 -45
  1513. package/dist/src/setup-surface.js.map +0 -7
  1514. package/dist/src/startup-maintenance.js +0 -29
  1515. package/dist/src/startup-maintenance.js.map +0 -7
  1516. package/dist/src/storage-paths.js +0 -24
  1517. package/dist/src/storage-paths.js.map +0 -7
  1518. package/dist/src/test-helpers.js +0 -49
  1519. package/dist/src/test-helpers.js.map +0 -7
  1520. package/dist/src/test-mocks.js +0 -40
  1521. package/dist/src/test-mocks.js.map +0 -7
  1522. package/dist/src/test-runtime.js +0 -65
  1523. package/dist/src/test-runtime.js.map +0 -7
  1524. package/dist/src/tool-actions.js +0 -68
  1525. package/dist/src/tool-actions.js.map +0 -7
  1526. package/dist/src/tool-actions.runtime.js +0 -73
  1527. package/dist/src/tool-actions.runtime.js.map +0 -7
  1528. package/dist/src/types.js +0 -7
  1529. package/dist/src/types.js.map +0 -7
  1530. package/dist/test-api.js +0 -82
  1531. package/dist/test-api.js.map +0 -7
  1532. package/dist/thread-bindings-runtime.js +0 -15
  1533. package/dist/thread-bindings-runtime.js.map +0 -7
@@ -0,0 +1,2952 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { recordSessionMetaFromInbound } from "openclaw/plugin-sdk/config-runtime";
5
+ import {
6
+ __testing as sessionBindingTesting,
7
+ registerSessionBindingAdapter,
8
+ } from "openclaw/plugin-sdk/conversation-runtime";
9
+ import { beforeEach, describe, expect, it, vi } from "vitest";
10
+ import { installMatrixMonitorTestRuntime } from "../../test-runtime.js";
11
+ import { MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY } from "../send/types.js";
12
+ import { createMatrixRoomMessageHandler } from "./handler.js";
13
+ import {
14
+ createMatrixHandlerTestHarness,
15
+ createMatrixReactionEvent,
16
+ createMatrixRoomMessageEvent,
17
+ createMatrixTextMessageEvent,
18
+ } from "./handler.test-helpers.js";
19
+ import type { MatrixRawEvent } from "./types.js";
20
+ import { EventType } from "./types.js";
21
+
22
+ const sendMessageMatrixMock = vi.hoisted(() =>
23
+ vi.fn(async (..._args: unknown[]) => ({ messageId: "evt", roomId: "!room" })),
24
+ );
25
+ const sendSingleTextMessageMatrixMock = vi.hoisted(() =>
26
+ vi.fn(async (..._args: unknown[]) => ({ messageId: "$draft1", roomId: "!room" })),
27
+ );
28
+ const editMessageMatrixMock = vi.hoisted(() => vi.fn(async () => "$edited"));
29
+ const prepareMatrixSingleTextMock = vi.hoisted(() =>
30
+ vi.fn((text: string) => {
31
+ const trimmedText = text.trim();
32
+ return {
33
+ trimmedText,
34
+ convertedText: trimmedText,
35
+ singleEventLimit: 4000,
36
+ fitsInSingleEvent: true,
37
+ };
38
+ }),
39
+ );
40
+
41
+ vi.mock("../send.js", () => ({
42
+ editMessageMatrix: editMessageMatrixMock,
43
+ prepareMatrixSingleText: prepareMatrixSingleTextMock,
44
+ reactMatrixMessage: vi.fn(async () => {}),
45
+ sendMessageMatrix: sendMessageMatrixMock,
46
+ sendSingleTextMessageMatrix: sendSingleTextMessageMatrixMock,
47
+ sendReadReceiptMatrix: vi.fn(async () => {}),
48
+ sendTypingMatrix: vi.fn(async () => {}),
49
+ }));
50
+
51
+ const deliverMatrixRepliesMock = vi.hoisted(() => vi.fn(async () => true));
52
+
53
+ vi.mock("./replies.js", () => ({
54
+ deliverMatrixReplies: deliverMatrixRepliesMock,
55
+ }));
56
+
57
+ beforeEach(() => {
58
+ sessionBindingTesting.resetSessionBindingAdaptersForTests();
59
+ installMatrixMonitorTestRuntime();
60
+ prepareMatrixSingleTextMock.mockReset().mockImplementation((text: string) => {
61
+ const trimmedText = text.trim();
62
+ return {
63
+ trimmedText,
64
+ convertedText: trimmedText,
65
+ singleEventLimit: 4000,
66
+ fitsInSingleEvent: true,
67
+ };
68
+ });
69
+ });
70
+
71
+ function createReactionHarness(params?: {
72
+ cfg?: unknown;
73
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled";
74
+ allowFrom?: string[];
75
+ storeAllowFrom?: string[];
76
+ targetSender?: string;
77
+ isDirectMessage?: boolean;
78
+ senderName?: string;
79
+ client?: NonNullable<Parameters<typeof createMatrixHandlerTestHarness>[0]>["client"];
80
+ }) {
81
+ return createMatrixHandlerTestHarness({
82
+ cfg: params?.cfg,
83
+ dmPolicy: params?.dmPolicy,
84
+ allowFrom: params?.allowFrom,
85
+ readAllowFromStore: vi.fn(async () => params?.storeAllowFrom ?? []),
86
+ client: {
87
+ getEvent: async () => ({ sender: params?.targetSender ?? "@bot:example.org" }),
88
+ ...params?.client,
89
+ },
90
+ isDirectMessage: params?.isDirectMessage,
91
+ getMemberDisplayName: async () => params?.senderName ?? "sender",
92
+ });
93
+ }
94
+
95
+ describe("matrix monitor handler pairing account scope", () => {
96
+ it("caches account-scoped allowFrom store reads on hot path", async () => {
97
+ const readAllowFromStore = vi.fn(async () => [] as string[]);
98
+ sendMessageMatrixMock.mockClear();
99
+
100
+ const { handler } = createMatrixHandlerTestHarness({
101
+ readAllowFromStore,
102
+ dmPolicy: "pairing",
103
+ buildPairingReply: () => "pairing",
104
+ });
105
+
106
+ await handler(
107
+ "!room:example.org",
108
+ createMatrixTextMessageEvent({
109
+ eventId: "$event1",
110
+ body: "@room hello",
111
+ mentions: { room: true },
112
+ }),
113
+ );
114
+
115
+ await handler(
116
+ "!room:example.org",
117
+ createMatrixTextMessageEvent({
118
+ eventId: "$event2",
119
+ body: "@room hello again",
120
+ mentions: { room: true },
121
+ }),
122
+ );
123
+
124
+ expect(readAllowFromStore).toHaveBeenCalledTimes(1);
125
+ });
126
+
127
+ it("refreshes the account-scoped allowFrom cache after its ttl expires", async () => {
128
+ vi.useFakeTimers();
129
+ vi.setSystemTime(new Date("2026-03-01T10:00:00.000Z"));
130
+ try {
131
+ const readAllowFromStore = vi.fn(async () => [] as string[]);
132
+ const { handler } = createMatrixHandlerTestHarness({
133
+ readAllowFromStore,
134
+ dmPolicy: "pairing",
135
+ buildPairingReply: () => "pairing",
136
+ });
137
+
138
+ const makeEvent = (id: string): MatrixRawEvent =>
139
+ createMatrixTextMessageEvent({
140
+ eventId: id,
141
+ body: "@room hello",
142
+ mentions: { room: true },
143
+ });
144
+
145
+ await handler("!room:example.org", makeEvent("$event1"));
146
+ await handler("!room:example.org", makeEvent("$event2"));
147
+ expect(readAllowFromStore).toHaveBeenCalledTimes(1);
148
+
149
+ await vi.advanceTimersByTimeAsync(30_001);
150
+ await handler("!room:example.org", makeEvent("$event3"));
151
+
152
+ expect(readAllowFromStore).toHaveBeenCalledTimes(2);
153
+ } finally {
154
+ vi.useRealTimers();
155
+ }
156
+ });
157
+
158
+ it("sends pairing reminders for pending requests with cooldown", async () => {
159
+ vi.useFakeTimers();
160
+ vi.setSystemTime(new Date("2026-03-01T10:00:00.000Z"));
161
+ try {
162
+ const readAllowFromStore = vi.fn(async () => [] as string[]);
163
+ sendMessageMatrixMock.mockClear();
164
+
165
+ const { handler } = createMatrixHandlerTestHarness({
166
+ readAllowFromStore,
167
+ dmPolicy: "pairing",
168
+ buildPairingReply: () => "Pairing code: ABCDEFGH",
169
+ isDirectMessage: true,
170
+ getMemberDisplayName: async () => "sender",
171
+ });
172
+
173
+ const makeEvent = (id: string): MatrixRawEvent =>
174
+ createMatrixTextMessageEvent({
175
+ eventId: id,
176
+ body: "hello",
177
+ mentions: { room: true },
178
+ });
179
+
180
+ await handler("!room:example.org", makeEvent("$event1"));
181
+ await handler("!room:example.org", makeEvent("$event2"));
182
+ expect(sendMessageMatrixMock).toHaveBeenCalledTimes(1);
183
+ expect(sendMessageMatrixMock.mock.calls[0]?.[1]).toContain(
184
+ "Pairing request is still pending approval.",
185
+ );
186
+
187
+ await vi.advanceTimersByTimeAsync(5 * 60_000 + 1);
188
+ await handler("!room:example.org", makeEvent("$event3"));
189
+ expect(sendMessageMatrixMock).toHaveBeenCalledTimes(2);
190
+ } finally {
191
+ vi.useRealTimers();
192
+ }
193
+ });
194
+
195
+ it("uses account-scoped pairing store reads and upserts for dm pairing", async () => {
196
+ const readAllowFromStore = vi.fn(async () => [] as string[]);
197
+ const upsertPairingRequest = vi.fn(async () => ({ code: "ABCDEFGH", created: false }));
198
+
199
+ const { handler } = createMatrixHandlerTestHarness({
200
+ readAllowFromStore,
201
+ upsertPairingRequest,
202
+ dmPolicy: "pairing",
203
+ isDirectMessage: true,
204
+ getMemberDisplayName: async () => "sender",
205
+ dropPreStartupMessages: true,
206
+ needsRoomAliasesForConfig: false,
207
+ });
208
+
209
+ await handler(
210
+ "!room:example.org",
211
+ createMatrixTextMessageEvent({
212
+ eventId: "$event1",
213
+ body: "hello",
214
+ mentions: { room: true },
215
+ }),
216
+ );
217
+
218
+ expect(readAllowFromStore).toHaveBeenCalledWith({
219
+ channel: "matrix",
220
+ env: process.env,
221
+ accountId: "ops",
222
+ });
223
+ expect(upsertPairingRequest).toHaveBeenCalledWith({
224
+ channel: "matrix",
225
+ id: "@user:example.org",
226
+ accountId: "ops",
227
+ meta: { name: "sender" },
228
+ });
229
+ });
230
+
231
+ it("passes accountId into route resolution for inbound dm messages", async () => {
232
+ const resolveAgentRoute = vi.fn(() => ({
233
+ agentId: "ops",
234
+ channel: "matrix",
235
+ accountId: "ops",
236
+ sessionKey: "agent:ops:main",
237
+ mainSessionKey: "agent:ops:main",
238
+ matchedBy: "binding.account" as const,
239
+ }));
240
+
241
+ const { handler } = createMatrixHandlerTestHarness({
242
+ resolveAgentRoute,
243
+ isDirectMessage: true,
244
+ getMemberDisplayName: async () => "sender",
245
+ });
246
+
247
+ await handler(
248
+ "!room:example.org",
249
+ createMatrixTextMessageEvent({
250
+ eventId: "$event2",
251
+ body: "hello",
252
+ mentions: { room: true },
253
+ }),
254
+ );
255
+
256
+ expect(resolveAgentRoute).toHaveBeenCalledWith(
257
+ expect.objectContaining({
258
+ channel: "matrix",
259
+ accountId: "ops",
260
+ }),
261
+ );
262
+ });
263
+
264
+ it("does not enqueue delivered text messages into system events", async () => {
265
+ const dispatchReplyFromConfig = vi.fn(async () => ({
266
+ queuedFinal: true,
267
+ counts: { final: 1, block: 0, tool: 0 },
268
+ }));
269
+ const { handler, enqueueSystemEvent } = createMatrixHandlerTestHarness({
270
+ dispatchReplyFromConfig,
271
+ isDirectMessage: true,
272
+ getMemberDisplayName: async () => "sender",
273
+ });
274
+
275
+ await handler(
276
+ "!room:example.org",
277
+ createMatrixTextMessageEvent({
278
+ eventId: "$event-system-preview",
279
+ body: "hello from matrix",
280
+ mentions: { room: true },
281
+ }),
282
+ );
283
+
284
+ expect(dispatchReplyFromConfig).toHaveBeenCalled();
285
+ expect(enqueueSystemEvent).not.toHaveBeenCalled();
286
+ });
287
+
288
+ it("drops room messages from configured Matrix bot accounts when allowBots is off", async () => {
289
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
290
+ isDirectMessage: false,
291
+ configuredBotUserIds: new Set(["@ops:example.org"]),
292
+ roomsConfig: {
293
+ "!room:example.org": { requireMention: false },
294
+ },
295
+ getMemberDisplayName: async () => "ops-bot",
296
+ });
297
+
298
+ await handler(
299
+ "!room:example.org",
300
+ createMatrixTextMessageEvent({
301
+ eventId: "$bot-off",
302
+ sender: "@ops:example.org",
303
+ body: "hello from bot",
304
+ }),
305
+ );
306
+
307
+ expect(recordInboundSession).not.toHaveBeenCalled();
308
+ });
309
+
310
+ it("accepts room messages from configured Matrix bot accounts when allowBots is true", async () => {
311
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
312
+ isDirectMessage: false,
313
+ accountAllowBots: true,
314
+ configuredBotUserIds: new Set(["@ops:example.org"]),
315
+ roomsConfig: {
316
+ "!room:example.org": { requireMention: false },
317
+ },
318
+ getMemberDisplayName: async () => "ops-bot",
319
+ });
320
+
321
+ await handler(
322
+ "!room:example.org",
323
+ createMatrixTextMessageEvent({
324
+ eventId: "$bot-on",
325
+ sender: "@ops:example.org",
326
+ body: "hello from bot",
327
+ }),
328
+ );
329
+
330
+ expect(recordInboundSession).toHaveBeenCalled();
331
+ });
332
+
333
+ it("does not treat unconfigured Matrix users as bots when allowBots is off", async () => {
334
+ const { handler, resolveAgentRoute, recordInboundSession } = createMatrixHandlerTestHarness({
335
+ isDirectMessage: false,
336
+ configuredBotUserIds: new Set(["@ops:example.org"]),
337
+ roomsConfig: {
338
+ "!room:example.org": { requireMention: false },
339
+ },
340
+ getMemberDisplayName: async () => "human",
341
+ });
342
+
343
+ await handler(
344
+ "!room:example.org",
345
+ createMatrixTextMessageEvent({
346
+ eventId: "$non-bot",
347
+ sender: "@alice:example.org",
348
+ body: "hello from human",
349
+ }),
350
+ );
351
+
352
+ expect(resolveAgentRoute).toHaveBeenCalled();
353
+ expect(recordInboundSession).toHaveBeenCalled();
354
+ });
355
+
356
+ it('drops configured Matrix bot room messages without a mention when allowBots="mentions"', async () => {
357
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
358
+ isDirectMessage: false,
359
+ accountAllowBots: "mentions",
360
+ configuredBotUserIds: new Set(["@ops:example.org"]),
361
+ roomsConfig: {
362
+ "!room:example.org": { requireMention: false },
363
+ },
364
+ mentionRegexes: [/@bot/i],
365
+ getMemberDisplayName: async () => "ops-bot",
366
+ });
367
+
368
+ await handler(
369
+ "!room:example.org",
370
+ createMatrixTextMessageEvent({
371
+ eventId: "$bot-mentions-off",
372
+ sender: "@ops:example.org",
373
+ body: "hello from bot",
374
+ }),
375
+ );
376
+
377
+ expect(recordInboundSession).not.toHaveBeenCalled();
378
+ });
379
+
380
+ it('accepts configured Matrix bot room messages with a mention when allowBots="mentions"', async () => {
381
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
382
+ isDirectMessage: false,
383
+ accountAllowBots: "mentions",
384
+ configuredBotUserIds: new Set(["@ops:example.org"]),
385
+ roomsConfig: {
386
+ "!room:example.org": { requireMention: false },
387
+ },
388
+ mentionRegexes: [/@bot/i],
389
+ getMemberDisplayName: async () => "ops-bot",
390
+ });
391
+
392
+ await handler(
393
+ "!room:example.org",
394
+ createMatrixTextMessageEvent({
395
+ eventId: "$bot-mentions-on",
396
+ sender: "@ops:example.org",
397
+ body: "hello @bot",
398
+ mentions: { user_ids: ["@bot:example.org"] },
399
+ }),
400
+ );
401
+
402
+ expect(recordInboundSession).toHaveBeenCalled();
403
+ });
404
+
405
+ it('accepts configured Matrix bot DMs without a mention when allowBots="mentions"', async () => {
406
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
407
+ isDirectMessage: true,
408
+ accountAllowBots: "mentions",
409
+ configuredBotUserIds: new Set(["@ops:example.org"]),
410
+ getMemberDisplayName: async () => "ops-bot",
411
+ });
412
+
413
+ await handler(
414
+ "!dm:example.org",
415
+ createMatrixTextMessageEvent({
416
+ eventId: "$bot-dm-mentions",
417
+ sender: "@ops:example.org",
418
+ body: "hello from dm bot",
419
+ }),
420
+ );
421
+
422
+ expect(recordInboundSession).toHaveBeenCalled();
423
+ });
424
+
425
+ it("lets room-level allowBots override a permissive account default", async () => {
426
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
427
+ isDirectMessage: false,
428
+ accountAllowBots: true,
429
+ configuredBotUserIds: new Set(["@ops:example.org"]),
430
+ roomsConfig: {
431
+ "!room:example.org": { requireMention: false, allowBots: false },
432
+ },
433
+ getMemberDisplayName: async () => "ops-bot",
434
+ });
435
+
436
+ await handler(
437
+ "!room:example.org",
438
+ createMatrixTextMessageEvent({
439
+ eventId: "$bot-room-override",
440
+ sender: "@ops:example.org",
441
+ body: "hello from bot",
442
+ }),
443
+ );
444
+
445
+ expect(recordInboundSession).not.toHaveBeenCalled();
446
+ });
447
+
448
+ it("processes room messages mentioned via displayName in formatted_body", async () => {
449
+ const recordInboundSession = vi.fn(async () => {});
450
+ const { handler } = createMatrixHandlerTestHarness({
451
+ isDirectMessage: false,
452
+ getMemberDisplayName: async () => "Tom Servo",
453
+ recordInboundSession,
454
+ });
455
+
456
+ await handler(
457
+ "!room:example.org",
458
+ createMatrixRoomMessageEvent({
459
+ eventId: "$display-name-mention",
460
+ content: {
461
+ msgtype: "m.text",
462
+ body: "Tom Servo: hello",
463
+ formatted_body: '<a href="https://matrix.to/#/@bot:example.org">Tom Servo</a>: hello',
464
+ },
465
+ }),
466
+ );
467
+
468
+ expect(recordInboundSession).toHaveBeenCalled();
469
+ });
470
+
471
+ it("does not fetch self displayName for plain-text room mentions", async () => {
472
+ const getMemberDisplayName = vi.fn(async () => "Tom Servo");
473
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
474
+ isDirectMessage: false,
475
+ mentionRegexes: [/\btom servo\b/i],
476
+ getMemberDisplayName,
477
+ });
478
+
479
+ await handler(
480
+ "!room:example.org",
481
+ createMatrixTextMessageEvent({
482
+ eventId: "$plain-text-mention",
483
+ body: "Tom Servo: hello",
484
+ }),
485
+ );
486
+
487
+ expect(recordInboundSession).toHaveBeenCalled();
488
+ expect(getMemberDisplayName).not.toHaveBeenCalledWith("!room:example.org", "@bot:example.org");
489
+ });
490
+
491
+ it("drops forged metadata-only mentions before session recording", async () => {
492
+ const { handler, recordInboundSession, resolveAgentRoute } = createMatrixHandlerTestHarness({
493
+ isDirectMessage: false,
494
+ mentionRegexes: [/@bot/i],
495
+ getMemberDisplayName: async () => "sender",
496
+ });
497
+
498
+ await handler(
499
+ "!room:example.org",
500
+ createMatrixTextMessageEvent({
501
+ eventId: "$spoofed-mention",
502
+ body: "hello there",
503
+ mentions: { user_ids: ["@bot:example.org"] },
504
+ }),
505
+ );
506
+
507
+ expect(recordInboundSession).not.toHaveBeenCalled();
508
+ expect(resolveAgentRoute).toHaveBeenCalledTimes(1);
509
+ });
510
+
511
+ it("skips media downloads for unmentioned group media messages", async () => {
512
+ const downloadContent = vi.fn(async () => Buffer.from("image"));
513
+ const getMemberDisplayName = vi.fn(async () => "sender");
514
+ const getRoomInfo = vi.fn(async () => ({ altAliases: [] }));
515
+ const { handler } = createMatrixHandlerTestHarness({
516
+ client: {
517
+ downloadContent,
518
+ },
519
+ isDirectMessage: false,
520
+ mentionRegexes: [/@bot/i],
521
+ getMemberDisplayName,
522
+ getRoomInfo,
523
+ });
524
+
525
+ await handler("!room:example.org", {
526
+ type: EventType.RoomMessage,
527
+ sender: "@user:example.org",
528
+ event_id: "$media1",
529
+ origin_server_ts: Date.now(),
530
+ content: {
531
+ msgtype: "m.image",
532
+ body: "",
533
+ url: "mxc://example.org/media",
534
+ info: {
535
+ mimetype: "image/png",
536
+ size: 5,
537
+ },
538
+ },
539
+ } as MatrixRawEvent);
540
+
541
+ expect(downloadContent).not.toHaveBeenCalled();
542
+ expect(getMemberDisplayName).not.toHaveBeenCalled();
543
+ expect(getRoomInfo).not.toHaveBeenCalled();
544
+ });
545
+
546
+ it("skips poll snapshot fetches for unmentioned group poll responses", async () => {
547
+ const getEvent = vi.fn(async () => ({
548
+ event_id: "$poll",
549
+ sender: "@user:example.org",
550
+ type: "m.poll.start",
551
+ origin_server_ts: Date.now(),
552
+ content: {
553
+ "m.poll.start": {
554
+ question: { "m.text": "Lunch?" },
555
+ kind: "m.poll.disclosed",
556
+ max_selections: 1,
557
+ answers: [{ id: "a1", "m.text": "Pizza" }],
558
+ },
559
+ },
560
+ }));
561
+ const getRelations = vi.fn(async () => ({
562
+ events: [],
563
+ nextBatch: null,
564
+ prevBatch: null,
565
+ }));
566
+ const getMemberDisplayName = vi.fn(async () => "sender");
567
+ const getRoomInfo = vi.fn(async () => ({ altAliases: [] }));
568
+ const { handler } = createMatrixHandlerTestHarness({
569
+ client: {
570
+ getEvent,
571
+ getRelations,
572
+ },
573
+ isDirectMessage: false,
574
+ mentionRegexes: [/@bot/i],
575
+ getMemberDisplayName,
576
+ getRoomInfo,
577
+ });
578
+
579
+ await handler("!room:example.org", {
580
+ type: "m.poll.response",
581
+ sender: "@user:example.org",
582
+ event_id: "$poll-response-1",
583
+ origin_server_ts: Date.now(),
584
+ content: {
585
+ "m.poll.response": {
586
+ answers: ["a1"],
587
+ },
588
+ "m.relates_to": {
589
+ rel_type: "m.reference",
590
+ event_id: "$poll",
591
+ },
592
+ },
593
+ } as MatrixRawEvent);
594
+
595
+ expect(getEvent).not.toHaveBeenCalled();
596
+ expect(getRelations).not.toHaveBeenCalled();
597
+ expect(getMemberDisplayName).not.toHaveBeenCalled();
598
+ expect(getRoomInfo).not.toHaveBeenCalled();
599
+ });
600
+
601
+ it("records thread starter context for inbound thread replies", async () => {
602
+ const { handler, finalizeInboundContext, recordInboundSession } =
603
+ createMatrixHandlerTestHarness({
604
+ client: {
605
+ getEvent: async () =>
606
+ createMatrixTextMessageEvent({
607
+ eventId: "$root",
608
+ sender: "@alice:example.org",
609
+ body: "Root topic",
610
+ }),
611
+ },
612
+ isDirectMessage: false,
613
+ getMemberDisplayName: async (_roomId, userId) =>
614
+ userId === "@alice:example.org" ? "Alice" : "sender",
615
+ });
616
+
617
+ await handler(
618
+ "!room:example.org",
619
+ createMatrixTextMessageEvent({
620
+ eventId: "$reply1",
621
+ body: "@room follow up",
622
+ relatesTo: {
623
+ rel_type: "m.thread",
624
+ event_id: "$root",
625
+ "m.in_reply_to": { event_id: "$root" },
626
+ },
627
+ mentions: { room: true },
628
+ }),
629
+ );
630
+
631
+ expect(finalizeInboundContext).toHaveBeenCalledWith(
632
+ expect.objectContaining({
633
+ MessageThreadId: "$root",
634
+ ThreadStarterBody: "Matrix thread root $root from Alice:\nRoot topic",
635
+ }),
636
+ );
637
+ expect(recordInboundSession).toHaveBeenCalledWith(
638
+ expect.objectContaining({
639
+ sessionKey: "agent:ops:main:thread:$root",
640
+ }),
641
+ );
642
+ });
643
+
644
+ it("keeps threaded DMs flat when dm threadReplies is off", async () => {
645
+ const { handler, finalizeInboundContext, recordInboundSession } =
646
+ createMatrixHandlerTestHarness({
647
+ threadReplies: "always",
648
+ dmThreadReplies: "off",
649
+ isDirectMessage: true,
650
+ client: {
651
+ getEvent: async (_roomId, eventId) =>
652
+ eventId === "$root"
653
+ ? createMatrixTextMessageEvent({
654
+ eventId: "$root",
655
+ sender: "@alice:example.org",
656
+ body: "Root topic",
657
+ })
658
+ : ({ sender: "@bot:example.org" } as never),
659
+ },
660
+ getMemberDisplayName: async (_roomId, userId) =>
661
+ userId === "@alice:example.org" ? "Alice" : "sender",
662
+ });
663
+
664
+ await handler(
665
+ "!dm:example.org",
666
+ createMatrixTextMessageEvent({
667
+ eventId: "$reply1",
668
+ body: "follow up",
669
+ relatesTo: {
670
+ rel_type: "m.thread",
671
+ event_id: "$root",
672
+ "m.in_reply_to": { event_id: "$root" },
673
+ },
674
+ }),
675
+ );
676
+
677
+ expect(finalizeInboundContext).toHaveBeenCalledWith(
678
+ expect.objectContaining({
679
+ MessageThreadId: undefined,
680
+ ReplyToId: "$root",
681
+ ThreadStarterBody: "Matrix thread root $root from Alice:\nRoot topic",
682
+ }),
683
+ );
684
+ expect(recordInboundSession).toHaveBeenCalledWith(
685
+ expect.objectContaining({
686
+ sessionKey: "agent:ops:main",
687
+ }),
688
+ );
689
+ });
690
+
691
+ it("posts a one-time notice when another Matrix DM room already owns the shared DM session", async () => {
692
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-shared-notice-"));
693
+ const storePath = path.join(tempDir, "sessions.json");
694
+ const sendNotice = vi.fn(async () => "$notice");
695
+
696
+ try {
697
+ await recordSessionMetaFromInbound({
698
+ storePath,
699
+ sessionKey: "agent:ops:main",
700
+ ctx: {
701
+ SessionKey: "agent:ops:main",
702
+ AccountId: "ops",
703
+ ChatType: "direct",
704
+ Provider: "matrix",
705
+ Surface: "matrix",
706
+ From: "matrix:@user:example.org",
707
+ To: "room:!other:example.org",
708
+ NativeChannelId: "!other:example.org",
709
+ OriginatingChannel: "matrix",
710
+ OriginatingTo: "room:!other:example.org",
711
+ },
712
+ });
713
+
714
+ const { handler } = createMatrixHandlerTestHarness({
715
+ isDirectMessage: true,
716
+ resolveStorePath: () => storePath,
717
+ client: {
718
+ sendMessage: sendNotice,
719
+ },
720
+ });
721
+
722
+ await handler(
723
+ "!dm:example.org",
724
+ createMatrixTextMessageEvent({
725
+ eventId: "$dm1",
726
+ body: "follow up",
727
+ }),
728
+ );
729
+
730
+ expect(sendNotice).toHaveBeenCalledWith(
731
+ "!dm:example.org",
732
+ expect.objectContaining({
733
+ msgtype: "m.notice",
734
+ body: expect.stringContaining("channels.lobi.dm.sessionScope"),
735
+ }),
736
+ );
737
+
738
+ await handler(
739
+ "!dm:example.org",
740
+ createMatrixTextMessageEvent({
741
+ eventId: "$dm2",
742
+ body: "again",
743
+ }),
744
+ );
745
+
746
+ expect(sendNotice).toHaveBeenCalledTimes(1);
747
+ } finally {
748
+ fs.rmSync(tempDir, { recursive: true, force: true });
749
+ }
750
+ });
751
+
752
+ it("checks flat DM collision notices against the current DM session key", async () => {
753
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-flat-notice-"));
754
+ const storePath = path.join(tempDir, "sessions.json");
755
+ const sendNotice = vi.fn(async () => "$notice");
756
+
757
+ try {
758
+ await recordSessionMetaFromInbound({
759
+ storePath,
760
+ sessionKey: "agent:ops:matrix:direct:@user:example.org",
761
+ ctx: {
762
+ SessionKey: "agent:ops:matrix:direct:@user:example.org",
763
+ AccountId: "ops",
764
+ ChatType: "direct",
765
+ Provider: "matrix",
766
+ Surface: "matrix",
767
+ From: "matrix:@user:example.org",
768
+ To: "room:!other:example.org",
769
+ NativeChannelId: "!other:example.org",
770
+ OriginatingChannel: "matrix",
771
+ OriginatingTo: "room:!other:example.org",
772
+ },
773
+ });
774
+
775
+ const { handler } = createMatrixHandlerTestHarness({
776
+ isDirectMessage: true,
777
+ resolveStorePath: () => storePath,
778
+ resolveAgentRoute: () => ({
779
+ agentId: "ops",
780
+ channel: "matrix",
781
+ accountId: "ops",
782
+ sessionKey: "agent:ops:matrix:direct:@user:example.org",
783
+ mainSessionKey: "agent:ops:main",
784
+ matchedBy: "binding.account" as const,
785
+ }),
786
+ client: {
787
+ sendMessage: sendNotice,
788
+ },
789
+ });
790
+
791
+ await handler(
792
+ "!dm:example.org",
793
+ createMatrixTextMessageEvent({
794
+ eventId: "$dm-flat-1",
795
+ body: "follow up",
796
+ }),
797
+ );
798
+
799
+ expect(sendNotice).toHaveBeenCalledWith(
800
+ "!dm:example.org",
801
+ expect.objectContaining({
802
+ msgtype: "m.notice",
803
+ body: expect.stringContaining("channels.lobi.dm.sessionScope"),
804
+ }),
805
+ );
806
+ } finally {
807
+ fs.rmSync(tempDir, { recursive: true, force: true });
808
+ }
809
+ });
810
+
811
+ it("checks threaded DM collision notices against the parent DM session", async () => {
812
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-thread-notice-"));
813
+ const storePath = path.join(tempDir, "sessions.json");
814
+ const sendNotice = vi.fn(async () => "$notice");
815
+
816
+ try {
817
+ await recordSessionMetaFromInbound({
818
+ storePath,
819
+ sessionKey: "agent:ops:main",
820
+ ctx: {
821
+ SessionKey: "agent:ops:main",
822
+ AccountId: "ops",
823
+ ChatType: "direct",
824
+ Provider: "matrix",
825
+ Surface: "matrix",
826
+ From: "matrix:@user:example.org",
827
+ To: "room:!other:example.org",
828
+ NativeChannelId: "!other:example.org",
829
+ OriginatingChannel: "matrix",
830
+ OriginatingTo: "room:!other:example.org",
831
+ },
832
+ });
833
+
834
+ const { handler } = createMatrixHandlerTestHarness({
835
+ isDirectMessage: true,
836
+ threadReplies: "always",
837
+ resolveStorePath: () => storePath,
838
+ client: {
839
+ sendMessage: sendNotice,
840
+ getEvent: async (_roomId, eventId) =>
841
+ eventId === "$root"
842
+ ? createMatrixTextMessageEvent({
843
+ eventId: "$root",
844
+ sender: "@alice:example.org",
845
+ body: "Root topic",
846
+ })
847
+ : ({ sender: "@bot:example.org" } as never),
848
+ },
849
+ getMemberDisplayName: async (_roomId, userId) =>
850
+ userId === "@alice:example.org" ? "Alice" : "sender",
851
+ });
852
+
853
+ await handler(
854
+ "!dm:example.org",
855
+ createMatrixTextMessageEvent({
856
+ eventId: "$reply1",
857
+ body: "follow up",
858
+ relatesTo: {
859
+ rel_type: "m.thread",
860
+ event_id: "$root",
861
+ "m.in_reply_to": { event_id: "$root" },
862
+ },
863
+ }),
864
+ );
865
+
866
+ expect(sendNotice).toHaveBeenCalledWith(
867
+ "!dm:example.org",
868
+ expect.objectContaining({
869
+ msgtype: "m.notice",
870
+ body: expect.stringContaining("channels.lobi.dm.sessionScope"),
871
+ }),
872
+ );
873
+ } finally {
874
+ fs.rmSync(tempDir, { recursive: true, force: true });
875
+ }
876
+ });
877
+
878
+ it("keeps the shared-session notice after user-target outbound metadata overwrites latest room fields", async () => {
879
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-shared-notice-stable-"));
880
+ const storePath = path.join(tempDir, "sessions.json");
881
+ const sendNotice = vi.fn(async () => "$notice");
882
+
883
+ try {
884
+ await recordSessionMetaFromInbound({
885
+ storePath,
886
+ sessionKey: "agent:ops:main",
887
+ ctx: {
888
+ SessionKey: "agent:ops:main",
889
+ AccountId: "ops",
890
+ ChatType: "direct",
891
+ Provider: "matrix",
892
+ Surface: "matrix",
893
+ From: "matrix:@user:example.org",
894
+ To: "room:!other:example.org",
895
+ NativeChannelId: "!other:example.org",
896
+ OriginatingChannel: "matrix",
897
+ OriginatingTo: "room:!other:example.org",
898
+ },
899
+ });
900
+ await recordSessionMetaFromInbound({
901
+ storePath,
902
+ sessionKey: "agent:ops:main",
903
+ ctx: {
904
+ SessionKey: "agent:ops:main",
905
+ AccountId: "ops",
906
+ ChatType: "direct",
907
+ Provider: "matrix",
908
+ Surface: "matrix",
909
+ From: "matrix:@other:example.org",
910
+ To: "room:@other:example.org",
911
+ NativeDirectUserId: "@user:example.org",
912
+ OriginatingChannel: "matrix",
913
+ OriginatingTo: "room:@other:example.org",
914
+ },
915
+ });
916
+
917
+ const { handler } = createMatrixHandlerTestHarness({
918
+ isDirectMessage: true,
919
+ resolveStorePath: () => storePath,
920
+ client: {
921
+ sendMessage: sendNotice,
922
+ },
923
+ });
924
+
925
+ await handler(
926
+ "!dm:example.org",
927
+ createMatrixTextMessageEvent({
928
+ eventId: "$dm1",
929
+ body: "follow up",
930
+ }),
931
+ );
932
+
933
+ expect(sendNotice).toHaveBeenCalledWith(
934
+ "!dm:example.org",
935
+ expect.objectContaining({
936
+ msgtype: "m.notice",
937
+ body: expect.stringContaining("channels.lobi.dm.sessionScope"),
938
+ }),
939
+ );
940
+ } finally {
941
+ fs.rmSync(tempDir, { recursive: true, force: true });
942
+ }
943
+ });
944
+
945
+ it("skips the shared-session notice when the prior Matrix session metadata is not a DM", async () => {
946
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-shared-notice-room-"));
947
+ const storePath = path.join(tempDir, "sessions.json");
948
+ const sendNotice = vi.fn(async () => "$notice");
949
+
950
+ try {
951
+ await recordSessionMetaFromInbound({
952
+ storePath,
953
+ sessionKey: "agent:ops:main",
954
+ ctx: {
955
+ SessionKey: "agent:ops:main",
956
+ AccountId: "ops",
957
+ ChatType: "group",
958
+ Provider: "matrix",
959
+ Surface: "matrix",
960
+ From: "matrix:channel:!group:example.org",
961
+ To: "room:!group:example.org",
962
+ NativeChannelId: "!group:example.org",
963
+ OriginatingChannel: "matrix",
964
+ OriginatingTo: "room:!group:example.org",
965
+ },
966
+ });
967
+
968
+ const { handler } = createMatrixHandlerTestHarness({
969
+ isDirectMessage: true,
970
+ resolveStorePath: () => storePath,
971
+ client: {
972
+ sendMessage: sendNotice,
973
+ },
974
+ });
975
+
976
+ await handler(
977
+ "!dm:example.org",
978
+ createMatrixTextMessageEvent({
979
+ eventId: "$dm1",
980
+ body: "follow up",
981
+ }),
982
+ );
983
+
984
+ expect(sendNotice).not.toHaveBeenCalled();
985
+ } finally {
986
+ fs.rmSync(tempDir, { recursive: true, force: true });
987
+ }
988
+ });
989
+
990
+ it("skips the shared-session notice when Matrix DMs are isolated per room", async () => {
991
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-room-scope-"));
992
+ const storePath = path.join(tempDir, "sessions.json");
993
+ fs.writeFileSync(
994
+ storePath,
995
+ JSON.stringify({
996
+ "agent:ops:main": {
997
+ sessionId: "sess-main",
998
+ updatedAt: Date.now(),
999
+ deliveryContext: {
1000
+ channel: "matrix",
1001
+ to: "room:!other:example.org",
1002
+ accountId: "ops",
1003
+ },
1004
+ },
1005
+ }),
1006
+ "utf8",
1007
+ );
1008
+ const sendNotice = vi.fn(async () => "$notice");
1009
+
1010
+ try {
1011
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
1012
+ isDirectMessage: true,
1013
+ dmSessionScope: "per-room",
1014
+ resolveStorePath: () => storePath,
1015
+ client: {
1016
+ sendMessage: sendNotice,
1017
+ },
1018
+ });
1019
+
1020
+ await handler(
1021
+ "!dm:example.org",
1022
+ createMatrixTextMessageEvent({
1023
+ eventId: "$dm1",
1024
+ body: "follow up",
1025
+ }),
1026
+ );
1027
+
1028
+ expect(sendNotice).not.toHaveBeenCalled();
1029
+ expect(recordInboundSession).toHaveBeenCalledWith(
1030
+ expect.objectContaining({
1031
+ sessionKey: "agent:ops:matrix:channel:!dm:example.org",
1032
+ }),
1033
+ );
1034
+ } finally {
1035
+ fs.rmSync(tempDir, { recursive: true, force: true });
1036
+ }
1037
+ });
1038
+
1039
+ it("skips the shared-session notice when a Matrix DM is explicitly bound", async () => {
1040
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-dm-bound-notice-"));
1041
+ const storePath = path.join(tempDir, "sessions.json");
1042
+ fs.writeFileSync(
1043
+ storePath,
1044
+ JSON.stringify({
1045
+ "agent:bound:session-1": {
1046
+ sessionId: "sess-bound",
1047
+ updatedAt: Date.now(),
1048
+ deliveryContext: {
1049
+ channel: "matrix",
1050
+ to: "room:!other:example.org",
1051
+ accountId: "ops",
1052
+ },
1053
+ },
1054
+ }),
1055
+ "utf8",
1056
+ );
1057
+ const sendNotice = vi.fn(async () => "$notice");
1058
+ const touch = vi.fn();
1059
+ registerSessionBindingAdapter({
1060
+ channel: "matrix",
1061
+ accountId: "ops",
1062
+ listBySession: () => [],
1063
+ resolveByConversation: (ref) =>
1064
+ ref.conversationId === "!dm:example.org"
1065
+ ? {
1066
+ bindingId: "ops:!dm:example.org",
1067
+ targetSessionKey: "agent:bound:session-1",
1068
+ targetKind: "session",
1069
+ conversation: {
1070
+ channel: "matrix",
1071
+ accountId: "ops",
1072
+ conversationId: "!dm:example.org",
1073
+ },
1074
+ status: "active",
1075
+ boundAt: Date.now(),
1076
+ metadata: {
1077
+ boundBy: "user-1",
1078
+ },
1079
+ }
1080
+ : null,
1081
+ touch,
1082
+ });
1083
+
1084
+ try {
1085
+ const { handler } = createMatrixHandlerTestHarness({
1086
+ isDirectMessage: true,
1087
+ resolveStorePath: () => storePath,
1088
+ client: {
1089
+ sendMessage: sendNotice,
1090
+ },
1091
+ });
1092
+
1093
+ await handler(
1094
+ "!dm:example.org",
1095
+ createMatrixTextMessageEvent({
1096
+ eventId: "$dm-bound-1",
1097
+ body: "follow up",
1098
+ }),
1099
+ );
1100
+
1101
+ expect(sendNotice).not.toHaveBeenCalled();
1102
+ expect(touch).toHaveBeenCalledOnce();
1103
+ } finally {
1104
+ fs.rmSync(tempDir, { recursive: true, force: true });
1105
+ }
1106
+ });
1107
+
1108
+ it("uses stable room ids instead of room-declared aliases in group context", async () => {
1109
+ const { handler, finalizeInboundContext } = createMatrixHandlerTestHarness({
1110
+ isDirectMessage: false,
1111
+ getRoomInfo: async () => ({
1112
+ name: "Ops Room",
1113
+ canonicalAlias: "#spoofed:example.org",
1114
+ altAliases: ["#alt:example.org"],
1115
+ }),
1116
+ getMemberDisplayName: async () => "sender",
1117
+ dispatchReplyFromConfig: async () => ({
1118
+ queuedFinal: false,
1119
+ counts: { final: 0, block: 0, tool: 0 },
1120
+ }),
1121
+ });
1122
+
1123
+ await handler(
1124
+ "!room:example.org",
1125
+ createMatrixTextMessageEvent({
1126
+ eventId: "$group1",
1127
+ body: "@room hello",
1128
+ mentions: { room: true },
1129
+ }),
1130
+ );
1131
+
1132
+ const finalized = vi.mocked(finalizeInboundContext).mock.calls.at(-1)?.[0];
1133
+ expect(finalized).toEqual(
1134
+ expect.objectContaining({
1135
+ GroupSubject: "Ops Room",
1136
+ GroupId: "!room:example.org",
1137
+ }),
1138
+ );
1139
+ expect(finalized).not.toHaveProperty("GroupChannel");
1140
+ });
1141
+
1142
+ it("routes bound Matrix threads to the target session key", async () => {
1143
+ const touch = vi.fn();
1144
+ registerSessionBindingAdapter({
1145
+ channel: "matrix",
1146
+ accountId: "ops",
1147
+ listBySession: () => [],
1148
+ resolveByConversation: (ref) =>
1149
+ ref.conversationId === "$root"
1150
+ ? {
1151
+ bindingId: "ops:!room:example:$root",
1152
+ targetSessionKey: "agent:bound:session-1",
1153
+ targetKind: "session",
1154
+ conversation: {
1155
+ channel: "matrix",
1156
+ accountId: "ops",
1157
+ conversationId: "$root",
1158
+ parentConversationId: "!room:example",
1159
+ },
1160
+ status: "active",
1161
+ boundAt: Date.now(),
1162
+ metadata: {
1163
+ boundBy: "user-1",
1164
+ },
1165
+ }
1166
+ : null,
1167
+ touch,
1168
+ });
1169
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
1170
+ client: {
1171
+ getEvent: async () =>
1172
+ createMatrixTextMessageEvent({
1173
+ eventId: "$root",
1174
+ sender: "@alice:example.org",
1175
+ body: "Root topic",
1176
+ }),
1177
+ },
1178
+ isDirectMessage: false,
1179
+ finalizeInboundContext: (ctx: unknown) => ctx,
1180
+ getMemberDisplayName: async () => "sender",
1181
+ });
1182
+
1183
+ await handler(
1184
+ "!room:example",
1185
+ createMatrixTextMessageEvent({
1186
+ eventId: "$reply1",
1187
+ body: "@room follow up",
1188
+ relatesTo: {
1189
+ rel_type: "m.thread",
1190
+ event_id: "$root",
1191
+ "m.in_reply_to": { event_id: "$root" },
1192
+ },
1193
+ mentions: { room: true },
1194
+ }),
1195
+ );
1196
+
1197
+ expect(recordInboundSession).toHaveBeenCalledWith(
1198
+ expect.objectContaining({
1199
+ sessionKey: "agent:bound:session-1",
1200
+ }),
1201
+ );
1202
+ expect(touch).toHaveBeenCalledTimes(1);
1203
+ });
1204
+
1205
+ it("does not refresh bound Matrix thread bindings for room messages dropped before routing", async () => {
1206
+ const touch = vi.fn();
1207
+ registerSessionBindingAdapter({
1208
+ channel: "matrix",
1209
+ accountId: "ops",
1210
+ listBySession: () => [],
1211
+ resolveByConversation: (ref) =>
1212
+ ref.conversationId === "$root"
1213
+ ? {
1214
+ bindingId: "ops:!room:example:$root",
1215
+ targetSessionKey: "agent:bound:session-1",
1216
+ targetKind: "session",
1217
+ conversation: {
1218
+ channel: "matrix",
1219
+ accountId: "ops",
1220
+ conversationId: "$root",
1221
+ parentConversationId: "!room:example",
1222
+ },
1223
+ status: "active",
1224
+ boundAt: Date.now(),
1225
+ metadata: {
1226
+ boundBy: "user-1",
1227
+ },
1228
+ }
1229
+ : null,
1230
+ touch,
1231
+ });
1232
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
1233
+ client: {
1234
+ getEvent: async () =>
1235
+ createMatrixTextMessageEvent({
1236
+ eventId: "$root",
1237
+ sender: "@alice:example.org",
1238
+ body: "Root topic",
1239
+ }),
1240
+ },
1241
+ isDirectMessage: false,
1242
+ getMemberDisplayName: async () => "sender",
1243
+ });
1244
+
1245
+ await handler(
1246
+ "!room:example",
1247
+ createMatrixTextMessageEvent({
1248
+ eventId: "$reply-no-mention",
1249
+ body: "follow up without mention",
1250
+ relatesTo: {
1251
+ rel_type: "m.thread",
1252
+ event_id: "$root",
1253
+ "m.in_reply_to": { event_id: "$root" },
1254
+ },
1255
+ }),
1256
+ );
1257
+
1258
+ expect(recordInboundSession).not.toHaveBeenCalled();
1259
+ expect(touch).not.toHaveBeenCalled();
1260
+ });
1261
+
1262
+ it("does not enqueue system events for delivered text replies", async () => {
1263
+ const enqueueSystemEvent = vi.fn();
1264
+
1265
+ const handler = createMatrixRoomMessageHandler({
1266
+ client: {
1267
+ getUserId: async () => "@bot:example.org",
1268
+ } as never,
1269
+ core: {
1270
+ channel: {
1271
+ pairing: {
1272
+ readAllowFromStore: async () => [] as string[],
1273
+ upsertPairingRequest: async () => ({ code: "ABCDEFGH", created: false }),
1274
+ buildPairingReply: () => "pairing",
1275
+ },
1276
+ commands: {
1277
+ shouldHandleTextCommands: () => false,
1278
+ },
1279
+ text: {
1280
+ hasControlCommand: () => false,
1281
+ resolveMarkdownTableMode: () => "preserve",
1282
+ },
1283
+ routing: {
1284
+ resolveAgentRoute: () => ({
1285
+ agentId: "ops",
1286
+ channel: "matrix",
1287
+ accountId: "ops",
1288
+ sessionKey: "agent:ops:main",
1289
+ mainSessionKey: "agent:ops:main",
1290
+ matchedBy: "binding.account",
1291
+ }),
1292
+ },
1293
+ mentions: {
1294
+ buildMentionRegexes: () => [],
1295
+ },
1296
+ session: {
1297
+ resolveStorePath: () => "/tmp/session-store",
1298
+ readSessionUpdatedAt: () => undefined,
1299
+ recordInboundSession: vi.fn(async () => {}),
1300
+ },
1301
+ reply: {
1302
+ resolveEnvelopeFormatOptions: () => ({}),
1303
+ formatAgentEnvelope: ({ body }: { body: string }) => body,
1304
+ finalizeInboundContext: (ctx: unknown) => ctx,
1305
+ createReplyDispatcherWithTyping: () => ({
1306
+ dispatcher: {},
1307
+ replyOptions: {},
1308
+ markDispatchIdle: () => {},
1309
+ markRunComplete: () => {},
1310
+ }),
1311
+ resolveHumanDelayConfig: () => undefined,
1312
+ dispatchReplyFromConfig: async () => ({
1313
+ queuedFinal: true,
1314
+ counts: { final: 1, block: 0, tool: 0 },
1315
+ }),
1316
+ withReplyDispatcher: async <T>({
1317
+ dispatcher,
1318
+ run,
1319
+ onSettled,
1320
+ }: {
1321
+ dispatcher: {
1322
+ markComplete?: () => void;
1323
+ waitForIdle?: () => Promise<void>;
1324
+ };
1325
+ run: () => Promise<T>;
1326
+ onSettled?: () => void | Promise<void>;
1327
+ }) => {
1328
+ try {
1329
+ return await run();
1330
+ } finally {
1331
+ dispatcher.markComplete?.();
1332
+ try {
1333
+ await dispatcher.waitForIdle?.();
1334
+ } finally {
1335
+ await onSettled?.();
1336
+ }
1337
+ }
1338
+ },
1339
+ },
1340
+ reactions: {
1341
+ shouldAckReaction: () => false,
1342
+ },
1343
+ },
1344
+ system: {
1345
+ enqueueSystemEvent,
1346
+ },
1347
+ } as never,
1348
+ cfg: {} as never,
1349
+ accountId: "ops",
1350
+ runtime: {
1351
+ error: () => {},
1352
+ } as never,
1353
+ logger: {
1354
+ info: () => {},
1355
+ warn: () => {},
1356
+ } as never,
1357
+ logVerboseMessage: () => {},
1358
+ allowFrom: [],
1359
+ groupPolicy: "open",
1360
+ replyToMode: "off",
1361
+ threadReplies: "inbound",
1362
+ streaming: "off",
1363
+ blockStreamingEnabled: false,
1364
+ dmEnabled: true,
1365
+ dmPolicy: "open",
1366
+ textLimit: 8_000,
1367
+ mediaMaxBytes: 10_000_000,
1368
+ historyLimit: 0,
1369
+ startupMs: 0,
1370
+ startupGraceMs: 0,
1371
+ directTracker: {
1372
+ isDirectMessage: async () => false,
1373
+ },
1374
+ dropPreStartupMessages: true,
1375
+ getRoomInfo: async () => ({ altAliases: [] }),
1376
+ getMemberDisplayName: async () => "sender",
1377
+ needsRoomAliasesForConfig: false,
1378
+ });
1379
+
1380
+ await handler(
1381
+ "!room:example.org",
1382
+ createMatrixTextMessageEvent({
1383
+ eventId: "$message1",
1384
+ sender: "@user:example.org",
1385
+ body: "hello there",
1386
+ mentions: { room: true },
1387
+ }),
1388
+ );
1389
+
1390
+ expect(enqueueSystemEvent).not.toHaveBeenCalled();
1391
+ });
1392
+
1393
+ it("enqueues system events for reactions on bot-authored messages", async () => {
1394
+ const { handler, enqueueSystemEvent, resolveAgentRoute } = createReactionHarness();
1395
+
1396
+ await handler(
1397
+ "!room:example.org",
1398
+ createMatrixReactionEvent({
1399
+ eventId: "$reaction1",
1400
+ targetEventId: "$msg1",
1401
+ key: "👍",
1402
+ }),
1403
+ );
1404
+
1405
+ expect(resolveAgentRoute).toHaveBeenCalledWith(
1406
+ expect.objectContaining({
1407
+ channel: "matrix",
1408
+ accountId: "ops",
1409
+ }),
1410
+ );
1411
+ expect(enqueueSystemEvent).toHaveBeenCalledWith(
1412
+ "Matrix reaction added: 👍 by sender on msg $msg1",
1413
+ {
1414
+ sessionKey: "agent:ops:main",
1415
+ contextKey: "matrix:reaction:add:!room:example.org:$msg1:@user:example.org:👍",
1416
+ },
1417
+ );
1418
+ });
1419
+
1420
+ it("routes reaction notifications for bound thread messages to the bound session", async () => {
1421
+ registerSessionBindingAdapter({
1422
+ channel: "matrix",
1423
+ accountId: "ops",
1424
+ listBySession: () => [],
1425
+ resolveByConversation: (ref) =>
1426
+ ref.conversationId === "$root"
1427
+ ? {
1428
+ bindingId: "ops:!room:example.org:$root",
1429
+ targetSessionKey: "agent:bound:session-1",
1430
+ targetKind: "session",
1431
+ conversation: {
1432
+ channel: "matrix",
1433
+ accountId: "ops",
1434
+ conversationId: "$root",
1435
+ parentConversationId: "!room:example.org",
1436
+ },
1437
+ status: "active",
1438
+ boundAt: Date.now(),
1439
+ metadata: {
1440
+ boundBy: "user-1",
1441
+ },
1442
+ }
1443
+ : null,
1444
+ touch: vi.fn(),
1445
+ });
1446
+
1447
+ const { handler, enqueueSystemEvent } = createMatrixHandlerTestHarness({
1448
+ client: {
1449
+ getEvent: async () =>
1450
+ createMatrixTextMessageEvent({
1451
+ eventId: "$reply1",
1452
+ sender: "@bot:example.org",
1453
+ body: "follow up",
1454
+ relatesTo: {
1455
+ rel_type: "m.thread",
1456
+ event_id: "$root",
1457
+ "m.in_reply_to": { event_id: "$root" },
1458
+ },
1459
+ }),
1460
+ },
1461
+ isDirectMessage: false,
1462
+ });
1463
+
1464
+ await handler(
1465
+ "!room:example.org",
1466
+ createMatrixReactionEvent({
1467
+ eventId: "$reaction-thread",
1468
+ targetEventId: "$reply1",
1469
+ key: "🎯",
1470
+ }),
1471
+ );
1472
+
1473
+ expect(enqueueSystemEvent).toHaveBeenCalledWith(
1474
+ "Matrix reaction added: 🎯 by sender on msg $reply1",
1475
+ {
1476
+ sessionKey: "agent:bound:session-1",
1477
+ contextKey: "matrix:reaction:add:!room:example.org:$reply1:@user:example.org:🎯",
1478
+ },
1479
+ );
1480
+ });
1481
+
1482
+ it("keeps threaded DM reaction notifications on the flat session when dm threadReplies is off", async () => {
1483
+ const { handler, enqueueSystemEvent } = createReactionHarness({
1484
+ cfg: {
1485
+ channels: {
1486
+ matrix: {
1487
+ threadReplies: "always",
1488
+ dm: { threadReplies: "off" },
1489
+ },
1490
+ },
1491
+ },
1492
+ isDirectMessage: true,
1493
+ client: {
1494
+ getEvent: async () =>
1495
+ createMatrixTextMessageEvent({
1496
+ eventId: "$reply1",
1497
+ sender: "@bot:example.org",
1498
+ body: "follow up",
1499
+ relatesTo: {
1500
+ rel_type: "m.thread",
1501
+ event_id: "$root",
1502
+ "m.in_reply_to": { event_id: "$root" },
1503
+ },
1504
+ }),
1505
+ },
1506
+ });
1507
+
1508
+ await handler(
1509
+ "!dm:example.org",
1510
+ createMatrixReactionEvent({
1511
+ eventId: "$reaction-thread",
1512
+ targetEventId: "$reply1",
1513
+ key: "🎯",
1514
+ }),
1515
+ );
1516
+
1517
+ expect(enqueueSystemEvent).toHaveBeenCalledWith(
1518
+ "Matrix reaction added: 🎯 by sender on msg $reply1",
1519
+ {
1520
+ sessionKey: "agent:ops:main",
1521
+ contextKey: "matrix:reaction:add:!dm:example.org:$reply1:@user:example.org:🎯",
1522
+ },
1523
+ );
1524
+ });
1525
+
1526
+ it("routes thread-root reaction notifications to the thread session when threadReplies is always", async () => {
1527
+ const { handler, enqueueSystemEvent } = createReactionHarness({
1528
+ cfg: {
1529
+ channels: {
1530
+ matrix: {
1531
+ threadReplies: "always",
1532
+ },
1533
+ },
1534
+ },
1535
+ isDirectMessage: false,
1536
+ client: {
1537
+ getEvent: async () =>
1538
+ createMatrixTextMessageEvent({
1539
+ eventId: "$root",
1540
+ sender: "@bot:example.org",
1541
+ body: "start thread",
1542
+ }),
1543
+ },
1544
+ });
1545
+
1546
+ await handler(
1547
+ "!room:example.org",
1548
+ createMatrixReactionEvent({
1549
+ eventId: "$reaction-root",
1550
+ targetEventId: "$root",
1551
+ key: "🧵",
1552
+ }),
1553
+ );
1554
+
1555
+ expect(enqueueSystemEvent).toHaveBeenCalledWith(
1556
+ "Matrix reaction added: 🧵 by sender on msg $root",
1557
+ {
1558
+ sessionKey: "agent:ops:main:thread:$root",
1559
+ contextKey: "matrix:reaction:add:!room:example.org:$root:@user:example.org:🧵",
1560
+ },
1561
+ );
1562
+ });
1563
+
1564
+ it("ignores reactions that do not target bot-authored messages", async () => {
1565
+ const { handler, enqueueSystemEvent, resolveAgentRoute } = createReactionHarness({
1566
+ targetSender: "@other:example.org",
1567
+ });
1568
+
1569
+ await handler(
1570
+ "!room:example.org",
1571
+ createMatrixReactionEvent({
1572
+ eventId: "$reaction2",
1573
+ targetEventId: "$msg2",
1574
+ key: "👀",
1575
+ }),
1576
+ );
1577
+
1578
+ expect(enqueueSystemEvent).not.toHaveBeenCalled();
1579
+ expect(resolveAgentRoute).not.toHaveBeenCalled();
1580
+ });
1581
+
1582
+ it("does not create pairing requests for unauthorized dm reactions", async () => {
1583
+ const { handler, enqueueSystemEvent, upsertPairingRequest } = createReactionHarness({
1584
+ dmPolicy: "pairing",
1585
+ });
1586
+
1587
+ await handler(
1588
+ "!room:example.org",
1589
+ createMatrixReactionEvent({
1590
+ eventId: "$reaction3",
1591
+ targetEventId: "$msg3",
1592
+ key: "🔥",
1593
+ }),
1594
+ );
1595
+
1596
+ expect(upsertPairingRequest).not.toHaveBeenCalled();
1597
+ expect(enqueueSystemEvent).not.toHaveBeenCalled();
1598
+ });
1599
+
1600
+ it("honors account-scoped reaction notification overrides", async () => {
1601
+ const { handler, enqueueSystemEvent } = createReactionHarness({
1602
+ cfg: {
1603
+ channels: {
1604
+ matrix: {
1605
+ reactionNotifications: "own",
1606
+ accounts: {
1607
+ ops: {
1608
+ reactionNotifications: "off",
1609
+ },
1610
+ },
1611
+ },
1612
+ },
1613
+ },
1614
+ });
1615
+
1616
+ await handler(
1617
+ "!room:example.org",
1618
+ createMatrixReactionEvent({
1619
+ eventId: "$reaction4",
1620
+ targetEventId: "$msg4",
1621
+ key: "✅",
1622
+ }),
1623
+ );
1624
+
1625
+ expect(enqueueSystemEvent).not.toHaveBeenCalled();
1626
+ });
1627
+
1628
+ it("drops pre-startup dm messages on cold start", async () => {
1629
+ const resolveAgentRoute = vi.fn(() => ({
1630
+ agentId: "ops",
1631
+ channel: "matrix",
1632
+ accountId: "ops",
1633
+ sessionKey: "agent:ops:main",
1634
+ mainSessionKey: "agent:ops:main",
1635
+ matchedBy: "binding.account" as const,
1636
+ }));
1637
+ const { handler } = createMatrixHandlerTestHarness({
1638
+ resolveAgentRoute,
1639
+ isDirectMessage: true,
1640
+ startupMs: 1_000,
1641
+ startupGraceMs: 0,
1642
+ dropPreStartupMessages: true,
1643
+ });
1644
+
1645
+ await handler(
1646
+ "!room:example.org",
1647
+ createMatrixTextMessageEvent({
1648
+ eventId: "$old-cold-start",
1649
+ body: "hello",
1650
+ originServerTs: 999,
1651
+ }),
1652
+ );
1653
+
1654
+ expect(resolveAgentRoute).not.toHaveBeenCalled();
1655
+ });
1656
+
1657
+ it("replays pre-startup dm messages when persisted sync state exists", async () => {
1658
+ const resolveAgentRoute = vi.fn(() => ({
1659
+ agentId: "ops",
1660
+ channel: "matrix",
1661
+ accountId: "ops",
1662
+ sessionKey: "agent:ops:main",
1663
+ mainSessionKey: "agent:ops:main",
1664
+ matchedBy: "binding.account" as const,
1665
+ }));
1666
+ const { handler } = createMatrixHandlerTestHarness({
1667
+ resolveAgentRoute,
1668
+ isDirectMessage: true,
1669
+ startupMs: 1_000,
1670
+ startupGraceMs: 0,
1671
+ dropPreStartupMessages: false,
1672
+ });
1673
+
1674
+ await handler(
1675
+ "!room:example.org",
1676
+ createMatrixTextMessageEvent({
1677
+ eventId: "$old-resume",
1678
+ body: "hello",
1679
+ originServerTs: 999,
1680
+ }),
1681
+ );
1682
+
1683
+ expect(resolveAgentRoute).toHaveBeenCalledTimes(1);
1684
+ });
1685
+ });
1686
+
1687
+ describe("matrix monitor handler durable inbound dedupe", () => {
1688
+ it("skips replayed inbound events before session recording", async () => {
1689
+ const inboundDeduper = {
1690
+ claimEvent: vi.fn(() => false),
1691
+ commitEvent: vi.fn(async () => undefined),
1692
+ releaseEvent: vi.fn(),
1693
+ };
1694
+ const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
1695
+ inboundDeduper,
1696
+ dispatchReplyFromConfig: vi.fn(async () => ({
1697
+ queuedFinal: true,
1698
+ counts: { final: 1, block: 0, tool: 0 },
1699
+ })),
1700
+ });
1701
+
1702
+ await handler(
1703
+ "!room:example.org",
1704
+ createMatrixTextMessageEvent({
1705
+ eventId: "$dup",
1706
+ body: "hello",
1707
+ }),
1708
+ );
1709
+
1710
+ expect(inboundDeduper.claimEvent).toHaveBeenCalledWith({
1711
+ roomId: "!room:example.org",
1712
+ eventId: "$dup",
1713
+ });
1714
+ expect(recordInboundSession).not.toHaveBeenCalled();
1715
+ expect(inboundDeduper.commitEvent).not.toHaveBeenCalled();
1716
+ expect(inboundDeduper.releaseEvent).not.toHaveBeenCalled();
1717
+ });
1718
+
1719
+ it("commits inbound events only after queued replies finish delivering", async () => {
1720
+ const callOrder: string[] = [];
1721
+ const inboundDeduper = {
1722
+ claimEvent: vi.fn(() => {
1723
+ callOrder.push("claim");
1724
+ return true;
1725
+ }),
1726
+ commitEvent: vi.fn(async () => {
1727
+ callOrder.push("commit");
1728
+ }),
1729
+ releaseEvent: vi.fn(() => {
1730
+ callOrder.push("release");
1731
+ }),
1732
+ };
1733
+ const recordInboundSession = vi.fn(async () => {
1734
+ callOrder.push("record");
1735
+ });
1736
+ const dispatchReplyFromConfig = vi.fn(async () => {
1737
+ callOrder.push("dispatch");
1738
+ return {
1739
+ queuedFinal: true,
1740
+ counts: { final: 1, block: 0, tool: 0 },
1741
+ };
1742
+ });
1743
+ const { handler } = createMatrixHandlerTestHarness({
1744
+ inboundDeduper,
1745
+ recordInboundSession,
1746
+ dispatchReplyFromConfig,
1747
+ createReplyDispatcherWithTyping: () => ({
1748
+ dispatcher: {
1749
+ markComplete: () => {
1750
+ callOrder.push("mark-complete");
1751
+ },
1752
+ waitForIdle: async () => {
1753
+ callOrder.push("wait-for-idle");
1754
+ },
1755
+ },
1756
+ replyOptions: {},
1757
+ markDispatchIdle: () => {
1758
+ callOrder.push("dispatch-idle");
1759
+ },
1760
+ markRunComplete: () => {
1761
+ callOrder.push("run-complete");
1762
+ },
1763
+ }),
1764
+ });
1765
+
1766
+ await handler(
1767
+ "!room:example.org",
1768
+ createMatrixTextMessageEvent({
1769
+ eventId: "$commit-order",
1770
+ body: "hello",
1771
+ }),
1772
+ );
1773
+
1774
+ expect(callOrder).toEqual([
1775
+ "claim",
1776
+ "record",
1777
+ "dispatch",
1778
+ "run-complete",
1779
+ "mark-complete",
1780
+ "wait-for-idle",
1781
+ "dispatch-idle",
1782
+ "commit",
1783
+ ]);
1784
+ expect(inboundDeduper.releaseEvent).not.toHaveBeenCalled();
1785
+ });
1786
+
1787
+ it("releases a claimed event when reply dispatch fails before completion", async () => {
1788
+ const inboundDeduper = {
1789
+ claimEvent: vi.fn(() => true),
1790
+ commitEvent: vi.fn(async () => undefined),
1791
+ releaseEvent: vi.fn(),
1792
+ };
1793
+ const runtime = {
1794
+ error: vi.fn(),
1795
+ };
1796
+ const { handler } = createMatrixHandlerTestHarness({
1797
+ inboundDeduper,
1798
+ runtime: runtime as never,
1799
+ recordInboundSession: vi.fn(async () => {
1800
+ throw new Error("disk failed");
1801
+ }),
1802
+ dispatchReplyFromConfig: vi.fn(async () => ({
1803
+ queuedFinal: true,
1804
+ counts: { final: 1, block: 0, tool: 0 },
1805
+ })),
1806
+ });
1807
+
1808
+ await handler(
1809
+ "!room:example.org",
1810
+ createMatrixTextMessageEvent({
1811
+ eventId: "$release-on-error",
1812
+ body: "hello",
1813
+ }),
1814
+ );
1815
+
1816
+ expect(inboundDeduper.commitEvent).not.toHaveBeenCalled();
1817
+ expect(inboundDeduper.releaseEvent).toHaveBeenCalledWith({
1818
+ roomId: "!room:example.org",
1819
+ eventId: "$release-on-error",
1820
+ });
1821
+ expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("matrix handler failed"));
1822
+ });
1823
+
1824
+ it("releases a claimed event when queued final delivery fails", async () => {
1825
+ const inboundDeduper = {
1826
+ claimEvent: vi.fn(() => true),
1827
+ commitEvent: vi.fn(async () => undefined),
1828
+ releaseEvent: vi.fn(),
1829
+ };
1830
+ const runtime = {
1831
+ error: vi.fn(),
1832
+ };
1833
+ const { handler } = createMatrixHandlerTestHarness({
1834
+ inboundDeduper,
1835
+ runtime: runtime as never,
1836
+ dispatchReplyFromConfig: vi.fn(async () => ({
1837
+ queuedFinal: true,
1838
+ counts: { final: 1, block: 0, tool: 0 },
1839
+ })),
1840
+ createReplyDispatcherWithTyping: (params) => ({
1841
+ dispatcher: {
1842
+ markComplete: () => {},
1843
+ waitForIdle: async () => {
1844
+ params?.onError?.(new Error("send failed"), { kind: "final" });
1845
+ },
1846
+ },
1847
+ replyOptions: {},
1848
+ markDispatchIdle: () => {},
1849
+ markRunComplete: () => {},
1850
+ }),
1851
+ });
1852
+
1853
+ await handler(
1854
+ "!room:example.org",
1855
+ createMatrixTextMessageEvent({
1856
+ eventId: "$release-on-final-delivery-error",
1857
+ body: "hello",
1858
+ }),
1859
+ );
1860
+
1861
+ expect(inboundDeduper.commitEvent).not.toHaveBeenCalled();
1862
+ expect(inboundDeduper.releaseEvent).toHaveBeenCalledWith({
1863
+ roomId: "!room:example.org",
1864
+ eventId: "$release-on-final-delivery-error",
1865
+ });
1866
+ expect(runtime.error).toHaveBeenCalledWith(
1867
+ expect.stringContaining("matrix final reply failed"),
1868
+ );
1869
+ });
1870
+
1871
+ it.each(["tool", "block"] as const)(
1872
+ "releases a claimed event when queued %s delivery fails and no final reply exists",
1873
+ async (kind) => {
1874
+ const inboundDeduper = {
1875
+ claimEvent: vi.fn(() => true),
1876
+ commitEvent: vi.fn(async () => undefined),
1877
+ releaseEvent: vi.fn(),
1878
+ };
1879
+ const runtime = {
1880
+ error: vi.fn(),
1881
+ };
1882
+ const { handler } = createMatrixHandlerTestHarness({
1883
+ inboundDeduper,
1884
+ runtime: runtime as never,
1885
+ dispatchReplyFromConfig: vi.fn(async () => ({
1886
+ queuedFinal: false,
1887
+ counts: {
1888
+ final: 0,
1889
+ block: kind === "block" ? 1 : 0,
1890
+ tool: kind === "tool" ? 1 : 0,
1891
+ },
1892
+ })),
1893
+ createReplyDispatcherWithTyping: (params) => ({
1894
+ dispatcher: {
1895
+ markComplete: () => {},
1896
+ waitForIdle: async () => {
1897
+ params?.onError?.(new Error("send failed"), { kind });
1898
+ },
1899
+ },
1900
+ replyOptions: {},
1901
+ markDispatchIdle: () => {},
1902
+ markRunComplete: () => {},
1903
+ }),
1904
+ });
1905
+
1906
+ await handler(
1907
+ "!room:example.org",
1908
+ createMatrixTextMessageEvent({
1909
+ eventId: `$release-on-${kind}-delivery-error`,
1910
+ body: "hello",
1911
+ }),
1912
+ );
1913
+
1914
+ expect(inboundDeduper.commitEvent).not.toHaveBeenCalled();
1915
+ expect(inboundDeduper.releaseEvent).toHaveBeenCalledWith({
1916
+ roomId: "!room:example.org",
1917
+ eventId: `$release-on-${kind}-delivery-error`,
1918
+ });
1919
+ expect(runtime.error).toHaveBeenCalledWith(
1920
+ expect.stringContaining(`matrix ${kind} reply failed`),
1921
+ );
1922
+ },
1923
+ );
1924
+
1925
+ it("commits a claimed event when dispatch completes without a final reply", async () => {
1926
+ const callOrder: string[] = [];
1927
+ const inboundDeduper = {
1928
+ claimEvent: vi.fn(() => {
1929
+ callOrder.push("claim");
1930
+ return true;
1931
+ }),
1932
+ commitEvent: vi.fn(async () => {
1933
+ callOrder.push("commit");
1934
+ }),
1935
+ releaseEvent: vi.fn(() => {
1936
+ callOrder.push("release");
1937
+ }),
1938
+ };
1939
+ const { handler } = createMatrixHandlerTestHarness({
1940
+ inboundDeduper,
1941
+ recordInboundSession: vi.fn(async () => {
1942
+ callOrder.push("record");
1943
+ }),
1944
+ dispatchReplyFromConfig: vi.fn(async () => {
1945
+ callOrder.push("dispatch");
1946
+ return {
1947
+ queuedFinal: false,
1948
+ counts: { final: 0, block: 0, tool: 0 },
1949
+ };
1950
+ }),
1951
+ });
1952
+
1953
+ await handler(
1954
+ "!room:example.org",
1955
+ createMatrixTextMessageEvent({
1956
+ eventId: "$no-final",
1957
+ body: "hello",
1958
+ }),
1959
+ );
1960
+
1961
+ expect(callOrder).toEqual(["claim", "record", "dispatch", "commit"]);
1962
+ expect(inboundDeduper.releaseEvent).not.toHaveBeenCalled();
1963
+ });
1964
+ });
1965
+
1966
+ describe("matrix monitor handler draft streaming", () => {
1967
+ type DeliverFn = (
1968
+ payload: {
1969
+ text?: string;
1970
+ mediaUrl?: string;
1971
+ mediaUrls?: string[];
1972
+ isCompactionNotice?: boolean;
1973
+ replyToId?: string;
1974
+ },
1975
+ info: { kind: string },
1976
+ ) => Promise<void>;
1977
+ type ReplyOpts = {
1978
+ onPartialReply?: (payload: { text: string }) => void;
1979
+ onBlockReplyQueued?: (
1980
+ payload: {
1981
+ text?: string;
1982
+ isCompactionNotice?: boolean;
1983
+ },
1984
+ context?: { assistantMessageIndex?: number },
1985
+ ) => Promise<void> | void;
1986
+ onAssistantMessageStart?: () => void;
1987
+ disableBlockStreaming?: boolean;
1988
+ };
1989
+
1990
+ function createStreamingHarness(opts?: {
1991
+ replyToMode?: "off" | "first" | "all" | "batched";
1992
+ blockStreamingEnabled?: boolean;
1993
+ streaming?: "partial" | "quiet";
1994
+ }) {
1995
+ let capturedDeliver: DeliverFn | undefined;
1996
+ let capturedReplyOpts: ReplyOpts | undefined;
1997
+ // Gate that keeps the handler's model run alive until the test releases it.
1998
+ let resolveRunGate: (() => void) | undefined;
1999
+ const runGate = new Promise<void>((resolve) => {
2000
+ resolveRunGate = resolve;
2001
+ });
2002
+
2003
+ sendMessageMatrixMock.mockReset().mockResolvedValue({ messageId: "$draft1", roomId: "!room" });
2004
+ sendSingleTextMessageMatrixMock
2005
+ .mockReset()
2006
+ .mockResolvedValue({ messageId: "$draft1", roomId: "!room" });
2007
+ editMessageMatrixMock.mockReset().mockResolvedValue("$edited");
2008
+ deliverMatrixRepliesMock.mockReset().mockResolvedValue(true);
2009
+
2010
+ const redactEventMock = vi.fn(async () => "$redacted");
2011
+
2012
+ const { handler } = createMatrixHandlerTestHarness({
2013
+ streaming: opts?.streaming ?? "quiet",
2014
+ blockStreamingEnabled: opts?.blockStreamingEnabled ?? false,
2015
+ replyToMode: opts?.replyToMode ?? "off",
2016
+ client: { redactEvent: redactEventMock },
2017
+ createReplyDispatcherWithTyping: (params: Record<string, unknown> | undefined) => {
2018
+ capturedDeliver = params?.deliver as DeliverFn | undefined;
2019
+ return {
2020
+ dispatcher: {
2021
+ markComplete: () => {},
2022
+ waitForIdle: async () => {},
2023
+ },
2024
+ replyOptions: {},
2025
+ markDispatchIdle: () => {},
2026
+ markRunComplete: () => {},
2027
+ };
2028
+ },
2029
+ dispatchReplyFromConfig: vi.fn(async (args: { replyOptions?: ReplyOpts }) => {
2030
+ capturedReplyOpts = args?.replyOptions;
2031
+ // Block until the test is done exercising callbacks.
2032
+ await runGate;
2033
+ return { queuedFinal: true, counts: { final: 1, block: 0, tool: 0 } };
2034
+ }) as never,
2035
+ withReplyDispatcher: async <T>(params: {
2036
+ dispatcher: { markComplete?: () => void; waitForIdle?: () => Promise<void> };
2037
+ run: () => Promise<T>;
2038
+ onSettled?: () => void | Promise<void>;
2039
+ }) => {
2040
+ const result = await params.run();
2041
+ await params.onSettled?.();
2042
+ return result;
2043
+ },
2044
+ });
2045
+
2046
+ const dispatch = async () => {
2047
+ // Start handler without awaiting — it blocks on runGate.
2048
+ const handlerDone = handler(
2049
+ "!room:example.org",
2050
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2051
+ );
2052
+ // Wait for callbacks to be captured.
2053
+ await vi.waitFor(() => {
2054
+ if (!capturedDeliver || !capturedReplyOpts) {
2055
+ throw new Error("Streaming callbacks not captured yet");
2056
+ }
2057
+ });
2058
+ return {
2059
+ deliver: capturedDeliver!,
2060
+ opts: capturedReplyOpts!,
2061
+ // Release the run gate and wait for the handler to finish
2062
+ // (including the finally block that stops the draft stream).
2063
+ finish: async () => {
2064
+ resolveRunGate?.();
2065
+ await handlerDone;
2066
+ },
2067
+ };
2068
+ };
2069
+
2070
+ return { dispatch, redactEventMock };
2071
+ }
2072
+
2073
+ it("finalizes a single quiet-preview block in place when block streaming is enabled", async () => {
2074
+ const { dispatch, redactEventMock } = createStreamingHarness({ blockStreamingEnabled: true });
2075
+ const { deliver, opts, finish } = await dispatch();
2076
+
2077
+ opts.onPartialReply?.({ text: "Single block" });
2078
+ await vi.waitFor(() => {
2079
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2080
+ });
2081
+
2082
+ deliverMatrixRepliesMock.mockClear();
2083
+ await deliver({ text: "Single block" }, { kind: "final" });
2084
+
2085
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2086
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2087
+ "!room:example.org",
2088
+ "$draft1",
2089
+ "Single block",
2090
+ expect.objectContaining({
2091
+ extraContent: { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true },
2092
+ }),
2093
+ );
2094
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2095
+ expect(redactEventMock).not.toHaveBeenCalled();
2096
+ await finish();
2097
+ });
2098
+
2099
+ it("keeps partial preview-first finalization on the existing draft when text is unchanged", async () => {
2100
+ const { dispatch, redactEventMock } = createStreamingHarness({
2101
+ blockStreamingEnabled: true,
2102
+ streaming: "partial",
2103
+ });
2104
+ const { deliver, opts, finish } = await dispatch();
2105
+
2106
+ opts.onPartialReply?.({ text: "Single block" });
2107
+ await vi.waitFor(() => {
2108
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2109
+ });
2110
+
2111
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledWith(
2112
+ "!room:example.org",
2113
+ "Single block",
2114
+ expect.not.objectContaining({
2115
+ msgtype: "m.notice",
2116
+ includeMentions: false,
2117
+ }),
2118
+ );
2119
+
2120
+ await deliver({ text: "Single block" }, { kind: "final" });
2121
+
2122
+ // MSC4357: even when text is unchanged, a finalize edit is sent to clear
2123
+ // the live marker so supporting clients stop the streaming animation.
2124
+ expect(editMessageMatrixMock).toHaveBeenCalledTimes(1);
2125
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2126
+ "!room:example.org",
2127
+ "$draft1",
2128
+ "Single block",
2129
+ expect.objectContaining({ live: false }),
2130
+ );
2131
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2132
+ expect(redactEventMock).not.toHaveBeenCalled();
2133
+ await finish();
2134
+ });
2135
+
2136
+ it("still edits partial preview-first drafts when the final text changes", async () => {
2137
+ const { dispatch, redactEventMock } = createStreamingHarness({
2138
+ blockStreamingEnabled: true,
2139
+ streaming: "partial",
2140
+ });
2141
+ const { deliver, opts, finish } = await dispatch();
2142
+
2143
+ opts.onPartialReply?.({ text: "Single" });
2144
+ await vi.waitFor(() => {
2145
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2146
+ });
2147
+
2148
+ await deliver({ text: "Single block" }, { kind: "final" });
2149
+
2150
+ expect(editMessageMatrixMock).toHaveBeenCalledTimes(1);
2151
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2152
+ "!room:example.org",
2153
+ "$draft1",
2154
+ "Single block",
2155
+ expect.not.objectContaining({ live: false }),
2156
+ );
2157
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2158
+ expect(redactEventMock).not.toHaveBeenCalled();
2159
+ await finish();
2160
+ });
2161
+
2162
+ it("preserves completed blocks by rotating to a new quiet preview", async () => {
2163
+ const { dispatch, redactEventMock } = createStreamingHarness({ blockStreamingEnabled: true });
2164
+ const { deliver, opts, finish } = await dispatch();
2165
+
2166
+ opts.onPartialReply?.({ text: "Block one" });
2167
+ await vi.waitFor(() => {
2168
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2169
+ });
2170
+
2171
+ deliverMatrixRepliesMock.mockClear();
2172
+ await deliver({ text: "Block one" }, { kind: "block" });
2173
+
2174
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2175
+ "!room:example.org",
2176
+ "$draft1",
2177
+ "Block one",
2178
+ expect.objectContaining({
2179
+ extraContent: { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true },
2180
+ }),
2181
+ );
2182
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2183
+ expect(redactEventMock).not.toHaveBeenCalled();
2184
+
2185
+ opts.onAssistantMessageStart?.();
2186
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2187
+ messageId: "$draft2",
2188
+ roomId: "!room",
2189
+ });
2190
+ opts.onPartialReply?.({ text: "Block two" });
2191
+ await vi.waitFor(() => {
2192
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(2);
2193
+ });
2194
+
2195
+ await deliver({ text: "Block two" }, { kind: "final" });
2196
+
2197
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2198
+ "!room:example.org",
2199
+ "$draft2",
2200
+ "Block two",
2201
+ expect.objectContaining({
2202
+ extraContent: { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true },
2203
+ }),
2204
+ );
2205
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2206
+ expect(redactEventMock).not.toHaveBeenCalled();
2207
+ await finish();
2208
+ });
2209
+
2210
+ it("queues late partials behind block-boundary rotation", async () => {
2211
+ const { dispatch, redactEventMock } = createStreamingHarness({ blockStreamingEnabled: true });
2212
+ const { deliver, opts, finish } = await dispatch();
2213
+
2214
+ opts.onPartialReply?.({ text: "Alpha" });
2215
+ await vi.waitFor(() => {
2216
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2217
+ });
2218
+
2219
+ await opts.onBlockReplyQueued?.({ text: "Alpha" });
2220
+
2221
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2222
+ messageId: "$draft2",
2223
+ roomId: "!room",
2224
+ });
2225
+ opts.onPartialReply?.({ text: "AlphaBeta" });
2226
+
2227
+ // The next block must not update the previous block's draft while the
2228
+ // prior block delivery is still draining.
2229
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2230
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2231
+
2232
+ await deliver({ text: "Alpha" }, { kind: "block" });
2233
+
2234
+ await vi.waitFor(() => {
2235
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(2);
2236
+ });
2237
+ expect(sendSingleTextMessageMatrixMock.mock.calls[1]?.[1]).toBe("Beta");
2238
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2239
+ expect(redactEventMock).not.toHaveBeenCalled();
2240
+ await finish();
2241
+ });
2242
+
2243
+ it("keeps delayed same-message block boundaries at the emitted block length", async () => {
2244
+ const { dispatch, redactEventMock } = createStreamingHarness({ blockStreamingEnabled: true });
2245
+ const { deliver, opts, finish } = await dispatch();
2246
+
2247
+ opts.onPartialReply?.({ text: "Alpha" });
2248
+ await vi.waitFor(() => {
2249
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2250
+ });
2251
+
2252
+ opts.onPartialReply?.({ text: "AlphaBeta" });
2253
+ await vi.waitFor(() => {
2254
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2255
+ "!room:example.org",
2256
+ "$draft1",
2257
+ "AlphaBeta",
2258
+ expect.anything(),
2259
+ );
2260
+ });
2261
+
2262
+ await opts.onBlockReplyQueued?.({ text: "Alpha" });
2263
+
2264
+ sendSingleTextMessageMatrixMock.mockClear();
2265
+ editMessageMatrixMock.mockClear();
2266
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2267
+ messageId: "$draft2",
2268
+ roomId: "!room",
2269
+ });
2270
+ await deliver({ text: "Alpha" }, { kind: "block" });
2271
+
2272
+ await vi.waitFor(() => {
2273
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2274
+ });
2275
+ expect(sendSingleTextMessageMatrixMock.mock.calls[0]?.[1]).toBe("Beta");
2276
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2277
+ "!room:example.org",
2278
+ "$draft1",
2279
+ "Alpha",
2280
+ expect.anything(),
2281
+ );
2282
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2283
+ expect(redactEventMock).not.toHaveBeenCalled();
2284
+ await finish();
2285
+ });
2286
+
2287
+ it("falls back to deliverMatrixReplies when final edit fails", async () => {
2288
+ const { dispatch } = createStreamingHarness();
2289
+ const { deliver, opts, finish } = await dispatch();
2290
+
2291
+ opts.onPartialReply?.({ text: "Hello" });
2292
+ await vi.waitFor(() => {
2293
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2294
+ });
2295
+
2296
+ editMessageMatrixMock.mockRejectedValueOnce(new Error("rate limited"));
2297
+
2298
+ await deliver({ text: "Hello world" }, { kind: "block" });
2299
+
2300
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2301
+ await finish();
2302
+ });
2303
+
2304
+ it("does not reset draft stream after final delivery", async () => {
2305
+ vi.useFakeTimers();
2306
+ try {
2307
+ const { dispatch } = createStreamingHarness();
2308
+ const { deliver, opts, finish } = await dispatch();
2309
+
2310
+ opts.onPartialReply?.({ text: "Hello" });
2311
+ await vi.waitFor(() => {
2312
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2313
+ });
2314
+
2315
+ // Final delivery — stream should stay stopped.
2316
+ await deliver({ text: "Hello" }, { kind: "final" });
2317
+
2318
+ // Further partial updates should NOT create new messages.
2319
+ sendSingleTextMessageMatrixMock.mockClear();
2320
+ opts.onPartialReply?.({ text: "Ghost" });
2321
+
2322
+ await vi.advanceTimersByTimeAsync(50);
2323
+ expect(sendSingleTextMessageMatrixMock).not.toHaveBeenCalled();
2324
+ await finish();
2325
+ } finally {
2326
+ vi.useRealTimers();
2327
+ }
2328
+ });
2329
+
2330
+ it("resets draft block offsets on assistant message start", async () => {
2331
+ const { dispatch } = createStreamingHarness();
2332
+ const { deliver, opts, finish } = await dispatch();
2333
+
2334
+ // Block 1: stream and deliver.
2335
+ opts.onPartialReply?.({ text: "Block one" });
2336
+ await vi.waitFor(() => {
2337
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2338
+ });
2339
+ await deliver({ text: "Block one" }, { kind: "block" });
2340
+
2341
+ // Tool call delivered (bypasses draft stream).
2342
+ await deliver({ text: "tool result" }, { kind: "tool" });
2343
+
2344
+ // New assistant message starts — payload.text will reset upstream.
2345
+ opts.onAssistantMessageStart?.();
2346
+
2347
+ // Block 2: partial text starts fresh (no stale offset).
2348
+ sendSingleTextMessageMatrixMock.mockClear();
2349
+ sendSingleTextMessageMatrixMock.mockResolvedValue({ messageId: "$draft2", roomId: "!room" });
2350
+
2351
+ opts.onPartialReply?.({ text: "Block two" });
2352
+ await vi.waitFor(() => {
2353
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2354
+ });
2355
+
2356
+ // The draft stream should have received "Block two", not empty string.
2357
+ const sentBody = sendSingleTextMessageMatrixMock.mock.calls[0]?.[1];
2358
+ expect(sentBody).toBeTruthy();
2359
+ await finish();
2360
+ });
2361
+
2362
+ it("preserves queued block boundaries across assistant message start", async () => {
2363
+ const { dispatch, redactEventMock } = createStreamingHarness({ blockStreamingEnabled: true });
2364
+ const { deliver, opts, finish } = await dispatch();
2365
+
2366
+ opts.onPartialReply?.({ text: "Alpha" });
2367
+ await vi.waitFor(() => {
2368
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2369
+ });
2370
+
2371
+ await opts.onBlockReplyQueued?.({ text: "Alpha" });
2372
+ opts.onAssistantMessageStart?.();
2373
+ opts.onPartialReply?.({ text: "Beta" });
2374
+
2375
+ await vi.waitFor(() => {
2376
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2377
+ "!room:example.org",
2378
+ "$draft1",
2379
+ "Beta",
2380
+ expect.anything(),
2381
+ );
2382
+ });
2383
+
2384
+ sendSingleTextMessageMatrixMock.mockClear();
2385
+ editMessageMatrixMock.mockClear();
2386
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2387
+ messageId: "$draft2",
2388
+ roomId: "!room",
2389
+ });
2390
+ await deliver({ text: "Alpha" }, { kind: "block" });
2391
+
2392
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2393
+ "!room:example.org",
2394
+ "$draft1",
2395
+ "Alpha",
2396
+ expect.anything(),
2397
+ );
2398
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2399
+ expect(redactEventMock).not.toHaveBeenCalled();
2400
+ await vi.waitFor(() => {
2401
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2402
+ });
2403
+ expect(sendSingleTextMessageMatrixMock.mock.calls[0]?.[1]).toBe("Beta");
2404
+
2405
+ await deliver({ text: "Beta" }, { kind: "final" });
2406
+
2407
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2408
+ expect(redactEventMock).not.toHaveBeenCalled();
2409
+ await finish();
2410
+ });
2411
+
2412
+ it("queues late block boundaries against the source assistant message", async () => {
2413
+ const { dispatch, redactEventMock } = createStreamingHarness({ blockStreamingEnabled: true });
2414
+ const { deliver, opts, finish } = await dispatch();
2415
+
2416
+ opts.onAssistantMessageStart?.();
2417
+ opts.onPartialReply?.({ text: "Alpha" });
2418
+ await vi.waitFor(() => {
2419
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2420
+ });
2421
+
2422
+ opts.onAssistantMessageStart?.();
2423
+ await opts.onBlockReplyQueued?.({ text: "Alpha" }, { assistantMessageIndex: 1 });
2424
+ opts.onPartialReply?.({ text: "Beta" });
2425
+
2426
+ await vi.waitFor(() => {
2427
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2428
+ "!room:example.org",
2429
+ "$draft1",
2430
+ "Beta",
2431
+ expect.anything(),
2432
+ );
2433
+ });
2434
+
2435
+ sendSingleTextMessageMatrixMock.mockClear();
2436
+ editMessageMatrixMock.mockClear();
2437
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2438
+ messageId: "$draft2",
2439
+ roomId: "!room",
2440
+ });
2441
+ await deliver({ text: "Alpha" }, { kind: "block" });
2442
+
2443
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2444
+ "!room:example.org",
2445
+ "$draft1",
2446
+ "Alpha",
2447
+ expect.anything(),
2448
+ );
2449
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2450
+ expect(redactEventMock).not.toHaveBeenCalled();
2451
+ await vi.waitFor(() => {
2452
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2453
+ });
2454
+ expect(sendSingleTextMessageMatrixMock.mock.calls[0]?.[1]).toBe("Beta");
2455
+
2456
+ await deliver({ text: "Beta" }, { kind: "final" });
2457
+
2458
+ expect(deliverMatrixRepliesMock).not.toHaveBeenCalled();
2459
+ expect(redactEventMock).not.toHaveBeenCalled();
2460
+ await finish();
2461
+ });
2462
+
2463
+ it("keeps queued block boundaries ordered while Matrix deliveries drain", async () => {
2464
+ const { dispatch } = createStreamingHarness({ blockStreamingEnabled: true });
2465
+ const { deliver, opts, finish } = await dispatch();
2466
+
2467
+ opts.onPartialReply?.({ text: "Alpha" });
2468
+ await vi.waitFor(() => {
2469
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2470
+ });
2471
+ expect(sendSingleTextMessageMatrixMock.mock.calls[0]?.[1]).toBe("Alpha");
2472
+
2473
+ await opts.onBlockReplyQueued?.({ text: "Alpha" });
2474
+ opts.onPartialReply?.({ text: "AlphaBeta" });
2475
+ await opts.onBlockReplyQueued?.({ text: "Beta" });
2476
+ opts.onPartialReply?.({ text: "AlphaBetaGamma" });
2477
+
2478
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2479
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2480
+
2481
+ sendSingleTextMessageMatrixMock.mockClear();
2482
+ editMessageMatrixMock.mockClear();
2483
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2484
+ messageId: "$draft2",
2485
+ roomId: "!room",
2486
+ });
2487
+ await deliver({ text: "Alpha" }, { kind: "block" });
2488
+
2489
+ await vi.waitFor(() => {
2490
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2491
+ });
2492
+ expect(sendSingleTextMessageMatrixMock.mock.calls[0]?.[1]).toBe("Beta");
2493
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2494
+ "!room:example.org",
2495
+ "$draft1",
2496
+ "Alpha",
2497
+ expect.objectContaining({
2498
+ extraContent: { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true },
2499
+ }),
2500
+ );
2501
+
2502
+ sendSingleTextMessageMatrixMock.mockClear();
2503
+ editMessageMatrixMock.mockClear();
2504
+ sendSingleTextMessageMatrixMock.mockResolvedValueOnce({
2505
+ messageId: "$draft3",
2506
+ roomId: "!room",
2507
+ });
2508
+ await deliver({ text: "Beta" }, { kind: "block" });
2509
+
2510
+ await vi.waitFor(() => {
2511
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2512
+ });
2513
+ expect(sendSingleTextMessageMatrixMock.mock.calls[0]?.[1]).toBe("Gamma");
2514
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2515
+ "!room:example.org",
2516
+ "$draft2",
2517
+ "Beta",
2518
+ expect.objectContaining({
2519
+ extraContent: { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true },
2520
+ }),
2521
+ );
2522
+
2523
+ await finish();
2524
+ });
2525
+
2526
+ it("stops draft stream on handler error (no leaked timer)", async () => {
2527
+ vi.useFakeTimers();
2528
+ try {
2529
+ sendSingleTextMessageMatrixMock
2530
+ .mockReset()
2531
+ .mockResolvedValue({ messageId: "$draft1", roomId: "!room" });
2532
+ editMessageMatrixMock.mockReset().mockResolvedValue("$edited");
2533
+ deliverMatrixRepliesMock.mockReset().mockResolvedValue(true);
2534
+ const redactEventMock = vi.fn(async () => "$redacted");
2535
+
2536
+ let capturedReplyOpts: ReplyOpts | undefined;
2537
+
2538
+ const { handler } = createMatrixHandlerTestHarness({
2539
+ streaming: "quiet",
2540
+ client: { redactEvent: redactEventMock },
2541
+ createReplyDispatcherWithTyping: () => ({
2542
+ dispatcher: { markComplete: () => {}, waitForIdle: async () => {} },
2543
+ replyOptions: {},
2544
+ markDispatchIdle: () => {},
2545
+ markRunComplete: () => {},
2546
+ }),
2547
+ dispatchReplyFromConfig: vi.fn(async (args: { replyOptions?: ReplyOpts }) => {
2548
+ capturedReplyOpts = args?.replyOptions;
2549
+ // Simulate streaming then model error.
2550
+ capturedReplyOpts?.onPartialReply?.({ text: "partial" });
2551
+ await vi.waitFor(() => {
2552
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2553
+ });
2554
+ throw new Error("model timeout");
2555
+ }) as never,
2556
+ withReplyDispatcher: async <T>(params: {
2557
+ dispatcher: { markComplete?: () => void; waitForIdle?: () => Promise<void> };
2558
+ run: () => Promise<T>;
2559
+ onSettled?: () => void | Promise<void>;
2560
+ }) => {
2561
+ const result = await params.run();
2562
+ await params.onSettled?.();
2563
+ return result;
2564
+ },
2565
+ });
2566
+
2567
+ // Handler should not throw (outer catch absorbs it).
2568
+ await handler(
2569
+ "!room:example.org",
2570
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2571
+ );
2572
+
2573
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2574
+
2575
+ // After handler exits, draft stream timer must not fire.
2576
+ sendSingleTextMessageMatrixMock.mockClear();
2577
+ editMessageMatrixMock.mockClear();
2578
+ await vi.advanceTimersByTimeAsync(50);
2579
+ expect(sendSingleTextMessageMatrixMock).not.toHaveBeenCalled();
2580
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2581
+ } finally {
2582
+ vi.useRealTimers();
2583
+ }
2584
+ });
2585
+
2586
+ it("redacts partial live drafts when generation aborts mid-stream", async () => {
2587
+ sendSingleTextMessageMatrixMock
2588
+ .mockReset()
2589
+ .mockResolvedValue({ messageId: "$draft1", roomId: "!room" });
2590
+ editMessageMatrixMock.mockReset().mockResolvedValue("$edited");
2591
+ deliverMatrixRepliesMock.mockReset().mockResolvedValue(true);
2592
+
2593
+ const redactEventMock = vi.fn(async () => "$redacted");
2594
+ let capturedReplyOpts: ReplyOpts | undefined;
2595
+
2596
+ const { handler } = createMatrixHandlerTestHarness({
2597
+ streaming: "partial",
2598
+ client: { redactEvent: redactEventMock },
2599
+ createReplyDispatcherWithTyping: () => ({
2600
+ dispatcher: { markComplete: () => {}, waitForIdle: async () => {} },
2601
+ replyOptions: {},
2602
+ markDispatchIdle: () => {},
2603
+ markRunComplete: () => {},
2604
+ }),
2605
+ dispatchReplyFromConfig: vi.fn(async (args: { replyOptions?: ReplyOpts }) => {
2606
+ capturedReplyOpts = args?.replyOptions;
2607
+ capturedReplyOpts?.onPartialReply?.({ text: "partial" });
2608
+ await vi.waitFor(() => {
2609
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2610
+ });
2611
+ throw new Error("model timeout");
2612
+ }) as never,
2613
+ withReplyDispatcher: async <T>(params: {
2614
+ dispatcher: { markComplete?: () => void; waitForIdle?: () => Promise<void> };
2615
+ run: () => Promise<T>;
2616
+ onSettled?: () => void | Promise<void>;
2617
+ }) => {
2618
+ const result = await params.run();
2619
+ await params.onSettled?.();
2620
+ return result;
2621
+ },
2622
+ });
2623
+
2624
+ await handler(
2625
+ "!room:example.org",
2626
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2627
+ );
2628
+
2629
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2630
+ });
2631
+
2632
+ it("keeps shutdown cleanup for empty final payloads that send nothing", async () => {
2633
+ const { dispatch, redactEventMock } = createStreamingHarness({ streaming: "partial" });
2634
+ const { deliver, opts, finish } = await dispatch();
2635
+
2636
+ opts.onPartialReply?.({ text: "Partial reply" });
2637
+ await vi.waitFor(() => {
2638
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2639
+ });
2640
+
2641
+ deliverMatrixRepliesMock.mockClear();
2642
+ deliverMatrixRepliesMock.mockResolvedValue(false);
2643
+ await deliver({}, { kind: "final" });
2644
+
2645
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2646
+ expect(redactEventMock).not.toHaveBeenCalled();
2647
+
2648
+ await finish();
2649
+
2650
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2651
+ });
2652
+
2653
+ it("skips compaction notices in draft finalization", async () => {
2654
+ const { dispatch } = createStreamingHarness();
2655
+ const { deliver, opts, finish } = await dispatch();
2656
+
2657
+ opts.onPartialReply?.({ text: "Streaming" });
2658
+ await vi.waitFor(() => {
2659
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2660
+ });
2661
+
2662
+ // Compaction notice should bypass draft path and go to normal delivery.
2663
+ deliverMatrixRepliesMock.mockClear();
2664
+ await deliver({ text: "Compacting...", isCompactionNotice: true }, { kind: "block" });
2665
+
2666
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2667
+ // Edit should NOT have been called for the compaction notice.
2668
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2669
+ await finish();
2670
+ });
2671
+
2672
+ it("redacts stale draft when payload reply target mismatches", async () => {
2673
+ const { dispatch, redactEventMock } = createStreamingHarness({ replyToMode: "first" });
2674
+ const { deliver, opts, finish } = await dispatch();
2675
+
2676
+ // Simulate streaming: partial reply creates draft message.
2677
+ opts.onPartialReply?.({ text: "Partial reply" });
2678
+ await vi.waitFor(() => {
2679
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2680
+ });
2681
+
2682
+ // Final delivery carries a different replyToId than the draft's.
2683
+ deliverMatrixRepliesMock.mockClear();
2684
+ await deliver({ text: "Final text", replyToId: "$different_msg" }, { kind: "final" });
2685
+
2686
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2687
+ // Draft should be redacted since it can't change reply relation.
2688
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2689
+ // Final answer delivered via normal path.
2690
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2691
+ await finish();
2692
+ });
2693
+
2694
+ it("redacts stale draft when final payload intentionally drops reply threading", async () => {
2695
+ const { dispatch, redactEventMock } = createStreamingHarness({ replyToMode: "first" });
2696
+ const { deliver, opts, finish } = await dispatch();
2697
+
2698
+ // A tool payload can consume the first reply slot upstream while draft
2699
+ // streaming for the next assistant block still starts from the original
2700
+ // reply target.
2701
+ await deliver({ text: "tool result", replyToId: "$msg1" }, { kind: "tool" });
2702
+ opts.onAssistantMessageStart?.();
2703
+
2704
+ opts.onPartialReply?.({ text: "Partial reply" });
2705
+ await vi.waitFor(() => {
2706
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2707
+ });
2708
+
2709
+ deliverMatrixRepliesMock.mockClear();
2710
+ await deliver({ text: "Final text" }, { kind: "final" });
2711
+
2712
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2713
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2714
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2715
+ await finish();
2716
+ });
2717
+
2718
+ it("redacts stale draft for media-only finals", async () => {
2719
+ const { dispatch, redactEventMock } = createStreamingHarness();
2720
+ const { deliver, opts, finish } = await dispatch();
2721
+
2722
+ opts.onPartialReply?.({ text: "Partial reply" });
2723
+ await vi.waitFor(() => {
2724
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2725
+ });
2726
+
2727
+ deliverMatrixRepliesMock.mockClear();
2728
+ await deliver({ mediaUrl: "https://example.com/image.png" }, { kind: "final" });
2729
+
2730
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2731
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2732
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2733
+ await finish();
2734
+ });
2735
+
2736
+ it("finalizes partial drafts before reusing unchanged media captions", async () => {
2737
+ const { dispatch, redactEventMock } = createStreamingHarness({ streaming: "partial" });
2738
+ const { deliver, opts, finish } = await dispatch();
2739
+
2740
+ opts.onPartialReply?.({ text: "@room screenshot ready" });
2741
+ await vi.waitFor(() => {
2742
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2743
+ });
2744
+
2745
+ deliverMatrixRepliesMock.mockClear();
2746
+ await deliver(
2747
+ {
2748
+ text: "@room screenshot ready",
2749
+ mediaUrl: "https://example.com/image.png",
2750
+ },
2751
+ { kind: "final" },
2752
+ );
2753
+
2754
+ expect(editMessageMatrixMock).toHaveBeenCalledTimes(1);
2755
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2756
+ "!room:example.org",
2757
+ "$draft1",
2758
+ "@room screenshot ready",
2759
+ expect.objectContaining({ live: false }),
2760
+ );
2761
+ expect(redactEventMock).not.toHaveBeenCalled();
2762
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledWith(
2763
+ expect.objectContaining({
2764
+ replies: [
2765
+ expect.objectContaining({
2766
+ mediaUrl: "https://example.com/image.png",
2767
+ text: undefined,
2768
+ }),
2769
+ ],
2770
+ }),
2771
+ );
2772
+ await finish();
2773
+ });
2774
+
2775
+ it("finalizes quiet drafts before reusing unchanged media captions", async () => {
2776
+ const { dispatch, redactEventMock } = createStreamingHarness({ streaming: "quiet" });
2777
+ const { deliver, opts, finish } = await dispatch();
2778
+
2779
+ opts.onPartialReply?.({ text: "@room screenshot ready" });
2780
+ await vi.waitFor(() => {
2781
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2782
+ });
2783
+
2784
+ deliverMatrixRepliesMock.mockClear();
2785
+ await deliver(
2786
+ {
2787
+ text: "@room screenshot ready",
2788
+ mediaUrl: "https://example.com/image.png",
2789
+ },
2790
+ { kind: "final" },
2791
+ );
2792
+
2793
+ expect(editMessageMatrixMock).toHaveBeenCalledWith(
2794
+ "!room:example.org",
2795
+ "$draft1",
2796
+ "@room screenshot ready",
2797
+ expect.objectContaining({
2798
+ extraContent: { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true },
2799
+ }),
2800
+ );
2801
+ expect(redactEventMock).not.toHaveBeenCalled();
2802
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledWith(
2803
+ expect.objectContaining({
2804
+ replies: [
2805
+ expect.objectContaining({
2806
+ mediaUrl: "https://example.com/image.png",
2807
+ text: undefined,
2808
+ }),
2809
+ ],
2810
+ }),
2811
+ );
2812
+ await finish();
2813
+ });
2814
+
2815
+ it("redacts stale draft and sends the final once when a later preview exceeds the event limit", async () => {
2816
+ const { dispatch, redactEventMock } = createStreamingHarness();
2817
+ const { deliver, opts, finish } = await dispatch();
2818
+
2819
+ opts.onPartialReply?.({ text: "1234" });
2820
+ await vi.waitFor(() => {
2821
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2822
+ });
2823
+
2824
+ prepareMatrixSingleTextMock.mockImplementation((text: string) => {
2825
+ const trimmedText = text.trim();
2826
+ return {
2827
+ trimmedText,
2828
+ convertedText: trimmedText,
2829
+ singleEventLimit: 5,
2830
+ fitsInSingleEvent: trimmedText.length <= 5,
2831
+ };
2832
+ });
2833
+
2834
+ opts.onPartialReply?.({ text: "123456" });
2835
+ await deliver({ text: "123456" }, { kind: "final" });
2836
+
2837
+ expect(editMessageMatrixMock).not.toHaveBeenCalled();
2838
+ expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
2839
+ expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
2840
+ expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
2841
+ await finish();
2842
+ });
2843
+ });
2844
+
2845
+ describe("matrix monitor handler block streaming config", () => {
2846
+ it("keeps final-only delivery when draft streaming is off by default", async () => {
2847
+ let capturedDisableBlockStreaming: boolean | undefined;
2848
+
2849
+ const { handler } = createMatrixHandlerTestHarness({
2850
+ streaming: "off",
2851
+ dispatchReplyFromConfig: vi.fn(
2852
+ async (args: { replyOptions?: { disableBlockStreaming?: boolean } }) => {
2853
+ capturedDisableBlockStreaming = args.replyOptions?.disableBlockStreaming;
2854
+ return { queuedFinal: false, counts: { final: 0, block: 0, tool: 0 } };
2855
+ },
2856
+ ) as never,
2857
+ });
2858
+
2859
+ await handler(
2860
+ "!room:example.org",
2861
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2862
+ );
2863
+
2864
+ expect(capturedDisableBlockStreaming).toBe(true);
2865
+ });
2866
+
2867
+ it("keeps block streaming disabled when partial previews are on and block streaming is off", async () => {
2868
+ let capturedDisableBlockStreaming: boolean | undefined;
2869
+
2870
+ const { handler } = createMatrixHandlerTestHarness({
2871
+ streaming: "partial",
2872
+ dispatchReplyFromConfig: vi.fn(
2873
+ async (args: { replyOptions?: { disableBlockStreaming?: boolean } }) => {
2874
+ capturedDisableBlockStreaming = args.replyOptions?.disableBlockStreaming;
2875
+ return { queuedFinal: false, counts: { final: 0, block: 0, tool: 0 } };
2876
+ },
2877
+ ) as never,
2878
+ });
2879
+
2880
+ await handler(
2881
+ "!room:example.org",
2882
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2883
+ );
2884
+
2885
+ expect(capturedDisableBlockStreaming).toBe(true);
2886
+ });
2887
+
2888
+ it("keeps block streaming disabled when quiet previews are on and block streaming is off", async () => {
2889
+ let capturedDisableBlockStreaming: boolean | undefined;
2890
+
2891
+ const { handler } = createMatrixHandlerTestHarness({
2892
+ streaming: "quiet",
2893
+ dispatchReplyFromConfig: vi.fn(
2894
+ async (args: { replyOptions?: { disableBlockStreaming?: boolean } }) => {
2895
+ capturedDisableBlockStreaming = args.replyOptions?.disableBlockStreaming;
2896
+ return { queuedFinal: false, counts: { final: 0, block: 0, tool: 0 } };
2897
+ },
2898
+ ) as never,
2899
+ });
2900
+
2901
+ await handler(
2902
+ "!room:example.org",
2903
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2904
+ );
2905
+
2906
+ expect(capturedDisableBlockStreaming).toBe(true);
2907
+ });
2908
+
2909
+ it("allows shared block streaming when partial previews and block streaming are both enabled", async () => {
2910
+ let capturedDisableBlockStreaming: boolean | undefined;
2911
+
2912
+ const { handler } = createMatrixHandlerTestHarness({
2913
+ streaming: "partial",
2914
+ blockStreamingEnabled: true,
2915
+ dispatchReplyFromConfig: vi.fn(
2916
+ async (args: { replyOptions?: { disableBlockStreaming?: boolean } }) => {
2917
+ capturedDisableBlockStreaming = args.replyOptions?.disableBlockStreaming;
2918
+ return { queuedFinal: false, counts: { final: 0, block: 0, tool: 0 } };
2919
+ },
2920
+ ) as never,
2921
+ });
2922
+
2923
+ await handler(
2924
+ "!room:example.org",
2925
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2926
+ );
2927
+
2928
+ expect(capturedDisableBlockStreaming).toBe(false);
2929
+ });
2930
+
2931
+ it("uses shared block streaming when explicitly enabled for Matrix", async () => {
2932
+ let capturedDisableBlockStreaming: boolean | undefined;
2933
+
2934
+ const { handler } = createMatrixHandlerTestHarness({
2935
+ streaming: "off",
2936
+ blockStreamingEnabled: true,
2937
+ dispatchReplyFromConfig: vi.fn(
2938
+ async (args: { replyOptions?: { disableBlockStreaming?: boolean } }) => {
2939
+ capturedDisableBlockStreaming = args.replyOptions?.disableBlockStreaming;
2940
+ return { queuedFinal: false, counts: { final: 0, block: 0, tool: 0 } };
2941
+ },
2942
+ ) as never,
2943
+ });
2944
+
2945
+ await handler(
2946
+ "!room:example.org",
2947
+ createMatrixTextMessageEvent({ eventId: "$msg1", body: "hello" }),
2948
+ );
2949
+
2950
+ expect(capturedDisableBlockStreaming).toBe(false);
2951
+ });
2952
+ });