@athenaintel/react 0.20.0 → 0.21.0

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 (347) hide show
  1. package/README.md +74 -0
  2. package/dist/assets/use-asset-embed.cjs +8 -0
  3. package/dist/assets/use-asset-embed.cjs.map +1 -1
  4. package/dist/assets/use-asset-embed.js +8 -0
  5. package/dist/assets/use-asset-embed.js.map +1 -1
  6. package/dist/chat/StatewireApprovalCard.cjs +22 -4
  7. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  8. package/dist/chat/StatewireApprovalCard.d.ts +14 -0
  9. package/dist/chat/StatewireApprovalCard.js +23 -5
  10. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  11. package/dist/chat/StatewireClientToolBridge.cjs +2 -1
  12. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  13. package/dist/chat/StatewireClientToolBridge.js +2 -1
  14. package/dist/chat/StatewireClientToolBridge.js.map +1 -1
  15. package/dist/chat/StatewireQueuedMessages.cjs +2 -1
  16. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  17. package/dist/chat/StatewireQueuedMessages.js +2 -1
  18. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  19. package/dist/chat/athena-citation-links.cjs +17 -1
  20. package/dist/chat/athena-citation-links.cjs.map +1 -1
  21. package/dist/chat/athena-citation-links.js +17 -1
  22. package/dist/chat/athena-citation-links.js.map +1 -1
  23. package/dist/chat/statewire-client-tools.cjs +2 -1
  24. package/dist/chat/statewire-client-tools.cjs.map +1 -1
  25. package/dist/chat/statewire-client-tools.js +2 -1
  26. package/dist/chat/statewire-client-tools.js.map +1 -1
  27. package/dist/chat/super-grouping/SuperGroupingCard.cjs +69 -187
  28. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  29. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +10 -6
  30. package/dist/chat/super-grouping/SuperGroupingCard.js +73 -191
  31. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  32. package/dist/chat/super-grouping/ToolTimeline.cjs +131 -0
  33. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -0
  34. package/dist/chat/super-grouping/ToolTimeline.d.ts +16 -0
  35. package/dist/chat/super-grouping/ToolTimeline.js +131 -0
  36. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -0
  37. package/dist/chat/super-grouping/activity-timeline.cjs +14 -8
  38. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  39. package/dist/chat/super-grouping/activity-timeline.d.ts +3 -0
  40. package/dist/chat/super-grouping/activity-timeline.js +14 -8
  41. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  42. package/dist/chat/super-grouping/timeline-step.cjs +65 -0
  43. package/dist/chat/super-grouping/timeline-step.cjs.map +1 -0
  44. package/dist/chat/super-grouping/timeline-step.d.ts +17 -0
  45. package/dist/chat/super-grouping/timeline-step.js +65 -0
  46. package/dist/chat/super-grouping/timeline-step.js.map +1 -0
  47. package/dist/chat/tiptap-text.cjs +8 -8
  48. package/dist/chat/tiptap-text.cjs.map +1 -1
  49. package/dist/chat/use-athena-run-live.cjs +2 -1
  50. package/dist/chat/use-athena-run-live.cjs.map +1 -1
  51. package/dist/chat/use-athena-run-live.js +2 -1
  52. package/dist/chat/use-athena-run-live.js.map +1 -1
  53. package/dist/chat/use-statewire-approval-request.cjs +7 -2
  54. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  55. package/dist/chat/use-statewire-approval-request.d.ts +12 -2
  56. package/dist/chat/use-statewire-approval-request.js +8 -3
  57. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  58. package/dist/chat-ui/composer/tiptap-composer.cjs +24 -65
  59. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  60. package/dist/chat-ui/composer/tiptap-composer.js +24 -65
  61. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  62. package/dist/chat-ui/index.cjs +2 -1
  63. package/dist/chat-ui/index.cjs.map +1 -1
  64. package/dist/chat-ui/index.js +2 -1
  65. package/dist/chat-ui/index.js.map +1 -1
  66. package/dist/chat-ui/mentions/mention-chip.cjs +49 -4
  67. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  68. package/dist/chat-ui/mentions/mention-chip.d.ts +11 -0
  69. package/dist/chat-ui/mentions/mention-chip.js +50 -5
  70. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  71. package/dist/chat-ui/mentions/mention-extension.cjs +18 -6
  72. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  73. package/dist/chat-ui/mentions/mention-extension.d.ts +2 -0
  74. package/dist/chat-ui/mentions/mention-extension.js +18 -6
  75. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  76. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +1 -1
  77. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  78. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +1 -1
  79. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  80. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs +9 -6
  81. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs.map +1 -1
  82. package/dist/chat-ui/mentions/suggestions/components/menu-item.d.ts +2 -2
  83. package/dist/chat-ui/mentions/suggestions/components/menu-item.js +10 -7
  84. package/dist/chat-ui/mentions/suggestions/components/menu-item.js.map +1 -1
  85. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +2 -2
  86. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  87. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +2 -2
  88. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +2 -2
  89. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  90. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +2 -1
  91. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  92. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +3 -2
  93. package/dist/chat-ui/mentions/suggestions/data/api-client.js +2 -1
  94. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  95. package/dist/chat-ui/messages/message-components.cjs +6 -29
  96. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  97. package/dist/chat-ui/messages/message-components.d.ts +1 -13
  98. package/dist/chat-ui/messages/message-components.js +8 -31
  99. package/dist/chat-ui/messages/message-components.js.map +1 -1
  100. package/dist/chat-ui/messages/runtime-message.cjs +3 -2
  101. package/dist/chat-ui/messages/runtime-message.cjs.map +1 -1
  102. package/dist/chat-ui/messages/runtime-message.js +3 -2
  103. package/dist/chat-ui/messages/runtime-message.js.map +1 -1
  104. package/dist/chat-ui/messages/statewire-continue-run.cjs +23 -8
  105. package/dist/chat-ui/messages/statewire-continue-run.cjs.map +1 -1
  106. package/dist/chat-ui/messages/statewire-continue-run.d.ts +14 -4
  107. package/dist/chat-ui/messages/statewire-continue-run.js +23 -8
  108. package/dist/chat-ui/messages/statewire-continue-run.js.map +1 -1
  109. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -1
  110. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  111. package/dist/chat-ui/messages/user-edit-composer.js +2 -1
  112. package/dist/chat-ui/messages/user-edit-composer.js.map +1 -1
  113. package/dist/chat-ui/rich-text/chat-message-body.cjs +76 -0
  114. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -0
  115. package/dist/chat-ui/rich-text/chat-message-body.d.ts +5 -0
  116. package/dist/chat-ui/rich-text/chat-message-body.js +76 -0
  117. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -0
  118. package/dist/chat-ui/rich-text/chat-node-views.cjs +51 -0
  119. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -0
  120. package/dist/chat-ui/rich-text/chat-node-views.d.ts +13 -0
  121. package/dist/chat-ui/rich-text/chat-node-views.js +51 -0
  122. package/dist/chat-ui/rich-text/chat-node-views.js.map +1 -0
  123. package/dist/chat-ui/rich-text/chat-text-schema.cjs +70 -0
  124. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -0
  125. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +7 -0
  126. package/dist/chat-ui/rich-text/chat-text-schema.js +70 -0
  127. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -0
  128. package/dist/chat-ui/rich-text/dom-output-spec.cjs +83 -0
  129. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -0
  130. package/dist/chat-ui/rich-text/dom-output-spec.d.ts +11 -0
  131. package/dist/chat-ui/rich-text/dom-output-spec.js +83 -0
  132. package/dist/chat-ui/rich-text/dom-output-spec.js.map +1 -0
  133. package/dist/chat-ui/statewire.cjs +2 -1
  134. package/dist/chat-ui/statewire.cjs.map +1 -1
  135. package/dist/chat-ui/statewire.js +2 -1
  136. package/dist/chat-ui/statewire.js.map +1 -1
  137. package/dist/chat-ui/thread/statewire-history-edge.cjs +2 -1
  138. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  139. package/dist/chat-ui/thread/statewire-history-edge.js +2 -1
  140. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  141. package/dist/index.cjs +2 -1
  142. package/dist/index.cjs.map +1 -1
  143. package/dist/index.js +2 -1
  144. package/dist/index.js.map +1 -1
  145. package/dist/node_modules/qrcode-generator/dist/qrcode.cjs +32 -0
  146. package/dist/node_modules/qrcode-generator/dist/qrcode.cjs.map +1 -0
  147. package/dist/node_modules/qrcode-generator/dist/qrcode.js +31 -0
  148. package/dist/node_modules/qrcode-generator/dist/qrcode.js.map +1 -0
  149. package/dist/node_modules/zod/v4/classic/errors.cjs +44 -0
  150. package/dist/node_modules/zod/v4/classic/errors.cjs.map +1 -0
  151. package/dist/node_modules/zod/v4/classic/errors.js +44 -0
  152. package/dist/node_modules/zod/v4/classic/errors.js.map +1 -0
  153. package/dist/node_modules/zod/v4/classic/iso.cjs +43 -0
  154. package/dist/node_modules/zod/v4/classic/iso.cjs.map +1 -0
  155. package/dist/node_modules/zod/v4/classic/iso.js +43 -0
  156. package/dist/node_modules/zod/v4/classic/iso.js.map +1 -0
  157. package/dist/node_modules/zod/v4/classic/parse.cjs +29 -0
  158. package/dist/node_modules/zod/v4/classic/parse.cjs.map +1 -0
  159. package/dist/node_modules/zod/v4/classic/parse.js +29 -0
  160. package/dist/node_modules/zod/v4/classic/parse.js.map +1 -0
  161. package/dist/node_modules/zod/v4/classic/schemas.cjs +871 -0
  162. package/dist/node_modules/zod/v4/classic/schemas.cjs.map +1 -0
  163. package/dist/node_modules/zod/v4/classic/schemas.js +871 -0
  164. package/dist/node_modules/zod/v4/classic/schemas.js.map +1 -0
  165. package/dist/node_modules/zod/v4/core/api.cjs +570 -0
  166. package/dist/node_modules/zod/v4/core/api.cjs.map +1 -0
  167. package/dist/node_modules/zod/v4/core/api.js +570 -0
  168. package/dist/node_modules/zod/v4/core/api.js.map +1 -0
  169. package/dist/node_modules/zod/v4/core/checks.cjs +411 -0
  170. package/dist/node_modules/zod/v4/core/checks.cjs.map +1 -0
  171. package/dist/node_modules/zod/v4/core/checks.js +411 -0
  172. package/dist/node_modules/zod/v4/core/checks.js.map +1 -0
  173. package/dist/node_modules/zod/v4/core/core.cjs +77 -0
  174. package/dist/node_modules/zod/v4/core/core.cjs.map +1 -0
  175. package/dist/node_modules/zod/v4/core/core.js +77 -0
  176. package/dist/node_modules/zod/v4/core/core.js.map +1 -0
  177. package/dist/node_modules/zod/v4/core/doc.cjs +38 -0
  178. package/dist/node_modules/zod/v4/core/doc.cjs.map +1 -0
  179. package/dist/node_modules/zod/v4/core/doc.js +38 -0
  180. package/dist/node_modules/zod/v4/core/doc.js.map +1 -0
  181. package/dist/node_modules/zod/v4/core/errors.cjs +76 -0
  182. package/dist/node_modules/zod/v4/core/errors.cjs.map +1 -0
  183. package/dist/node_modules/zod/v4/core/errors.js +76 -0
  184. package/dist/node_modules/zod/v4/core/errors.js.map +1 -0
  185. package/dist/node_modules/zod/v4/core/json-schema-processors.cjs +312 -0
  186. package/dist/node_modules/zod/v4/core/json-schema-processors.cjs.map +1 -0
  187. package/dist/node_modules/zod/v4/core/json-schema-processors.js +312 -0
  188. package/dist/node_modules/zod/v4/core/json-schema-processors.js.map +1 -0
  189. package/dist/node_modules/zod/v4/core/parse.cjs +96 -0
  190. package/dist/node_modules/zod/v4/core/parse.cjs.map +1 -0
  191. package/dist/node_modules/zod/v4/core/parse.js +96 -0
  192. package/dist/node_modules/zod/v4/core/parse.js.map +1 -0
  193. package/dist/node_modules/zod/v4/core/regexes.cjs +86 -0
  194. package/dist/node_modules/zod/v4/core/regexes.cjs.map +1 -0
  195. package/dist/node_modules/zod/v4/core/regexes.js +86 -0
  196. package/dist/node_modules/zod/v4/core/regexes.js.map +1 -0
  197. package/dist/node_modules/zod/v4/core/registries.cjs +52 -0
  198. package/dist/node_modules/zod/v4/core/registries.cjs.map +1 -0
  199. package/dist/node_modules/zod/v4/core/registries.js +52 -0
  200. package/dist/node_modules/zod/v4/core/registries.js.map +1 -0
  201. package/dist/node_modules/zod/v4/core/schemas.cjs +1412 -0
  202. package/dist/node_modules/zod/v4/core/schemas.cjs.map +1 -0
  203. package/dist/node_modules/zod/v4/core/schemas.js +1413 -0
  204. package/dist/node_modules/zod/v4/core/schemas.js.map +1 -0
  205. package/dist/node_modules/zod/v4/core/to-json-schema.cjs +370 -0
  206. package/dist/node_modules/zod/v4/core/to-json-schema.cjs.map +1 -0
  207. package/dist/node_modules/zod/v4/core/to-json-schema.js +370 -0
  208. package/dist/node_modules/zod/v4/core/to-json-schema.js.map +1 -0
  209. package/dist/node_modules/zod/v4/core/util.cjs +444 -0
  210. package/dist/node_modules/zod/v4/core/util.cjs.map +1 -0
  211. package/dist/node_modules/zod/v4/core/util.js +444 -0
  212. package/dist/node_modules/zod/v4/core/util.js.map +1 -0
  213. package/dist/node_modules/zod/v4/core/versions.cjs +9 -0
  214. package/dist/node_modules/zod/v4/core/versions.cjs.map +1 -0
  215. package/dist/node_modules/zod/v4/core/versions.js +9 -0
  216. package/dist/node_modules/zod/v4/core/versions.js.map +1 -0
  217. package/dist/packages/agent-runtime/src/client-tool-bridge.cjs +7 -1
  218. package/dist/packages/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  219. package/dist/packages/agent-runtime/src/client-tool-bridge.js +7 -1
  220. package/dist/packages/agent-runtime/src/client-tool-bridge.js.map +1 -1
  221. package/dist/packages/agent-runtime/src/conversation-list.cjs +4 -0
  222. package/dist/packages/agent-runtime/src/conversation-list.cjs.map +1 -1
  223. package/dist/packages/agent-runtime/src/conversation-list.js +4 -0
  224. package/dist/packages/agent-runtime/src/conversation-list.js.map +1 -1
  225. package/dist/packages/agent-runtime/src/edit-command.cjs.map +1 -1
  226. package/dist/packages/agent-runtime/src/edit-command.js.map +1 -1
  227. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -0
  228. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  229. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -0
  230. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  231. package/dist/packages/agent-runtime/src/interrupts.cjs +31 -7
  232. package/dist/packages/agent-runtime/src/interrupts.cjs.map +1 -1
  233. package/dist/packages/agent-runtime/src/interrupts.js +31 -7
  234. package/dist/packages/agent-runtime/src/interrupts.js.map +1 -1
  235. package/dist/packages/agent-runtime/src/messages.cjs +35 -5
  236. package/dist/packages/agent-runtime/src/messages.cjs.map +1 -1
  237. package/dist/packages/agent-runtime/src/messages.js +35 -5
  238. package/dist/packages/agent-runtime/src/messages.js.map +1 -1
  239. package/dist/packages/agent-runtime/src/protocol.cjs +4 -6
  240. package/dist/packages/agent-runtime/src/protocol.cjs.map +1 -1
  241. package/dist/packages/agent-runtime/src/protocol.js +4 -6
  242. package/dist/packages/agent-runtime/src/protocol.js.map +1 -1
  243. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs +296 -14
  244. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  245. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js +293 -11
  246. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  247. package/dist/packages/agent-runtime/src/screen-point.cjs +68 -0
  248. package/dist/packages/agent-runtime/src/screen-point.cjs.map +1 -0
  249. package/dist/packages/agent-runtime/src/screen-point.js +68 -0
  250. package/dist/packages/agent-runtime/src/screen-point.js.map +1 -0
  251. package/dist/packages/agent-runtime/src/statewire-transport.cjs +6 -1
  252. package/dist/packages/agent-runtime/src/statewire-transport.cjs.map +1 -1
  253. package/dist/packages/agent-runtime/src/statewire-transport.js +6 -1
  254. package/dist/packages/agent-runtime/src/statewire-transport.js.map +1 -1
  255. package/dist/packages/agent-runtime/src/thread-handoff.cjs +85 -0
  256. package/dist/packages/agent-runtime/src/thread-handoff.cjs.map +1 -0
  257. package/dist/packages/agent-runtime/src/thread-handoff.js +85 -0
  258. package/dist/packages/agent-runtime/src/thread-handoff.js.map +1 -0
  259. package/dist/packages/agent-runtime/src/thread-snapshot-cache.cjs +1 -1
  260. package/dist/packages/agent-runtime/src/thread-snapshot-cache.cjs.map +1 -1
  261. package/dist/packages/agent-runtime/src/thread-snapshot-cache.js +1 -1
  262. package/dist/packages/agent-runtime/src/thread-snapshot-cache.js.map +1 -1
  263. package/dist/packages/agent-runtime/src/tool-metadata.cjs +0 -8
  264. package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +1 -1
  265. package/dist/packages/agent-runtime/src/tool-metadata.js +0 -8
  266. package/dist/packages/agent-runtime/src/tool-metadata.js.map +1 -1
  267. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs +14 -0
  268. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs.map +1 -0
  269. package/dist/packages/agent-runtime/src/use-deep-agent-config.js +14 -0
  270. package/dist/packages/agent-runtime/src/use-deep-agent-config.js.map +1 -0
  271. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs +21 -5
  272. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  273. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js +21 -5
  274. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -1
  275. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.cjs +13 -3
  276. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  277. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.js +14 -4
  278. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  279. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs +35 -15
  280. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  281. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js +35 -15
  282. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  283. package/dist/packages/agent-runtime/src/voice-presentation.cjs.map +1 -1
  284. package/dist/packages/agent-runtime/src/voice-presentation.js.map +1 -1
  285. package/dist/packages/react/package.json.cjs +1 -1
  286. package/dist/packages/react/package.json.js +1 -1
  287. package/dist/provider/AthenaProvider.cjs +2 -1
  288. package/dist/provider/AthenaProvider.cjs.map +1 -1
  289. package/dist/provider/AthenaProvider.js +2 -1
  290. package/dist/provider/AthenaProvider.js.map +1 -1
  291. package/dist/runtime/statewire-lifecycle.cjs +2 -1
  292. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  293. package/dist/runtime/statewire-lifecycle.js +2 -1
  294. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  295. package/dist/runtime/useAthenaStatewireRuntime.cjs +2 -1
  296. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  297. package/dist/runtime/useAthenaStatewireRuntime.js +2 -1
  298. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  299. package/dist/styles.css +1 -1
  300. package/dist/threads/conversation-list-fetcher.cjs +4 -0
  301. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  302. package/dist/threads/conversation-list-fetcher.js +4 -0
  303. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  304. package/dist/threads/statewire-thread-list.cjs +2 -1
  305. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  306. package/dist/threads/statewire-thread-list.js +2 -1
  307. package/dist/threads/statewire-thread-list.js.map +1 -1
  308. package/dist/threads/use-rest-conversation-history.cjs +2 -1
  309. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  310. package/dist/threads/use-rest-conversation-history.js +2 -1
  311. package/dist/threads/use-rest-conversation-history.js.map +1 -1
  312. package/dist/threads/use-statewire-conversation-history.cjs +2 -1
  313. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  314. package/dist/threads/use-statewire-conversation-history.d.ts +1 -0
  315. package/dist/threads/use-statewire-conversation-history.js +2 -1
  316. package/dist/threads/use-statewire-conversation-history.js.map +1 -1
  317. package/dist/tools/index.cjs +2 -1
  318. package/dist/tools/index.cjs.map +1 -1
  319. package/dist/tools/index.js +2 -1
  320. package/dist/tools/index.js.map +1 -1
  321. package/dist/tools/misc-tool-uis.cjs +2 -1
  322. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  323. package/dist/tools/misc-tool-uis.js +2 -1
  324. package/dist/tools/misc-tool-uis.js.map +1 -1
  325. package/dist/tools/primitives.cjs +2 -1
  326. package/dist/tools/primitives.cjs.map +1 -1
  327. package/dist/tools/primitives.js +2 -1
  328. package/dist/tools/primitives.js.map +1 -1
  329. package/dist/tools/tool-fallback.cjs +2 -1
  330. package/dist/tools/tool-fallback.cjs.map +1 -1
  331. package/dist/tools/tool-fallback.js +2 -1
  332. package/dist/tools/tool-fallback.js.map +1 -1
  333. package/dist/tools/voice-update-tool-ui.cjs +2 -1
  334. package/dist/tools/voice-update-tool-ui.cjs.map +1 -1
  335. package/dist/tools/voice-update-tool-ui.js +2 -1
  336. package/dist/tools/voice-update-tool-ui.js.map +1 -1
  337. package/dist/voice/index.cjs +6 -0
  338. package/dist/voice/index.cjs.map +1 -0
  339. package/dist/voice/index.d.ts +2 -0
  340. package/dist/voice/index.js +6 -0
  341. package/dist/voice/index.js.map +1 -0
  342. package/dist/voice/use-athena-voice-session.cjs +315 -0
  343. package/dist/voice/use-athena-voice-session.cjs.map +1 -0
  344. package/dist/voice/use-athena-voice-session.d.ts +145 -0
  345. package/dist/voice/use-athena-voice-session.js +315 -0
  346. package/dist/voice/use-athena-voice-session.js.map +1 -0
  347. package/package.json +17 -3
@@ -1 +1 @@
1
- {"version":3,"file":"statewire-continue-run.cjs","sources":["../../../src/chat-ui/messages/statewire-continue-run.tsx"],"sourcesContent":["import { type ThreadMessage, useAuiState } from \"@assistant-ui/react\";\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n} from \"@assistant-ui/react-statewire\";\nimport {\n ATHENA_RUN_MARKER_CANCELLED,\n ATHENA_RUN_MARKER_FAILED,\n type AthenaRuntimeMessage,\n type AthenaRuntimeMessageKind,\n type DeepAgentThreadStatus,\n hasStatewireThreadExtras,\n readRetryableRunRefusal,\n readRunMarkerFromSourceMessages,\n readRuntimeMessageFromSourceMessages,\n useDeepAgentThreadStatus,\n} from \"@athenaintel/agent-runtime\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { ContinuePill } from \"./continue-pill\";\nimport { RuntimeMessageCard } from \"./runtime-message\";\n\nexport interface StatewireContinueRunButtonProps {\n /**\n * Also offer Continue while the thread projects `ready`. An old snapshot\n * can report a resting thread whose last persisted ending is still\n * continuable; the marker row that mounts this button knows that.\n */\n allowReadyFallback?: boolean;\n /**\n * Called as the continue dispatches (after the pill's exit animation) —\n * the host's telemetry hook. Receives the settled status and live run id.\n */\n onContinue?: (context: { status: DeepAgentThreadStatus; runId: string | null }) => void;\n}\n\n/**\n * Dispatches the bare `run/continue` for the live Statewire thread — the\n * heal-then-continue recovery for stopped, errored, and pod-drained runs. The\n * command is exactly what the library's `onResume` emits, so it inherits the\n * optimistic running-flip (the pill unmounts once the dispatch is accepted)\n * and routes rejections to the runtime's shared `onError` policy.\n *\n * Gated on the LIVE thread status, never on the persisted marker: markers live\n * in the transcript forever, while continuability is a property of the\n * current run state. Requires `capabilities.continue` on the host thread and\n * a statewire aui scope (throws outside one, like every `useStatewire*` hook).\n */\nexport function StatewireContinueRunButton({\n allowReadyFallback = false,\n onContinue,\n}: StatewireContinueRunButtonProps = {}): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { runId } = useStatewireRuns();\n const sendCommand = useStatewireSendCommand();\n\n const isSettled = status === \"stopped\" || status === \"error\";\n if (!isSettled && !(allowReadyFallback && status === \"ready\")) return null;\n\n return (\n <ContinuePill\n ariaLabel=\"Continue this run from where it stopped\"\n dataTestId=\"statewire-continue-run\"\n onClick={() => {\n onContinue?.({ status, runId });\n sendCommand({\n type: \"run/continue\",\n ...(runId !== null && { runId }),\n });\n }}\n />\n );\n}\n\n/**\n * Recovery affordance for the latest persisted stopped/failed run marker,\n * for the `runtimeMessageAction` slot of `createAssistantMessage`.\n *\n * Marker messages remain in history forever, so only the current last message\n * may continue. The extras guard keeps Statewire hooks out of read-only or\n * legacy runtimes where they would throw.\n */\nexport function StatewireContinueRunAffordance(): ReactElement | null {\n const messageId = useAuiState((state) => state.message.id);\n const lastMessageId = useAuiState(\n (state) => state.thread.messages.at(-1)?.id,\n );\n const runMarker = useAuiState(\n (state) => readRunMarkerFromSourceMessages(state.message)?.marker,\n );\n const threadExtras = useAuiState((state) => state.thread.extras);\n\n const isContinuableMarker =\n runMarker === ATHENA_RUN_MARKER_CANCELLED ||\n runMarker === ATHENA_RUN_MARKER_FAILED;\n if (messageId !== lastMessageId || !isContinuableMarker) return null;\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n\n return (\n <div className=\"flex w-full justify-center py-1\">\n <StatewireContinueRunButton allowReadyFallback />\n </div>\n );\n}\n\n/** The ending a transcript row paints, as the footer needs to know it. */\nexport interface StatewireTailEnding {\n kind: AthenaRuntimeMessageKind;\n /** A send-now cancellation: kept in the data, painted as nothing. */\n silent: boolean;\n}\n\n/** Reads the runtime ending (marker or handoff) a message row renders, if any. */\nexport type ReadStatewireTailEnding = (message: ThreadMessage) => StatewireTailEnding | null;\n\nconst readRuntimeTailEnding: ReadStatewireTailEnding = (message) => {\n const runtime = readRuntimeMessageFromSourceMessages(message);\n return runtime ? { kind: runtime.kind, silent: runtime.silent } : null;\n};\n\nexport interface StatewireRunEndedFooterActionsContext {\n /** The live settled status the footer describes. */\n status: \"stopped\" | \"error\";\n /** The ending the tail row renders, when it renders one (silent markers read as none). */\n tailEndingKind: AthenaRuntimeMessageKind | null;\n}\n\nexport interface StatewireRunEndedFooterProps {\n /** Merged onto the recovery card's default classes. */\n className?: string;\n /**\n * How the host's assistant row paints the transcript tail. The default reads\n * the runtime ending only (a persisted marker or handoff); a host whose row\n * also styles an assistant-ui error status as a failed ending passes a\n * reader that reports it, so the footer never doubles that row's recovery.\n */\n readTailEnding?: ReadStatewireTailEnding;\n /**\n * The recovery controls. The default renders Continue unless the tail row\n * (a marker of another kind) already carries it; hosts with richer recovery\n * (Retry + Continue) supply their own and decide ownership from the context.\n */\n renderActions?: (context: StatewireRunEndedFooterActionsContext) => ReactNode;\n}\n\n/**\n * Recovery row for a settled run whose persisted ending is no longer the\n * transcript tail — rendered after the messages (`renderMessages`). Rewinds,\n * compaction, and older snapshots can all leave the durable run state\n * recoverable without a marker row that owns the action. The failure copy\n * comes from the replicated run error (`runs.error.message`) — the same text\n * the marker would have carried. A RETRYABLE refusal recorded there\n * (`readRetryableRunRefusal`: a closing host refused to start the queued\n * work, which stays in its lane and re-dispatches on the thread's next\n * placement) is not a failure of the run and paints as a pause, keeping\n * Continue as the manual way on. Renders nothing on legacy (non-statewire)\n * threads.\n */\nexport function StatewireRunEndedFooter({\n className,\n readTailEnding,\n renderActions,\n}: StatewireRunEndedFooterProps = {}): ReactElement | null {\n const threadExtras = useAuiState((state) => state.thread.extras);\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n return (\n <StatewireRunEndedFooterContent\n className={className}\n readTailEnding={readTailEnding}\n renderActions={renderActions}\n />\n );\n}\n\nfunction StatewireRunEndedFooterContent({\n className,\n readTailEnding = readRuntimeTailEnding,\n renderActions,\n}: StatewireRunEndedFooterProps): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { error } = useStatewireRuns();\n // The reader builds a fresh object per call; select primitives so the\n // snapshots stay stable under `Object.is` comparison.\n const tailEndingKind = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.kind ?? null) : null;\n });\n const tailEndingSilent = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.silent ?? false) : false;\n });\n\n if (status !== \"stopped\" && status !== \"error\") return null;\n\n // A send-now promotion intentionally cancels the superseded run without a\n // visible ending. Statewire can briefly report that cancellation as stopped;\n // preserve the silent contract instead of presenting a false recovery state.\n // A genuine error still wins and remains recoverable below.\n if (status === \"stopped\" && tailEndingSilent) return null;\n\n const tailRendersEnding = tailEndingKind !== null && !tailEndingSilent;\n const tailMatchesStatus =\n status === \"error\"\n ? tailEndingKind === \"failed\"\n : tailEndingKind === \"stopped\" || tailEndingKind === \"paused\";\n if (tailRendersEnding && tailMatchesStatus) return null;\n\n // An older run's marker at the tail still carries its own Continue (the\n // marker-row affordance); a handoff banner does not.\n const tailOwnsContinue = tailRendersEnding && tailEndingKind !== \"handoff\";\n const action = renderActions ? (\n renderActions({ status, tailEndingKind: tailRendersEnding ? tailEndingKind : null })\n ) : tailOwnsContinue ? undefined : (\n <StatewireContinueRunButton />\n );\n const refusal = status === \"error\" ? readRetryableRunRefusal(error) : null;\n const message: AthenaRuntimeMessage =\n status === \"error\"\n ? refusal\n ? {\n kind: \"paused\",\n reason: refusal.code,\n severity: \"info\",\n title: \"Waiting for a server update\",\n detail:\n \"The server hosting this chat is restarting, so the queued message could not start yet. It runs on a ready server automatically.\",\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"failed\",\n reason: \"error\",\n severity: \"error\",\n title: \"Run failed\",\n detail: undefined,\n text: error?.message ? `⚠️ The run failed: ${error.message}` : undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"stopped\",\n reason: undefined,\n severity: \"info\",\n title: \"Conversation stopped\",\n detail: undefined,\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n };\n\n return (\n <RuntimeMessageCard\n data-testid=\"statewire-run-ended-footer\"\n message={message}\n action={action}\n className={cn(\"mx-auto max-w-[95%]\", className)}\n />\n );\n}\n"],"names":["useDeepAgentThreadStatus","useStatewireRuns","useStatewireSendCommand","jsx","ContinuePill","useAuiState","readRunMarkerFromSourceMessages","threadExtras","ATHENA_RUN_MARKER_CANCELLED","ATHENA_RUN_MARKER_FAILED","hasStatewireThreadExtras","readRuntimeMessageFromSourceMessages","readRetryableRunRefusal","RuntimeMessageCard","cn"],"mappings":"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"}
1
+ {"version":3,"file":"statewire-continue-run.cjs","sources":["../../../src/chat-ui/messages/statewire-continue-run.tsx"],"sourcesContent":["import { type ThreadMessage, useAuiState } from \"@assistant-ui/react\";\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n} from \"@assistant-ui/react-statewire\";\nimport {\n ATHENA_RUN_MARKER_CANCELLED,\n ATHENA_RUN_MARKER_FAILED,\n type AthenaRuntimeMessage,\n type AthenaRuntimeMessageKind,\n type DeepAgentThreadStatus,\n hasStatewireThreadExtras,\n readRetryableRunRefusal,\n readRunMarkerFromSourceMessages,\n readRuntimeMessageFromSourceMessages,\n useDeepAgentThreadStatus,\n} from \"@athenaintel/agent-runtime\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { ContinuePill } from \"./continue-pill\";\nimport { RuntimeMessageCard } from \"./runtime-message\";\n\nexport interface StatewireContinueRunButtonProps {\n /**\n * Also offer Continue while the thread projects `ready`. An old snapshot\n * can report a resting thread whose last persisted ending is still\n * continuable; the marker row that mounts this button knows that.\n */\n allowReadyFallback?: boolean;\n /**\n * Called as the continue dispatches (after the pill's exit animation),\n * immediately before the command queues — the host's telemetry hook.\n * Receives the settled status and live run id the user acted on. Queueing\n * publishes the command's first update synchronously, so a hook that pairs\n * this click with that update must run first. Best-effort: a throwing hook\n * is swallowed and never blocks the dispatch.\n */\n onContinue?: (context: { status: DeepAgentThreadStatus; runId: string | null }) => void;\n}\n\nfunction notifyContinue(\n onContinue: StatewireContinueRunButtonProps[\"onContinue\"],\n context: { status: DeepAgentThreadStatus; runId: string | null },\n): void {\n try {\n onContinue?.(context);\n } catch (error) {\n console.debug(\"[StatewireContinueRunButton] onContinue hook failed:\", error);\n }\n}\n\n/**\n * Dispatches the bare `run/continue` for the live Statewire thread — the\n * heal-then-continue recovery for stopped, errored, and pod-drained runs. The\n * command is exactly what the library's `onResume` emits, so it inherits the\n * optimistic running-flip (the pill unmounts once the dispatch is accepted)\n * and routes rejections to the runtime's shared `onError` policy.\n *\n * Gated on the LIVE thread status, never on the persisted marker: markers live\n * in the transcript forever, while continuability is a property of the\n * current run state. Requires `capabilities.continue` on the host thread and\n * a statewire aui scope (throws outside one, like every `useStatewire*` hook).\n */\nexport function StatewireContinueRunButton({\n allowReadyFallback = false,\n onContinue,\n}: StatewireContinueRunButtonProps = {}): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { runId } = useStatewireRuns();\n const sendCommand = useStatewireSendCommand();\n\n const isSettled = status === \"stopped\" || status === \"error\";\n if (!isSettled && !(allowReadyFallback && status === \"ready\")) return null;\n\n return (\n <ContinuePill\n ariaLabel=\"Continue this run from where it stopped\"\n dataTestId=\"statewire-continue-run\"\n onClick={() => {\n notifyContinue(onContinue, { status, runId });\n sendCommand({\n type: \"run/continue\",\n ...(runId !== null && { runId }),\n });\n }}\n />\n );\n}\n\nexport interface StatewireContinueRunAffordanceProps {\n /** Forwarded to the mounted `StatewireContinueRunButton`. */\n onContinue?: StatewireContinueRunButtonProps[\"onContinue\"];\n}\n\n/**\n * Recovery affordance for the latest persisted stopped/failed run marker,\n * for the `runtimeMessageAction` slot of `createAssistantMessage`.\n *\n * Marker messages remain in history forever, so only the current last message\n * may continue. The extras guard keeps Statewire hooks out of read-only or\n * legacy runtimes where they would throw.\n */\nexport function StatewireContinueRunAffordance({\n onContinue,\n}: StatewireContinueRunAffordanceProps = {}): ReactElement | null {\n const messageId = useAuiState((state) => state.message.id);\n const lastMessageId = useAuiState(\n (state) => state.thread.messages.at(-1)?.id,\n );\n const runMarker = useAuiState(\n (state) => readRunMarkerFromSourceMessages(state.message)?.marker,\n );\n const threadExtras = useAuiState((state) => state.thread.extras);\n\n const isContinuableMarker =\n runMarker === ATHENA_RUN_MARKER_CANCELLED ||\n runMarker === ATHENA_RUN_MARKER_FAILED;\n if (messageId !== lastMessageId || !isContinuableMarker) return null;\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n\n return (\n <div className=\"flex w-full justify-center py-1\">\n <StatewireContinueRunButton allowReadyFallback onContinue={onContinue} />\n </div>\n );\n}\n\n/** The ending a transcript row paints, as the footer needs to know it. */\nexport interface StatewireTailEnding {\n kind: AthenaRuntimeMessageKind;\n /** A send-now cancellation: kept in the data, painted as nothing. */\n silent: boolean;\n}\n\n/** Reads the runtime ending (marker or handoff) a message row renders, if any. */\nexport type ReadStatewireTailEnding = (message: ThreadMessage) => StatewireTailEnding | null;\n\nconst readRuntimeTailEnding: ReadStatewireTailEnding = (message) => {\n const runtime = readRuntimeMessageFromSourceMessages(message);\n return runtime ? { kind: runtime.kind, silent: runtime.silent } : null;\n};\n\nexport interface StatewireRunEndedFooterActionsContext {\n /** The live settled status the footer describes. */\n status: \"stopped\" | \"error\";\n /** The ending the tail row renders, when it renders one (silent markers read as none). */\n tailEndingKind: AthenaRuntimeMessageKind | null;\n}\n\nexport interface StatewireRunEndedFooterProps {\n /** Merged onto the recovery card's default classes. */\n className?: string;\n /**\n * How the host's assistant row paints the transcript tail. The default reads\n * the runtime ending only (a persisted marker or handoff); a host whose row\n * also styles an assistant-ui error status as a failed ending passes a\n * reader that reports it, so the footer never doubles that row's recovery.\n */\n readTailEnding?: ReadStatewireTailEnding;\n /**\n * The recovery controls. The default renders Continue unless the tail row\n * (a marker of another kind) already carries it; hosts with richer recovery\n * (Retry + Continue) supply their own and decide ownership from the context.\n */\n renderActions?: (context: StatewireRunEndedFooterActionsContext) => ReactNode;\n /** Forwarded to the default Continue action (unused when `renderActions` is set). */\n onContinue?: StatewireContinueRunButtonProps[\"onContinue\"];\n}\n\n/**\n * Recovery row for a settled run whose persisted ending is no longer the\n * transcript tail — rendered after the messages (`renderMessages`). Rewinds,\n * compaction, and older snapshots can all leave the durable run state\n * recoverable without a marker row that owns the action. The failure copy\n * comes from the replicated run error (`runs.error.message`) — the same text\n * the marker would have carried. A RETRYABLE refusal recorded there\n * (`readRetryableRunRefusal`: a closing host refused to start the queued\n * work, which stays in its lane and re-dispatches on the thread's next\n * placement) is not a failure of the run and paints as a pause, keeping\n * Continue as the manual way on. Renders nothing on legacy (non-statewire)\n * threads.\n */\nexport function StatewireRunEndedFooter({\n className,\n readTailEnding,\n renderActions,\n onContinue,\n}: StatewireRunEndedFooterProps = {}): ReactElement | null {\n const threadExtras = useAuiState((state) => state.thread.extras);\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n return (\n <StatewireRunEndedFooterContent\n className={className}\n readTailEnding={readTailEnding}\n renderActions={renderActions}\n onContinue={onContinue}\n />\n );\n}\n\nfunction StatewireRunEndedFooterContent({\n className,\n readTailEnding = readRuntimeTailEnding,\n renderActions,\n onContinue,\n}: StatewireRunEndedFooterProps): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { error } = useStatewireRuns();\n // The reader builds a fresh object per call; select primitives so the\n // snapshots stay stable under `Object.is` comparison.\n const tailEndingKind = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.kind ?? null) : null;\n });\n const tailEndingSilent = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.silent ?? false) : false;\n });\n const transcriptEmpty = useAuiState((state) => state.thread.messages.length === 0);\n\n if (status !== \"stopped\" && status !== \"error\") return null;\n\n // A user stop that retracted the only turn (its text went back to the\n // composer) settles as stopped over an empty transcript: there is no\n // conversation to continue or retry, so the thread reads as fresh.\n if (status === \"stopped\" && transcriptEmpty) return null;\n\n // A send-now promotion intentionally cancels the superseded run without a\n // visible ending. Statewire can briefly report that cancellation as stopped;\n // preserve the silent contract instead of presenting a false recovery state.\n // A genuine error still wins and remains recoverable below.\n if (status === \"stopped\" && tailEndingSilent) return null;\n\n const tailRendersEnding = tailEndingKind !== null && !tailEndingSilent;\n const tailMatchesStatus =\n status === \"error\"\n ? tailEndingKind === \"failed\"\n : tailEndingKind === \"stopped\" || tailEndingKind === \"paused\";\n if (tailRendersEnding && tailMatchesStatus) return null;\n\n // An older run's marker at the tail still carries its own Continue (the\n // marker-row affordance); a handoff banner does not.\n const tailOwnsContinue = tailRendersEnding && tailEndingKind !== \"handoff\";\n const action = renderActions ? (\n renderActions({ status, tailEndingKind: tailRendersEnding ? tailEndingKind : null })\n ) : tailOwnsContinue ? undefined : (\n <StatewireContinueRunButton onContinue={onContinue} />\n );\n const refusal = status === \"error\" ? readRetryableRunRefusal(error) : null;\n const message: AthenaRuntimeMessage =\n status === \"error\"\n ? refusal\n ? {\n kind: \"paused\",\n reason: refusal.code,\n severity: \"info\",\n title: \"Waiting for a server update\",\n detail:\n \"The server hosting this chat is restarting, so the queued message could not start yet. It runs on a ready server automatically.\",\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"failed\",\n reason: \"error\",\n severity: \"error\",\n title: \"Run failed\",\n detail: undefined,\n text: error?.message ? `⚠️ The run failed: ${error.message}` : undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"stopped\",\n reason: undefined,\n severity: \"info\",\n title: \"Conversation stopped\",\n detail: undefined,\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n };\n\n return (\n <RuntimeMessageCard\n data-testid=\"statewire-run-ended-footer\"\n message={message}\n action={action}\n className={cn(\"mx-auto max-w-[95%]\", className)}\n />\n );\n}\n"],"names":["useDeepAgentThreadStatus","useStatewireRuns","useStatewireSendCommand","jsx","ContinuePill","useAuiState","readRunMarkerFromSourceMessages","threadExtras","ATHENA_RUN_MARKER_CANCELLED","ATHENA_RUN_MARKER_FAILED","hasStatewireThreadExtras","readRuntimeMessageFromSourceMessages","readRetryableRunRefusal","RuntimeMessageCard","cn"],"mappings":"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"}
@@ -9,8 +9,12 @@ export interface StatewireContinueRunButtonProps {
9
9
  */
10
10
  allowReadyFallback?: boolean;
11
11
  /**
12
- * Called as the continue dispatches (after the pill's exit animation)
13
- * the host's telemetry hook. Receives the settled status and live run id.
12
+ * Called as the continue dispatches (after the pill's exit animation),
13
+ * immediately before the command queues — the host's telemetry hook.
14
+ * Receives the settled status and live run id the user acted on. Queueing
15
+ * publishes the command's first update synchronously, so a hook that pairs
16
+ * this click with that update must run first. Best-effort: a throwing hook
17
+ * is swallowed and never blocks the dispatch.
14
18
  */
15
19
  onContinue?: (context: {
16
20
  status: DeepAgentThreadStatus;
@@ -30,6 +34,10 @@ export interface StatewireContinueRunButtonProps {
30
34
  * a statewire aui scope (throws outside one, like every `useStatewire*` hook).
31
35
  */
32
36
  export declare function StatewireContinueRunButton({ allowReadyFallback, onContinue, }?: StatewireContinueRunButtonProps): ReactElement | null;
37
+ export interface StatewireContinueRunAffordanceProps {
38
+ /** Forwarded to the mounted `StatewireContinueRunButton`. */
39
+ onContinue?: StatewireContinueRunButtonProps["onContinue"];
40
+ }
33
41
  /**
34
42
  * Recovery affordance for the latest persisted stopped/failed run marker,
35
43
  * for the `runtimeMessageAction` slot of `createAssistantMessage`.
@@ -38,7 +46,7 @@ export declare function StatewireContinueRunButton({ allowReadyFallback, onConti
38
46
  * may continue. The extras guard keeps Statewire hooks out of read-only or
39
47
  * legacy runtimes where they would throw.
40
48
  */
41
- export declare function StatewireContinueRunAffordance(): ReactElement | null;
49
+ export declare function StatewireContinueRunAffordance({ onContinue, }?: StatewireContinueRunAffordanceProps): ReactElement | null;
42
50
  /** The ending a transcript row paints, as the footer needs to know it. */
43
51
  export interface StatewireTailEnding {
44
52
  kind: AthenaRuntimeMessageKind;
@@ -69,6 +77,8 @@ export interface StatewireRunEndedFooterProps {
69
77
  * (Retry + Continue) supply their own and decide ownership from the context.
70
78
  */
71
79
  renderActions?: (context: StatewireRunEndedFooterActionsContext) => ReactNode;
80
+ /** Forwarded to the default Continue action (unused when `renderActions` is set). */
81
+ onContinue?: StatewireContinueRunButtonProps["onContinue"];
72
82
  }
73
83
  /**
74
84
  * Recovery row for a settled run whose persisted ending is no longer the
@@ -83,4 +93,4 @@ export interface StatewireRunEndedFooterProps {
83
93
  * Continue as the manual way on. Renders nothing on legacy (non-statewire)
84
94
  * threads.
85
95
  */
86
- export declare function StatewireRunEndedFooter({ className, readTailEnding, renderActions, }?: StatewireRunEndedFooterProps): ReactElement | null;
96
+ export declare function StatewireRunEndedFooter({ className, readTailEnding, renderActions, onContinue, }?: StatewireRunEndedFooterProps): ReactElement | null;
@@ -12,13 +12,21 @@ import "../../packages/agent-runtime/src/statewire-state.js";
12
12
  import { readRunMarkerFromSourceMessages, ATHENA_RUN_MARKER_CANCELLED, ATHENA_RUN_MARKER_FAILED } from "../../packages/agent-runtime/src/messages.js";
13
13
  import { hasStatewireThreadExtras } from "../../packages/agent-runtime/src/thread-extras.js";
14
14
  import "@assistant-ui/store";
15
- import "@assistant-ui/react-statewire/local-storage";
15
+ import "../../packages/agent-runtime/src/quota-safe-local-storage-session.js";
16
16
  import "../../packages/agent-runtime/src/statewire-attach-observer.js";
17
17
  import { useDeepAgentThreadStatus } from "../../packages/agent-runtime/src/thread-status.js";
18
18
  import { readRuntimeMessageFromSourceMessages } from "../../packages/agent-runtime/src/runtime-messages.js";
19
+ import "../../packages/agent-runtime/src/thread-handoff.js";
19
20
  import { ContinuePill } from "./continue-pill.js";
20
21
  import { RuntimeMessageCard } from "./runtime-message.js";
21
22
  import { cn } from "cnfast";
23
+ function notifyContinue(onContinue, context) {
24
+ try {
25
+ onContinue == null ? void 0 : onContinue(context);
26
+ } catch (error) {
27
+ console.debug("[StatewireContinueRunButton] onContinue hook failed:", error);
28
+ }
29
+ }
22
30
  function StatewireContinueRunButton({
23
31
  allowReadyFallback = false,
24
32
  onContinue
@@ -34,7 +42,7 @@ function StatewireContinueRunButton({
34
42
  ariaLabel: "Continue this run from where it stopped",
35
43
  dataTestId: "statewire-continue-run",
36
44
  onClick: () => {
37
- onContinue == null ? void 0 : onContinue({ status, runId });
45
+ notifyContinue(onContinue, { status, runId });
38
46
  sendCommand({
39
47
  type: "run/continue",
40
48
  ...runId !== null && { runId }
@@ -43,7 +51,9 @@ function StatewireContinueRunButton({
43
51
  }
44
52
  );
45
53
  }
46
- function StatewireContinueRunAffordance() {
54
+ function StatewireContinueRunAffordance({
55
+ onContinue
56
+ } = {}) {
47
57
  const messageId = useAuiState((state) => state.message.id);
48
58
  const lastMessageId = useAuiState(
49
59
  (state) => {
@@ -61,7 +71,7 @@ function StatewireContinueRunAffordance() {
61
71
  const isContinuableMarker = runMarker === ATHENA_RUN_MARKER_CANCELLED || runMarker === ATHENA_RUN_MARKER_FAILED;
62
72
  if (messageId !== lastMessageId || !isContinuableMarker) return null;
63
73
  if (!hasStatewireThreadExtras(threadExtras)) return null;
64
- return /* @__PURE__ */ jsx("div", { className: "flex w-full justify-center py-1", children: /* @__PURE__ */ jsx(StatewireContinueRunButton, { allowReadyFallback: true }) });
74
+ return /* @__PURE__ */ jsx("div", { className: "flex w-full justify-center py-1", children: /* @__PURE__ */ jsx(StatewireContinueRunButton, { allowReadyFallback: true, onContinue }) });
65
75
  }
66
76
  const readRuntimeTailEnding = (message) => {
67
77
  const runtime = readRuntimeMessageFromSourceMessages(message);
@@ -70,7 +80,8 @@ const readRuntimeTailEnding = (message) => {
70
80
  function StatewireRunEndedFooter({
71
81
  className,
72
82
  readTailEnding,
73
- renderActions
83
+ renderActions,
84
+ onContinue
74
85
  } = {}) {
75
86
  const threadExtras = useAuiState((state) => state.thread.extras);
76
87
  if (!hasStatewireThreadExtras(threadExtras)) return null;
@@ -79,14 +90,16 @@ function StatewireRunEndedFooter({
79
90
  {
80
91
  className,
81
92
  readTailEnding,
82
- renderActions
93
+ renderActions,
94
+ onContinue
83
95
  }
84
96
  );
85
97
  }
86
98
  function StatewireRunEndedFooterContent({
87
99
  className,
88
100
  readTailEnding = readRuntimeTailEnding,
89
- renderActions
101
+ renderActions,
102
+ onContinue
90
103
  }) {
91
104
  const status = useDeepAgentThreadStatus();
92
105
  const { error } = useStatewireRuns();
@@ -100,13 +113,15 @@ function StatewireRunEndedFooterContent({
100
113
  const last = state.thread.messages.at(-1);
101
114
  return last ? ((_a = readTailEnding(last)) == null ? void 0 : _a.silent) ?? false : false;
102
115
  });
116
+ const transcriptEmpty = useAuiState((state) => state.thread.messages.length === 0);
103
117
  if (status !== "stopped" && status !== "error") return null;
118
+ if (status === "stopped" && transcriptEmpty) return null;
104
119
  if (status === "stopped" && tailEndingSilent) return null;
105
120
  const tailRendersEnding = tailEndingKind !== null && !tailEndingSilent;
106
121
  const tailMatchesStatus = status === "error" ? tailEndingKind === "failed" : tailEndingKind === "stopped" || tailEndingKind === "paused";
107
122
  if (tailRendersEnding && tailMatchesStatus) return null;
108
123
  const tailOwnsContinue = tailRendersEnding && tailEndingKind !== "handoff";
109
- const action = renderActions ? renderActions({ status, tailEndingKind: tailRendersEnding ? tailEndingKind : null }) : tailOwnsContinue ? void 0 : /* @__PURE__ */ jsx(StatewireContinueRunButton, {});
124
+ const action = renderActions ? renderActions({ status, tailEndingKind: tailRendersEnding ? tailEndingKind : null }) : tailOwnsContinue ? void 0 : /* @__PURE__ */ jsx(StatewireContinueRunButton, { onContinue });
110
125
  const refusal = status === "error" ? readRetryableRunRefusal(error) : null;
111
126
  const message = status === "error" ? refusal ? {
112
127
  kind: "paused",
@@ -1 +1 @@
1
- {"version":3,"file":"statewire-continue-run.js","sources":["../../../src/chat-ui/messages/statewire-continue-run.tsx"],"sourcesContent":["import { type ThreadMessage, useAuiState } from \"@assistant-ui/react\";\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n} from \"@assistant-ui/react-statewire\";\nimport {\n ATHENA_RUN_MARKER_CANCELLED,\n ATHENA_RUN_MARKER_FAILED,\n type AthenaRuntimeMessage,\n type AthenaRuntimeMessageKind,\n type DeepAgentThreadStatus,\n hasStatewireThreadExtras,\n readRetryableRunRefusal,\n readRunMarkerFromSourceMessages,\n readRuntimeMessageFromSourceMessages,\n useDeepAgentThreadStatus,\n} from \"@athenaintel/agent-runtime\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { ContinuePill } from \"./continue-pill\";\nimport { RuntimeMessageCard } from \"./runtime-message\";\n\nexport interface StatewireContinueRunButtonProps {\n /**\n * Also offer Continue while the thread projects `ready`. An old snapshot\n * can report a resting thread whose last persisted ending is still\n * continuable; the marker row that mounts this button knows that.\n */\n allowReadyFallback?: boolean;\n /**\n * Called as the continue dispatches (after the pill's exit animation) —\n * the host's telemetry hook. Receives the settled status and live run id.\n */\n onContinue?: (context: { status: DeepAgentThreadStatus; runId: string | null }) => void;\n}\n\n/**\n * Dispatches the bare `run/continue` for the live Statewire thread — the\n * heal-then-continue recovery for stopped, errored, and pod-drained runs. The\n * command is exactly what the library's `onResume` emits, so it inherits the\n * optimistic running-flip (the pill unmounts once the dispatch is accepted)\n * and routes rejections to the runtime's shared `onError` policy.\n *\n * Gated on the LIVE thread status, never on the persisted marker: markers live\n * in the transcript forever, while continuability is a property of the\n * current run state. Requires `capabilities.continue` on the host thread and\n * a statewire aui scope (throws outside one, like every `useStatewire*` hook).\n */\nexport function StatewireContinueRunButton({\n allowReadyFallback = false,\n onContinue,\n}: StatewireContinueRunButtonProps = {}): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { runId } = useStatewireRuns();\n const sendCommand = useStatewireSendCommand();\n\n const isSettled = status === \"stopped\" || status === \"error\";\n if (!isSettled && !(allowReadyFallback && status === \"ready\")) return null;\n\n return (\n <ContinuePill\n ariaLabel=\"Continue this run from where it stopped\"\n dataTestId=\"statewire-continue-run\"\n onClick={() => {\n onContinue?.({ status, runId });\n sendCommand({\n type: \"run/continue\",\n ...(runId !== null && { runId }),\n });\n }}\n />\n );\n}\n\n/**\n * Recovery affordance for the latest persisted stopped/failed run marker,\n * for the `runtimeMessageAction` slot of `createAssistantMessage`.\n *\n * Marker messages remain in history forever, so only the current last message\n * may continue. The extras guard keeps Statewire hooks out of read-only or\n * legacy runtimes where they would throw.\n */\nexport function StatewireContinueRunAffordance(): ReactElement | null {\n const messageId = useAuiState((state) => state.message.id);\n const lastMessageId = useAuiState(\n (state) => state.thread.messages.at(-1)?.id,\n );\n const runMarker = useAuiState(\n (state) => readRunMarkerFromSourceMessages(state.message)?.marker,\n );\n const threadExtras = useAuiState((state) => state.thread.extras);\n\n const isContinuableMarker =\n runMarker === ATHENA_RUN_MARKER_CANCELLED ||\n runMarker === ATHENA_RUN_MARKER_FAILED;\n if (messageId !== lastMessageId || !isContinuableMarker) return null;\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n\n return (\n <div className=\"flex w-full justify-center py-1\">\n <StatewireContinueRunButton allowReadyFallback />\n </div>\n );\n}\n\n/** The ending a transcript row paints, as the footer needs to know it. */\nexport interface StatewireTailEnding {\n kind: AthenaRuntimeMessageKind;\n /** A send-now cancellation: kept in the data, painted as nothing. */\n silent: boolean;\n}\n\n/** Reads the runtime ending (marker or handoff) a message row renders, if any. */\nexport type ReadStatewireTailEnding = (message: ThreadMessage) => StatewireTailEnding | null;\n\nconst readRuntimeTailEnding: ReadStatewireTailEnding = (message) => {\n const runtime = readRuntimeMessageFromSourceMessages(message);\n return runtime ? { kind: runtime.kind, silent: runtime.silent } : null;\n};\n\nexport interface StatewireRunEndedFooterActionsContext {\n /** The live settled status the footer describes. */\n status: \"stopped\" | \"error\";\n /** The ending the tail row renders, when it renders one (silent markers read as none). */\n tailEndingKind: AthenaRuntimeMessageKind | null;\n}\n\nexport interface StatewireRunEndedFooterProps {\n /** Merged onto the recovery card's default classes. */\n className?: string;\n /**\n * How the host's assistant row paints the transcript tail. The default reads\n * the runtime ending only (a persisted marker or handoff); a host whose row\n * also styles an assistant-ui error status as a failed ending passes a\n * reader that reports it, so the footer never doubles that row's recovery.\n */\n readTailEnding?: ReadStatewireTailEnding;\n /**\n * The recovery controls. The default renders Continue unless the tail row\n * (a marker of another kind) already carries it; hosts with richer recovery\n * (Retry + Continue) supply their own and decide ownership from the context.\n */\n renderActions?: (context: StatewireRunEndedFooterActionsContext) => ReactNode;\n}\n\n/**\n * Recovery row for a settled run whose persisted ending is no longer the\n * transcript tail — rendered after the messages (`renderMessages`). Rewinds,\n * compaction, and older snapshots can all leave the durable run state\n * recoverable without a marker row that owns the action. The failure copy\n * comes from the replicated run error (`runs.error.message`) — the same text\n * the marker would have carried. A RETRYABLE refusal recorded there\n * (`readRetryableRunRefusal`: a closing host refused to start the queued\n * work, which stays in its lane and re-dispatches on the thread's next\n * placement) is not a failure of the run and paints as a pause, keeping\n * Continue as the manual way on. Renders nothing on legacy (non-statewire)\n * threads.\n */\nexport function StatewireRunEndedFooter({\n className,\n readTailEnding,\n renderActions,\n}: StatewireRunEndedFooterProps = {}): ReactElement | null {\n const threadExtras = useAuiState((state) => state.thread.extras);\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n return (\n <StatewireRunEndedFooterContent\n className={className}\n readTailEnding={readTailEnding}\n renderActions={renderActions}\n />\n );\n}\n\nfunction StatewireRunEndedFooterContent({\n className,\n readTailEnding = readRuntimeTailEnding,\n renderActions,\n}: StatewireRunEndedFooterProps): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { error } = useStatewireRuns();\n // The reader builds a fresh object per call; select primitives so the\n // snapshots stay stable under `Object.is` comparison.\n const tailEndingKind = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.kind ?? null) : null;\n });\n const tailEndingSilent = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.silent ?? false) : false;\n });\n\n if (status !== \"stopped\" && status !== \"error\") return null;\n\n // A send-now promotion intentionally cancels the superseded run without a\n // visible ending. Statewire can briefly report that cancellation as stopped;\n // preserve the silent contract instead of presenting a false recovery state.\n // A genuine error still wins and remains recoverable below.\n if (status === \"stopped\" && tailEndingSilent) return null;\n\n const tailRendersEnding = tailEndingKind !== null && !tailEndingSilent;\n const tailMatchesStatus =\n status === \"error\"\n ? tailEndingKind === \"failed\"\n : tailEndingKind === \"stopped\" || tailEndingKind === \"paused\";\n if (tailRendersEnding && tailMatchesStatus) return null;\n\n // An older run's marker at the tail still carries its own Continue (the\n // marker-row affordance); a handoff banner does not.\n const tailOwnsContinue = tailRendersEnding && tailEndingKind !== \"handoff\";\n const action = renderActions ? (\n renderActions({ status, tailEndingKind: tailRendersEnding ? tailEndingKind : null })\n ) : tailOwnsContinue ? undefined : (\n <StatewireContinueRunButton />\n );\n const refusal = status === \"error\" ? readRetryableRunRefusal(error) : null;\n const message: AthenaRuntimeMessage =\n status === \"error\"\n ? refusal\n ? {\n kind: \"paused\",\n reason: refusal.code,\n severity: \"info\",\n title: \"Waiting for a server update\",\n detail:\n \"The server hosting this chat is restarting, so the queued message could not start yet. It runs on a ready server automatically.\",\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"failed\",\n reason: \"error\",\n severity: \"error\",\n title: \"Run failed\",\n detail: undefined,\n text: error?.message ? `⚠️ The run failed: ${error.message}` : undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"stopped\",\n reason: undefined,\n severity: \"info\",\n title: \"Conversation stopped\",\n detail: undefined,\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n };\n\n return (\n <RuntimeMessageCard\n data-testid=\"statewire-run-ended-footer\"\n message={message}\n action={action}\n className={cn(\"mx-auto max-w-[95%]\", className)}\n />\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"statewire-continue-run.js","sources":["../../../src/chat-ui/messages/statewire-continue-run.tsx"],"sourcesContent":["import { type ThreadMessage, useAuiState } from \"@assistant-ui/react\";\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n} from \"@assistant-ui/react-statewire\";\nimport {\n ATHENA_RUN_MARKER_CANCELLED,\n ATHENA_RUN_MARKER_FAILED,\n type AthenaRuntimeMessage,\n type AthenaRuntimeMessageKind,\n type DeepAgentThreadStatus,\n hasStatewireThreadExtras,\n readRetryableRunRefusal,\n readRunMarkerFromSourceMessages,\n readRuntimeMessageFromSourceMessages,\n useDeepAgentThreadStatus,\n} from \"@athenaintel/agent-runtime\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { ContinuePill } from \"./continue-pill\";\nimport { RuntimeMessageCard } from \"./runtime-message\";\n\nexport interface StatewireContinueRunButtonProps {\n /**\n * Also offer Continue while the thread projects `ready`. An old snapshot\n * can report a resting thread whose last persisted ending is still\n * continuable; the marker row that mounts this button knows that.\n */\n allowReadyFallback?: boolean;\n /**\n * Called as the continue dispatches (after the pill's exit animation),\n * immediately before the command queues — the host's telemetry hook.\n * Receives the settled status and live run id the user acted on. Queueing\n * publishes the command's first update synchronously, so a hook that pairs\n * this click with that update must run first. Best-effort: a throwing hook\n * is swallowed and never blocks the dispatch.\n */\n onContinue?: (context: { status: DeepAgentThreadStatus; runId: string | null }) => void;\n}\n\nfunction notifyContinue(\n onContinue: StatewireContinueRunButtonProps[\"onContinue\"],\n context: { status: DeepAgentThreadStatus; runId: string | null },\n): void {\n try {\n onContinue?.(context);\n } catch (error) {\n console.debug(\"[StatewireContinueRunButton] onContinue hook failed:\", error);\n }\n}\n\n/**\n * Dispatches the bare `run/continue` for the live Statewire thread — the\n * heal-then-continue recovery for stopped, errored, and pod-drained runs. The\n * command is exactly what the library's `onResume` emits, so it inherits the\n * optimistic running-flip (the pill unmounts once the dispatch is accepted)\n * and routes rejections to the runtime's shared `onError` policy.\n *\n * Gated on the LIVE thread status, never on the persisted marker: markers live\n * in the transcript forever, while continuability is a property of the\n * current run state. Requires `capabilities.continue` on the host thread and\n * a statewire aui scope (throws outside one, like every `useStatewire*` hook).\n */\nexport function StatewireContinueRunButton({\n allowReadyFallback = false,\n onContinue,\n}: StatewireContinueRunButtonProps = {}): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { runId } = useStatewireRuns();\n const sendCommand = useStatewireSendCommand();\n\n const isSettled = status === \"stopped\" || status === \"error\";\n if (!isSettled && !(allowReadyFallback && status === \"ready\")) return null;\n\n return (\n <ContinuePill\n ariaLabel=\"Continue this run from where it stopped\"\n dataTestId=\"statewire-continue-run\"\n onClick={() => {\n notifyContinue(onContinue, { status, runId });\n sendCommand({\n type: \"run/continue\",\n ...(runId !== null && { runId }),\n });\n }}\n />\n );\n}\n\nexport interface StatewireContinueRunAffordanceProps {\n /** Forwarded to the mounted `StatewireContinueRunButton`. */\n onContinue?: StatewireContinueRunButtonProps[\"onContinue\"];\n}\n\n/**\n * Recovery affordance for the latest persisted stopped/failed run marker,\n * for the `runtimeMessageAction` slot of `createAssistantMessage`.\n *\n * Marker messages remain in history forever, so only the current last message\n * may continue. The extras guard keeps Statewire hooks out of read-only or\n * legacy runtimes where they would throw.\n */\nexport function StatewireContinueRunAffordance({\n onContinue,\n}: StatewireContinueRunAffordanceProps = {}): ReactElement | null {\n const messageId = useAuiState((state) => state.message.id);\n const lastMessageId = useAuiState(\n (state) => state.thread.messages.at(-1)?.id,\n );\n const runMarker = useAuiState(\n (state) => readRunMarkerFromSourceMessages(state.message)?.marker,\n );\n const threadExtras = useAuiState((state) => state.thread.extras);\n\n const isContinuableMarker =\n runMarker === ATHENA_RUN_MARKER_CANCELLED ||\n runMarker === ATHENA_RUN_MARKER_FAILED;\n if (messageId !== lastMessageId || !isContinuableMarker) return null;\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n\n return (\n <div className=\"flex w-full justify-center py-1\">\n <StatewireContinueRunButton allowReadyFallback onContinue={onContinue} />\n </div>\n );\n}\n\n/** The ending a transcript row paints, as the footer needs to know it. */\nexport interface StatewireTailEnding {\n kind: AthenaRuntimeMessageKind;\n /** A send-now cancellation: kept in the data, painted as nothing. */\n silent: boolean;\n}\n\n/** Reads the runtime ending (marker or handoff) a message row renders, if any. */\nexport type ReadStatewireTailEnding = (message: ThreadMessage) => StatewireTailEnding | null;\n\nconst readRuntimeTailEnding: ReadStatewireTailEnding = (message) => {\n const runtime = readRuntimeMessageFromSourceMessages(message);\n return runtime ? { kind: runtime.kind, silent: runtime.silent } : null;\n};\n\nexport interface StatewireRunEndedFooterActionsContext {\n /** The live settled status the footer describes. */\n status: \"stopped\" | \"error\";\n /** The ending the tail row renders, when it renders one (silent markers read as none). */\n tailEndingKind: AthenaRuntimeMessageKind | null;\n}\n\nexport interface StatewireRunEndedFooterProps {\n /** Merged onto the recovery card's default classes. */\n className?: string;\n /**\n * How the host's assistant row paints the transcript tail. The default reads\n * the runtime ending only (a persisted marker or handoff); a host whose row\n * also styles an assistant-ui error status as a failed ending passes a\n * reader that reports it, so the footer never doubles that row's recovery.\n */\n readTailEnding?: ReadStatewireTailEnding;\n /**\n * The recovery controls. The default renders Continue unless the tail row\n * (a marker of another kind) already carries it; hosts with richer recovery\n * (Retry + Continue) supply their own and decide ownership from the context.\n */\n renderActions?: (context: StatewireRunEndedFooterActionsContext) => ReactNode;\n /** Forwarded to the default Continue action (unused when `renderActions` is set). */\n onContinue?: StatewireContinueRunButtonProps[\"onContinue\"];\n}\n\n/**\n * Recovery row for a settled run whose persisted ending is no longer the\n * transcript tail — rendered after the messages (`renderMessages`). Rewinds,\n * compaction, and older snapshots can all leave the durable run state\n * recoverable without a marker row that owns the action. The failure copy\n * comes from the replicated run error (`runs.error.message`) — the same text\n * the marker would have carried. A RETRYABLE refusal recorded there\n * (`readRetryableRunRefusal`: a closing host refused to start the queued\n * work, which stays in its lane and re-dispatches on the thread's next\n * placement) is not a failure of the run and paints as a pause, keeping\n * Continue as the manual way on. Renders nothing on legacy (non-statewire)\n * threads.\n */\nexport function StatewireRunEndedFooter({\n className,\n readTailEnding,\n renderActions,\n onContinue,\n}: StatewireRunEndedFooterProps = {}): ReactElement | null {\n const threadExtras = useAuiState((state) => state.thread.extras);\n if (!hasStatewireThreadExtras(threadExtras)) return null;\n return (\n <StatewireRunEndedFooterContent\n className={className}\n readTailEnding={readTailEnding}\n renderActions={renderActions}\n onContinue={onContinue}\n />\n );\n}\n\nfunction StatewireRunEndedFooterContent({\n className,\n readTailEnding = readRuntimeTailEnding,\n renderActions,\n onContinue,\n}: StatewireRunEndedFooterProps): ReactElement | null {\n const status = useDeepAgentThreadStatus();\n const { error } = useStatewireRuns();\n // The reader builds a fresh object per call; select primitives so the\n // snapshots stay stable under `Object.is` comparison.\n const tailEndingKind = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.kind ?? null) : null;\n });\n const tailEndingSilent = useAuiState((state) => {\n const last = state.thread.messages.at(-1);\n return last ? (readTailEnding(last)?.silent ?? false) : false;\n });\n const transcriptEmpty = useAuiState((state) => state.thread.messages.length === 0);\n\n if (status !== \"stopped\" && status !== \"error\") return null;\n\n // A user stop that retracted the only turn (its text went back to the\n // composer) settles as stopped over an empty transcript: there is no\n // conversation to continue or retry, so the thread reads as fresh.\n if (status === \"stopped\" && transcriptEmpty) return null;\n\n // A send-now promotion intentionally cancels the superseded run without a\n // visible ending. Statewire can briefly report that cancellation as stopped;\n // preserve the silent contract instead of presenting a false recovery state.\n // A genuine error still wins and remains recoverable below.\n if (status === \"stopped\" && tailEndingSilent) return null;\n\n const tailRendersEnding = tailEndingKind !== null && !tailEndingSilent;\n const tailMatchesStatus =\n status === \"error\"\n ? tailEndingKind === \"failed\"\n : tailEndingKind === \"stopped\" || tailEndingKind === \"paused\";\n if (tailRendersEnding && tailMatchesStatus) return null;\n\n // An older run's marker at the tail still carries its own Continue (the\n // marker-row affordance); a handoff banner does not.\n const tailOwnsContinue = tailRendersEnding && tailEndingKind !== \"handoff\";\n const action = renderActions ? (\n renderActions({ status, tailEndingKind: tailRendersEnding ? tailEndingKind : null })\n ) : tailOwnsContinue ? undefined : (\n <StatewireContinueRunButton onContinue={onContinue} />\n );\n const refusal = status === \"error\" ? readRetryableRunRefusal(error) : null;\n const message: AthenaRuntimeMessage =\n status === \"error\"\n ? refusal\n ? {\n kind: \"paused\",\n reason: refusal.code,\n severity: \"info\",\n title: \"Waiting for a server update\",\n detail:\n \"The server hosting this chat is restarting, so the queued message could not start yet. It runs on a ready server automatically.\",\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"failed\",\n reason: \"error\",\n severity: \"error\",\n title: \"Run failed\",\n detail: undefined,\n text: error?.message ? `⚠️ The run failed: ${error.message}` : undefined,\n silent: false,\n isSoleSourceMessage: true,\n }\n : {\n kind: \"stopped\",\n reason: undefined,\n severity: \"info\",\n title: \"Conversation stopped\",\n detail: undefined,\n text: undefined,\n silent: false,\n isSoleSourceMessage: true,\n };\n\n return (\n <RuntimeMessageCard\n data-testid=\"statewire-run-ended-footer\"\n message={message}\n action={action}\n className={cn(\"mx-auto max-w-[95%]\", className)}\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -12,10 +12,11 @@ require("../../packages/agent-runtime/src/statewire-state.cjs");
12
12
  require("../../packages/agent-runtime/src/messages.cjs");
13
13
  require("@assistant-ui/react-statewire");
14
14
  const useDeepAgentEditSubmit = require("../../packages/agent-runtime/src/use-deep-agent-edit-submit.cjs");
15
- require("@assistant-ui/react-statewire/local-storage");
15
+ require("../../packages/agent-runtime/src/quota-safe-local-storage-session.cjs");
16
16
  require("../../packages/agent-runtime/src/statewire-attach-observer.cjs");
17
17
  require("../../packages/agent-runtime/src/thread-status.cjs");
18
18
  require("@assistant-ui/core");
19
+ require("../../packages/agent-runtime/src/thread-handoff.cjs");
19
20
  const UserEditComposer = () => {
20
21
  const submit = useDeepAgentEditSubmit.useDeepAgentMessageEditSubmit();
21
22
  const isEmpty = react.useAuiState((s) => s.message.composer.isEmpty);
@@ -1 +1 @@
1
- {"version":3,"file":"user-edit-composer.cjs","sources":["../../../src/chat-ui/messages/user-edit-composer.tsx"],"sourcesContent":["import { ComposerPrimitive, useAuiState } from \"@assistant-ui/react\";\nimport { useDeepAgentMessageEditSubmit } from \"@athenaintel/agent-runtime\";\nimport type { FC, KeyboardEvent } from \"react\";\n\n/**\n * Rendered in place of a user message while it is being edited (entered via\n * the action bar's Edit control, which seeds this composer with the message\n * text). Sending leaves as a `run/edit` anchored on the host's own parent of\n * the message (`useDeepAgentMessageEditSubmit`) — on a windowed wire the\n * lane's `anchorBefore` at the window edge — so the rewind is never rejected\n * `wrong-anchor` the way the library's converted-message anchor is after a\n * chunked assistant turn; Escape/Cancel exits edit mode.\n */\nexport const UserEditComposer: FC = () => {\n const submit = useDeepAgentMessageEditSubmit();\n const isEmpty = useAuiState((s) => s.message.composer.isEmpty);\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey || event.nativeEvent.isComposing) return;\n event.preventDefault();\n void submit();\n };\n return (\n <div className=\"mb-3 flex justify-end\" data-testid=\"chat-user-edit-composer\">\n <ComposerPrimitive.Root className=\"flex w-full max-w-[85%] flex-col gap-2 rounded-2xl rounded-br-md border border-border bg-muted px-3.5 py-2.5\">\n <ComposerPrimitive.Input\n autoFocus\n submitMode=\"none\"\n onKeyDown={onKeyDown}\n className=\"w-full resize-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n <div className=\"flex items-center justify-end gap-1.5\">\n <ComposerPrimitive.Cancel asChild>\n <button\n type=\"button\"\n className=\"rounded-lg px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\"\n >\n Cancel\n </button>\n </ComposerPrimitive.Cancel>\n <button\n type=\"button\"\n data-testid=\"chat-user-edit-send\"\n disabled={isEmpty}\n onClick={() => void submit()}\n className=\"rounded-lg bg-foreground px-2.5 py-1 text-xs font-medium text-background shadow-sm transition-colors hover:bg-foreground/80 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n Send\n </button>\n </div>\n </ComposerPrimitive.Root>\n </div>\n );\n};\n"],"names":["useDeepAgentMessageEditSubmit","useAuiState","jsx","jsxs","ComposerPrimitive"],"mappings":";;;;;;;;;;;;;;;;;;AAaO,MAAM,mBAAuB,MAAM;AACxC,QAAM,SAASA,uBAAAA,8BAAA;AACf,QAAM,UAAUC,MAAAA,YAAY,CAAC,MAAM,EAAE,QAAQ,SAAS,OAAO;AAC7D,QAAM,YAAY,CAAC,UAA8C;AAC/D,QAAI,MAAM,QAAQ,WAAW,MAAM,YAAY,MAAM,YAAY,YAAa;AAC9E,UAAM,eAAA;AACN,SAAK,OAAA;AAAA,EACP;AACA,SACEC,2BAAAA,IAAC,OAAA,EAAI,WAAU,yBAAwB,eAAY,2BACjD,UAAAC,2BAAAA,KAACC,MAAAA,kBAAkB,MAAlB,EAAuB,WAAU,gHAChC,UAAA;AAAA,IAAAF,2BAAAA;AAAAA,MAACE,MAAAA,kBAAkB;AAAA,MAAlB;AAAA,QACC,WAAS;AAAA,QACT,YAAW;AAAA,QACX;AAAA,QACA,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZD,2BAAAA,KAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,MAAAD,2BAAAA,IAACE,MAAAA,kBAAkB,QAAlB,EAAyB,SAAO,MAC/B,UAAAF,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA,GAGH;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,eAAY;AAAA,UACZ,UAAU;AAAA,UACV,SAAS,MAAM,KAAK,OAAA;AAAA,UACpB,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;;"}
1
+ {"version":3,"file":"user-edit-composer.cjs","sources":["../../../src/chat-ui/messages/user-edit-composer.tsx"],"sourcesContent":["import { ComposerPrimitive, useAuiState } from \"@assistant-ui/react\";\nimport { useDeepAgentMessageEditSubmit } from \"@athenaintel/agent-runtime\";\nimport type { FC, KeyboardEvent } from \"react\";\n\n/**\n * Rendered in place of a user message while it is being edited (entered via\n * the action bar's Edit control, which seeds this composer with the message\n * text). Sending leaves as a `run/edit` anchored on the host's own parent of\n * the message (`useDeepAgentMessageEditSubmit`) — on a windowed wire the\n * lane's `anchorBefore` at the window edge — so the rewind is never rejected\n * `wrong-anchor` the way the library's converted-message anchor is after a\n * chunked assistant turn; Escape/Cancel exits edit mode.\n */\nexport const UserEditComposer: FC = () => {\n const submit = useDeepAgentMessageEditSubmit();\n const isEmpty = useAuiState((s) => s.message.composer.isEmpty);\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey || event.nativeEvent.isComposing) return;\n event.preventDefault();\n void submit();\n };\n return (\n <div className=\"mb-3 flex justify-end\" data-testid=\"chat-user-edit-composer\">\n <ComposerPrimitive.Root className=\"flex w-full max-w-[85%] flex-col gap-2 rounded-2xl rounded-br-md border border-border bg-muted px-3.5 py-2.5\">\n <ComposerPrimitive.Input\n autoFocus\n submitMode=\"none\"\n onKeyDown={onKeyDown}\n className=\"w-full resize-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n <div className=\"flex items-center justify-end gap-1.5\">\n <ComposerPrimitive.Cancel asChild>\n <button\n type=\"button\"\n className=\"rounded-lg px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\"\n >\n Cancel\n </button>\n </ComposerPrimitive.Cancel>\n <button\n type=\"button\"\n data-testid=\"chat-user-edit-send\"\n disabled={isEmpty}\n onClick={() => void submit()}\n className=\"rounded-lg bg-foreground px-2.5 py-1 text-xs font-medium text-background shadow-sm transition-colors hover:bg-foreground/80 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n Send\n </button>\n </div>\n </ComposerPrimitive.Root>\n </div>\n );\n};\n"],"names":["useDeepAgentMessageEditSubmit","useAuiState","jsx","jsxs","ComposerPrimitive"],"mappings":";;;;;;;;;;;;;;;;;;;AAaO,MAAM,mBAAuB,MAAM;AACxC,QAAM,SAASA,uBAAAA,8BAAA;AACf,QAAM,UAAUC,MAAAA,YAAY,CAAC,MAAM,EAAE,QAAQ,SAAS,OAAO;AAC7D,QAAM,YAAY,CAAC,UAA8C;AAC/D,QAAI,MAAM,QAAQ,WAAW,MAAM,YAAY,MAAM,YAAY,YAAa;AAC9E,UAAM,eAAA;AACN,SAAK,OAAA;AAAA,EACP;AACA,SACEC,2BAAAA,IAAC,OAAA,EAAI,WAAU,yBAAwB,eAAY,2BACjD,UAAAC,2BAAAA,KAACC,MAAAA,kBAAkB,MAAlB,EAAuB,WAAU,gHAChC,UAAA;AAAA,IAAAF,2BAAAA;AAAAA,MAACE,MAAAA,kBAAkB;AAAA,MAAlB;AAAA,QACC,WAAS;AAAA,QACT,YAAW;AAAA,QACX;AAAA,QACA,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZD,2BAAAA,KAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,MAAAD,2BAAAA,IAACE,MAAAA,kBAAkB,QAAlB,EAAyB,SAAO,MAC/B,UAAAF,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA,GAGH;AAAA,MACAA,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,eAAY;AAAA,UACZ,UAAU;AAAA,UACV,SAAS,MAAM,KAAK,OAAA;AAAA,UACpB,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;;"}
@@ -10,10 +10,11 @@ import "../../packages/agent-runtime/src/statewire-state.js";
10
10
  import "../../packages/agent-runtime/src/messages.js";
11
11
  import "@assistant-ui/react-statewire";
12
12
  import { useDeepAgentMessageEditSubmit } from "../../packages/agent-runtime/src/use-deep-agent-edit-submit.js";
13
- import "@assistant-ui/react-statewire/local-storage";
13
+ import "../../packages/agent-runtime/src/quota-safe-local-storage-session.js";
14
14
  import "../../packages/agent-runtime/src/statewire-attach-observer.js";
15
15
  import "../../packages/agent-runtime/src/thread-status.js";
16
16
  import "@assistant-ui/core";
17
+ import "../../packages/agent-runtime/src/thread-handoff.js";
17
18
  const UserEditComposer = () => {
18
19
  const submit = useDeepAgentMessageEditSubmit();
19
20
  const isEmpty = useAuiState((s) => s.message.composer.isEmpty);
@@ -1 +1 @@
1
- {"version":3,"file":"user-edit-composer.js","sources":["../../../src/chat-ui/messages/user-edit-composer.tsx"],"sourcesContent":["import { ComposerPrimitive, useAuiState } from \"@assistant-ui/react\";\nimport { useDeepAgentMessageEditSubmit } from \"@athenaintel/agent-runtime\";\nimport type { FC, KeyboardEvent } from \"react\";\n\n/**\n * Rendered in place of a user message while it is being edited (entered via\n * the action bar's Edit control, which seeds this composer with the message\n * text). Sending leaves as a `run/edit` anchored on the host's own parent of\n * the message (`useDeepAgentMessageEditSubmit`) — on a windowed wire the\n * lane's `anchorBefore` at the window edge — so the rewind is never rejected\n * `wrong-anchor` the way the library's converted-message anchor is after a\n * chunked assistant turn; Escape/Cancel exits edit mode.\n */\nexport const UserEditComposer: FC = () => {\n const submit = useDeepAgentMessageEditSubmit();\n const isEmpty = useAuiState((s) => s.message.composer.isEmpty);\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey || event.nativeEvent.isComposing) return;\n event.preventDefault();\n void submit();\n };\n return (\n <div className=\"mb-3 flex justify-end\" data-testid=\"chat-user-edit-composer\">\n <ComposerPrimitive.Root className=\"flex w-full max-w-[85%] flex-col gap-2 rounded-2xl rounded-br-md border border-border bg-muted px-3.5 py-2.5\">\n <ComposerPrimitive.Input\n autoFocus\n submitMode=\"none\"\n onKeyDown={onKeyDown}\n className=\"w-full resize-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n <div className=\"flex items-center justify-end gap-1.5\">\n <ComposerPrimitive.Cancel asChild>\n <button\n type=\"button\"\n className=\"rounded-lg px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\"\n >\n Cancel\n </button>\n </ComposerPrimitive.Cancel>\n <button\n type=\"button\"\n data-testid=\"chat-user-edit-send\"\n disabled={isEmpty}\n onClick={() => void submit()}\n className=\"rounded-lg bg-foreground px-2.5 py-1 text-xs font-medium text-background shadow-sm transition-colors hover:bg-foreground/80 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n Send\n </button>\n </div>\n </ComposerPrimitive.Root>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAaO,MAAM,mBAAuB,MAAM;AACxC,QAAM,SAAS,8BAAA;AACf,QAAM,UAAU,YAAY,CAAC,MAAM,EAAE,QAAQ,SAAS,OAAO;AAC7D,QAAM,YAAY,CAAC,UAA8C;AAC/D,QAAI,MAAM,QAAQ,WAAW,MAAM,YAAY,MAAM,YAAY,YAAa;AAC9E,UAAM,eAAA;AACN,SAAK,OAAA;AAAA,EACP;AACA,SACE,oBAAC,OAAA,EAAI,WAAU,yBAAwB,eAAY,2BACjD,UAAA,qBAAC,kBAAkB,MAAlB,EAAuB,WAAU,gHAChC,UAAA;AAAA,IAAA;AAAA,MAAC,kBAAkB;AAAA,MAAlB;AAAA,QACC,WAAS;AAAA,QACT,YAAW;AAAA,QACX;AAAA,QACA,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZ,qBAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,MAAA,oBAAC,kBAAkB,QAAlB,EAAyB,SAAO,MAC/B,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA,GAGH;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,eAAY;AAAA,UACZ,UAAU;AAAA,UACV,SAAS,MAAM,KAAK,OAAA;AAAA,UACpB,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
1
+ {"version":3,"file":"user-edit-composer.js","sources":["../../../src/chat-ui/messages/user-edit-composer.tsx"],"sourcesContent":["import { ComposerPrimitive, useAuiState } from \"@assistant-ui/react\";\nimport { useDeepAgentMessageEditSubmit } from \"@athenaintel/agent-runtime\";\nimport type { FC, KeyboardEvent } from \"react\";\n\n/**\n * Rendered in place of a user message while it is being edited (entered via\n * the action bar's Edit control, which seeds this composer with the message\n * text). Sending leaves as a `run/edit` anchored on the host's own parent of\n * the message (`useDeepAgentMessageEditSubmit`) — on a windowed wire the\n * lane's `anchorBefore` at the window edge — so the rewind is never rejected\n * `wrong-anchor` the way the library's converted-message anchor is after a\n * chunked assistant turn; Escape/Cancel exits edit mode.\n */\nexport const UserEditComposer: FC = () => {\n const submit = useDeepAgentMessageEditSubmit();\n const isEmpty = useAuiState((s) => s.message.composer.isEmpty);\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey || event.nativeEvent.isComposing) return;\n event.preventDefault();\n void submit();\n };\n return (\n <div className=\"mb-3 flex justify-end\" data-testid=\"chat-user-edit-composer\">\n <ComposerPrimitive.Root className=\"flex w-full max-w-[85%] flex-col gap-2 rounded-2xl rounded-br-md border border-border bg-muted px-3.5 py-2.5\">\n <ComposerPrimitive.Input\n autoFocus\n submitMode=\"none\"\n onKeyDown={onKeyDown}\n className=\"w-full resize-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n <div className=\"flex items-center justify-end gap-1.5\">\n <ComposerPrimitive.Cancel asChild>\n <button\n type=\"button\"\n className=\"rounded-lg px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\"\n >\n Cancel\n </button>\n </ComposerPrimitive.Cancel>\n <button\n type=\"button\"\n data-testid=\"chat-user-edit-send\"\n disabled={isEmpty}\n onClick={() => void submit()}\n className=\"rounded-lg bg-foreground px-2.5 py-1 text-xs font-medium text-background shadow-sm transition-colors hover:bg-foreground/80 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n Send\n </button>\n </div>\n </ComposerPrimitive.Root>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAaO,MAAM,mBAAuB,MAAM;AACxC,QAAM,SAAS,8BAAA;AACf,QAAM,UAAU,YAAY,CAAC,MAAM,EAAE,QAAQ,SAAS,OAAO;AAC7D,QAAM,YAAY,CAAC,UAA8C;AAC/D,QAAI,MAAM,QAAQ,WAAW,MAAM,YAAY,MAAM,YAAY,YAAa;AAC9E,UAAM,eAAA;AACN,SAAK,OAAA;AAAA,EACP;AACA,SACE,oBAAC,OAAA,EAAI,WAAU,yBAAwB,eAAY,2BACjD,UAAA,qBAAC,kBAAkB,MAAlB,EAAuB,WAAU,gHAChC,UAAA;AAAA,IAAA;AAAA,MAAC,kBAAkB;AAAA,MAAlB;AAAA,QACC,WAAS;AAAA,QACT,YAAW;AAAA,QACX;AAAA,QACA,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZ,qBAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,MAAA,oBAAC,kBAAkB,QAAlB,EAAyB,SAAO,MAC/B,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA,GAGH;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,eAAY;AAAA,UACZ,UAAU;AAAA,UACV,SAAS,MAAM,KAAK,OAAA;AAAA,UACpB,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const mentionChip = require("../mentions/mention-chip.cjs");
6
+ const chatNodeViews = require("./chat-node-views.cjs");
7
+ const chatTextSchema = require("./chat-text-schema.cjs");
8
+ const domOutputSpec = require("./dom-output-spec.cjs");
9
+ const subscribe = () => () => {
10
+ };
11
+ const browserSnapshot = () => true;
12
+ const serverSnapshot = () => false;
13
+ function ChatMessageBody({
14
+ text,
15
+ isRunning = false
16
+ }) {
17
+ const hasDom = react.useSyncExternalStore(
18
+ subscribe,
19
+ browserSnapshot,
20
+ serverSnapshot
21
+ );
22
+ const doc = react.useMemo(
23
+ () => hasDom ? chatTextSchema.parseChatText(mentionChip.normalizeAthenaMentionHtml(text)) : null,
24
+ [hasDom, text]
25
+ );
26
+ return /* @__PURE__ */ jsxRuntime.jsx(
27
+ "div",
28
+ {
29
+ className: chatTextSchema.CHAT_TEXT_CLASS,
30
+ "data-chat-text": "",
31
+ "data-status": isRunning ? "running" : "complete",
32
+ children: doc ? renderContent(doc) : text
33
+ }
34
+ );
35
+ }
36
+ function renderNode(node) {
37
+ if (node.isText) return node.text;
38
+ if (node.type.name === "mention") return /* @__PURE__ */ jsxRuntime.jsx(chatNodeViews.ChatMention, { node });
39
+ if (node.type.name === "codeBlock") {
40
+ return /* @__PURE__ */ jsxRuntime.jsx(chatNodeViews.ChatCodeBlock, { node, children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: node.textContent }) });
41
+ }
42
+ const toDOM = node.type.spec.toDOM;
43
+ return toDOM ? domOutputSpec.renderDOMOutputSpec(toDOM(node), node.isLeaf ? null : renderContent(node)) : null;
44
+ }
45
+ function renderContent(parent) {
46
+ const nodes = [];
47
+ parent.forEach((node) => {
48
+ nodes.push(node);
49
+ });
50
+ return renderMarkRuns(nodes, 0);
51
+ }
52
+ function renderMarkRuns(nodes, depth) {
53
+ var _a, _b;
54
+ const children = [];
55
+ let index = 0;
56
+ while (index < nodes.length) {
57
+ const node = nodes[index];
58
+ const mark = node.marks[depth];
59
+ if (!mark) {
60
+ children.push(/* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: renderNode(node) }, index));
61
+ index++;
62
+ continue;
63
+ }
64
+ let end = index + 1;
65
+ if (mark.type.spec.spanning !== false) {
66
+ while (end < nodes.length && ((_b = (_a = nodes[end]) == null ? void 0 : _a.marks[depth]) == null ? void 0 : _b.eq(mark))) end++;
67
+ }
68
+ const content = renderMarkRuns(nodes.slice(index, end), depth + 1);
69
+ const rendered = mark.type.name === "link" ? /* @__PURE__ */ jsxRuntime.jsx(mentionChip.MentionLink, { href: mark.attrs.href, children: content }) : mark.type.spec.toDOM ? domOutputSpec.renderDOMOutputSpec(mark.type.spec.toDOM(mark, true), content) : content;
70
+ children.push(/* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: rendered }, index));
71
+ index = end;
72
+ }
73
+ return children;
74
+ }
75
+ exports.ChatMessageBody = ChatMessageBody;
76
+ //# sourceMappingURL=chat-message-body.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-message-body.cjs","sources":["../../../src/chat-ui/rich-text/chat-message-body.tsx"],"sourcesContent":["import type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { Fragment, type ReactNode, useMemo, useSyncExternalStore } from \"react\";\nimport {\n MentionLink,\n normalizeAthenaMentionHtml,\n} from \"../mentions/mention-chip\";\nimport { ChatCodeBlock, ChatMention } from \"./chat-node-views\";\nimport { CHAT_TEXT_CLASS, parseChatText } from \"./chat-text-schema\";\nimport { renderDOMOutputSpec } from \"./dom-output-spec\";\n\nconst subscribe = () => () => {};\nconst browserSnapshot = () => true;\nconst serverSnapshot = () => false;\n\n/** Render the composer's document schema through its own node/mark serializers. */\nexport function ChatMessageBody({\n text,\n isRunning = false,\n}: {\n text: string;\n isRunning?: boolean;\n}) {\n const hasDom = useSyncExternalStore(\n subscribe,\n browserSnapshot,\n serverSnapshot,\n );\n const doc = useMemo(\n () => (hasDom ? parseChatText(normalizeAthenaMentionHtml(text)) : null),\n [hasDom, text],\n );\n return (\n <div\n className={CHAT_TEXT_CLASS}\n data-chat-text=\"\"\n data-status={isRunning ? \"running\" : \"complete\"}\n >\n {doc ? renderContent(doc) : text}\n </div>\n );\n}\n\nfunction renderNode(node: ProseMirrorNode): ReactNode {\n if (node.isText) return node.text;\n if (node.type.name === \"mention\") return <ChatMention node={node} />;\n if (node.type.name === \"codeBlock\") {\n return (\n <ChatCodeBlock node={node}>\n <code>{node.textContent}</code>\n </ChatCodeBlock>\n );\n }\n const toDOM = node.type.spec.toDOM;\n return toDOM\n ? renderDOMOutputSpec(toDOM(node), node.isLeaf ? null : renderContent(node))\n : null;\n}\n\nfunction renderContent(parent: ProseMirrorNode): ReactNode[] {\n const nodes: ProseMirrorNode[] = [];\n parent.forEach((node) => {\n nodes.push(node);\n });\n return renderMarkRuns(nodes, 0);\n}\n\n/** Match ProseMirror's spanning marks: a link with bold words stays one link. */\nfunction renderMarkRuns(\n nodes: readonly ProseMirrorNode[],\n depth: number,\n): ReactNode[] {\n const children: ReactNode[] = [];\n let index = 0;\n while (index < nodes.length) {\n const node = nodes[index]!;\n const mark = node.marks[depth];\n if (!mark) {\n children.push(<Fragment key={index}>{renderNode(node)}</Fragment>);\n index++;\n continue;\n }\n let end = index + 1;\n if (mark.type.spec.spanning !== false) {\n while (end < nodes.length && nodes[end]?.marks[depth]?.eq(mark)) end++;\n }\n const content = renderMarkRuns(nodes.slice(index, end), depth + 1);\n const rendered =\n mark.type.name === \"link\" ? (\n <MentionLink href={mark.attrs.href}>{content}</MentionLink>\n ) : mark.type.spec.toDOM ? (\n renderDOMOutputSpec(mark.type.spec.toDOM(mark, true), content)\n ) : (\n content\n );\n children.push(<Fragment key={index}>{rendered}</Fragment>);\n index = end;\n }\n return children;\n}\n"],"names":["useSyncExternalStore","useMemo","parseChatText","normalizeAthenaMentionHtml","jsx","CHAT_TEXT_CLASS","ChatMention","ChatCodeBlock","renderDOMOutputSpec","Fragment","MentionLink"],"mappings":";;;;;;;;AAUA,MAAM,YAAY,MAAM,MAAM;AAAC;AAC/B,MAAM,kBAAkB,MAAM;AAC9B,MAAM,iBAAiB,MAAM;AAGtB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,YAAY;AACd,GAGG;AACD,QAAM,SAASA,MAAAA;AAAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEF,QAAM,MAAMC,MAAAA;AAAAA,IACV,MAAO,SAASC,eAAAA,cAAcC,YAAAA,2BAA2B,IAAI,CAAC,IAAI;AAAA,IAClE,CAAC,QAAQ,IAAI;AAAA,EAAA;AAEf,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,eAAAA;AAAAA,MACX,kBAAe;AAAA,MACf,eAAa,YAAY,YAAY;AAAA,MAEpC,UAAA,MAAM,cAAc,GAAG,IAAI;AAAA,IAAA;AAAA,EAAA;AAGlC;AAEA,SAAS,WAAW,MAAkC;AACpD,MAAI,KAAK,OAAQ,QAAO,KAAK;AAC7B,MAAI,KAAK,KAAK,SAAS,UAAW,QAAOD,+BAACE,cAAAA,eAAY,MAAY;AAClE,MAAI,KAAK,KAAK,SAAS,aAAa;AAClC,0CACGC,cAAAA,eAAA,EAAc,MACb,yCAAC,QAAA,EAAM,UAAA,KAAK,aAAY,EAAA,CAC1B;AAAA,EAEJ;AACA,QAAM,QAAQ,KAAK,KAAK,KAAK;AAC7B,SAAO,QACHC,cAAAA,oBAAoB,MAAM,IAAI,GAAG,KAAK,SAAS,OAAO,cAAc,IAAI,CAAC,IACzE;AACN;AAEA,SAAS,cAAc,QAAsC;AAC3D,QAAM,QAA2B,CAAA;AACjC,SAAO,QAAQ,CAAC,SAAS;AACvB,UAAM,KAAK,IAAI;AAAA,EACjB,CAAC;AACD,SAAO,eAAe,OAAO,CAAC;AAChC;AAGA,SAAS,eACP,OACA,OACa;;AACb,QAAM,WAAwB,CAAA;AAC9B,MAAI,QAAQ;AACZ,SAAO,QAAQ,MAAM,QAAQ;AAC3B,UAAM,OAAO,MAAM,KAAK;AACxB,UAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,QAAI,CAAC,MAAM;AACT,eAAS,KAAKJ,2BAAAA,IAACK,gBAAA,EAAsB,qBAAW,IAAI,KAAvB,KAAyB,CAAW;AACjE;AACA;AAAA,IACF;AACA,QAAI,MAAM,QAAQ;AAClB,QAAI,KAAK,KAAK,KAAK,aAAa,OAAO;AACrC,aAAO,MAAM,MAAM,YAAU,iBAAM,GAAG,MAAT,mBAAY,MAAM,WAAlB,mBAA0B,GAAG,OAAO;AAAA,IACnE;AACA,UAAM,UAAU,eAAe,MAAM,MAAM,OAAO,GAAG,GAAG,QAAQ,CAAC;AACjE,UAAM,WACJ,KAAK,KAAK,SAAS,SACjBL,2BAAAA,IAACM,yBAAA,EAAY,MAAM,KAAK,MAAM,MAAO,UAAA,QAAA,CAAQ,IAC3C,KAAK,KAAK,KAAK,QACjBF,cAAAA,oBAAoB,KAAK,KAAK,KAAK,MAAM,MAAM,IAAI,GAAG,OAAO,IAE7D;AAEJ,aAAS,KAAKJ,2BAAAA,IAACK,MAAAA,UAAA,EAAsB,UAAA,SAAA,GAAR,KAAiB,CAAW;AACzD,YAAQ;AAAA,EACV;AACA,SAAO;AACT;;"}
@@ -0,0 +1,5 @@
1
+ /** Render the composer's document schema through its own node/mark serializers. */
2
+ export declare function ChatMessageBody({ text, isRunning, }: {
3
+ text: string;
4
+ isRunning?: boolean;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,76 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useSyncExternalStore, useMemo, Fragment } from "react";
3
+ import { normalizeAthenaMentionHtml, MentionLink } from "../mentions/mention-chip.js";
4
+ import { ChatMention, ChatCodeBlock } from "./chat-node-views.js";
5
+ import { parseChatText, CHAT_TEXT_CLASS } from "./chat-text-schema.js";
6
+ import { renderDOMOutputSpec } from "./dom-output-spec.js";
7
+ const subscribe = () => () => {
8
+ };
9
+ const browserSnapshot = () => true;
10
+ const serverSnapshot = () => false;
11
+ function ChatMessageBody({
12
+ text,
13
+ isRunning = false
14
+ }) {
15
+ const hasDom = useSyncExternalStore(
16
+ subscribe,
17
+ browserSnapshot,
18
+ serverSnapshot
19
+ );
20
+ const doc = useMemo(
21
+ () => hasDom ? parseChatText(normalizeAthenaMentionHtml(text)) : null,
22
+ [hasDom, text]
23
+ );
24
+ return /* @__PURE__ */ jsx(
25
+ "div",
26
+ {
27
+ className: CHAT_TEXT_CLASS,
28
+ "data-chat-text": "",
29
+ "data-status": isRunning ? "running" : "complete",
30
+ children: doc ? renderContent(doc) : text
31
+ }
32
+ );
33
+ }
34
+ function renderNode(node) {
35
+ if (node.isText) return node.text;
36
+ if (node.type.name === "mention") return /* @__PURE__ */ jsx(ChatMention, { node });
37
+ if (node.type.name === "codeBlock") {
38
+ return /* @__PURE__ */ jsx(ChatCodeBlock, { node, children: /* @__PURE__ */ jsx("code", { children: node.textContent }) });
39
+ }
40
+ const toDOM = node.type.spec.toDOM;
41
+ return toDOM ? renderDOMOutputSpec(toDOM(node), node.isLeaf ? null : renderContent(node)) : null;
42
+ }
43
+ function renderContent(parent) {
44
+ const nodes = [];
45
+ parent.forEach((node) => {
46
+ nodes.push(node);
47
+ });
48
+ return renderMarkRuns(nodes, 0);
49
+ }
50
+ function renderMarkRuns(nodes, depth) {
51
+ var _a, _b;
52
+ const children = [];
53
+ let index = 0;
54
+ while (index < nodes.length) {
55
+ const node = nodes[index];
56
+ const mark = node.marks[depth];
57
+ if (!mark) {
58
+ children.push(/* @__PURE__ */ jsx(Fragment, { children: renderNode(node) }, index));
59
+ index++;
60
+ continue;
61
+ }
62
+ let end = index + 1;
63
+ if (mark.type.spec.spanning !== false) {
64
+ while (end < nodes.length && ((_b = (_a = nodes[end]) == null ? void 0 : _a.marks[depth]) == null ? void 0 : _b.eq(mark))) end++;
65
+ }
66
+ const content = renderMarkRuns(nodes.slice(index, end), depth + 1);
67
+ const rendered = mark.type.name === "link" ? /* @__PURE__ */ jsx(MentionLink, { href: mark.attrs.href, children: content }) : mark.type.spec.toDOM ? renderDOMOutputSpec(mark.type.spec.toDOM(mark, true), content) : content;
68
+ children.push(/* @__PURE__ */ jsx(Fragment, { children: rendered }, index));
69
+ index = end;
70
+ }
71
+ return children;
72
+ }
73
+ export {
74
+ ChatMessageBody
75
+ };
76
+ //# sourceMappingURL=chat-message-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-message-body.js","sources":["../../../src/chat-ui/rich-text/chat-message-body.tsx"],"sourcesContent":["import type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport { Fragment, type ReactNode, useMemo, useSyncExternalStore } from \"react\";\nimport {\n MentionLink,\n normalizeAthenaMentionHtml,\n} from \"../mentions/mention-chip\";\nimport { ChatCodeBlock, ChatMention } from \"./chat-node-views\";\nimport { CHAT_TEXT_CLASS, parseChatText } from \"./chat-text-schema\";\nimport { renderDOMOutputSpec } from \"./dom-output-spec\";\n\nconst subscribe = () => () => {};\nconst browserSnapshot = () => true;\nconst serverSnapshot = () => false;\n\n/** Render the composer's document schema through its own node/mark serializers. */\nexport function ChatMessageBody({\n text,\n isRunning = false,\n}: {\n text: string;\n isRunning?: boolean;\n}) {\n const hasDom = useSyncExternalStore(\n subscribe,\n browserSnapshot,\n serverSnapshot,\n );\n const doc = useMemo(\n () => (hasDom ? parseChatText(normalizeAthenaMentionHtml(text)) : null),\n [hasDom, text],\n );\n return (\n <div\n className={CHAT_TEXT_CLASS}\n data-chat-text=\"\"\n data-status={isRunning ? \"running\" : \"complete\"}\n >\n {doc ? renderContent(doc) : text}\n </div>\n );\n}\n\nfunction renderNode(node: ProseMirrorNode): ReactNode {\n if (node.isText) return node.text;\n if (node.type.name === \"mention\") return <ChatMention node={node} />;\n if (node.type.name === \"codeBlock\") {\n return (\n <ChatCodeBlock node={node}>\n <code>{node.textContent}</code>\n </ChatCodeBlock>\n );\n }\n const toDOM = node.type.spec.toDOM;\n return toDOM\n ? renderDOMOutputSpec(toDOM(node), node.isLeaf ? null : renderContent(node))\n : null;\n}\n\nfunction renderContent(parent: ProseMirrorNode): ReactNode[] {\n const nodes: ProseMirrorNode[] = [];\n parent.forEach((node) => {\n nodes.push(node);\n });\n return renderMarkRuns(nodes, 0);\n}\n\n/** Match ProseMirror's spanning marks: a link with bold words stays one link. */\nfunction renderMarkRuns(\n nodes: readonly ProseMirrorNode[],\n depth: number,\n): ReactNode[] {\n const children: ReactNode[] = [];\n let index = 0;\n while (index < nodes.length) {\n const node = nodes[index]!;\n const mark = node.marks[depth];\n if (!mark) {\n children.push(<Fragment key={index}>{renderNode(node)}</Fragment>);\n index++;\n continue;\n }\n let end = index + 1;\n if (mark.type.spec.spanning !== false) {\n while (end < nodes.length && nodes[end]?.marks[depth]?.eq(mark)) end++;\n }\n const content = renderMarkRuns(nodes.slice(index, end), depth + 1);\n const rendered =\n mark.type.name === \"link\" ? (\n <MentionLink href={mark.attrs.href}>{content}</MentionLink>\n ) : mark.type.spec.toDOM ? (\n renderDOMOutputSpec(mark.type.spec.toDOM(mark, true), content)\n ) : (\n content\n );\n children.push(<Fragment key={index}>{rendered}</Fragment>);\n index = end;\n }\n return children;\n}\n"],"names":[],"mappings":";;;;;;AAUA,MAAM,YAAY,MAAM,MAAM;AAAC;AAC/B,MAAM,kBAAkB,MAAM;AAC9B,MAAM,iBAAiB,MAAM;AAGtB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,YAAY;AACd,GAGG;AACD,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEF,QAAM,MAAM;AAAA,IACV,MAAO,SAAS,cAAc,2BAA2B,IAAI,CAAC,IAAI;AAAA,IAClE,CAAC,QAAQ,IAAI;AAAA,EAAA;AAEf,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,MACX,kBAAe;AAAA,MACf,eAAa,YAAY,YAAY;AAAA,MAEpC,UAAA,MAAM,cAAc,GAAG,IAAI;AAAA,IAAA;AAAA,EAAA;AAGlC;AAEA,SAAS,WAAW,MAAkC;AACpD,MAAI,KAAK,OAAQ,QAAO,KAAK;AAC7B,MAAI,KAAK,KAAK,SAAS,UAAW,QAAO,oBAAC,eAAY,MAAY;AAClE,MAAI,KAAK,KAAK,SAAS,aAAa;AAClC,+BACG,eAAA,EAAc,MACb,8BAAC,QAAA,EAAM,UAAA,KAAK,aAAY,EAAA,CAC1B;AAAA,EAEJ;AACA,QAAM,QAAQ,KAAK,KAAK,KAAK;AAC7B,SAAO,QACH,oBAAoB,MAAM,IAAI,GAAG,KAAK,SAAS,OAAO,cAAc,IAAI,CAAC,IACzE;AACN;AAEA,SAAS,cAAc,QAAsC;AAC3D,QAAM,QAA2B,CAAA;AACjC,SAAO,QAAQ,CAAC,SAAS;AACvB,UAAM,KAAK,IAAI;AAAA,EACjB,CAAC;AACD,SAAO,eAAe,OAAO,CAAC;AAChC;AAGA,SAAS,eACP,OACA,OACa;;AACb,QAAM,WAAwB,CAAA;AAC9B,MAAI,QAAQ;AACZ,SAAO,QAAQ,MAAM,QAAQ;AAC3B,UAAM,OAAO,MAAM,KAAK;AACxB,UAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,QAAI,CAAC,MAAM;AACT,eAAS,KAAK,oBAAC,UAAA,EAAsB,qBAAW,IAAI,KAAvB,KAAyB,CAAW;AACjE;AACA;AAAA,IACF;AACA,QAAI,MAAM,QAAQ;AAClB,QAAI,KAAK,KAAK,KAAK,aAAa,OAAO;AACrC,aAAO,MAAM,MAAM,YAAU,iBAAM,GAAG,MAAT,mBAAY,MAAM,WAAlB,mBAA0B,GAAG,OAAO;AAAA,IACnE;AACA,UAAM,UAAU,eAAe,MAAM,MAAM,OAAO,GAAG,GAAG,QAAQ,CAAC;AACjE,UAAM,WACJ,KAAK,KAAK,SAAS,SACjB,oBAAC,aAAA,EAAY,MAAM,KAAK,MAAM,MAAO,UAAA,QAAA,CAAQ,IAC3C,KAAK,KAAK,KAAK,QACjB,oBAAoB,KAAK,KAAK,KAAK,MAAM,MAAM,IAAI,GAAG,OAAO,IAE7D;AAEJ,aAAS,KAAK,oBAAC,UAAA,EAAsB,UAAA,SAAA,GAAR,KAAiB,CAAW;AACzD,YAAQ;AAAA,EACV;AACA,SAAO;AACT;"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("@tiptap/react");
5
+ const mentionChip = require("../mentions/mention-chip.cjs");
6
+ const mentionExtension = require("../mentions/mention-extension.cjs");
7
+ function ChatMention({
8
+ node,
9
+ interactive = true
10
+ }) {
11
+ return /* @__PURE__ */ jsxRuntime.jsx(
12
+ "span",
13
+ {
14
+ className: "mention-chip",
15
+ "data-mention": "",
16
+ "data-type": node.attrs.type,
17
+ "data-name": node.attrs.name,
18
+ "data-id": node.attrs.id,
19
+ "data-asset-type": node.attrs.assetType,
20
+ "data-display-as-preview": String(node.attrs.displayAsPreview === true),
21
+ children: /* @__PURE__ */ jsxRuntime.jsx(
22
+ mentionChip.MentionLink,
23
+ {
24
+ href: mentionExtension.makeMentionUrl(node.attrs),
25
+ interactive,
26
+ children: node.attrs.name
27
+ }
28
+ )
29
+ }
30
+ );
31
+ }
32
+ function ChatMentionNodeView({ node, editor }) {
33
+ return /* @__PURE__ */ jsxRuntime.jsx(react.NodeViewWrapper, { as: "span", children: /* @__PURE__ */ jsxRuntime.jsx(ChatMention, { node, interactive: !editor.isEditable }) });
34
+ }
35
+ function ChatCodeBlock({
36
+ node,
37
+ children
38
+ }) {
39
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "not-prose my-2 overflow-hidden rounded-lg border border-border bg-muted/30", children: [
40
+ node.attrs.language && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-border bg-muted/50 px-3 py-1 text-[10px] font-medium text-muted-foreground", children: node.attrs.language }),
41
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "overflow-x-auto p-3 font-mono text-xs leading-relaxed text-foreground", children })
42
+ ] });
43
+ }
44
+ function ChatCodeBlockNodeView({ node }) {
45
+ return /* @__PURE__ */ jsxRuntime.jsx(react.NodeViewWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(ChatCodeBlock, { node, children: /* @__PURE__ */ jsxRuntime.jsx(react.NodeViewContent, { as: "code" }) }) });
46
+ }
47
+ exports.ChatCodeBlock = ChatCodeBlock;
48
+ exports.ChatCodeBlockNodeView = ChatCodeBlockNodeView;
49
+ exports.ChatMention = ChatMention;
50
+ exports.ChatMentionNodeView = ChatMentionNodeView;
51
+ //# sourceMappingURL=chat-node-views.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-node-views.cjs","sources":["../../../src/chat-ui/rich-text/chat-node-views.tsx"],"sourcesContent":["import type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport {\n NodeViewContent,\n NodeViewWrapper,\n type NodeViewProps,\n} from \"@tiptap/react\";\nimport type { ReactNode } from \"react\";\nimport { MentionLink } from \"../mentions/mention-chip\";\nimport {\n makeMentionUrl,\n type MentionNodeAttrs,\n} from \"../mentions/mention-extension\";\n\nexport function ChatMention({\n node,\n interactive = true,\n}: {\n node: ProseMirrorNode;\n interactive?: boolean;\n}) {\n return (\n <span\n className=\"mention-chip\"\n data-mention=\"\"\n data-type={node.attrs.type}\n data-name={node.attrs.name}\n data-id={node.attrs.id}\n data-asset-type={node.attrs.assetType}\n data-display-as-preview={String(node.attrs.displayAsPreview === true)}\n >\n <MentionLink\n href={makeMentionUrl(node.attrs as MentionNodeAttrs)}\n interactive={interactive}\n >\n {node.attrs.name}\n </MentionLink>\n </span>\n );\n}\n\nexport function ChatMentionNodeView({ node, editor }: NodeViewProps) {\n return (\n <NodeViewWrapper as=\"span\">\n <ChatMention node={node} interactive={!editor.isEditable} />\n </NodeViewWrapper>\n );\n}\n\nexport function ChatCodeBlock({\n node,\n children,\n}: {\n node: ProseMirrorNode;\n children: ReactNode;\n}) {\n return (\n <div className=\"not-prose my-2 overflow-hidden rounded-lg border border-border bg-muted/30\">\n {node.attrs.language && (\n <div className=\"border-b border-border bg-muted/50 px-3 py-1 text-[10px] font-medium text-muted-foreground\">\n {node.attrs.language}\n </div>\n )}\n <pre className=\"overflow-x-auto p-3 font-mono text-xs leading-relaxed text-foreground\">\n {children}\n </pre>\n </div>\n );\n}\n\nexport function ChatCodeBlockNodeView({ node }: NodeViewProps) {\n return (\n <NodeViewWrapper>\n <ChatCodeBlock node={node}>\n <NodeViewContent as=\"code\" />\n </ChatCodeBlock>\n </NodeViewWrapper>\n );\n}\n"],"names":["jsx","MentionLink","makeMentionUrl","NodeViewWrapper","jsxs","NodeViewContent"],"mappings":";;;;;;AAaO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,cAAc;AAChB,GAGG;AACD,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,gBAAa;AAAA,MACb,aAAW,KAAK,MAAM;AAAA,MACtB,aAAW,KAAK,MAAM;AAAA,MACtB,WAAS,KAAK,MAAM;AAAA,MACpB,mBAAiB,KAAK,MAAM;AAAA,MAC5B,2BAAyB,OAAO,KAAK,MAAM,qBAAqB,IAAI;AAAA,MAEpE,UAAAA,2BAAAA;AAAAA,QAACC,YAAAA;AAAAA,QAAA;AAAA,UACC,MAAMC,iBAAAA,eAAe,KAAK,KAAyB;AAAA,UACnD;AAAA,UAEC,eAAK,MAAM;AAAA,QAAA;AAAA,MAAA;AAAA,IACd;AAAA,EAAA;AAGN;AAEO,SAAS,oBAAoB,EAAE,MAAM,UAAyB;AACnE,SACEF,2BAAAA,IAACG,MAAAA,iBAAA,EAAgB,IAAG,QAClB,UAAAH,2BAAAA,IAAC,aAAA,EAAY,MAAY,aAAa,CAAC,OAAO,WAAA,CAAY,EAAA,CAC5D;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AACF,GAGG;AACD,SACEI,2BAAAA,KAAC,OAAA,EAAI,WAAU,8EACZ,UAAA;AAAA,IAAA,KAAK,MAAM,YACVJ,2BAAAA,IAAC,OAAA,EAAI,WAAU,8FACZ,UAAA,KAAK,MAAM,SAAA,CACd;AAAA,IAEFA,2BAAAA,IAAC,OAAA,EAAI,WAAU,yEACZ,SAAA,CACH;AAAA,EAAA,GACF;AAEJ;AAEO,SAAS,sBAAsB,EAAE,QAAuB;AAC7D,SACEA,2BAAAA,IAACG,MAAAA,iBAAA,EACC,UAAAH,2BAAAA,IAAC,eAAA,EAAc,MACb,yCAACK,MAAAA,iBAAA,EAAgB,IAAG,OAAA,CAAO,EAAA,CAC7B,GACF;AAEJ;;;;;"}