@athenaintel/react 0.41.3 → 0.42.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (479) hide show
  1. package/README.md +132 -10
  2. package/dist/agent-runtime/src/asset-attachment.d.ts +98 -0
  3. package/dist/agent-runtime/src/athena-asset-drag.d.ts +32 -0
  4. package/dist/agent-runtime/src/auth-denial.d.ts +29 -0
  5. package/dist/agent-runtime/src/chat-outbox-attachments.cjs +41 -0
  6. package/dist/agent-runtime/src/chat-outbox-attachments.cjs.map +1 -0
  7. package/dist/agent-runtime/src/chat-outbox-attachments.d.ts +38 -0
  8. package/dist/agent-runtime/src/chat-outbox-attachments.js +41 -0
  9. package/dist/agent-runtime/src/chat-outbox-attachments.js.map +1 -0
  10. package/dist/agent-runtime/src/chat-outbox-signals.cjs +63 -0
  11. package/dist/agent-runtime/src/chat-outbox-signals.cjs.map +1 -0
  12. package/dist/agent-runtime/src/chat-outbox-signals.d.ts +12 -0
  13. package/dist/agent-runtime/src/chat-outbox-signals.js +63 -0
  14. package/dist/agent-runtime/src/chat-outbox-signals.js.map +1 -0
  15. package/dist/agent-runtime/src/chat-outbox-store.cjs +509 -0
  16. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-store.d.ts +203 -0
  18. package/dist/agent-runtime/src/chat-outbox-store.js +509 -0
  19. package/dist/agent-runtime/src/chat-outbox-store.js.map +1 -0
  20. package/dist/agent-runtime/src/chat-outbox-thread.cjs +136 -0
  21. package/dist/agent-runtime/src/chat-outbox-thread.cjs.map +1 -0
  22. package/dist/agent-runtime/src/chat-outbox-thread.d.ts +118 -0
  23. package/dist/agent-runtime/src/chat-outbox-thread.js +136 -0
  24. package/dist/agent-runtime/src/chat-outbox-thread.js.map +1 -0
  25. package/dist/agent-runtime/src/chat-outbox.cjs +696 -0
  26. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -0
  27. package/dist/agent-runtime/src/chat-outbox.d.ts +285 -0
  28. package/dist/agent-runtime/src/chat-outbox.js +696 -0
  29. package/dist/agent-runtime/src/chat-outbox.js.map +1 -0
  30. package/dist/agent-runtime/src/chat-socket-reachability.d.ts +45 -0
  31. package/dist/agent-runtime/src/client-tool-bridge.d.ts +152 -0
  32. package/dist/agent-runtime/src/client-tools.d.ts +133 -0
  33. package/dist/agent-runtime/src/composer-markdown.cjs +10 -0
  34. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
  35. package/dist/agent-runtime/src/composer-markdown.d.ts +108 -0
  36. package/dist/agent-runtime/src/composer-markdown.js +10 -0
  37. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  38. package/dist/agent-runtime/src/config-mutations.d.ts +51 -0
  39. package/dist/agent-runtime/src/conversation-index.d.ts +110 -0
  40. package/dist/agent-runtime/src/conversation-list.d.ts +343 -0
  41. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +3 -2
  42. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  43. package/dist/agent-runtime/src/deep-agent-transport-recipe.d.ts +166 -0
  44. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -2
  45. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  46. package/dist/agent-runtime/src/desktop-handoff.d.ts +139 -0
  47. package/dist/agent-runtime/src/durable-thread-snapshot-cache.d.ts +60 -0
  48. package/dist/agent-runtime/src/edit-command.d.ts +156 -0
  49. package/dist/agent-runtime/src/errors.d.ts +174 -0
  50. package/dist/agent-runtime/src/execute-output.d.ts +31 -0
  51. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +16 -2
  52. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  53. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +202 -0
  54. package/dist/agent-runtime/src/generated/runconfig-contract.js +16 -2
  55. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  56. package/dist/agent-runtime/src/github-wake-event.d.ts +77 -0
  57. package/dist/agent-runtime/src/index.d.ts +74 -0
  58. package/dist/agent-runtime/src/interrupts.cjs +17 -0
  59. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  60. package/dist/agent-runtime/src/interrupts.d.ts +348 -0
  61. package/dist/agent-runtime/src/interrupts.js +17 -0
  62. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  63. package/dist/agent-runtime/src/lane-follow.d.ts +121 -0
  64. package/dist/agent-runtime/src/lane-history.cjs +209 -0
  65. package/dist/agent-runtime/src/lane-history.cjs.map +1 -0
  66. package/dist/agent-runtime/src/lane-history.d.ts +175 -0
  67. package/dist/agent-runtime/src/lane-history.js +209 -0
  68. package/dist/agent-runtime/src/lane-history.js.map +1 -0
  69. package/dist/agent-runtime/src/lane-images.d.ts +184 -0
  70. package/dist/agent-runtime/src/message-author.d.ts +43 -0
  71. package/dist/agent-runtime/src/message-text.cjs +15 -0
  72. package/dist/agent-runtime/src/message-text.cjs.map +1 -0
  73. package/dist/agent-runtime/src/message-text.d.ts +47 -0
  74. package/dist/agent-runtime/src/message-text.js +15 -0
  75. package/dist/agent-runtime/src/message-text.js.map +1 -0
  76. package/dist/agent-runtime/src/message-window.cjs +15 -1
  77. package/dist/agent-runtime/src/message-window.cjs.map +1 -1
  78. package/dist/agent-runtime/src/message-window.d.ts +159 -0
  79. package/dist/agent-runtime/src/message-window.js +16 -2
  80. package/dist/agent-runtime/src/message-window.js.map +1 -1
  81. package/dist/agent-runtime/src/messages.cjs +123 -8
  82. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  83. package/dist/agent-runtime/src/messages.d.ts +621 -0
  84. package/dist/agent-runtime/src/messages.js +123 -8
  85. package/dist/agent-runtime/src/messages.js.map +1 -1
  86. package/dist/agent-runtime/src/model-context.d.ts +22 -0
  87. package/dist/agent-runtime/src/offline-status.d.ts +157 -0
  88. package/dist/agent-runtime/src/optimistic-content.d.ts +21 -0
  89. package/dist/agent-runtime/src/protocol.cjs +12 -4
  90. package/dist/agent-runtime/src/protocol.cjs.map +1 -1
  91. package/dist/agent-runtime/src/protocol.d.ts +119 -0
  92. package/dist/agent-runtime/src/protocol.js +13 -5
  93. package/dist/agent-runtime/src/protocol.js.map +1 -1
  94. package/dist/agent-runtime/src/ptc-subcalls.d.ts +51 -0
  95. package/dist/agent-runtime/src/queue.d.ts +138 -0
  96. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +10 -0
  97. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  98. package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +161 -0
  99. package/dist/agent-runtime/src/quota-safe-local-storage-session.js +10 -0
  100. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  101. package/dist/agent-runtime/src/running-tool-placeholder.cjs +11 -0
  102. package/dist/agent-runtime/src/running-tool-placeholder.cjs.map +1 -0
  103. package/dist/agent-runtime/src/running-tool-placeholder.d.ts +25 -0
  104. package/dist/agent-runtime/src/running-tool-placeholder.js +11 -0
  105. package/dist/agent-runtime/src/running-tool-placeholder.js.map +1 -0
  106. package/dist/agent-runtime/src/runtime-messages.d.ts +104 -0
  107. package/dist/agent-runtime/src/screen-point.d.ts +151 -0
  108. package/dist/agent-runtime/src/sealed-idb.cjs +112 -0
  109. package/dist/agent-runtime/src/sealed-idb.cjs.map +1 -0
  110. package/dist/agent-runtime/src/sealed-idb.d.ts +106 -0
  111. package/dist/agent-runtime/src/sealed-idb.js +112 -0
  112. package/dist/agent-runtime/src/sealed-idb.js.map +1 -0
  113. package/dist/agent-runtime/src/send-recovery.d.ts +40 -0
  114. package/dist/agent-runtime/src/session-lane-scope.cjs +25 -0
  115. package/dist/agent-runtime/src/session-lane-scope.cjs.map +1 -0
  116. package/dist/agent-runtime/src/session-lane-scope.d.ts +59 -0
  117. package/dist/agent-runtime/src/session-lane-scope.js +25 -0
  118. package/dist/agent-runtime/src/session-lane-scope.js.map +1 -0
  119. package/dist/agent-runtime/src/statewire-attach-observer.d.ts +194 -0
  120. package/dist/agent-runtime/src/statewire-diagnostics.d.ts +74 -0
  121. package/dist/agent-runtime/src/statewire-state.d.ts +29 -0
  122. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  123. package/dist/agent-runtime/src/statewire-suspended.d.ts +27 -0
  124. package/dist/agent-runtime/src/statewire-suspended.js.map +1 -1
  125. package/dist/agent-runtime/src/statewire-transport.d.ts +40 -0
  126. package/dist/agent-runtime/src/streaming-markdown.d.ts +46 -0
  127. package/dist/agent-runtime/src/subagent-transcripts.cjs +209 -0
  128. package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -0
  129. package/dist/agent-runtime/src/subagent-transcripts.d.ts +71 -0
  130. package/dist/agent-runtime/src/subagent-transcripts.js +209 -0
  131. package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -0
  132. package/dist/agent-runtime/src/subagents.cjs +253 -0
  133. package/dist/agent-runtime/src/subagents.cjs.map +1 -0
  134. package/dist/agent-runtime/src/subagents.d.ts +311 -0
  135. package/dist/agent-runtime/src/subagents.js +253 -0
  136. package/dist/agent-runtime/src/subagents.js.map +1 -0
  137. package/dist/agent-runtime/src/subscription-wake-event.d.ts +111 -0
  138. package/dist/agent-runtime/src/thread-extras.d.ts +43 -0
  139. package/dist/agent-runtime/src/thread-handoff.d.ts +364 -0
  140. package/dist/agent-runtime/src/thread-prewarm-controller.d.ts +76 -0
  141. package/dist/agent-runtime/src/thread-prewarm.d.ts +118 -0
  142. package/dist/agent-runtime/src/thread-snapshot-cache.d.ts +99 -0
  143. package/dist/agent-runtime/src/thread-snapshot-mirror.cjs +46 -117
  144. package/dist/agent-runtime/src/thread-snapshot-mirror.cjs.map +1 -1
  145. package/dist/agent-runtime/src/thread-snapshot-mirror.d.ts +101 -0
  146. package/dist/agent-runtime/src/thread-snapshot-mirror.js +17 -88
  147. package/dist/agent-runtime/src/thread-snapshot-mirror.js.map +1 -1
  148. package/dist/agent-runtime/src/thread-status.d.ts +53 -0
  149. package/dist/agent-runtime/src/tool-metadata.d.ts +146 -0
  150. package/dist/agent-runtime/src/tool-names.cjs +71 -0
  151. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  152. package/dist/agent-runtime/src/tool-names.d.ts +67 -0
  153. package/dist/agent-runtime/src/tool-names.js +72 -1
  154. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  155. package/dist/agent-runtime/src/tool-outputs.d.ts +35 -0
  156. package/dist/agent-runtime/src/tool-result.cjs +1 -0
  157. package/dist/agent-runtime/src/tool-result.cjs.map +1 -1
  158. package/dist/agent-runtime/src/tool-result.d.ts +126 -0
  159. package/dist/agent-runtime/src/tool-result.js +1 -0
  160. package/dist/agent-runtime/src/tool-result.js.map +1 -1
  161. package/dist/agent-runtime/src/types.d.ts +159 -0
  162. package/dist/agent-runtime/src/use-conversation-list.d.ts +76 -0
  163. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +136 -0
  164. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -0
  165. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +64 -0
  166. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +136 -0
  167. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -0
  168. package/dist/agent-runtime/src/use-deep-agent-config.d.ts +169 -0
  169. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +13 -0
  170. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  171. package/dist/agent-runtime/src/use-deep-agent-edit-submit.d.ts +22 -0
  172. package/dist/agent-runtime/src/use-deep-agent-edit-submit.js +13 -0
  173. package/dist/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -1
  174. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +37 -2
  175. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  176. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +177 -0
  177. package/dist/agent-runtime/src/use-deep-agent-runtime.js +38 -3
  178. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  179. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +39 -13
  180. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  181. package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +352 -0
  182. package/dist/agent-runtime/src/use-deep-agent-thread.js +39 -13
  183. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  184. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +1019 -0
  185. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -0
  186. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +409 -0
  187. package/dist/agent-runtime/src/use-deep-agent-voice.js +1019 -0
  188. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -0
  189. package/dist/agent-runtime/src/use-deep-agent-window-sync.d.ts +102 -0
  190. package/dist/agent-runtime/src/use-historical-edit-attachments.d.ts +2 -0
  191. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +84 -0
  192. package/dist/agent-runtime/src/voice-presentation.cjs +2 -0
  193. package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -1
  194. package/dist/agent-runtime/src/voice-presentation.d.ts +80 -0
  195. package/dist/agent-runtime/src/voice-presentation.js +2 -0
  196. package/dist/agent-runtime/src/voice-presentation.js.map +1 -1
  197. package/dist/agent-runtime/src/voice-turn-grouping.d.ts +28 -0
  198. package/dist/agent-runtime/src/voice-wire-types.d.ts +15 -0
  199. package/dist/agent-runtime/src/withdrawn-turns.d.ts +97 -0
  200. package/dist/catalog/runtime-catalog.js +1 -1
  201. package/dist/chat/AthenaChat.cjs +192 -103
  202. package/dist/chat/AthenaChat.cjs.map +1 -1
  203. package/dist/chat/AthenaChat.d.ts +9 -0
  204. package/dist/chat/AthenaChat.js +194 -105
  205. package/dist/chat/AthenaChat.js.map +1 -1
  206. package/dist/chat/StatewireApprovalCard.d.ts +1 -1
  207. package/dist/chat/StatewireClientToolBridge.d.ts +1 -1
  208. package/dist/chat/StatewireQueuedMessages.cjs +11 -4
  209. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  210. package/dist/chat/StatewireQueuedMessages.d.ts +1 -1
  211. package/dist/chat/StatewireQueuedMessages.js +11 -4
  212. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  213. package/dist/chat/chat-outbox-rows.cjs +223 -0
  214. package/dist/chat/chat-outbox-rows.cjs.map +1 -0
  215. package/dist/chat/chat-outbox-rows.d.ts +29 -0
  216. package/dist/chat/chat-outbox-rows.js +223 -0
  217. package/dist/chat/chat-outbox-rows.js.map +1 -0
  218. package/dist/chat/chat-voice-controls.cjs +128 -0
  219. package/dist/chat/chat-voice-controls.cjs.map +1 -0
  220. package/dist/chat/chat-voice-controls.d.ts +19 -0
  221. package/dist/chat/chat-voice-controls.js +128 -0
  222. package/dist/chat/chat-voice-controls.js.map +1 -0
  223. package/dist/chat/statewire-approval.d.ts +1 -1
  224. package/dist/chat/statewire-client-tools.d.ts +1 -1
  225. package/dist/chat/super-grouping/SuperGroupingCard.cjs +3 -1
  226. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  227. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +7 -1
  228. package/dist/chat/super-grouping/SuperGroupingCard.js +3 -1
  229. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  230. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +7 -2
  231. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  232. package/dist/chat/super-grouping/SuperGroupingTranscript.d.ts +2 -2
  233. package/dist/chat/super-grouping/SuperGroupingTranscript.js +7 -2
  234. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  235. package/dist/chat/super-grouping/activity-timeline.cjs +15 -8
  236. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  237. package/dist/chat/super-grouping/activity-timeline.d.ts +18 -8
  238. package/dist/chat/super-grouping/activity-timeline.js +15 -8
  239. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  240. package/dist/chat/use-statewire-approval-request.cjs +36 -0
  241. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  242. package/dist/chat/use-statewire-approval-request.d.ts +49 -1
  243. package/dist/chat/use-statewire-approval-request.js +39 -3
  244. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  245. package/dist/chat-ui/composer/tiptap-composer.cjs +133 -14
  246. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  247. package/dist/chat-ui/composer/tiptap-composer.d.ts +33 -1
  248. package/dist/chat-ui/composer/tiptap-composer.js +135 -16
  249. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  250. package/dist/chat-ui/header/conversation-history-panel.d.ts +1 -1
  251. package/dist/chat-ui/index.d.ts +1 -1
  252. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +2 -1
  253. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  254. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +3 -1
  255. package/dist/chat-ui/mentions/suggestions/data/api-client.js +2 -1
  256. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  257. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +29 -51
  258. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
  259. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +2 -2
  260. package/dist/chat-ui/mentions/use-account-workspace-id.js +30 -52
  261. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
  262. package/dist/chat-ui/messages/message-components.cjs +15 -0
  263. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  264. package/dist/chat-ui/messages/message-components.js +15 -0
  265. package/dist/chat-ui/messages/message-components.js.map +1 -1
  266. package/dist/chat-ui/messages/runtime-message.d.ts +1 -1
  267. package/dist/chat-ui/messages/statewire-continue-run.d.ts +1 -1
  268. package/dist/chat-ui/messages/user-edit-composer.cjs +15 -2
  269. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  270. package/dist/chat-ui/messages/user-edit-composer.d.ts +4 -2
  271. package/dist/chat-ui/messages/user-edit-composer.js +15 -2
  272. package/dist/chat-ui/messages/user-edit-composer.js.map +1 -1
  273. package/dist/chat-ui/messages/wake-marker.d.ts +1 -1
  274. package/dist/chat-ui/rich-text/chat-text-schema.cjs +1 -0
  275. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
  276. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +3 -0
  277. package/dist/chat-ui/rich-text/chat-text-schema.js +1 -0
  278. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
  279. package/dist/chat-ui/statewire.cjs +1 -0
  280. package/dist/chat-ui/statewire.cjs.map +1 -1
  281. package/dist/chat-ui/statewire.d.ts +2 -2
  282. package/dist/chat-ui/statewire.js +2 -1
  283. package/dist/chat-ui/thread/composer-send-or-stop.cjs +2 -1
  284. package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
  285. package/dist/chat-ui/thread/composer-send-or-stop.d.ts +2 -0
  286. package/dist/chat-ui/thread/composer-send-or-stop.js +2 -1
  287. package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
  288. package/dist/chat-ui/thread/statewire-history-edge.d.ts +1 -1
  289. package/dist/composer/AttachmentContext.cjs +8 -4
  290. package/dist/composer/AttachmentContext.cjs.map +1 -1
  291. package/dist/composer/AttachmentContext.d.ts +7 -0
  292. package/dist/composer/AttachmentContext.js +8 -4
  293. package/dist/composer/AttachmentContext.js.map +1 -1
  294. package/dist/composer/build-composed-message.cjs +34 -0
  295. package/dist/composer/build-composed-message.cjs.map +1 -1
  296. package/dist/composer/build-composed-message.d.ts +20 -0
  297. package/dist/composer/build-composed-message.js +35 -1
  298. package/dist/composer/build-composed-message.js.map +1 -1
  299. package/dist/composer/composer-handoff.cjs +39 -2
  300. package/dist/composer/composer-handoff.cjs.map +1 -1
  301. package/dist/composer/composer-handoff.d.ts +28 -3
  302. package/dist/composer/composer-handoff.js +39 -2
  303. package/dist/composer/composer-handoff.js.map +1 -1
  304. package/dist/composer/useAttachFiles.cjs +15 -2
  305. package/dist/composer/useAttachFiles.cjs.map +1 -1
  306. package/dist/composer/useAttachFiles.d.ts +11 -0
  307. package/dist/composer/useAttachFiles.js +15 -2
  308. package/dist/composer/useAttachFiles.js.map +1 -1
  309. package/dist/composer/useSendMessage.cjs.map +1 -1
  310. package/dist/composer/useSendMessage.d.ts +4 -3
  311. package/dist/composer/useSendMessage.js.map +1 -1
  312. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  313. package/dist/diagnostics/athena-diagnostics.d.ts +3 -1
  314. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  315. package/dist/index.cjs +13 -0
  316. package/dist/index.cjs.map +1 -1
  317. package/dist/index.d.ts +14 -7
  318. package/dist/index.js +14 -1
  319. package/dist/index.js.map +1 -1
  320. package/dist/offline/chat-outbox.cjs +57 -0
  321. package/dist/offline/chat-outbox.cjs.map +1 -0
  322. package/dist/offline/chat-outbox.d.ts +80 -0
  323. package/dist/offline/chat-outbox.js +57 -0
  324. package/dist/offline/chat-outbox.js.map +1 -0
  325. package/dist/offline/offline-history.d.ts +1 -1
  326. package/dist/provider/AthenaProvider.cjs +162 -8
  327. package/dist/provider/AthenaProvider.cjs.map +1 -1
  328. package/dist/provider/AthenaProvider.d.ts +15 -1
  329. package/dist/provider/AthenaProvider.js +163 -9
  330. package/dist/provider/AthenaProvider.js.map +1 -1
  331. package/dist/provider/statewire-window-context.d.ts +1 -1
  332. package/dist/react/package.json.cjs +1 -1
  333. package/dist/react/package.json.js +1 -1
  334. package/dist/references/src/anchors/file-line-range.d.ts +58 -0
  335. package/dist/references/src/anchors/format.d.ts +21 -0
  336. package/dist/references/src/anchors/message-anchors.d.ts +71 -0
  337. package/dist/references/src/anchors/parse.d.ts +8 -0
  338. package/dist/references/src/anchors/registry-contract.d.ts +24 -0
  339. package/dist/references/src/anchors/registry.d.ts +19 -0
  340. package/dist/references/src/anchors/schemas.d.ts +194 -0
  341. package/dist/references/src/anchors/serialize.d.ts +8 -0
  342. package/dist/references/src/anchors/time.d.ts +78 -0
  343. package/dist/references/src/anchors/types.d.ts +474 -0
  344. package/dist/references/src/asset-bounds.d.ts +27 -0
  345. package/dist/references/src/asset-links.d.ts +23 -0
  346. package/dist/references/src/asset-reference.d.ts +16 -0
  347. package/dist/references/src/formats/format-catalog.d.ts +79 -0
  348. package/dist/references/src/formats/markdown/parse-reference-markdown.d.ts +28 -0
  349. package/dist/references/src/formats/markdown/reference-display-name.d.ts +6 -0
  350. package/dist/references/src/formats/object/asset-object.d.ts +9 -0
  351. package/dist/references/src/formats/object/callable-object.d.ts +6 -0
  352. package/dist/references/src/formats/object/decode-reference-object-payload.d.ts +3 -0
  353. package/dist/references/src/formats/object/external-url-object.d.ts +9 -0
  354. package/dist/references/src/formats/object/group-object.d.ts +9 -0
  355. package/dist/references/src/formats/object/navigation-object.d.ts +9 -0
  356. package/dist/references/src/formats/object/parse-reference-object.d.ts +11 -0
  357. package/dist/references/src/formats/object/person-object.d.ts +9 -0
  358. package/dist/references/src/formats/uri/asset-mention-uri.d.ts +9 -0
  359. package/dist/references/src/formats/uri/asset-spaces-url.d.ts +9 -0
  360. package/dist/references/src/formats/uri/callable-mention-uris.d.ts +9 -0
  361. package/dist/references/src/formats/uri/detect-uri-wire.d.ts +9 -0
  362. package/dist/references/src/formats/uri/group-mention-uri.d.ts +12 -0
  363. package/dist/references/src/formats/uri/navigation-spaces-url.d.ts +14 -0
  364. package/dist/references/src/formats/uri/parse-reference-uri.d.ts +20 -0
  365. package/dist/references/src/formats/uri/person-mention-uri.d.ts +9 -0
  366. package/dist/references/src/formats/uri/template-placeholder.d.ts +12 -0
  367. package/dist/references/src/index.d.ts +47 -0
  368. package/dist/references/src/legacy/index.d.ts +14 -0
  369. package/dist/references/src/legacy/pre-reference-asset-url.d.ts +57 -0
  370. package/dist/references/src/legacy/pre-reference-citation-bridge.d.ts +22 -0
  371. package/dist/references/src/legacy/pre-reference-citation.d.ts +138 -0
  372. package/dist/references/src/legacy/pre-reference-external-url.d.ts +31 -0
  373. package/dist/references/src/legacy/pre-reference-format.d.ts +8 -0
  374. package/dist/references/src/legacy/pre-reference-mention.d.ts +27 -0
  375. package/dist/references/src/legacy/pre-reference-object.d.ts +8 -0
  376. package/dist/references/src/legacy/pre-reference-uri.d.ts +12 -0
  377. package/dist/references/src/legacy.d.ts +2 -0
  378. package/dist/references/src/mention-href-patterns.d.ts +19 -0
  379. package/dist/references/src/mention-node/index.d.ts +5 -0
  380. package/dist/references/src/mention-node/mention-node.d.ts +31 -0
  381. package/dist/references/src/mention-node/resolve-node-attrs.d.ts +27 -0
  382. package/dist/references/src/parse-reference.d.ts +23 -0
  383. package/dist/references/src/schemas.d.ts +463 -0
  384. package/dist/references/src/serialize-reference.d.ts +50 -0
  385. package/dist/references/src/sheet-name.d.ts +10 -0
  386. package/dist/references/src/tool-option-schemas.d.ts +597 -0
  387. package/dist/references/src/types.d.ts +125 -0
  388. package/dist/references/src/version-ref.d.ts +30 -0
  389. package/dist/runtime/statewire-lifecycle.d.ts +1 -1
  390. package/dist/runtime/statewire-model-lane.d.ts +1 -1
  391. package/dist/runtime/statewire-server-lane-context.d.ts +1 -1
  392. package/dist/runtime/statewire-session-key.cjs +7 -0
  393. package/dist/runtime/statewire-session-key.cjs.map +1 -1
  394. package/dist/runtime/statewire-session-key.d.ts +19 -0
  395. package/dist/runtime/statewire-session-key.js +8 -1
  396. package/dist/runtime/statewire-session-key.js.map +1 -1
  397. package/dist/runtime/statewire-session-lane.cjs +48 -0
  398. package/dist/runtime/statewire-session-lane.cjs.map +1 -0
  399. package/dist/runtime/statewire-session-lane.d.ts +29 -0
  400. package/dist/runtime/statewire-session-lane.js +48 -0
  401. package/dist/runtime/statewire-session-lane.js.map +1 -0
  402. package/dist/runtime/statewire-thread-config-lane.d.ts +1 -1
  403. package/dist/runtime/useAthenaStatewireRuntime.cjs +19 -5
  404. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  405. package/dist/runtime/useAthenaStatewireRuntime.d.ts +15 -1
  406. package/dist/runtime/useAthenaStatewireRuntime.js +20 -6
  407. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  408. package/dist/styles.css +1 -1
  409. package/dist/threads/api.d.ts +1 -1
  410. package/dist/threads/conversation-list-fetcher.d.ts +1 -1
  411. package/dist/threads/index-triggered-refresh.cjs +164 -0
  412. package/dist/threads/index-triggered-refresh.cjs.map +1 -0
  413. package/dist/threads/index-triggered-refresh.d.ts +70 -0
  414. package/dist/threads/index-triggered-refresh.js +164 -0
  415. package/dist/threads/index-triggered-refresh.js.map +1 -0
  416. package/dist/threads/offline-session-list.d.ts +1 -1
  417. package/dist/threads/pull-request-display.d.ts +1 -1
  418. package/dist/threads/session-list-model.d.ts +1 -1
  419. package/dist/threads/session-list-tab-share.cjs +150 -0
  420. package/dist/threads/session-list-tab-share.cjs.map +1 -0
  421. package/dist/threads/session-list-tab-share.d.ts +73 -0
  422. package/dist/threads/session-list-tab-share.js +150 -0
  423. package/dist/threads/session-list-tab-share.js.map +1 -0
  424. package/dist/threads/session-row-parts.d.ts +1 -1
  425. package/dist/threads/sessions-query.d.ts +1 -1
  426. package/dist/threads/statewire-thread-list.cjs +42 -16
  427. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  428. package/dist/threads/statewire-thread-list.d.ts +11 -2
  429. package/dist/threads/statewire-thread-list.js +43 -17
  430. package/dist/threads/statewire-thread-list.js.map +1 -1
  431. package/dist/threads/thread-prefetcher.d.ts +1 -1
  432. package/dist/threads/use-athena-session-attention.d.ts +1 -1
  433. package/dist/threads/use-athena-sessions.cjs +32 -22
  434. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  435. package/dist/threads/use-athena-sessions.js +33 -23
  436. package/dist/threads/use-athena-sessions.js.map +1 -1
  437. package/dist/threads/use-rest-conversation-history.d.ts +1 -1
  438. package/dist/threads/use-statewire-conversation-history.d.ts +5 -5
  439. package/dist/tiptap-markdown-table/src/markdown-table-serializer.d.ts +56 -0
  440. package/dist/tools/NestedPtcMessages.cjs +14 -9
  441. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  442. package/dist/tools/NestedPtcMessages.d.ts +9 -0
  443. package/dist/tools/NestedPtcMessages.js +6 -1
  444. package/dist/tools/NestedPtcMessages.js.map +1 -1
  445. package/dist/tools/index.d.ts +1 -1
  446. package/dist/tools/primitives.d.ts +1 -1
  447. package/dist/tools/subagent-task-tool-ui.cjs +494 -0
  448. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -0
  449. package/dist/tools/subagent-task-tool-ui.d.ts +109 -0
  450. package/dist/tools/subagent-task-tool-ui.js +494 -0
  451. package/dist/tools/subagent-task-tool-ui.js.map +1 -0
  452. package/dist/tools/tool-fallback.d.ts +1 -1
  453. package/dist/tools/tool-icons.d.ts +1 -1
  454. package/dist/tools/tool-summary.d.ts +1 -1
  455. package/dist/tools/tool-uis.cjs +4 -0
  456. package/dist/tools/tool-uis.cjs.map +1 -1
  457. package/dist/tools/tool-uis.js +4 -0
  458. package/dist/tools/tool-uis.js.map +1 -1
  459. package/dist/voice/chat.cjs +6 -0
  460. package/dist/voice/chat.cjs.map +1 -0
  461. package/dist/voice/chat.d.ts +2 -0
  462. package/dist/voice/chat.js +6 -0
  463. package/dist/voice/chat.js.map +1 -0
  464. package/dist/voice/livekit-join.cjs +119 -0
  465. package/dist/voice/livekit-join.cjs.map +1 -0
  466. package/dist/voice/livekit-join.d.ts +8 -0
  467. package/dist/voice/livekit-join.js +119 -0
  468. package/dist/voice/livekit-join.js.map +1 -0
  469. package/dist/voice/livekit.cjs +32 -0
  470. package/dist/voice/livekit.cjs.map +1 -0
  471. package/dist/voice/livekit.d.ts +80 -0
  472. package/dist/voice/livekit.js +32 -0
  473. package/dist/voice/livekit.js.map +1 -0
  474. package/dist/voice/use-chat-voice-enabled.cjs +43 -0
  475. package/dist/voice/use-chat-voice-enabled.cjs.map +1 -0
  476. package/dist/voice/use-chat-voice-enabled.d.ts +9 -0
  477. package/dist/voice/use-chat-voice-enabled.js +43 -0
  478. package/dist/voice/use-chat-voice-enabled.js.map +1 -0
  479. package/package.json +22 -16
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-outbox.js","sources":["../../../../agent-runtime/src/chat-outbox.ts"],"sourcesContent":["import type { ChatOutboxAttachmentCheck, ChatOutboxAttachmentVerdict } from \"./chat-outbox-attachments\";\nimport type {\n ChatOutboxAttachment,\n ChatOutboxClaim,\n ChatOutboxEntry,\n ChatOutboxFailureReason,\n ChatOutboxFile,\n ChatOutboxRecord,\n ChatOutboxStore,\n} from \"./chat-outbox-store\";\n\n/**\n * The chat outbox: a message typed while Athena can't be reached waits on this device and is sent\n * once Athena answers again, while the app is in front, after a few seconds the person can cancel\n * (decision 5 of the offline plan, `docs/plans/2026-10-27-offline-everywhere-plan.md`).\n *\n * - **Held before the conversation's journal, never inside it.** A send made while Athena can't be\n * reached does not reach statewire at all: statewire would replay it the moment its connection\n * returns (from a hidden tab too) and has no way to take a journaled statement back. The message\n * waits here instead, and reaches statewire only when this controller hands it over, under the\n * id minted when it was typed.\n * - **Sent in front, with a countdown.** Once Athena is reachable and the app is in front (a visible\n * tab, an active app, a focused desktop window), the waiting messages count down\n * ({@link CHAT_OUTBOX_COUNTDOWN_MS}) with a Cancel that gives the text back to the composer; then\n * each is handed over once. Going to the background or losing Athena stops the countdown; it\n * starts over, in full, when both are back.\n * - **A day is the limit for sending on its own.** A message that waited more than\n * {@link CHAT_OUTBOX_ASK_AFTER_MS} asks first (Send / Edit / Discard); the messages behind it wait\n * for the answer, so nothing is sent out of order.\n * - **Once per message, never a loop.** A message is handed over at most once per return of Athena.\n * A hand-off that fails before the conversation took it (anything but the conversation going\n * away) stays as \"Couldn't send\" with Retry and Discard, kept with the message so no window and\n * no later mount sends it again on its own. Once the conversation's journal took it, statewire\n * owns it: it delivers it exactly once, and a refusal lands in the conversation's own failed\n * lane (Retry / Discard there).\n * - **One sender per message.** A hand-off claims the message in the store first, atomically\n * across windows ({@link CHAT_OUTBOX_CLAIM_LEASE_MS}), so two windows on the same conversation\n * never hand the same message twice (a second hand-off of an id whose run is in flight would be\n * read as an edit of that turn). The gate is checked again once the claim is written: a tab\n * hidden (or an Athena lost) meanwhile lets the claim go, and the message waits again.\n * - **Nothing overtakes.** Until the conversation's kept messages are read, a new send waits too\n * (it goes at once if nothing older turns up), and a message the person told to go now still\n * goes after the older ones in line.\n * - **Kept until it is safe to let go.** The waiting record is removed only once statewire has the\n * statement durably (`posted`, `applied` or settled), or once the conversation shows the message\n * (a journal adopted from an earlier page, or the message already on the transcript).\n * - **Its attachments go with it, still valid.** A message keeps the files that had finished\n * uploading before Athena went out of reach (references to files already in Athena; one picked\n * while it can't be reached is never attached). Once the message is claimed they are asked about\n * ({@link ChatOutboxOptions.checkAttachments}): one Athena refuses (deleted, or no longer shared\n * with the person) keeps the message as \"Couldn't send\" with Retry, Edit and Discard, and a check\n * Athena could not answer keeps it the same way as a send error. Nothing goes unchecked, and the\n * text is never lost.\n */\n\n/** How long the countdown before a waiting message is sent lasts. */\nexport const CHAT_OUTBOX_COUNTDOWN_MS = 5_000;\n/** A message that waited longer than this asks before it is sent. */\nexport const CHAT_OUTBOX_ASK_AFTER_MS = 24 * 60 * 60 * 1000;\n/** How long a window's claim on a message holds against another window's hand-off. */\nexport const CHAT_OUTBOX_CLAIM_LEASE_MS = 30_000;\n/** How long the check of a message's attachments may take before it counts as unanswered. */\nexport const CHAT_OUTBOX_ATTACHMENT_CHECK_TIMEOUT_MS = 15_000;\n\n/**\n * Why a sent message's Edit is not offered while Athena can't be reached (its tooltip, or the hint\n * under it where there are no tooltips). An edit rewinds the conversation and re-runs it: a\n * journaled one would replay the moment the connection returns, from a hidden window too, so an\n * edit never waits the way a new message does.\n */\nexport const CHAT_EDIT_UNREACHABLE_LABEL = \"Can't edit while Athena can't be reached\";\n\n/** What an edit submitted while Athena can't be reached says: the edit stays where it was typed. */\nexport const CHAT_EDIT_KEPT_MESSAGE =\n \"Can't reach Athena right now. Your edit stays here — submit it once Athena is back.\";\n\n/** An edit submitted while Athena can't be reached: refused, never queued (its message says so). */\nexport class ChatEditUnreachableError extends Error {\n constructor() {\n super(CHAT_EDIT_KEPT_MESSAGE);\n this.name = \"ChatEditUnreachableError\";\n }\n}\n\n/** A boolean the host reports and notifies on: Athena's reachability, the app being in front. */\nexport interface ChatOutboxSignal {\n get(): boolean;\n subscribe(listener: () => void): () => void;\n}\n\n/**\n * Whether a hand-off reaches the conversation now: `ready` (attached, a never-started chat that\n * dials on its first send, or an idle channel that reattaches on demand — in each case what the\n * conversation shows is the server's, so a message missing from it never reached it),\n * `connecting` (reattaching: what it shows may be a remembered snapshot), `refused` (the host\n * refused the conversation: stopped, or parked on an authorization denial).\n */\nexport type ChatOutboxThreadReadiness = \"ready\" | \"connecting\" | \"refused\";\n\n/** The conversation the outbox hands messages to (`chat-outbox-thread.ts` adapts a statewire thread). */\nexport interface ChatOutboxThreadPort {\n readiness(): ChatOutboxThreadReadiness;\n /**\n * Message ids the conversation shows anywhere: its transcript, its queue and steer lanes, the\n * run being dispatched, its failed lane — this page's journal included (statewire folds a\n * journaled send into them, one adopted from an earlier page too).\n */\n heldIds(): ReadonlySet<string>;\n /** Hand the message to the conversation under its own id; settles with the server's verdict. */\n send(entry: ChatOutboxEntry): Promise<unknown>;\n subscribe(listener: () => void): () => void;\n}\n\nexport type ChatOutboxRowState =\n /** Not sent yet: Athena can't be reached, or the app is not in front. */\n | { kind: \"waiting\" }\n /** Athena is back: the message is sent when the countdown ends, unless cancelled. */\n | { kind: \"countdown\"; endsAt: number }\n /** It waited more than a day: Send, Edit or Discard. */\n | { kind: \"ask\" }\n /** Being handed to the conversation (by this window or another). */\n | { kind: \"sending\" }\n /** The hand-off failed for a reason other than Athena being unreachable. */\n | { kind: \"failed\"; reason: ChatOutboxFailureReason; message: string };\n\nexport interface ChatOutboxRow {\n entry: ChatOutboxEntry;\n state: ChatOutboxRowState;\n}\n\n/** Another conversation of the same person with messages waiting (the tray offers to open it). */\nexport interface ChatOutboxElsewhere {\n threadId: string;\n /** How many messages wait there. */\n count: number;\n /** The oldest of them: its text names the conversation. */\n first: ChatOutboxEntry;\n /**\n * Every message waiting there was typed into a chat that had never started, so it opens as the\n * new chat it still is (one typed after the chat started says it has a session now).\n */\n newChat: boolean;\n}\n\nexport interface ChatOutboxSnapshot {\n rows: readonly ChatOutboxRow[];\n /** When the running countdown ends (epoch ms), or `null`. */\n countdownEndsAt: number | null;\n /** Whether every waiting message is kept on this device (false: only while the page stays open). */\n durable: boolean;\n /** Whether the thread's kept messages have been read. */\n loaded: boolean;\n /** The person's other conversations with messages waiting, oldest first. */\n elsewhere: readonly ChatOutboxElsewhere[];\n}\n\n/** What a failed row says. */\nexport function chatOutboxFailureMessage(reason: ChatOutboxFailureReason): string {\n switch (reason) {\n case \"refused\":\n return \"This conversation can't be reached right now.\";\n case \"prepare\":\n return \"Couldn't prepare this message to send.\";\n case \"attachment\":\n return \"An attachment is no longer available to you.\";\n default:\n return \"Couldn't send this message.\";\n }\n}\n\nexport interface ChatOutboxInput {\n text: string;\n composerMarkdown?: string;\n /** The draft as an HTML composer holds it (the phone's), given back exactly on Cancel. */\n composerHtml?: string;\n metadata?: Record<string, unknown>;\n files?: ChatOutboxFile[];\n /** Files already in Athena the message carries, asked about before it goes. */\n attachments?: ChatOutboxAttachment[];\n}\n\nexport type ChatOutboxEvent =\n | { type: \"held\"; threadId: string; messageId: string; durable: boolean }\n | { type: \"countdown-started\"; threadId: string; count: number }\n | { type: \"asked\"; threadId: string; messageId: string; ageMs: number }\n | { type: \"handed\"; threadId: string; messageId: string; auto: boolean; ageMs: number }\n | { type: \"delivered\"; threadId: string; messageId: string; status: string }\n | { type: \"adopted\"; threadId: string; messageId: string }\n | { type: \"failed\"; threadId: string; messageId: string; message: string; reason: ChatOutboxFailureReason }\n | { type: \"cancelled\"; threadId: string; messageId: string }\n | { type: \"discarded\"; threadId: string; messageId: string };\n\n/** The command-lifecycle update statewire reports (`onCommandChange`), structurally. */\nexport interface ChatOutboxCommandUpdate {\n status: \"queued\" | \"posted\" | \"applied\" | \"settled\";\n params?: readonly unknown[];\n failure?: { fate: string; cause?: string } | undefined;\n}\n\nexport interface ChatOutbox {\n readonly threadId: string;\n getSnapshot(): ChatOutboxSnapshot;\n subscribe(listener: () => void): () => void;\n /**\n * Whether Athena can be reached, as this outbox reads it (the host's model; in the SDK the\n * conversation's own channel too). An edit of a sent message waits on it as a send does: while it\n * says no, the Edit action is not offered and a submitted edit is refused\n * ({@link CHAT_EDIT_UNREACHABLE_LABEL}, {@link ChatEditUnreachableError}).\n */\n readonly reachability: ChatOutboxSignal;\n /**\n * Whether a send made now must wait here: Athena can't be reached, or earlier messages of this\n * conversation are still waiting (a later message never overtakes them).\n */\n shouldHold(): boolean;\n /** Keep a message typed now; it waits until it can be sent. */\n hold(input: ChatOutboxInput): ChatOutboxEntry;\n /** Cancel (or the ask's Edit): the message leaves the outbox and its text goes back to the composer. */\n cancel(id: string): void;\n /** The ask's Send, a failed row's Retry: hand it over now (one attempt; waits if Athena is out of reach). */\n send(id: string): void;\n discard(id: string): void;\n /** Feed statewire's command lifecycle (`onCommandChange`). */\n observeCommand(update: ChatOutboxCommandUpdate): void;\n /** Open another conversation the tray lists as holding waiting messages (`null`: the host cannot). */\n readonly openThread: ((target: { threadId: string; newChat: boolean }) => void) | null;\n dispose(): void;\n}\n\nexport interface ChatOutboxOptions {\n threadId: string;\n /**\n * The conversation has never started (a new chat): what waits reopens with it. Read when a\n * message is held, so a chat that started since stamps its later messages as started.\n */\n isNewChat: boolean | (() => boolean);\n /** Where waiting messages are kept for this person; `null` keeps them in memory only. */\n store: ChatOutboxStore | null;\n reachability: ChatOutboxSignal;\n foreground: ChatOutboxSignal;\n thread: ChatOutboxThreadPort;\n /** Give a cancelled message's text back to the composer. */\n restore: (entry: ChatOutboxEntry) => void;\n /**\n * Open another of the person's conversations that holds waiting messages (the tray's Open);\n * omitted where the host cannot switch conversations (an embedded chat).\n */\n openThread?: (target: { threadId: string; newChat: boolean }) => void;\n onEvent?: (event: ChatOutboxEvent) => void;\n /**\n * Asks Athena whether a waiting message's attachments can still be opened, right before it goes\n * (`createChatOutboxAttachmentCheck`). `refused` keeps the message as \"Couldn't send\" (Retry,\n * Edit, Discard); `unknown` too, as a send error. Omitted: attachments go unchecked.\n */\n checkAttachments?: ChatOutboxAttachmentCheck;\n now?: () => number;\n countdownMs?: number;\n askAfterMs?: number;\n claimLeaseMs?: number;\n /** How long the attachment check may take before it counts as unanswered. */\n attachmentCheckTimeoutMs?: number;\n newMessageId?: () => string;\n /** Timer seam (tests): schedule `task` after `ms`, returning what cancels it. */\n setTimer?: (task: () => void, ms: number) => () => void;\n}\n\ntype Phase =\n /** Waiting in line. */\n | { kind: \"idle\" }\n /**\n * The countdown ended (or the person said Send) while the conversation was reattaching, or\n * while the message's own write was still landing: it goes as soon as both are done.\n */\n | { kind: \"awaiting-thread\" }\n /** Claiming it in the store before the hand-off. */\n | { kind: \"claiming\" }\n /** Handed to the conversation; `journaled` once statewire's journal took it. */\n | { kind: \"handed\"; journaled: boolean }\n | { kind: \"failed\"; reason: ChatOutboxFailureReason };\n\n/** Fates statewire settles a send with when the conversation went away under it (not a failure). */\nconst AWAY_CAUSES: ReadonlySet<string> = new Set([\"unmount\", \"stream-gone\"]);\n\n/** The message id a run send carries, off a command update's params. */\nexport function chatOutboxCommandMessageId(params: readonly unknown[] | undefined): string | null {\n const first = params?.[0] as { message?: { id?: unknown } } | undefined;\n const id = first?.message?.id;\n return typeof id === \"string\" ? id : null;\n}\n\nfunction failureOf(error: unknown): { fate?: string; cause?: string; message: string } {\n const failure = (error as { failure?: { fate?: unknown; cause?: unknown } } | null)?.failure;\n const fate = typeof failure?.fate === \"string\" ? failure.fate : undefined;\n const cause = typeof failure?.cause === \"string\" ? failure.cause : undefined;\n const message = error instanceof Error ? error.message : String(error);\n return { fate, cause, message };\n}\n\nfunction defaultMessageId(): string {\n const host = globalThis as { crypto?: { randomUUID?: () => string } };\n if (typeof host.crypto?.randomUUID === \"function\") return host.crypto.randomUUID();\n // Hosts without randomUUID (none Athena ships today): a random v4-shaped id.\n const hex = Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;\n}\n\nfunction sameChatOutboxRowState(a: ChatOutboxRowState, b: ChatOutboxRowState): boolean {\n if (a.kind !== b.kind) return false;\n switch (a.kind) {\n case \"countdown\":\n return a.endsAt === (b as typeof a).endsAt;\n case \"failed\":\n return a.reason === (b as typeof a).reason && a.message === (b as typeof a).message;\n default:\n return true;\n }\n}\n\n/** Whether two listings of a message show the same thing (another chat's preview is re-read per listing). */\nfunction sameChatOutboxEntry(a: ChatOutboxEntry, b: ChatOutboxEntry): boolean {\n return (\n a === b ||\n (a.id === b.id &&\n a.threadId === b.threadId &&\n a.text === b.text &&\n a.newChat === b.newChat &&\n a.queuedAt === b.queuedAt &&\n a.composerMarkdown === b.composerMarkdown)\n );\n}\n\n/** Whether two snapshots show the same thing (the rows' entries by identity: a listing keeps them). */\nexport function sameChatOutboxSnapshot(a: ChatOutboxSnapshot, b: ChatOutboxSnapshot): boolean {\n if (a === b) return true;\n if (a.countdownEndsAt !== b.countdownEndsAt || a.durable !== b.durable || a.loaded !== b.loaded) return false;\n if (a.rows.length !== b.rows.length || a.elsewhere.length !== b.elsewhere.length) return false;\n for (let index = 0; index < a.rows.length; index += 1) {\n const x = a.rows[index];\n const y = b.rows[index];\n if (!x || !y || x.entry !== y.entry || !sameChatOutboxRowState(x.state, y.state)) return false;\n }\n for (let index = 0; index < a.elsewhere.length; index += 1) {\n const x = a.elsewhere[index];\n const y = b.elsewhere[index];\n if (\n !x ||\n !y ||\n x.threadId !== y.threadId ||\n x.count !== y.count ||\n x.newChat !== y.newChat ||\n !sameChatOutboxEntry(x.first, y.first)\n ) {\n return false;\n }\n }\n return true;\n}\n\nexport function createChatOutbox(options: ChatOutboxOptions): ChatOutbox {\n const {\n threadId,\n isNewChat,\n store,\n reachability,\n foreground,\n thread,\n restore,\n openThread,\n onEvent,\n checkAttachments,\n now = () => Date.now(),\n countdownMs = CHAT_OUTBOX_COUNTDOWN_MS,\n askAfterMs = CHAT_OUTBOX_ASK_AFTER_MS,\n claimLeaseMs = CHAT_OUTBOX_CLAIM_LEASE_MS,\n attachmentCheckTimeoutMs = CHAT_OUTBOX_ATTACHMENT_CHECK_TIMEOUT_MS,\n newMessageId = defaultMessageId,\n setTimer = (task, ms) => {\n const timer = setTimeout(task, ms);\n return () => clearTimeout(timer);\n },\n } = options;\n\n /** This controller's name on the claims it takes. */\n const claimant = newMessageId();\n let disposed = false;\n let loaded = store === null;\n /** The thread's waiting messages, oldest first. */\n let entries: ChatOutboxEntry[] = [];\n /** The person's other conversations with messages waiting. */\n let elsewhere: readonly ChatOutboxElsewhere[] = [];\n /** Claims as the store last reported them (another window's hand-off in progress). */\n let claims = new Map<string, ChatOutboxClaim>();\n /** Messages kept on the device (absent: in the store's memory only, or no store at all). */\n const persisted = new Set<string>();\n /**\n * Messages this window wrote to the store (the message itself, or Retry's cleared failure) that\n * a listing may not show yet: how many listings had started when the write settled, or\n * `undefined` while it is pending. A listing that started before then is not believed about\n * them (it would drop a message just kept, or bring back a failure just cleared).\n */\n const unsettled = new Map<string, number | undefined>();\n let listingsStarted = 0;\n const phases = new Map<string, Phase>();\n /** Messages the person told to go now (the ask's Send, Retry): they skip the countdown. */\n const sendNow = new Set<string>();\n /** The return of Athena each message was last handed over in (one hand-off per return). */\n const handedInRegain = new Map<string, number>();\n let regain = 0;\n let wasReachable = reachability.get();\n let countdown: { endsAt: number; ids: readonly string[]; cancel: () => void } | null = null;\n let leaseTimer: (() => void) | null = null;\n /** The running attachment checks' time limits (stopped on dispose). */\n const checkTimers = new Set<() => void>();\n /**\n * Claimed messages ready to be handed over (their attachments checked, or none), each with\n * whether it goes on its own: they go in line, behind any older one still being claimed or\n * asked about ({@link releaseReady}).\n */\n const readyToGo = new Map<string, boolean>();\n let releasing = false;\n const asked = new Set<string>();\n const listeners = new Set<() => void>();\n let snapshot: ChatOutboxSnapshot = {\n rows: [],\n countdownEndsAt: null,\n durable: true,\n loaded,\n elsewhere,\n };\n\n const emit = (event: ChatOutboxEvent): void => {\n try {\n onEvent?.(event);\n } catch {\n // Telemetry never reaches the send path.\n }\n };\n\n const phaseOf = (id: string): Phase => phases.get(id) ?? { kind: \"idle\" };\n const isBusy = (phase: Phase): boolean =>\n phase.kind === \"claiming\" || phase.kind === \"handed\" || phase.kind === \"awaiting-thread\";\n /** Another window holds a live claim on it. */\n const claimedElsewhere = (id: string): boolean => {\n const claim = claims.get(id);\n return claim !== undefined && claim.by !== claimant && now() - claim.at < claimLeaseMs;\n };\n /** Whether a listing that started as listing number `listing` may speak for the message. */\n const settledFor = (id: string, listing: number): boolean => {\n if (!unsettled.has(id)) return true;\n const settledAt = unsettled.get(id);\n return settledAt !== undefined && listing > settledAt;\n };\n /** Whether this window's write of the message has not landed yet. */\n const writePending = (id: string): boolean => unsettled.has(id) && unsettled.get(id) === undefined;\n const markUnsettled = (id: string, write: Promise<unknown>): void => {\n unsettled.set(id, undefined);\n const settle = () => {\n if (!unsettled.has(id)) return;\n unsettled.set(id, listingsStarted);\n // A hand-off deferred for this write goes now.\n evaluate();\n };\n void write.then(settle, settle);\n };\n\n interface Line {\n /** The messages that would go next, in order, before any that must ask. */\n run: ChatOutboxEntry[];\n /** The head of the line when it waited more than a day. */\n askId: string | null;\n }\n\n const rowState = (entry: ChatOutboxEntry, line: Line): ChatOutboxRowState => {\n const phase = phaseOf(entry.id);\n if (phase.kind === \"failed\") {\n return { kind: \"failed\", reason: phase.reason, message: chatOutboxFailureMessage(phase.reason) };\n }\n if (isBusy(phase) || claimedElsewhere(entry.id)) return { kind: \"sending\" };\n // In line behind (or in) the running countdown: it goes when the countdown ends.\n if (countdown !== null && line.run.some((candidate) => candidate.id === entry.id)) {\n return { kind: \"countdown\", endsAt: countdown.endsAt };\n }\n if (line.askId === entry.id) return { kind: \"ask\" };\n return { kind: \"waiting\" };\n };\n\n /** The waiting messages in line to be sent, given that the gate is open. */\n const computeLine = (): Line => {\n const run: ChatOutboxEntry[] = [];\n for (const entry of entries) {\n const phase = phaseOf(entry.id);\n // A failed message is out of line until the person decides; one being handed (here or in\n // another window) is ahead of everything behind it.\n if (phase.kind === \"failed\") continue;\n if (isBusy(phase) || claimedElsewhere(entry.id)) continue;\n if (handedInRegain.get(entry.id) === regain && !sendNow.has(entry.id)) continue;\n if (!sendNow.has(entry.id) && now() - entry.queuedAt > askAfterMs) {\n return { run, askId: run.length === 0 ? entry.id : null };\n }\n run.push(entry);\n }\n return { run, askId: null };\n };\n\n const gateOpen = (): boolean => reachability.get() && foreground.get();\n\n /**\n * Re-read the snapshot; listeners hear from it only when something they would show changed.\n * The outbox re-evaluates on every notification of the thread it serves, and a host renders on\n * every snapshot it is handed (`useChatOutboxSnapshot`): a fresh object for an unchanged state\n * would send that host round again (render -> thread notification -> publish -> render).\n */\n const publish = (): void => {\n const line = gateOpen() ? computeLine() : { run: [], askId: null };\n const next: ChatOutboxSnapshot = {\n rows: entries.map((entry) => ({ entry, state: rowState(entry, line) })),\n countdownEndsAt: countdown?.endsAt ?? null,\n durable: entries.every((entry) => persisted.has(entry.id)),\n loaded,\n elsewhere,\n };\n if (sameChatOutboxSnapshot(snapshot, next)) return;\n snapshot = next;\n for (const listener of listeners) {\n try {\n listener();\n } catch {\n // A listener's fault never reaches the outbox.\n }\n }\n };\n\n const stopCountdown = (): void => {\n countdown?.cancel();\n countdown = null;\n };\n\n const dropEntry = (id: string): void => {\n entries = entries.filter((entry) => entry.id !== id);\n unsettled.delete(id);\n phases.delete(id);\n readyToGo.delete(id);\n sendNow.delete(id);\n persisted.delete(id);\n claims.delete(id);\n asked.delete(id);\n if (countdown?.ids.includes(id)) stopCountdown();\n };\n\n /** The conversation has the message now (its journal or its transcript): let the record go. */\n const letGo = (id: string, event: ChatOutboxEvent): void => {\n if (!entries.some((entry) => entry.id === id)) return;\n dropEntry(id);\n emit(event);\n if (store) void store.remove(threadId, id).catch(() => undefined);\n };\n\n /** \"Couldn't send\": kept with the message, so nothing sends it again until the person retries. */\n const fail = (id: string, reason: ChatOutboxFailureReason): void => {\n phases.set(id, { kind: \"failed\", reason });\n sendNow.delete(id);\n emit({ type: \"failed\", threadId, messageId: id, message: chatOutboxFailureMessage(reason), reason });\n if (store) {\n void store\n .markFailed({ threadId, id, claimant, failure: { reason, at: now() } })\n .catch(() => undefined);\n }\n };\n\n /** Let this window's claim go: the hand-off did not start. */\n const releaseClaim = (id: string): void => {\n if (store) void store.release({ threadId, id, claimant }).catch(() => undefined);\n };\n\n /** Statewire's journal took it, or it ended without reaching it. */\n const handOff = (entry: ChatOutboxEntry, auto: boolean): void => {\n // The conversation may have taken it since the last evaluation (an attach that just landed\n // shows a message an earlier page already delivered): never hand an id it holds.\n if (thread.heldIds().has(entry.id)) {\n letGo(entry.id, { type: \"adopted\", threadId, messageId: entry.id });\n return;\n }\n const readiness = thread.readiness();\n if (readiness === \"refused\") {\n fail(entry.id, \"refused\");\n return;\n }\n if (readiness === \"connecting\") {\n phases.set(entry.id, { kind: \"awaiting-thread\" });\n return;\n }\n // Its write (the message itself, or Retry's cleared failure) has not landed: claiming now\n // could find no record yet. It goes once the write settles (which evaluates again).\n if (writePending(entry.id)) {\n phases.set(entry.id, { kind: \"awaiting-thread\" });\n return;\n }\n sendNow.delete(entry.id);\n phases.set(entry.id, { kind: \"claiming\" });\n const claim: Promise<\"claimed\" | \"taken\" | \"gone\"> = store\n ? store.claim({ threadId, id: entry.id, claimant, now: now(), leaseMs: claimLeaseMs })\n : Promise.resolve(\"claimed\");\n void claim.then(\n (result) => {\n if (disposed || phaseOf(entry.id).kind !== \"claiming\") return;\n if (result === \"gone\") {\n // Cancelled, discarded or handed by another window meanwhile.\n dropEntry(entry.id);\n evaluate();\n return;\n }\n if (result === \"taken\") {\n phases.set(entry.id, { kind: \"idle\" });\n claims.set(entry.id, { by: \"elsewhere\", at: now() });\n evaluate();\n return;\n }\n // The claim took a moment to write: look again before anything reaches statewire.\n if (!stillGoes(entry)) return;\n checkThenDispatch(entry, auto);\n },\n () => {\n if (disposed || phaseOf(entry.id).kind !== \"claiming\") return;\n fail(entry.id, \"prepare\");\n evaluate();\n },\n );\n };\n\n /**\n * Whether a claimed hand-off goes on, looked at again once what it waited on landed (its claim,\n * its attachments' check): the conversation may show the message by now, or refuse it; the app\n * may have gone to the background or Athena out of reach (never sent from the background), or\n * the conversation be reattaching, and then the claim goes and the message waits again.\n */\n const stillGoes = (entry: ChatOutboxEntry): boolean => {\n if (thread.heldIds().has(entry.id)) {\n letGo(entry.id, { type: \"adopted\", threadId, messageId: entry.id });\n evaluate();\n return false;\n }\n const ready = thread.readiness();\n if (ready === \"refused\") {\n fail(entry.id, \"refused\");\n evaluate();\n return false;\n }\n if (!gateOpen() || ready !== \"ready\") {\n phases.set(entry.id, gateOpen() ? { kind: \"awaiting-thread\" } : { kind: \"idle\" });\n releaseClaim(entry.id);\n evaluate();\n return false;\n }\n return true;\n };\n\n /**\n * A claimed message's attachments are asked about before it is handed over: the claim holds\n * meanwhile (the row says Sending…, and no other window hands it), bounded by\n * `attachmentCheckTimeoutMs`. Only `ok` hands it over; a refusal, or a check Athena could not\n * answer, keeps it as \"Couldn't send\" until the person retries, edits or discards it.\n */\n const checkThenDispatch = (entry: ChatOutboxEntry, auto: boolean): void => {\n const attachments = entry.attachments ?? [];\n if (attachments.length === 0 || !checkAttachments) {\n readyToGo.set(entry.id, auto);\n releaseReady();\n return;\n }\n let answered = false;\n let stopTimer: () => void = () => undefined;\n const answer = (verdict: ChatOutboxAttachmentVerdict): void => {\n if (answered) return;\n answered = true;\n stopTimer();\n checkTimers.delete(stopTimer);\n if (disposed || phaseOf(entry.id).kind !== \"claiming\") return;\n if (!stillGoes(entry)) return;\n if (verdict === \"ok\") {\n readyToGo.set(entry.id, auto);\n releaseReady();\n return;\n }\n fail(entry.id, verdict === \"refused\" ? \"attachment\" : \"error\");\n evaluate();\n };\n stopTimer = setTimer(() => answer(\"unknown\"), attachmentCheckTimeoutMs);\n checkTimers.add(stopTimer);\n let checking: Promise<ChatOutboxAttachmentVerdict>;\n try {\n checking = checkAttachments(attachments);\n } catch (error) {\n checking = Promise.reject(error);\n }\n void checking.then(answer, () => answer(\"unknown\"));\n };\n\n /**\n * Hands the ready messages over in line: oldest first, and none while an older one is still\n * being claimed or asked about (a check takes a moment, and a later message must not reach the\n * conversation before it). One whose gate closed meanwhile waits again, and one that failed or\n * left lets the line move. Re-entered from `evaluate`, it runs once at a time.\n */\n function releaseReady(): void {\n if (releasing || disposed) return;\n releasing = true;\n try {\n for (const entry of [...entries]) {\n if (phaseOf(entry.id).kind !== \"claiming\") continue;\n const auto = readyToGo.get(entry.id);\n if (auto === undefined) return;\n readyToGo.delete(entry.id);\n if (stillGoes(entry)) dispatch(entry, auto);\n }\n } finally {\n releasing = false;\n }\n }\n\n const dispatch = (entry: ChatOutboxEntry, auto: boolean): void => {\n handedInRegain.set(entry.id, regain);\n phases.set(entry.id, { kind: \"handed\", journaled: false });\n emit({ type: \"handed\", threadId, messageId: entry.id, auto, ageMs: now() - entry.queuedAt });\n let sent: Promise<unknown>;\n try {\n sent = thread.send(entry);\n } catch (error) {\n sent = Promise.reject(error);\n }\n void sent.then(\n () => {\n if (disposed) return;\n letGo(entry.id, { type: \"delivered\", threadId, messageId: entry.id, status: \"accepted\" });\n evaluate();\n },\n (error: unknown) => {\n if (disposed) return;\n const phase = phaseOf(entry.id);\n // Statewire's journal took it: its own record decides what happens next (an exactly-once\n // replay, or its failed lane), and the settle update lets this record go.\n if (phase.kind === \"handed\" && phase.journaled) return;\n if (phase.kind !== \"handed\") return;\n const failure = failureOf(error);\n if (failure.cause !== undefined && AWAY_CAUSES.has(failure.cause)) {\n // The conversation went away before its journal took the message: it waits again.\n phases.set(entry.id, { kind: \"idle\" });\n handedInRegain.delete(entry.id);\n releaseClaim(entry.id);\n evaluate();\n return;\n }\n fail(entry.id, \"error\");\n evaluate();\n },\n );\n };\n\n const startCountdown = (run: readonly ChatOutboxEntry[]): void => {\n stopCountdown();\n const ids = run.map((entry) => entry.id);\n const endsAt = now() + countdownMs;\n const cancel = setTimer(() => {\n if (disposed || countdown?.endsAt !== endsAt) return;\n countdown = null;\n if (!gateOpen()) {\n evaluate();\n return;\n }\n for (const id of ids) {\n const entry = entries.find((candidate) => candidate.id === id);\n if (!entry) continue;\n const phase = phaseOf(id);\n if (phase.kind !== \"idle\" || claimedElsewhere(id)) continue;\n handOff(entry, true);\n }\n evaluate();\n }, countdownMs);\n countdown = { endsAt, ids, cancel };\n emit({ type: \"countdown-started\", threadId, count: ids.length });\n };\n\n const scheduleLeaseCheck = (): void => {\n leaseTimer?.();\n leaseTimer = null;\n let soonest = Number.POSITIVE_INFINITY;\n for (const [id, claim] of claims) {\n if (claim.by === claimant || !entries.some((entry) => entry.id === id)) continue;\n const expires = claim.at + claimLeaseMs - now();\n if (expires > 0) soonest = Math.min(soonest, expires);\n }\n if (Number.isFinite(soonest)) leaseTimer = setTimer(() => evaluate(), soonest + 1);\n };\n\n /** Re-derive everything from the inputs, then let the ready messages go in line. */\n function evaluate(): void {\n evaluateLine();\n releaseReady();\n }\n\n /** What the conversation holds, the gate, the line. */\n function evaluateLine(): void {\n if (disposed) return;\n const reachable = reachability.get();\n if (reachable && !wasReachable) regain += 1;\n wasReachable = reachable;\n\n if (loaded) {\n const held = thread.heldIds();\n for (const entry of [...entries]) {\n const phase = phaseOf(entry.id);\n if (phase.kind === \"handed\") {\n // This window's hand-off: the conversation folding it in means statewire's journal\n // took it; the record goes at `posted` (persisted before the wire) or a settle.\n if (held.has(entry.id)) phases.set(entry.id, { kind: \"handed\", journaled: true });\n continue;\n }\n if (phase.kind === \"claiming\") continue;\n // Not handed by this window, yet the conversation shows it: a journal adopted from an\n // earlier page (read back from storage, so durable), or the message already landed.\n if (held.has(entry.id)) letGo(entry.id, { type: \"adopted\", threadId, messageId: entry.id });\n }\n if (!gateOpen()) {\n // Gone to the background or out of reach before the conversation came back: those whose\n // countdown had ended go back in line, so returning starts the countdown over.\n for (const entry of entries) {\n if (phaseOf(entry.id).kind === \"awaiting-thread\") phases.set(entry.id, { kind: \"idle\" });\n }\n } else if (thread.readiness() !== \"connecting\") {\n // The conversation is back: the messages whose countdown already ended go now.\n for (const entry of entries) {\n if (phaseOf(entry.id).kind === \"awaiting-thread\") {\n phases.set(entry.id, { kind: \"idle\" });\n handOff(entry, true);\n }\n }\n }\n }\n\n if (!loaded || !gateOpen()) {\n stopCountdown();\n publish();\n return;\n }\n\n const line = computeLine();\n if (line.askId !== null && !asked.has(line.askId)) {\n asked.add(line.askId);\n const entry = entries.find((candidate) => candidate.id === line.askId);\n if (entry) emit({ type: \"asked\", threadId, messageId: entry.id, ageMs: now() - entry.queuedAt });\n }\n // Messages the person told to go now leave without a countdown, but never ahead of older\n // ones still in line: those count down first, and these follow them.\n const immediate: ChatOutboxEntry[] = [];\n for (const entry of line.run) {\n if (!sendNow.has(entry.id)) break;\n immediate.push(entry);\n }\n for (const entry of immediate) handOff(entry, false);\n const run = line.run.slice(immediate.length).filter((entry) => !sendNow.has(entry.id));\n if (run.length === 0) {\n stopCountdown();\n } else if (\n countdown === null ||\n countdown.ids.length !== run.length ||\n run.some((entry, index) => countdown?.ids[index] !== entry.id)\n ) {\n // A new countdown for a new line (a message added or cancelled starts it over).\n startCountdown(run);\n }\n scheduleLeaseCheck();\n publish();\n }\n\n const applyRecords = (records: readonly ChatOutboxRecord[], listing: number): void => {\n const mine = records.filter((record) => record.entry.threadId === threadId);\n const stored = new Map(mine.map((record) => [record.entry.id, record]));\n claims = new Map(\n mine.flatMap((record) => (record.claim ? [[record.entry.id, record.claim] as const] : [])),\n );\n for (const record of mine) {\n if (!settledFor(record.entry.id, listing)) continue;\n if (record.memoryOnly) persisted.delete(record.entry.id);\n else persisted.add(record.entry.id);\n // A hand-off that failed (in this window or another, now or before) stays failed until the\n // person retries it; this window's own failure is never cleared by a listing.\n const phase = phaseOf(record.entry.id);\n if (record.failure && phase.kind !== \"failed\" && !isBusy(phase)) {\n phases.set(record.entry.id, { kind: \"failed\", reason: record.failure.reason });\n }\n }\n // Messages the store no longer holds (sent, cancelled or discarded in another window) leave\n // this one too, unless this window is handing them or wrote them after the listing started.\n const kept = entries.filter(\n (entry) =>\n stored.has(entry.id) || !settledFor(entry.id, listing) || isBusy(phaseOf(entry.id)),\n );\n for (const entry of entries) {\n if (kept.includes(entry)) continue;\n if (countdown?.ids.includes(entry.id)) stopCountdown();\n phases.delete(entry.id);\n persisted.delete(entry.id);\n sendNow.delete(entry.id);\n }\n const known = new Set(kept.map((entry) => entry.id));\n const added = mine.filter((record) => !known.has(record.entry.id)).map((record) => record.entry);\n entries = [...kept, ...added].sort((a, b) => a.queuedAt - b.queuedAt);\n // Writes this listing has seen (it started after they settled) need no guard any more.\n for (const [id, settledAt] of unsettled) {\n if (settledAt !== undefined && listing > settledAt) unsettled.delete(id);\n }\n\n const byThread = new Map<string, { count: number; first: ChatOutboxEntry; newChat: boolean }>();\n for (const record of records) {\n if (record.entry.threadId === threadId) continue;\n const current = byThread.get(record.entry.threadId);\n if (current) {\n current.count += 1;\n current.newChat &&= record.entry.newChat;\n } else {\n byThread.set(record.entry.threadId, {\n count: 1,\n first: record.entry,\n newChat: record.entry.newChat,\n });\n }\n }\n elsewhere = [...byThread]\n .map(([otherThreadId, other]) => ({ threadId: otherThreadId, ...other }))\n .sort((a, b) => a.first.queuedAt - b.first.queuedAt);\n };\n\n let reading: Promise<void> | null = null;\n let readAgain = false;\n const reload = (): void => {\n if (!store || disposed) return;\n if (reading) {\n readAgain = true;\n return;\n }\n listingsStarted += 1;\n const listing = listingsStarted;\n reading = store\n .listAll()\n .then(\n (records) => {\n if (disposed) return;\n applyRecords(records, listing);\n loaded = true;\n },\n () => {\n loaded = true;\n },\n )\n .finally(() => {\n reading = null;\n if (disposed) return;\n evaluate();\n if (readAgain) {\n readAgain = false;\n reload();\n }\n });\n };\n\n const unsubscribers = [\n reachability.subscribe(evaluate),\n foreground.subscribe(evaluate),\n thread.subscribe(evaluate),\n ...(store ? [store.subscribe(reload)] : []),\n ];\n reload();\n publish();\n\n return {\n threadId,\n reachability,\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n shouldHold() {\n if (!reachability.get()) return true;\n // Until the conversation's kept messages are read, a new send could overtake one of them.\n if (!loaded) return true;\n // A message statewire's journal already took is ordered ahead of a new send by its seq;\n // one still waiting (or being claimed, or waiting for the conversation) is not.\n return entries.some((entry) => {\n const phase = phaseOf(entry.id);\n return phase.kind !== \"failed\" && !(phase.kind === \"handed\" && phase.journaled);\n });\n },\n hold(input) {\n const entry: ChatOutboxEntry = {\n id: newMessageId(),\n threadId,\n text: input.text,\n queuedAt: now(),\n newChat: typeof isNewChat === \"function\" ? isNewChat() : isNewChat,\n ...(input.composerMarkdown !== undefined && { composerMarkdown: input.composerMarkdown }),\n ...(input.composerHtml !== undefined && { composerHtml: input.composerHtml }),\n ...(input.metadata !== undefined && { metadata: input.metadata }),\n ...(input.files !== undefined && input.files.length > 0 && { files: input.files }),\n ...(input.attachments !== undefined &&\n input.attachments.length > 0 && { attachments: input.attachments }),\n };\n // Sent from in front while Athena answers, held only until the kept messages are read: it\n // goes at once when nothing older is waiting, after them otherwise.\n if (!loaded && gateOpen()) sendNow.add(entry.id);\n entries = [...entries, entry];\n if (store) {\n // Counted as kept from the start: a page closed before the write settles is the same\n // risk a draft has, and the row must not flash \"only while this page is open\".\n persisted.add(entry.id);\n const write = store.put(entry);\n markUnsettled(entry.id, write);\n void write.then(\n (kept) => {\n if (!kept) persisted.delete(entry.id);\n emit({ type: \"held\", threadId, messageId: entry.id, durable: kept });\n publish();\n },\n () => {\n persisted.delete(entry.id);\n emit({ type: \"held\", threadId, messageId: entry.id, durable: false });\n publish();\n },\n );\n } else {\n emit({ type: \"held\", threadId, messageId: entry.id, durable: false });\n }\n evaluate();\n return entry;\n },\n cancel(id) {\n const entry = entries.find((candidate) => candidate.id === id);\n if (!entry || isBusy(phaseOf(id))) return;\n dropEntry(id);\n emit({ type: \"cancelled\", threadId, messageId: id });\n if (store) void store.remove(threadId, id).catch(() => undefined);\n try {\n restore(entry);\n } finally {\n evaluate();\n }\n },\n send(id) {\n const entry = entries.find((candidate) => candidate.id === id);\n if (!entry || isBusy(phaseOf(id))) return;\n const wasFailed = phaseOf(id).kind === \"failed\";\n phases.set(id, { kind: \"idle\" });\n handedInRegain.delete(id);\n sendNow.add(id);\n if (wasFailed && store) {\n const write = store.clearFailure({ threadId, id });\n markUnsettled(id, write);\n void write.catch(() => undefined);\n }\n evaluate();\n },\n discard(id) {\n const entry = entries.find((candidate) => candidate.id === id);\n if (!entry || isBusy(phaseOf(id))) return;\n dropEntry(id);\n emit({ type: \"discarded\", threadId, messageId: id });\n if (store) void store.remove(threadId, id).catch(() => undefined);\n evaluate();\n },\n observeCommand(update) {\n if (disposed) return;\n const id = chatOutboxCommandMessageId(update.params);\n if (id === null) return;\n const phase = phaseOf(id);\n if (phase.kind === \"handed\") {\n if (update.status === \"queued\") {\n phases.set(id, { kind: \"handed\", journaled: true });\n return;\n }\n // Persisted before the wire (`posted`), admitted (`applied`), or settled: statewire owns\n // the message now (its exactly-once replay, or its failed lane).\n letGo(id, { type: \"delivered\", threadId, messageId: id, status: update.status });\n evaluate();\n return;\n }\n // A statement for a waiting message this window did not hand: a journal adopted from an\n // earlier page. The conversation folds it in, and the next evaluation lets the record go.\n if (entries.some((entry) => entry.id === id)) evaluate();\n },\n openThread: openThread ?? null,\n dispose() {\n if (disposed) return;\n disposed = true;\n stopCountdown();\n leaseTimer?.();\n for (const stop of checkTimers) stop();\n checkTimers.clear();\n readyToGo.clear();\n for (const unsubscribe of unsubscribers) unsubscribe();\n listeners.clear();\n // A claim taken for a hand-off that never started is released, so another window (or the\n // next mount) need not wait out the lease. One whose hand-off started stays until its lease\n // ends: statewire may still journal the statement, and the conversation then shows it.\n if (store) {\n for (const [id, phase] of phases) {\n if (phase.kind === \"claiming\") releaseClaim(id);\n }\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { ConnectionState } from './offline-status';
2
+ import type { DeepAgentConnectionState } from './types';
3
+ /**
4
+ * Where a chat surface stands with Athena when it has no reachability model of
5
+ * its own (the Chrome side panel, the Office task pane): read from what it
6
+ * already watches, with no polling — the browser's online flag, and the chat
7
+ * socket, which redials on its own and says when a redial failed. The result
8
+ * is the offline language's `ConnectionState` (`./offline-status`), so the
9
+ * surface's words come from the same place as every other app's.
10
+ */
11
+ /** How long "Back online" (`synced`) stays once Athena answers again. */
12
+ export declare const BACK_ONLINE_MS = 4000;
13
+ /** The browser's online flag, following its `online` / `offline` events (true where there is no browser). */
14
+ export declare function useBrowserOnline(): boolean;
15
+ /**
16
+ * Whether the chat socket says Athena can't be reached. Statewire's first
17
+ * redial after a drop is immediate and publishes nothing, so `retrying` means
18
+ * a redial already failed. An auth refusal (`unauthorized`) is not "can't
19
+ * reach": the surface renews the sign-in or parks the chat. A redial in flight
20
+ * reports no cause, so the episode's last answer (`previous`) stands.
21
+ */
22
+ export declare function chatSocketCannotReach({ connection, previous, }: {
23
+ connection: DeepAgentConnectionState | null;
24
+ previous: boolean;
25
+ }): boolean;
26
+ /** The outage a chat surface is in, if any: the browser's own flag first, then the socket. */
27
+ export declare function chatSocketOutage({ browserOnline: online, socketCannotReach, }: {
28
+ browserOnline: boolean;
29
+ socketCannotReach: boolean;
30
+ }): 'offline' | 'unreachable' | null;
31
+ /**
32
+ * The surface's connection state: `offline` or `unreachable` during an outage,
33
+ * then `synced` ("Back online") for `backOnlineMs` once it ends with the socket
34
+ * confirming Athena answers, then `online` (nothing shown). Never
35
+ * `reconnecting`: such a surface keeps nothing to send on the way back. An
36
+ * outage that ends with nothing to confirm Athena (a chat that hasn't dialed
37
+ * yet, when the browser's flag comes back) just ends, claiming nothing; one
38
+ * that ends with the socket `stopped` (the server ended the session, or a
39
+ * protocol or storage error) is not "back online" either: the surface's own
40
+ * error and connection indicator speak for a stopped chat.
41
+ */
42
+ export declare function useChatSocketReachability({ connection, backOnlineMs, }: {
43
+ connection: DeepAgentConnectionState | null;
44
+ backOnlineMs?: number;
45
+ }): ConnectionState;
@@ -0,0 +1,152 @@
1
+ /**
2
+ * The statewire client-tool bridge loop, shared by every surface that executes
3
+ * frontend tool calls (Olympus, the React SDK, the Office add-in, mobile).
4
+ *
5
+ * Tools declared through `runConfig.custom.client_tools` have no backend
6
+ * implementation: a call parks the run on an interrupt that arrives as a
7
+ * statewire input request. A bridge with handlers for the whole batch claims
8
+ * it (exactly-once per ownership domain), runs those handlers, and resumes
9
+ * with per-call result envelopes. Other attached tabs leave it for the
10
+ * executing surface; a thrown handler still returns an actionable error.
11
+ *
12
+ * Wire-adjacent correctness invariants this module owns, so they can never
13
+ * drift apart per surface again:
14
+ * - exactly-once claim per request, with un-claim on every path that did NOT
15
+ * run any handler (abandoned before execution, consent dismissed, unmount
16
+ * before the first handler) so a re-emitted request is executable instead
17
+ * of stranding the run;
18
+ * - once a batch has STARTED executing handlers, its claim is never released
19
+ * by unmount: handlers cannot be cancelled, so releasing would let another
20
+ * mount re-claim the re-emitted request and re-execute side effects that
21
+ * already ran (double-executing a mutating tool). The completed wire-safe
22
+ * result is cached and may be replayed across reconnects/remounts instead;
23
+ * - liveness checks between awaits (the run can be stopped or answered
24
+ * elsewhere while a handler runs) so a stale request is never resumed;
25
+ * - per-call JSON wire-safety, so one unrepresentable handler result answers
26
+ * that one call with an error instead of failing the whole batch.
27
+ *
28
+ * Like `interrupts.ts`, this is parameterized rather than self-wiring: the
29
+ * host component reads `useStatewireRuns().inputRequests` and
30
+ * `useStatewireSendCommand()` itself (both mockable per surface) and passes
31
+ * them in, together with its ownership tracker and write-consent policy.
32
+ */
33
+ import type { StatewireThread } from '@assistant-ui/react-statewire';
34
+ import { type ClientToolCallRequest, type ClientToolRequestTracker, type ClientToolResultEnvelope } from './client-tools';
35
+ /** A locally executable tool, normalized across the per-surface tool shapes. */
36
+ export interface ClientToolBridgeTool {
37
+ /** Snake_case tool id the model calls (e.g. `update_sheet_range`). */
38
+ name: string;
39
+ /** Mutating tools gate on the surface's write-consent flow (`confirmWrites`). */
40
+ requiresWrite?: boolean;
41
+ run: (args: Record<string, unknown>, context: {
42
+ toolCallId: string;
43
+ }) => Promise<unknown>;
44
+ }
45
+ /**
46
+ * Batch write-consent outcome. `proceed` runs the write calls, `declined`
47
+ * answers them with the declined message while reads still run, `abandoned`
48
+ * releases the claim without resuming (the request died, or the consent UI was
49
+ * dismissed by the run moving on). Grant persistence (a thread set, a stored
50
+ * preference) is the surface's own policy, applied inside its callback.
51
+ */
52
+ export type ClientToolWriteConsentDecision = 'proceed' | 'declined' | 'abandoned';
53
+ export interface ClientToolCallSettledEvent {
54
+ toolName: string;
55
+ status: 'success' | 'error' | 'declined';
56
+ errorType?: string;
57
+ }
58
+ /** Default resume error for a write call the user declined. */
59
+ export declare const CLIENT_TOOL_WRITE_DECLINED_MESSAGE = "The user declined this edit. Do not retry it; ask the user how to proceed.";
60
+ /** Default resume error for a call naming a tool this surface does not have. */
61
+ export declare function defaultMissingClientToolMessage(toolName: string): string;
62
+ /** Statewire request ids are unique per run, but a thread scope keeps a
63
+ * process-wide claim unambiguous when two conversations are open at once. */
64
+ export declare function clientToolClaimKey(threadId: string, requestId: string): string;
65
+ /**
66
+ * A wire-safe copy of a handler's return value: handlers can return values
67
+ * JSON cannot represent (DOM nodes, host objects, bigints), which must never
68
+ * reach the transport. Throws for an unrepresentable value so the caller can
69
+ * answer that one call with an error instead of stranding the whole batch.
70
+ */
71
+ export declare function jsonSafeClientToolResult(value: unknown): unknown;
72
+ /** A parked, unanswered client-tool input request. */
73
+ export declare function isPendingClientToolRequest(request: StatewireThread.InputRequestState): request is StatewireThread.CustomInputRequest;
74
+ export interface ExecuteClientToolBatchOptions {
75
+ calls: readonly ClientToolCallRequest[];
76
+ tools: readonly ClientToolBridgeTool[];
77
+ /** Whether the parked request still exists and this surface may answer it.
78
+ * Checked before consent resolution, before every call, and before the
79
+ * results are handed back for resume. */
80
+ isLive: () => boolean;
81
+ /** Batch write gate; absent means writes run without consent (surfaces that
82
+ * only register read tools). Called once per batch, before any handler. */
83
+ confirmWrites?: (batch: {
84
+ writeToolNames: readonly string[];
85
+ }) => Promise<ClientToolWriteConsentDecision>;
86
+ writeDeclinedMessage?: string;
87
+ missingToolMessage?: (toolName: string) => string;
88
+ /** Per-call telemetry (the Office add-in's tool events). */
89
+ onCallSettled?: (event: ClientToolCallSettledEvent) => void;
90
+ /**
91
+ * Called once, after the write-consent gate resolves and immediately before
92
+ * the first handler runs — the point where side effects begin. There is no
93
+ * await between this callback and the first handler invocation, so a caller
94
+ * marking "execution started" here can never miss a handler that ran.
95
+ */
96
+ onExecutionStart?: () => void;
97
+ }
98
+ /**
99
+ * Execute one batched client-tool park: consent, per-call execution with
100
+ * wire-safe envelopes, liveness aborts. Returns the per-interrupt result map
101
+ * to resume with, or `null` when the batch was abandoned (the request died,
102
+ * consent was abandoned, or the surface went away) — the caller must release
103
+ * its claim and must NOT resume.
104
+ */
105
+ export declare function executeClientToolBatch(options: ExecuteClientToolBatchOptions): Promise<Record<string, ClientToolResultEnvelope> | null>;
106
+ export interface UseStatewireClientToolBridgeOptions {
107
+ threadId: string;
108
+ tools: readonly ClientToolBridgeTool[];
109
+ /**
110
+ * Ownership domain for parked-request claims. Pass a module-scoped tracker
111
+ * to make ownership process-wide across every mount of the surface (two
112
+ * mounted surfaces of one conversation execute each request exactly once),
113
+ * or a per-mount tracker to scope ownership to one mounted bridge.
114
+ */
115
+ tracker: ClientToolRequestTracker;
116
+ /** The surface's `useStatewireRuns().inputRequests` read. */
117
+ inputRequests: readonly StatewireThread.InputRequestState[] | undefined;
118
+ /** Dispatch the `run/input` resume on the surface's transport. The value is
119
+ * already wire-safe (per-call JSON round-trip inside the batch engine). */
120
+ /** Dispatch the answer and settle only once the Statewire host accepts or
121
+ * rejects the command. The bridge deliberately keeps replaying while this
122
+ * promise is pending: `run/input` removes the request optimistically before
123
+ * the server has accepted the answer. */
124
+ sendResume: (requestId: string, value: Record<string, unknown>) => PromiseLike<unknown>;
125
+ /** Batch write gate, with the parked request's id so the surface can close
126
+ * its consent UI the instant that request disappears. */
127
+ confirmWrites?: (batch: {
128
+ requestId: string;
129
+ writeToolNames: readonly string[];
130
+ }) => Promise<ClientToolWriteConsentDecision>;
131
+ writeDeclinedMessage?: string;
132
+ missingToolMessage?: (toolName: string) => string;
133
+ onCallSettled?: (event: ClientToolCallSettledEvent) => void;
134
+ /** Log prefix for resume-dispatch failures. */
135
+ logLabel?: string;
136
+ }
137
+ /**
138
+ * The claim lifecycle around {@link executeClientToolBatch}: claim the pending
139
+ * request once per ownership domain, execute, resume — releasing the claim on
140
+ * every path that ran no handler, so re-emitted requests recover.
141
+ *
142
+ * Unmount splits by whether side effects began:
143
+ * - a claim whose batch has NOT started executing (claimed this tick, or
144
+ * parked on write consent) is released, so another mount — or a remount —
145
+ * can execute the re-emitted request instead of stranding the parked run;
146
+ * - a claim whose batch HAS started stays held: handlers cannot be cancelled,
147
+ * so releasing would let a sibling mount re-claim and re-execute a mutation
148
+ * whose side effects already ran. The detached execution caches its result
149
+ * and attempts one resume through its captured transport; a later mount can
150
+ * replay the same result without repeating the side effect.
151
+ */
152
+ export declare function useStatewireClientToolBridge(options: UseStatewireClientToolBridgeOptions): void;
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Client-executed tools for statewire deep-agent threads.
3
+ *
4
+ * A client (the Office add-in, the Chrome extension, …) declares tools it can
5
+ * execute locally by sending their JSON-schema definitions through
6
+ * `runConfig.custom.client_tools`. The deep-agent runtime binds them as
7
+ * interrupt-backed tools: when the model calls one, the run parks on a
8
+ * LangGraph interrupt whose payload carries the tool name and arguments, the
9
+ * statewire host publishes it as an `interrupt` input request, and the client
10
+ * executes the tool and resumes the run with the result envelope.
11
+ *
12
+ * This module is transport-agnostic: it holds the wire contract (definitions,
13
+ * interrupt payload shape, result envelopes) and a duplicate-execution guard.
14
+ * The React hook that watches input requests lives with each client, next to
15
+ * its host-specific tool handlers.
16
+ */
17
+ import { CLIENT_TOOL_INTERRUPT_SOURCE, CLIENT_TOOL_RESULT_STATUS_ERROR, CLIENT_TOOL_RESULT_STATUS_SUCCESS } from './generated/runconfig-contract';
18
+ /** `source`/`type` stamped on the interrupt payload by the agora runtime. */
19
+ export { CLIENT_TOOL_INTERRUPT_SOURCE } from './generated/runconfig-contract';
20
+ /** JSON-schema description of one client-executed tool. */
21
+ export interface ClientToolDefinition {
22
+ /** Snake_case tool id the model calls (e.g. `update_sheet_range`). */
23
+ name: string;
24
+ description: string;
25
+ /** JSON schema for the tool arguments (`{"type": "object", ...}`). */
26
+ parameters: Record<string, unknown>;
27
+ /** Mutating tools gate on the client's write-approval flow before running. */
28
+ requiresWrite: boolean;
29
+ }
30
+ /** Per-call context the client-tool bridge hands a handler; absent when a host
31
+ * invokes a handler outside a parked run. */
32
+ export interface ClientToolHandlerContext {
33
+ /** The model's tool-call id, for handlers that correlate calls. */
34
+ toolCallId: string;
35
+ }
36
+ export type ClientToolHandler = (args: Record<string, unknown>, context?: ClientToolHandlerContext) => Promise<unknown>;
37
+ export interface RegisteredClientTool {
38
+ definition: ClientToolDefinition;
39
+ handler: ClientToolHandler;
40
+ }
41
+ /** One parked tool call inside a batched client-tool input request. */
42
+ export interface ClientToolCallRequest {
43
+ /** LangGraph interrupt id — the key the resume result map must use. */
44
+ interrupt_id: string;
45
+ tool_name: string;
46
+ tool_args: Record<string, unknown>;
47
+ requires_write?: boolean;
48
+ }
49
+ /**
50
+ * The input-request payload the agora runtime publishes for parked client
51
+ * tool calls. A parallel model turn parks several interrupts at once; the
52
+ * runtime batches them into one payload and the client answers once with
53
+ * `{ client_tool_results: { <interrupt_id>: <result envelope> } }`.
54
+ */
55
+ export interface ClientToolInterruptPayload {
56
+ source: typeof CLIENT_TOOL_INTERRUPT_SOURCE;
57
+ type: typeof CLIENT_TOOL_INTERRUPT_SOURCE;
58
+ message: string;
59
+ context: {
60
+ requests: ClientToolCallRequest[];
61
+ };
62
+ }
63
+ /**
64
+ * Loose source check for surfaces that must NOT handle a client-tool park
65
+ * (e.g. the generic approval banner). Unlike `isClientToolInterrupt`, this
66
+ * matches any payload stamped with the client-tool source — including shapes
67
+ * from a mismatched client/server version — so a skewed deploy can never
68
+ * surface a generic "Continue" resume that corrupts a parked tool call.
69
+ */
70
+ export declare function hasClientToolInterruptSource(payload: unknown): boolean;
71
+ export declare function isClientToolInterrupt(payload: unknown): payload is ClientToolInterruptPayload;
72
+ /** Tool arguments from a call request, defaulting to an empty object. */
73
+ export declare function clientToolCallArgs(request: ClientToolCallRequest): Record<string, unknown>;
74
+ /** The `run/input` resume value answering a batched client-tool park. */
75
+ export declare function clientToolResultsResumeValue(results: Record<string, ClientToolResultEnvelope>): Record<string, unknown>;
76
+ /** Wire entries for `runConfig.custom.client_tools`. */
77
+ export declare function clientToolRunConfigEntries(tools: readonly RegisteredClientTool[]): Record<string, unknown>[];
78
+ /** Successful tool execution, resumed back into the parked run. */
79
+ export interface ClientToolSuccessEnvelope {
80
+ status: typeof CLIENT_TOOL_RESULT_STATUS_SUCCESS;
81
+ result: unknown;
82
+ }
83
+ /** Failed or declined tool execution, resumed back into the parked run. */
84
+ export interface ClientToolErrorEnvelope {
85
+ status: typeof CLIENT_TOOL_RESULT_STATUS_ERROR;
86
+ error: string;
87
+ }
88
+ export type ClientToolResultEnvelope = ClientToolSuccessEnvelope | ClientToolErrorEnvelope;
89
+ export declare function clientToolSuccessEnvelope(result: unknown): ClientToolSuccessEnvelope;
90
+ export declare function clientToolErrorEnvelope(error: unknown): ClientToolErrorEnvelope;
91
+ /**
92
+ * Once-per-request execution guard. Statewire re-emits the pending input
93
+ * request on every state update, so an executor effect can observe the same
94
+ * request many times; the tracker makes exactly one observation win.
95
+ */
96
+ export interface ClientToolRequestTracker {
97
+ /** True exactly once per request id; later calls return false. */
98
+ claim(requestId: string): boolean;
99
+ /** Un-claim a request that was NOT resumed (e.g. abandoned mid-approval),
100
+ * so a re-emitted request can be executed instead of stranding the run. */
101
+ release(requestId: string): void;
102
+ has(requestId: string): boolean;
103
+ /** Cache the completed, wire-safe resume value without releasing the
104
+ * exactly-once execution claim. A reconnect may replay this value, but it
105
+ * must never execute the local handler again. */
106
+ cacheResume(requestId: string, value: Record<string, unknown>): void;
107
+ getCachedResume(requestId: string): ClientToolCachedResume | undefined;
108
+ /** Give one mounted bridge ownership of retrying a cached resume. */
109
+ claimResumeReplay(requestId: string, owner: symbol): boolean;
110
+ releaseResumeReplay(requestId: string, owner: symbol): void;
111
+ /** Record authoritative host acceptance. The execution claim remains held
112
+ * so a briefly stale request cannot execute its local side effects again. */
113
+ settleResume(requestId: string): void;
114
+ /** Atomically consume one bounded replay attempt for the current owner. */
115
+ takeResumeAttempt(requestId: string, options: {
116
+ owner: symbol;
117
+ maxAttempts: number;
118
+ }): ClientToolResumeAttempt | undefined;
119
+ }
120
+ export interface ClientToolCachedResume {
121
+ value: Record<string, unknown>;
122
+ attemptCount: number;
123
+ }
124
+ export interface ClientToolResumeAttempt {
125
+ value: Record<string, unknown>;
126
+ attemptNumber: number;
127
+ }
128
+ export interface CreateClientToolRequestTrackerOptions {
129
+ /** Maximum completed resume values retained for reconnect recovery. Active
130
+ * executions are never evicted. */
131
+ maxCachedResumes?: number;
132
+ }
133
+ export declare function createClientToolRequestTracker(options?: CreateClientToolRequestTrackerOptions): ClientToolRequestTracker;
@@ -113,6 +113,15 @@ function withStagedComposerMarkdown({
113
113
  return captured instanceof Promise ? captured.then(merge) : merge(captured);
114
114
  };
115
115
  }
116
+ function withDeepAgentComposerMarkdown({
117
+ metadata,
118
+ text,
119
+ markdown
120
+ }) {
121
+ const { [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: _previous, ...rest } = metadata ?? {};
122
+ const next = markdown === text ? rest : { ...rest, [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: markdown };
123
+ return Object.keys(next).length > 0 ? next : void 0;
124
+ }
116
125
  exports.DEEP_AGENT_COMPOSER_MARKDOWN_KEY = DEEP_AGENT_COMPOSER_MARKDOWN_KEY;
117
126
  exports.STAGED_COMPOSER_MARKDOWN_TTL_MS = STAGED_COMPOSER_MARKDOWN_TTL_MS;
118
127
  exports.isComposerMarkdownOfText = isComposerMarkdownOfText;
@@ -120,5 +129,6 @@ exports.readDeepAgentComposerMarkdown = readDeepAgentComposerMarkdown;
120
129
  exports.stageComposerMarkdown = stageComposerMarkdown;
121
130
  exports.takeStagedComposerMarkdownMetadata = takeStagedComposerMarkdownMetadata;
122
131
  exports.trimComposerDraft = trimComposerDraft;
132
+ exports.withDeepAgentComposerMarkdown = withDeepAgentComposerMarkdown;
123
133
  exports.withStagedComposerMarkdown = withStagedComposerMarkdown;
124
134
  //# sourceMappingURL=composer-markdown.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"composer-markdown.cjs","sources":["../../../../agent-runtime/src/composer-markdown.ts"],"sourcesContent":["/**\n * The composer markdown a chat message was sent from.\n *\n * The chat composer sends a message's plain text exactly as typed, because the\n * model reads the text literally, and writes real formatting (bold, lists,\n * code, mention chips) as markdown. The sent text alone no longer says which\n * characters are formatting and which were typed: literal `**strong**` and\n * bold `strong` both send `**strong**`, and `List<T>`, `a\\\\b` or `2*3*4` read\n * as markup when the text is rendered as markdown. So the composer also\n * attaches the draft the text was serialized from (the same document with its\n * plain text escaped for markdown) under {@link DEEP_AGENT_COMPOSER_MARKDOWN_KEY}\n * in the message's metadata, and only when the two differ.\n *\n * It rides the statewire message, the queue and steer lanes and the persisted\n * HumanMessage (`additional_kwargs.metadata`, which the converter surfaces as\n * `metadata.custom`). It is display-only: the bubble renders it, and Edit,\n * branch-and-edit and a withdrawn turn load it back into the composer. The\n * model reads the message text, never this. A message without it (older\n * messages, other clients) renders its text as before.\n *\n * agora validates it with the same rule\n * (`agora/graphs/athena_deep_agent/composer_markdown.py`).\n */\nexport const DEEP_AGENT_COMPOSER_MARKDOWN_KEY = 'composer_markdown';\n\nconst DRAFT_CHARACTER_REFERENCES: Readonly<Record<string, string>> = {\n lt: '<',\n gt: '>',\n amp: '&',\n '#32': ' ',\n '#9': '\\t',\n};\n\n/**\n * A sent text in comparable form: every backslash dropped (the draft's\n * escapes, and the `\\` before a hard break's newline, are backslashes).\n */\nconst comparableText = (text: string): string => text.replace(/\\\\/g, '');\n\n/**\n * A draft in comparable form: every backslash dropped, then the character\n * references the draft serializer writes decoded in one pass (`&lt;` and\n * `&gt;` for typed `<` and `>`, `&amp;` for a typed `&` that starts a\n * reference, so typed `&lt;` is `&amp;lt;`, and `&#32;` / `&#9;` for the space\n * or tab a line starts with, which markdown would otherwise drop).\n */\nconst comparableDraft = (markdown: string): string =>\n comparableText(markdown).replace(\n /&(lt|gt|amp|#32|#9);/g,\n (reference, name: string) => DRAFT_CHARACTER_REFERENCES[name] ?? reference\n );\n\n/**\n * Escaping at most turns one character into four (`<` → `&lt;`). A line's\n * first space becomes five (`&#32;`), but only once a line, so a whole line\n * with its line break stays under four a character; the slack covers short\n * texts. agora caps a stored draft the same way.\n */\nconst MAX_EXPANSION = 4;\nconst EXPANSION_SLACK_CHARS = 1024;\n\n/**\n * Whether `markdown` is the draft of `text`: no longer than escaping could make\n * it, and equal to it once backslashes are dropped and the draft's character\n * references decoded. A draft that would show other\n * words than the text the model read (another message's, a client's mistake) is\n * not taken; such a message renders its text as before.\n */\nexport function isComposerMarkdownOfText({\n markdown,\n text,\n}: {\n markdown: string;\n text: string;\n}): boolean {\n return (\n markdown.length <= text.length * MAX_EXPANSION + EXPANSION_SLACK_CHARS &&\n comparableDraft(markdown) === comparableText(text)\n );\n}\n\n/** The references a draft writes a line's first space or tab as. */\nconst DRAFT_WHITESPACE_REFERENCES: readonly string[] = ['&#32;', '&#9;'];\n\nconst isWhitespace = (character: string): boolean => /\\s/.test(character);\n\n/** A hard break in a draft: `\\` before the newline (the text holds the newline alone). */\nconst DRAFT_HARD_BREAK = '\\\\\\n';\n\n/** Whether an odd run of backslashes ends at `end`: its last one escapes what follows, not a typed `\\` (`\\\\`). */\nfunction endsInEscapingBackslash({\n markdown,\n start,\n end,\n}: {\n markdown: string;\n start: number;\n end: number;\n}): boolean {\n let backslashes = 0;\n while (end - backslashes > start && markdown.charAt(end - backslashes - 1) === '\\\\') {\n backslashes += 1;\n }\n return backslashes % 2 === 1;\n}\n\n/**\n * `markdown`, a draft, trimmed as its text is trimmed (`text.trim()`): a\n * send that trims its text stays a draft of it. `markdown.trim()` would keep\n * the `&#32;` a draft writes for the space its first line starts with, and the\n * `\\` of a line break whose newline it trims.\n */\nexport function trimComposerDraft(markdown: string): string {\n let start = 0;\n let end = markdown.length;\n for (;;) {\n while (start < end && isWhitespace(markdown.charAt(start))) start += 1;\n const reference = [...DRAFT_WHITESPACE_REFERENCES, DRAFT_HARD_BREAK].find(\n (candidate) => start + candidate.length <= end && markdown.startsWith(candidate, start)\n );\n if (reference === undefined) break;\n start += reference.length;\n }\n for (;;) {\n while (end > start && isWhitespace(markdown.charAt(end - 1))) end -= 1;\n const reference = DRAFT_WHITESPACE_REFERENCES.find(\n (candidate) => end - candidate.length >= start && markdown.endsWith(candidate, end)\n );\n if (reference !== undefined) {\n end -= reference.length;\n } else if (\n markdown.charAt(end) === '\\n' &&\n endsInEscapingBackslash({ markdown, start, end })\n ) {\n // The newline just trimmed was a line break's: its `\\` goes with it.\n end -= 1;\n } else {\n break;\n }\n }\n return markdown.slice(start, end);\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * The composer markdown to render or load for a message whose metadata is\n * `metadata` (a message's `metadata.custom`, or a lane entry's `metadata`) and\n * whose text is `text`; `null` when it carries none, or one that is not a\n * draft of `text`.\n */\nexport function readDeepAgentComposerMarkdown({\n metadata,\n text,\n}: {\n metadata: unknown;\n text: string;\n}): string | null {\n if (!isRecord(metadata)) return null;\n const markdown: unknown = metadata[DEEP_AGENT_COMPOSER_MARKDOWN_KEY];\n return typeof markdown === 'string' && isComposerMarkdownOfText({ markdown, text })\n ? markdown\n : null;\n}\n\n/**\n * How long a staged composer markdown waits for its submission\n * ({@link stageComposerMarkdown}).\n */\nexport const STAGED_COMPOSER_MARKDOWN_TTL_MS = 10_000;\n\ninterface StagedComposerMarkdown {\n readonly markdown: string;\n readonly stagedAt: number;\n}\n\n/**\n * The staged drafts live on `globalThis`, not in module scope, because two\n * copies of this module run in one page: the SDK bundles agent-runtime into its\n * dist, so its composer stages through the SDK's copy, while the Chrome\n * extension and the Office add-in build their runtime on agent-runtime directly\n * and take the draft through their own (see `asset-attachment.ts`).\n */\nconst STAGED_COMPOSER_MARKDOWN = Symbol.for('@athenaintel/agent-runtime/staged-composer-markdown');\n\ntype StagedComposerMarkdownHost = typeof globalThis & {\n [STAGED_COMPOSER_MARKDOWN]?: Map<string, StagedComposerMarkdown>;\n};\n\nfunction stagedComposerMarkdownByThread(): Map<string, StagedComposerMarkdown> {\n const host = globalThis as StagedComposerMarkdownHost;\n return (host[STAGED_COMPOSER_MARKDOWN] ??= new Map());\n}\n\n/**\n * Stage the draft `markdown` of `text` for `threadId`'s next submission.\n *\n * statewire captures message metadata once per new user message\n * (`getMessageMetadata`, patched into `@assistant-ui/react-statewire@0.31.0`)\n * without saying which message it is for, so a composer stages its draft right\n * before it sends and the runtime's getter takes it for the submission that\n * follows ({@link withStagedComposerMarkdown}). A draft equal to its text adds\n * nothing and clears the slot. A slot nobody takes within\n * {@link STAGED_COMPOSER_MARKDOWN_TTL_MS} expires; one a submission the\n * composer did not make takes is harmless, since a composer markdown that is\n * not a draft of the message's own text is neither kept by agora nor rendered.\n */\nexport function stageComposerMarkdown({\n threadId,\n text,\n markdown,\n now = Date.now(),\n}: {\n threadId: string;\n text: string;\n markdown: string;\n /** Test seam: the time of the send. */\n now?: number;\n}): void {\n const staged = stagedComposerMarkdownByThread();\n if (markdown === text) {\n staged.delete(threadId);\n return;\n }\n staged.set(threadId, { markdown, stagedAt: now });\n}\n\n/**\n * The message metadata for `threadId`'s submission now being journaled: the\n * staged composer markdown, if one is waiting and fresh. Takes the slot.\n */\nexport function takeStagedComposerMarkdownMetadata(\n threadId: string,\n now: number = Date.now()\n): Record<string, unknown> | undefined {\n const staged = stagedComposerMarkdownByThread();\n const entry = staged.get(threadId);\n staged.delete(threadId);\n if (entry === undefined || now - entry.stagedAt > STAGED_COMPOSER_MARKDOWN_TTL_MS) {\n return undefined;\n }\n return { [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: entry.markdown };\n}\n\ntype MessageMetadataGetter = () =>\n | Record<string, unknown>\n | undefined\n | Promise<Record<string, unknown> | undefined>;\n\n/**\n * A runtime's `getMessageMetadata` that also carries the composer markdown a\n * composer staged for `threadId` ({@link stageComposerMarkdown}), on top of the\n * host's own metadata (`getMessageMetadata`, when it has one). The slot is\n * taken synchronously at submission, before the host's capture resolves, so a\n * draft never rides a later message. With nothing staged the host's own value\n * is returned as is.\n */\nexport function withStagedComposerMarkdown({\n threadId,\n getMessageMetadata,\n}: {\n threadId: string;\n getMessageMetadata?: MessageMetadataGetter | undefined;\n}): MessageMetadataGetter {\n return () => {\n const staged = takeStagedComposerMarkdownMetadata(threadId);\n const captured = getMessageMetadata?.();\n if (staged === undefined) return captured;\n const merge = (host: Record<string, unknown> | undefined): Record<string, unknown> => ({\n ...host,\n ...staged,\n });\n return captured instanceof Promise ? captured.then(merge) : merge(captured);\n };\n}\n\n/** Test seam: drop every staged composer markdown. */\nexport function resetStagedComposerMarkdown(): void {\n stagedComposerMarkdownByThread().clear();\n}\n\n/**\n * `metadata` with the composer markdown set to the draft `markdown` of `text`,\n * or without it when the draft equals the text (it adds nothing then).\n * Returns `undefined` when nothing is left.\n */\nexport function withDeepAgentComposerMarkdown({\n metadata,\n text,\n markdown,\n}: {\n metadata: Readonly<Record<string, unknown>> | undefined;\n text: string;\n markdown: string;\n}): Record<string, unknown> | undefined {\n const { [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: _previous, ...rest } = metadata ?? {};\n const next: Record<string, unknown> =\n markdown === text ? rest : { ...rest, [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: markdown };\n return Object.keys(next).length > 0 ? next : undefined;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"composer-markdown.cjs","sources":["../../../../agent-runtime/src/composer-markdown.ts"],"sourcesContent":["/**\n * The composer markdown a chat message was sent from.\n *\n * The chat composer sends a message's plain text exactly as typed, because the\n * model reads the text literally, and writes real formatting (bold, lists,\n * code, mention chips) as markdown. The sent text alone no longer says which\n * characters are formatting and which were typed: literal `**strong**` and\n * bold `strong` both send `**strong**`, and `List<T>`, `a\\\\b` or `2*3*4` read\n * as markup when the text is rendered as markdown. So the composer also\n * attaches the draft the text was serialized from (the same document with its\n * plain text escaped for markdown) under {@link DEEP_AGENT_COMPOSER_MARKDOWN_KEY}\n * in the message's metadata, and only when the two differ.\n *\n * It rides the statewire message, the queue and steer lanes and the persisted\n * HumanMessage (`additional_kwargs.metadata`, which the converter surfaces as\n * `metadata.custom`). It is display-only: the bubble renders it, and Edit,\n * branch-and-edit and a withdrawn turn load it back into the composer. The\n * model reads the message text, never this. A message without it (older\n * messages, other clients) renders its text as before.\n *\n * agora validates it with the same rule\n * (`agora/graphs/athena_deep_agent/composer_markdown.py`).\n */\nexport const DEEP_AGENT_COMPOSER_MARKDOWN_KEY = 'composer_markdown';\n\nconst DRAFT_CHARACTER_REFERENCES: Readonly<Record<string, string>> = {\n lt: '<',\n gt: '>',\n amp: '&',\n '#32': ' ',\n '#9': '\\t',\n};\n\n/**\n * A sent text in comparable form: every backslash dropped (the draft's\n * escapes, and the `\\` before a hard break's newline, are backslashes).\n */\nconst comparableText = (text: string): string => text.replace(/\\\\/g, '');\n\n/**\n * A draft in comparable form: every backslash dropped, then the character\n * references the draft serializer writes decoded in one pass (`&lt;` and\n * `&gt;` for typed `<` and `>`, `&amp;` for a typed `&` that starts a\n * reference, so typed `&lt;` is `&amp;lt;`, and `&#32;` / `&#9;` for the space\n * or tab a line starts with, which markdown would otherwise drop).\n */\nconst comparableDraft = (markdown: string): string =>\n comparableText(markdown).replace(\n /&(lt|gt|amp|#32|#9);/g,\n (reference, name: string) => DRAFT_CHARACTER_REFERENCES[name] ?? reference\n );\n\n/**\n * Escaping at most turns one character into four (`<` → `&lt;`). A line's\n * first space becomes five (`&#32;`), but only once a line, so a whole line\n * with its line break stays under four a character; the slack covers short\n * texts. agora caps a stored draft the same way.\n */\nconst MAX_EXPANSION = 4;\nconst EXPANSION_SLACK_CHARS = 1024;\n\n/**\n * Whether `markdown` is the draft of `text`: no longer than escaping could make\n * it, and equal to it once backslashes are dropped and the draft's character\n * references decoded. A draft that would show other\n * words than the text the model read (another message's, a client's mistake) is\n * not taken; such a message renders its text as before.\n */\nexport function isComposerMarkdownOfText({\n markdown,\n text,\n}: {\n markdown: string;\n text: string;\n}): boolean {\n return (\n markdown.length <= text.length * MAX_EXPANSION + EXPANSION_SLACK_CHARS &&\n comparableDraft(markdown) === comparableText(text)\n );\n}\n\n/** The references a draft writes a line's first space or tab as. */\nconst DRAFT_WHITESPACE_REFERENCES: readonly string[] = ['&#32;', '&#9;'];\n\nconst isWhitespace = (character: string): boolean => /\\s/.test(character);\n\n/** A hard break in a draft: `\\` before the newline (the text holds the newline alone). */\nconst DRAFT_HARD_BREAK = '\\\\\\n';\n\n/** Whether an odd run of backslashes ends at `end`: its last one escapes what follows, not a typed `\\` (`\\\\`). */\nfunction endsInEscapingBackslash({\n markdown,\n start,\n end,\n}: {\n markdown: string;\n start: number;\n end: number;\n}): boolean {\n let backslashes = 0;\n while (end - backslashes > start && markdown.charAt(end - backslashes - 1) === '\\\\') {\n backslashes += 1;\n }\n return backslashes % 2 === 1;\n}\n\n/**\n * `markdown`, a draft, trimmed as its text is trimmed (`text.trim()`): a\n * send that trims its text stays a draft of it. `markdown.trim()` would keep\n * the `&#32;` a draft writes for the space its first line starts with, and the\n * `\\` of a line break whose newline it trims.\n */\nexport function trimComposerDraft(markdown: string): string {\n let start = 0;\n let end = markdown.length;\n for (;;) {\n while (start < end && isWhitespace(markdown.charAt(start))) start += 1;\n const reference = [...DRAFT_WHITESPACE_REFERENCES, DRAFT_HARD_BREAK].find(\n (candidate) => start + candidate.length <= end && markdown.startsWith(candidate, start)\n );\n if (reference === undefined) break;\n start += reference.length;\n }\n for (;;) {\n while (end > start && isWhitespace(markdown.charAt(end - 1))) end -= 1;\n const reference = DRAFT_WHITESPACE_REFERENCES.find(\n (candidate) => end - candidate.length >= start && markdown.endsWith(candidate, end)\n );\n if (reference !== undefined) {\n end -= reference.length;\n } else if (\n markdown.charAt(end) === '\\n' &&\n endsInEscapingBackslash({ markdown, start, end })\n ) {\n // The newline just trimmed was a line break's: its `\\` goes with it.\n end -= 1;\n } else {\n break;\n }\n }\n return markdown.slice(start, end);\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * The composer markdown to render or load for a message whose metadata is\n * `metadata` (a message's `metadata.custom`, or a lane entry's `metadata`) and\n * whose text is `text`; `null` when it carries none, or one that is not a\n * draft of `text`.\n */\nexport function readDeepAgentComposerMarkdown({\n metadata,\n text,\n}: {\n metadata: unknown;\n text: string;\n}): string | null {\n if (!isRecord(metadata)) return null;\n const markdown: unknown = metadata[DEEP_AGENT_COMPOSER_MARKDOWN_KEY];\n return typeof markdown === 'string' && isComposerMarkdownOfText({ markdown, text })\n ? markdown\n : null;\n}\n\n/**\n * How long a staged composer markdown waits for its submission\n * ({@link stageComposerMarkdown}).\n */\nexport const STAGED_COMPOSER_MARKDOWN_TTL_MS = 10_000;\n\ninterface StagedComposerMarkdown {\n readonly markdown: string;\n readonly stagedAt: number;\n}\n\n/**\n * The staged drafts live on `globalThis`, not in module scope, because two\n * copies of this module run in one page: the SDK bundles agent-runtime into its\n * dist, so its composer stages through the SDK's copy, while the Chrome\n * extension and the Office add-in build their runtime on agent-runtime directly\n * and take the draft through their own (see `asset-attachment.ts`).\n */\nconst STAGED_COMPOSER_MARKDOWN = Symbol.for('@athenaintel/agent-runtime/staged-composer-markdown');\n\ntype StagedComposerMarkdownHost = typeof globalThis & {\n [STAGED_COMPOSER_MARKDOWN]?: Map<string, StagedComposerMarkdown>;\n};\n\nfunction stagedComposerMarkdownByThread(): Map<string, StagedComposerMarkdown> {\n const host = globalThis as StagedComposerMarkdownHost;\n return (host[STAGED_COMPOSER_MARKDOWN] ??= new Map());\n}\n\n/**\n * Stage the draft `markdown` of `text` for `threadId`'s next submission.\n *\n * statewire captures message metadata once per new user message\n * (`getMessageMetadata`, patched into `@assistant-ui/react-statewire@0.31.0`)\n * without saying which message it is for, so a composer stages its draft right\n * before it sends and the runtime's getter takes it for the submission that\n * follows ({@link withStagedComposerMarkdown}). A draft equal to its text adds\n * nothing and clears the slot. A slot nobody takes within\n * {@link STAGED_COMPOSER_MARKDOWN_TTL_MS} expires; one a submission the\n * composer did not make takes is harmless, since a composer markdown that is\n * not a draft of the message's own text is neither kept by agora nor rendered.\n */\nexport function stageComposerMarkdown({\n threadId,\n text,\n markdown,\n now = Date.now(),\n}: {\n threadId: string;\n text: string;\n markdown: string;\n /** Test seam: the time of the send. */\n now?: number;\n}): void {\n const staged = stagedComposerMarkdownByThread();\n if (markdown === text) {\n staged.delete(threadId);\n return;\n }\n staged.set(threadId, { markdown, stagedAt: now });\n}\n\n/**\n * The message metadata for `threadId`'s submission now being journaled: the\n * staged composer markdown, if one is waiting and fresh. Takes the slot.\n */\nexport function takeStagedComposerMarkdownMetadata(\n threadId: string,\n now: number = Date.now()\n): Record<string, unknown> | undefined {\n const staged = stagedComposerMarkdownByThread();\n const entry = staged.get(threadId);\n staged.delete(threadId);\n if (entry === undefined || now - entry.stagedAt > STAGED_COMPOSER_MARKDOWN_TTL_MS) {\n return undefined;\n }\n return { [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: entry.markdown };\n}\n\ntype MessageMetadataGetter = () =>\n | Record<string, unknown>\n | undefined\n | Promise<Record<string, unknown> | undefined>;\n\n/**\n * A runtime's `getMessageMetadata` that also carries the composer markdown a\n * composer staged for `threadId` ({@link stageComposerMarkdown}), on top of the\n * host's own metadata (`getMessageMetadata`, when it has one). The slot is\n * taken synchronously at submission, before the host's capture resolves, so a\n * draft never rides a later message. With nothing staged the host's own value\n * is returned as is.\n */\nexport function withStagedComposerMarkdown({\n threadId,\n getMessageMetadata,\n}: {\n threadId: string;\n getMessageMetadata?: MessageMetadataGetter | undefined;\n}): MessageMetadataGetter {\n return () => {\n const staged = takeStagedComposerMarkdownMetadata(threadId);\n const captured = getMessageMetadata?.();\n if (staged === undefined) return captured;\n const merge = (host: Record<string, unknown> | undefined): Record<string, unknown> => ({\n ...host,\n ...staged,\n });\n return captured instanceof Promise ? captured.then(merge) : merge(captured);\n };\n}\n\n/** Test seam: drop every staged composer markdown. */\nexport function resetStagedComposerMarkdown(): void {\n stagedComposerMarkdownByThread().clear();\n}\n\n/**\n * `metadata` with the composer markdown set to the draft `markdown` of `text`,\n * or without it when the draft equals the text (it adds nothing then).\n * Returns `undefined` when nothing is left.\n */\nexport function withDeepAgentComposerMarkdown({\n metadata,\n text,\n markdown,\n}: {\n metadata: Readonly<Record<string, unknown>> | undefined;\n text: string;\n markdown: string;\n}): Record<string, unknown> | undefined {\n const { [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: _previous, ...rest } = metadata ?? {};\n const next: Record<string, unknown> =\n markdown === text ? rest : { ...rest, [DEEP_AGENT_COMPOSER_MARKDOWN_KEY]: markdown };\n return Object.keys(next).length > 0 ? next : undefined;\n}\n"],"names":[],"mappings":"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"}