@athenaintel/react 0.43.0 → 0.50.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 (746) hide show
  1. package/README.md +258 -8
  2. package/dist/agent-runtime/src/answer-label.cjs +137 -0
  3. package/dist/agent-runtime/src/answer-label.cjs.map +1 -0
  4. package/dist/agent-runtime/src/answer-label.d.ts +104 -0
  5. package/dist/agent-runtime/src/answer-label.js +137 -0
  6. package/dist/agent-runtime/src/answer-label.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-rows.cjs +180 -0
  8. package/dist/agent-runtime/src/answer-rows.cjs.map +1 -0
  9. package/dist/agent-runtime/src/answer-rows.d.ts +86 -0
  10. package/dist/agent-runtime/src/answer-rows.js +180 -0
  11. package/dist/agent-runtime/src/answer-rows.js.map +1 -0
  12. package/dist/agent-runtime/src/call-recap.cjs +319 -0
  13. package/dist/agent-runtime/src/call-recap.cjs.map +1 -0
  14. package/dist/agent-runtime/src/call-recap.d.ts +142 -0
  15. package/dist/agent-runtime/src/call-recap.js +319 -0
  16. package/dist/agent-runtime/src/call-recap.js.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-store.cjs +1 -0
  18. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +1 -1
  19. package/dist/agent-runtime/src/chat-outbox-store.d.ts +7 -0
  20. package/dist/agent-runtime/src/chat-outbox-store.js +1 -0
  21. package/dist/agent-runtime/src/chat-outbox-store.js.map +1 -1
  22. package/dist/agent-runtime/src/chat-outbox.cjs +46 -5
  23. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
  24. package/dist/agent-runtime/src/chat-outbox.d.ts +29 -0
  25. package/dist/agent-runtime/src/chat-outbox.js +46 -5
  26. package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
  27. package/dist/agent-runtime/src/client-tool-bridge.cjs +15 -15
  28. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  29. package/dist/agent-runtime/src/conversation-index.cjs +8 -8
  30. package/dist/agent-runtime/src/conversation-index.cjs.map +1 -1
  31. package/dist/agent-runtime/src/conversation-index.d.ts +7 -0
  32. package/dist/agent-runtime/src/conversation-index.js.map +1 -1
  33. package/dist/agent-runtime/src/conversation-list.cjs +2 -1
  34. package/dist/agent-runtime/src/conversation-list.cjs.map +1 -1
  35. package/dist/agent-runtime/src/conversation-list.d.ts +19 -3
  36. package/dist/agent-runtime/src/conversation-list.js +2 -1
  37. package/dist/agent-runtime/src/conversation-list.js.map +1 -1
  38. package/dist/agent-runtime/src/decision-checks.cjs +207 -0
  39. package/dist/agent-runtime/src/decision-checks.cjs.map +1 -0
  40. package/dist/agent-runtime/src/decision-checks.d.ts +142 -0
  41. package/dist/agent-runtime/src/decision-checks.js +207 -0
  42. package/dist/agent-runtime/src/decision-checks.js.map +1 -0
  43. package/dist/agent-runtime/src/desktop-handoff.d.ts +12 -0
  44. package/dist/agent-runtime/src/errors.cjs +18 -0
  45. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  46. package/dist/agent-runtime/src/errors.d.ts +7 -0
  47. package/dist/agent-runtime/src/errors.js +18 -0
  48. package/dist/agent-runtime/src/errors.js.map +1 -1
  49. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +12 -0
  50. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  51. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +6 -6
  52. package/dist/agent-runtime/src/generated/runconfig-contract.js +12 -0
  53. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  54. package/dist/agent-runtime/src/handoff-arrival.cjs +60 -0
  55. package/dist/agent-runtime/src/handoff-arrival.cjs.map +1 -0
  56. package/dist/agent-runtime/src/handoff-arrival.d.ts +46 -0
  57. package/dist/agent-runtime/src/handoff-arrival.js +60 -0
  58. package/dist/agent-runtime/src/handoff-arrival.js.map +1 -0
  59. package/dist/agent-runtime/src/index.d.ts +16 -9
  60. package/dist/agent-runtime/src/interrupts.cjs +71 -19
  61. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  62. package/dist/agent-runtime/src/interrupts.d.ts +40 -3
  63. package/dist/agent-runtime/src/interrupts.js +56 -4
  64. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  65. package/dist/agent-runtime/src/lane-history.cjs +8 -8
  66. package/dist/agent-runtime/src/lane-history.cjs.map +1 -1
  67. package/dist/agent-runtime/src/messages.cjs +43 -8
  68. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  69. package/dist/agent-runtime/src/messages.d.ts +25 -3
  70. package/dist/agent-runtime/src/messages.js +43 -8
  71. package/dist/agent-runtime/src/messages.js.map +1 -1
  72. package/dist/agent-runtime/src/model-context.cjs +3 -2
  73. package/dist/agent-runtime/src/model-context.cjs.map +1 -1
  74. package/dist/agent-runtime/src/model-context.d.ts +6 -1
  75. package/dist/agent-runtime/src/model-context.js +3 -2
  76. package/dist/agent-runtime/src/model-context.js.map +1 -1
  77. package/dist/agent-runtime/src/offline-status.cjs +36 -0
  78. package/dist/agent-runtime/src/offline-status.cjs.map +1 -0
  79. package/dist/agent-runtime/src/offline-status.d.ts +118 -3
  80. package/dist/agent-runtime/src/offline-status.js +36 -0
  81. package/dist/agent-runtime/src/offline-status.js.map +1 -0
  82. package/dist/agent-runtime/src/queue.cjs +0 -9
  83. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  84. package/dist/agent-runtime/src/queue.js +0 -9
  85. package/dist/agent-runtime/src/queue.js.map +1 -1
  86. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +9 -9
  87. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  88. package/dist/agent-runtime/src/runtime-catalog.cjs +42 -0
  89. package/dist/agent-runtime/src/runtime-catalog.cjs.map +1 -0
  90. package/dist/agent-runtime/src/runtime-catalog.d.ts +35 -0
  91. package/dist/agent-runtime/src/runtime-catalog.js +42 -0
  92. package/dist/agent-runtime/src/runtime-catalog.js.map +1 -0
  93. package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -1
  94. package/dist/agent-runtime/src/runtime-messages.d.ts +1 -1
  95. package/dist/agent-runtime/src/runtime-messages.js.map +1 -1
  96. package/dist/agent-runtime/src/runtime.d.ts +41 -0
  97. package/dist/agent-runtime/src/send-recovery.cjs +37 -3
  98. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
  99. package/dist/agent-runtime/src/send-recovery.d.ts +19 -0
  100. package/dist/agent-runtime/src/send-recovery.js +37 -3
  101. package/dist/agent-runtime/src/send-recovery.js.map +1 -1
  102. package/dist/agent-runtime/src/statewire-suspended.cjs +3 -3
  103. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  104. package/dist/agent-runtime/src/subagents.cjs +32 -2
  105. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  106. package/dist/agent-runtime/src/subagents.d.ts +9 -0
  107. package/dist/agent-runtime/src/subagents.js +30 -0
  108. package/dist/agent-runtime/src/subagents.js.map +1 -1
  109. package/dist/agent-runtime/src/thread-driver.cjs +67 -0
  110. package/dist/agent-runtime/src/thread-driver.cjs.map +1 -0
  111. package/dist/agent-runtime/src/thread-driver.d.ts +49 -0
  112. package/dist/agent-runtime/src/thread-driver.js +67 -0
  113. package/dist/agent-runtime/src/thread-driver.js.map +1 -0
  114. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +172 -0
  115. package/dist/agent-runtime/src/thread-handoff-protocol.d.ts +868 -0
  116. package/dist/agent-runtime/src/thread-handoff-qr.d.ts +11 -0
  117. package/dist/agent-runtime/src/thread-handoff.d.ts +3 -364
  118. package/dist/agent-runtime/src/thread-status.cjs +3 -3
  119. package/dist/agent-runtime/src/thread-status.cjs.map +1 -1
  120. package/dist/agent-runtime/src/tool-metadata.cjs +210 -25
  121. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  122. package/dist/agent-runtime/src/tool-metadata.d.ts +12 -0
  123. package/dist/agent-runtime/src/tool-metadata.js +210 -25
  124. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  125. package/dist/agent-runtime/src/tool-names.cjs +2 -0
  126. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  127. package/dist/agent-runtime/src/tool-names.d.ts +2 -0
  128. package/dist/agent-runtime/src/tool-names.js +2 -0
  129. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  130. package/dist/agent-runtime/src/types.d.ts +10 -2
  131. package/dist/agent-runtime/src/use-conversation-list.cjs +14 -13
  132. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  133. package/dist/agent-runtime/src/use-conversation-list.d.ts +6 -0
  134. package/dist/agent-runtime/src/use-conversation-list.js +3 -2
  135. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
  136. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +45 -20
  137. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  138. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +10 -3
  139. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +27 -2
  140. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  141. package/dist/agent-runtime/src/use-deep-agent-config.cjs +14 -14
  142. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  143. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +6 -6
  144. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  145. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +40 -22
  146. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  147. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +17 -0
  148. package/dist/agent-runtime/src/use-deep-agent-runtime.js +24 -6
  149. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  150. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +45 -45
  151. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  152. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +588 -130
  153. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  154. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +162 -10
  155. package/dist/agent-runtime/src/use-deep-agent-voice.js +529 -71
  156. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  157. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +26 -26
  158. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  159. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +4 -4
  160. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -1
  161. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +34 -26
  162. package/dist/agent-runtime/src/voice-earcon.cjs +139 -0
  163. package/dist/agent-runtime/src/voice-earcon.cjs.map +1 -0
  164. package/dist/agent-runtime/src/voice-earcon.d.ts +38 -0
  165. package/dist/agent-runtime/src/voice-earcon.js +139 -0
  166. package/dist/agent-runtime/src/voice-earcon.js.map +1 -0
  167. package/dist/agent-runtime/src/voice-media.cjs +117 -0
  168. package/dist/agent-runtime/src/voice-media.cjs.map +1 -0
  169. package/dist/agent-runtime/src/voice-media.d.ts +63 -0
  170. package/dist/agent-runtime/src/voice-media.js +117 -0
  171. package/dist/agent-runtime/src/voice-media.js.map +1 -0
  172. package/dist/agent-runtime/src/voice-presentation.cjs +2 -0
  173. package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -1
  174. package/dist/agent-runtime/src/voice-presentation.js +2 -0
  175. package/dist/agent-runtime/src/voice-presentation.js.map +1 -1
  176. package/dist/agent-runtime/src/voice-wire-types.d.ts +32 -0
  177. package/dist/assets/AssetPanel.cjs +11 -11
  178. package/dist/assets/AssetPanel.cjs.map +1 -1
  179. package/dist/assets/AthenaAssetEmbed.cjs +11 -9
  180. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  181. package/dist/assets/AthenaAssetEmbed.d.ts +18 -5
  182. package/dist/assets/AthenaAssetEmbed.js +4 -2
  183. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  184. package/dist/assets/AthenaLayout.cjs +16 -16
  185. package/dist/assets/AthenaLayout.cjs.map +1 -1
  186. package/dist/assets/use-asset-content.cjs +4 -4
  187. package/dist/assets/use-asset-content.cjs.map +1 -1
  188. package/dist/assets/use-asset-embed.cjs +14 -7
  189. package/dist/assets/use-asset-embed.cjs.map +1 -1
  190. package/dist/assets/use-asset-embed.d.ts +23 -6
  191. package/dist/assets/use-asset-embed.js +10 -3
  192. package/dist/assets/use-asset-embed.js.map +1 -1
  193. package/dist/auth/AthenaAuthContext.cjs +3 -3
  194. package/dist/auth/AthenaAuthContext.cjs.map +1 -1
  195. package/dist/auth/AthenaAuthProvider.cjs +8 -8
  196. package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
  197. package/dist/auth/AthenaCredentialSourceContext.cjs +5 -5
  198. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  199. package/dist/auth/AthenaSSOProvider.cjs +14 -14
  200. package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
  201. package/dist/auth/credential-source.cjs +26 -13
  202. package/dist/auth/credential-source.cjs.map +1 -1
  203. package/dist/auth/credential-source.d.ts +8 -0
  204. package/dist/auth/credential-source.js +26 -13
  205. package/dist/auth/credential-source.js.map +1 -1
  206. package/dist/catalog/agent-model-options.cjs +25 -17
  207. package/dist/catalog/agent-model-options.cjs.map +1 -1
  208. package/dist/catalog/agent-model-options.d.ts +38 -5
  209. package/dist/catalog/agent-model-options.js +25 -17
  210. package/dist/catalog/agent-model-options.js.map +1 -1
  211. package/dist/catalog/channel-refusal.cjs +36 -0
  212. package/dist/catalog/channel-refusal.cjs.map +1 -0
  213. package/dist/catalog/channel-refusal.d.ts +29 -0
  214. package/dist/catalog/channel-refusal.js +36 -0
  215. package/dist/catalog/channel-refusal.js.map +1 -0
  216. package/dist/catalog/chat-pickers.cjs +60 -24
  217. package/dist/catalog/chat-pickers.cjs.map +1 -1
  218. package/dist/catalog/chat-pickers.d.ts +12 -2
  219. package/dist/catalog/chat-pickers.js +56 -20
  220. package/dist/catalog/chat-pickers.js.map +1 -1
  221. package/dist/catalog/runtime-catalog.cjs +89 -23
  222. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  223. package/dist/catalog/runtime-catalog.d.ts +8 -2
  224. package/dist/catalog/runtime-catalog.js +83 -17
  225. package/dist/catalog/runtime-catalog.js.map +1 -1
  226. package/dist/catalog/use-athena-chat-mode.cjs +12 -12
  227. package/dist/catalog/use-athena-chat-mode.cjs.map +1 -1
  228. package/dist/chat/AthenaChat.cjs +155 -67
  229. package/dist/chat/AthenaChat.cjs.map +1 -1
  230. package/dist/chat/AthenaChat.d.ts +42 -2
  231. package/dist/chat/AthenaChat.js +106 -18
  232. package/dist/chat/AthenaChat.js.map +1 -1
  233. package/dist/chat/AthenaChatErrorBoundary.cjs +3 -3
  234. package/dist/chat/AthenaChatErrorBoundary.cjs.map +1 -1
  235. package/dist/chat/DrivingOnChip.cjs +23 -0
  236. package/dist/chat/DrivingOnChip.cjs.map +1 -0
  237. package/dist/chat/DrivingOnChip.d.ts +17 -0
  238. package/dist/chat/DrivingOnChip.js +23 -0
  239. package/dist/chat/DrivingOnChip.js.map +1 -0
  240. package/dist/chat/StatewireApprovalCard.cjs +166 -37
  241. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  242. package/dist/chat/StatewireApprovalCard.d.ts +91 -2
  243. package/dist/chat/StatewireApprovalCard.js +156 -27
  244. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  245. package/dist/chat/StatewireClientToolBridge.cjs +2 -2
  246. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  247. package/dist/chat/StatewireQueuedMessages.cjs +81 -69
  248. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  249. package/dist/chat/StatewireQueuedMessages.d.ts +25 -13
  250. package/dist/chat/StatewireQueuedMessages.js +73 -61
  251. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  252. package/dist/chat/WaitingOnYouBanner.cjs +9 -5
  253. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
  254. package/dist/chat/WaitingOnYouBanner.js +7 -3
  255. package/dist/chat/WaitingOnYouBanner.js.map +1 -1
  256. package/dist/chat/athena-chat-welcome.cjs +2 -2
  257. package/dist/chat/athena-chat-welcome.cjs.map +1 -1
  258. package/dist/chat/athena-citation-links.cjs +5 -5
  259. package/dist/chat/athena-citation-links.cjs.map +1 -1
  260. package/dist/chat/athena-composer-controls.cjs +26 -16
  261. package/dist/chat/athena-composer-controls.cjs.map +1 -1
  262. package/dist/chat/athena-composer-controls.d.ts +6 -0
  263. package/dist/chat/athena-composer-controls.js +26 -16
  264. package/dist/chat/athena-composer-controls.js.map +1 -1
  265. package/dist/chat/athena-turn-end-status.cjs +42 -0
  266. package/dist/chat/athena-turn-end-status.cjs.map +1 -0
  267. package/dist/chat/athena-turn-end-status.d.ts +24 -0
  268. package/dist/chat/athena-turn-end-status.js +42 -0
  269. package/dist/chat/athena-turn-end-status.js.map +1 -0
  270. package/dist/chat/browser-decision-check.cjs +131 -0
  271. package/dist/chat/browser-decision-check.cjs.map +1 -0
  272. package/dist/chat/browser-decision-check.d.ts +61 -0
  273. package/dist/chat/browser-decision-check.js +131 -0
  274. package/dist/chat/browser-decision-check.js.map +1 -0
  275. package/dist/chat/chat-outbox-rows.cjs +3 -3
  276. package/dist/chat/chat-outbox-rows.cjs.map +1 -1
  277. package/dist/chat/chat-voice-controls.cjs +96 -29
  278. package/dist/chat/chat-voice-controls.cjs.map +1 -1
  279. package/dist/chat/chat-voice-controls.d.ts +42 -3
  280. package/dist/chat/chat-voice-controls.js +92 -25
  281. package/dist/chat/chat-voice-controls.js.map +1 -1
  282. package/dist/chat/composer-keyboard-hint.cjs +5 -5
  283. package/dist/chat/composer-keyboard-hint.cjs.map +1 -1
  284. package/dist/chat/device-operation.cjs +29 -0
  285. package/dist/chat/device-operation.cjs.map +1 -0
  286. package/dist/chat/device-operation.d.ts +34 -0
  287. package/dist/chat/device-operation.js +29 -0
  288. package/dist/chat/device-operation.js.map +1 -0
  289. package/dist/chat/super-grouping/CollapsibleGroup.cjs +14 -14
  290. package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
  291. package/dist/chat/super-grouping/GroupedMessageParts.cjs +4 -4
  292. package/dist/chat/super-grouping/GroupedMessageParts.cjs.map +1 -1
  293. package/dist/chat/super-grouping/SuperGroupingCard.cjs +52 -36
  294. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  295. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +19 -4
  296. package/dist/chat/super-grouping/SuperGroupingCard.js +29 -13
  297. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  298. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +32 -32
  299. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  300. package/dist/chat/super-grouping/SuperGroupingTranscript.js +3 -3
  301. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  302. package/dist/chat/super-grouping/ToolTimeline.cjs +73 -40
  303. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  304. package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -2
  305. package/dist/chat/super-grouping/ToolTimeline.js +69 -36
  306. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  307. package/dist/chat/super-grouping/activity-timeline.cjs +47 -12
  308. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  309. package/dist/chat/super-grouping/activity-timeline.d.ts +21 -0
  310. package/dist/chat/super-grouping/activity-timeline.js +47 -12
  311. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  312. package/dist/chat/super-grouping/grouping-function.cjs +4 -0
  313. package/dist/chat/super-grouping/grouping-function.cjs.map +1 -1
  314. package/dist/chat/super-grouping/grouping-function.d.ts +7 -0
  315. package/dist/chat/super-grouping/grouping-function.js +5 -1
  316. package/dist/chat/super-grouping/grouping-function.js.map +1 -1
  317. package/dist/chat/super-grouping/index.cjs +6 -0
  318. package/dist/chat/super-grouping/index.cjs.map +1 -1
  319. package/dist/chat/super-grouping/index.d.ts +5 -2
  320. package/dist/chat/super-grouping/index.js +7 -1
  321. package/dist/chat/super-grouping/index.js.map +1 -1
  322. package/dist/chat/super-grouping/tool-part-placement.cjs +17 -0
  323. package/dist/chat/super-grouping/tool-part-placement.cjs.map +1 -0
  324. package/dist/chat/super-grouping/tool-part-placement.d.ts +22 -0
  325. package/dist/chat/super-grouping/tool-part-placement.js +17 -0
  326. package/dist/chat/super-grouping/tool-part-placement.js.map +1 -0
  327. package/dist/chat/thread-scroll-to-bottom.cjs +2 -2
  328. package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -1
  329. package/dist/chat/thread-scroll-to-bottom.d.ts +10 -7
  330. package/dist/chat/thread-scroll-to-bottom.js +2 -2
  331. package/dist/chat/thread-scroll-to-bottom.js.map +1 -1
  332. package/dist/chat/tooltip-icon-button.cjs +2 -2
  333. package/dist/chat/tooltip-icon-button.cjs.map +1 -1
  334. package/dist/chat/use-athena-voice-live.cjs +11 -0
  335. package/dist/chat/use-athena-voice-live.cjs.map +1 -0
  336. package/dist/chat/use-athena-voice-live.d.ts +11 -0
  337. package/dist/chat/use-athena-voice-live.js +11 -0
  338. package/dist/chat/use-athena-voice-live.js.map +1 -0
  339. package/dist/chat/use-statewire-approval-request.cjs +56 -24
  340. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  341. package/dist/chat/use-statewire-approval-request.d.ts +33 -4
  342. package/dist/chat/use-statewire-approval-request.js +41 -9
  343. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  344. package/dist/chat-ui/auth/sign-in-card.cjs +2 -2
  345. package/dist/chat-ui/auth/sign-in-card.cjs.map +1 -1
  346. package/dist/chat-ui/composer/tiptap-composer.cjs +138 -107
  347. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  348. package/dist/chat-ui/composer/tiptap-composer.d.ts +20 -4
  349. package/dist/chat-ui/composer/tiptap-composer.js +85 -54
  350. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  351. package/dist/chat-ui/header/conversation-history-panel.cjs +49 -23
  352. package/dist/chat-ui/header/conversation-history-panel.cjs.map +1 -1
  353. package/dist/chat-ui/header/conversation-history-panel.d.ts +12 -1
  354. package/dist/chat-ui/header/conversation-history-panel.js +38 -12
  355. package/dist/chat-ui/header/conversation-history-panel.js.map +1 -1
  356. package/dist/chat-ui/index.cjs +21 -0
  357. package/dist/chat-ui/index.cjs.map +1 -1
  358. package/dist/chat-ui/index.d.ts +8 -1
  359. package/dist/chat-ui/index.js +21 -0
  360. package/dist/chat-ui/index.js.map +1 -1
  361. package/dist/chat-ui/mentions/mention-chip.cjs +4 -4
  362. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  363. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +10 -9
  364. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  365. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +3 -2
  366. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  367. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +2 -2
  368. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
  369. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +29 -6
  370. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  371. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +7 -1
  372. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +25 -2
  373. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  374. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs +2 -2
  375. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs.map +1 -1
  376. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs +2 -2
  377. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs.map +1 -1
  378. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +3 -3
  379. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  380. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs +56 -2
  381. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs.map +1 -1
  382. package/dist/chat-ui/mentions/suggestions/data/orchestrator.d.ts +12 -0
  383. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js +56 -2
  384. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js.map +1 -1
  385. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +24 -3
  386. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  387. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +7 -0
  388. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +24 -3
  389. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  390. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +35 -13
  391. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  392. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +15 -1
  393. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +28 -6
  394. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  395. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs +9 -6
  396. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs.map +1 -1
  397. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.d.ts +3 -0
  398. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js +5 -2
  399. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js.map +1 -1
  400. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +45 -10
  401. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
  402. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +24 -1
  403. package/dist/chat-ui/mentions/use-account-workspace-id.js +46 -11
  404. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
  405. package/dist/chat-ui/mentions/use-member-avatar.cjs +4 -4
  406. package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -1
  407. package/dist/chat-ui/mentions/use-mention-asset.cjs +3 -3
  408. package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -1
  409. package/dist/chat-ui/messages/answer-label.cjs +42 -0
  410. package/dist/chat-ui/messages/answer-label.cjs.map +1 -0
  411. package/dist/chat-ui/messages/answer-label.d.ts +33 -0
  412. package/dist/chat-ui/messages/answer-label.js +42 -0
  413. package/dist/chat-ui/messages/answer-label.js.map +1 -0
  414. package/dist/chat-ui/messages/arrival-animation.cjs +13 -0
  415. package/dist/chat-ui/messages/arrival-animation.cjs.map +1 -0
  416. package/dist/chat-ui/messages/arrival-animation.d.ts +14 -0
  417. package/dist/chat-ui/messages/arrival-animation.js +13 -0
  418. package/dist/chat-ui/messages/arrival-animation.js.map +1 -0
  419. package/dist/chat-ui/messages/continue-pill.cjs +5 -5
  420. package/dist/chat-ui/messages/continue-pill.cjs.map +1 -1
  421. package/dist/chat-ui/messages/from-the-call-card.cjs +124 -0
  422. package/dist/chat-ui/messages/from-the-call-card.cjs.map +1 -0
  423. package/dist/chat-ui/messages/from-the-call-card.d.ts +17 -0
  424. package/dist/chat-ui/messages/from-the-call-card.js +124 -0
  425. package/dist/chat-ui/messages/from-the-call-card.js.map +1 -0
  426. package/dist/chat-ui/messages/handoff-arrival-divider.cjs +44 -0
  427. package/dist/chat-ui/messages/handoff-arrival-divider.cjs.map +1 -0
  428. package/dist/chat-ui/messages/handoff-arrival-divider.d.ts +17 -0
  429. package/dist/chat-ui/messages/handoff-arrival-divider.js +44 -0
  430. package/dist/chat-ui/messages/handoff-arrival-divider.js.map +1 -0
  431. package/dist/chat-ui/messages/message-actions-config.cjs +3 -3
  432. package/dist/chat-ui/messages/message-actions-config.cjs.map +1 -1
  433. package/dist/chat-ui/messages/message-components.cjs +8 -4
  434. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  435. package/dist/chat-ui/messages/message-components.js +5 -1
  436. package/dist/chat-ui/messages/message-components.js.map +1 -1
  437. package/dist/chat-ui/messages/message-images.cjs +66 -0
  438. package/dist/chat-ui/messages/message-images.cjs.map +1 -0
  439. package/dist/chat-ui/messages/message-images.d.ts +16 -0
  440. package/dist/chat-ui/messages/message-images.js +66 -0
  441. package/dist/chat-ui/messages/message-images.js.map +1 -0
  442. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -2
  443. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  444. package/dist/chat-ui/messages/wake-marker.cjs +3 -3
  445. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  446. package/dist/chat-ui/rich-text/chat-link.cjs +3 -2
  447. package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
  448. package/dist/chat-ui/rich-text/chat-link.d.ts +4 -0
  449. package/dist/chat-ui/rich-text/chat-link.js +4 -3
  450. package/dist/chat-ui/rich-text/chat-link.js.map +1 -1
  451. package/dist/chat-ui/rich-text/chat-message-body.cjs +9 -8
  452. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  453. package/dist/chat-ui/rich-text/chat-message-body.d.ts +12 -0
  454. package/dist/chat-ui/rich-text/chat-message-body.js +2 -1
  455. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
  456. package/dist/chat-ui/rich-text/chat-node-views.cjs +6 -6
  457. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
  458. package/dist/chat-ui/rich-text/dom-output-spec.cjs +2 -2
  459. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -1
  460. package/dist/chat-ui/statewire.cjs +3 -0
  461. package/dist/chat-ui/statewire.cjs.map +1 -1
  462. package/dist/chat-ui/statewire.d.ts +2 -1
  463. package/dist/chat-ui/statewire.js +3 -0
  464. package/dist/chat-ui/statewire.js.map +1 -1
  465. package/dist/chat-ui/thread/chat-thread-shell.cjs +45 -14
  466. package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
  467. package/dist/chat-ui/thread/chat-thread-shell.d.ts +16 -2
  468. package/dist/chat-ui/thread/chat-thread-shell.js +37 -6
  469. package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
  470. package/dist/chat-ui/thread/composer-send-or-stop.cjs +30 -20
  471. package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
  472. package/dist/chat-ui/thread/composer-send-or-stop.d.ts +8 -0
  473. package/dist/chat-ui/thread/composer-send-or-stop.js +29 -19
  474. package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
  475. package/dist/chat-ui/thread/statewire-history-edge.cjs +20 -21
  476. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  477. package/dist/chat-ui/thread/statewire-history-edge.js +3 -4
  478. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  479. package/dist/chat-ui/thread/thread-loading-overlay.cjs +5 -5
  480. package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -1
  481. package/dist/collab/client.cjs +52 -3
  482. package/dist/collab/client.cjs.map +1 -1
  483. package/dist/collab/client.d.ts +27 -0
  484. package/dist/collab/client.js +52 -3
  485. package/dist/collab/client.js.map +1 -1
  486. package/dist/collab/document-status.cjs +150 -0
  487. package/dist/collab/document-status.cjs.map +1 -0
  488. package/dist/collab/document-status.d.ts +68 -0
  489. package/dist/collab/document-status.js +150 -0
  490. package/dist/collab/document-status.js.map +1 -0
  491. package/dist/collab/index.cjs +7 -0
  492. package/dist/collab/index.cjs.map +1 -1
  493. package/dist/collab/index.d.ts +6 -1
  494. package/dist/collab/index.js +7 -0
  495. package/dist/collab/index.js.map +1 -1
  496. package/dist/collab/presence-react.cjs +11 -11
  497. package/dist/collab/presence-react.cjs.map +1 -1
  498. package/dist/collab/react.cjs +6 -6
  499. package/dist/collab/react.cjs.map +1 -1
  500. package/dist/composer/AttachmentContext.cjs +24 -11
  501. package/dist/composer/AttachmentContext.cjs.map +1 -1
  502. package/dist/composer/AttachmentContext.js +18 -5
  503. package/dist/composer/AttachmentContext.js.map +1 -1
  504. package/dist/composer/ComposerAttachmentPreview.cjs +78 -23
  505. package/dist/composer/ComposerAttachmentPreview.cjs.map +1 -1
  506. package/dist/composer/ComposerAttachmentPreview.d.ts +5 -3
  507. package/dist/composer/ComposerAttachmentPreview.js +79 -24
  508. package/dist/composer/ComposerAttachmentPreview.js.map +1 -1
  509. package/dist/composer/ComposerDropZone.cjs +7 -7
  510. package/dist/composer/ComposerDropZone.cjs.map +1 -1
  511. package/dist/composer/FileUploadButton.cjs +37 -22
  512. package/dist/composer/FileUploadButton.cjs.map +1 -1
  513. package/dist/composer/FileUploadButton.d.ts +6 -0
  514. package/dist/composer/FileUploadButton.js +34 -19
  515. package/dist/composer/FileUploadButton.js.map +1 -1
  516. package/dist/composer/QuoteContext.cjs +8 -8
  517. package/dist/composer/QuoteContext.cjs.map +1 -1
  518. package/dist/composer/composer-handoff.cjs +4 -4
  519. package/dist/composer/composer-handoff.cjs.map +1 -1
  520. package/dist/composer/index.d.ts +1 -1
  521. package/dist/composer/useAppendToComposer.cjs +4 -4
  522. package/dist/composer/useAppendToComposer.cjs.map +1 -1
  523. package/dist/composer/useAttachFiles.cjs +23 -6
  524. package/dist/composer/useAttachFiles.cjs.map +1 -1
  525. package/dist/composer/useAttachFiles.d.ts +15 -7
  526. package/dist/composer/useAttachFiles.js +22 -5
  527. package/dist/composer/useAttachFiles.js.map +1 -1
  528. package/dist/composer/useComposerAttachment.cjs +4 -4
  529. package/dist/composer/useComposerAttachment.cjs.map +1 -1
  530. package/dist/composer/useFileUpload.cjs +21 -16
  531. package/dist/composer/useFileUpload.cjs.map +1 -1
  532. package/dist/composer/useFileUpload.d.ts +12 -0
  533. package/dist/composer/useFileUpload.js +12 -7
  534. package/dist/composer/useFileUpload.js.map +1 -1
  535. package/dist/composer/useReadComposerDraft.cjs +27 -8
  536. package/dist/composer/useReadComposerDraft.cjs.map +1 -1
  537. package/dist/composer/useReadComposerDraft.d.ts +23 -1
  538. package/dist/composer/useReadComposerDraft.js +27 -8
  539. package/dist/composer/useReadComposerDraft.js.map +1 -1
  540. package/dist/composer/useSendMessage.cjs +4 -4
  541. package/dist/composer/useSendMessage.cjs.map +1 -1
  542. package/dist/diagnostics/useAthenaDiagnostics.cjs +4 -4
  543. package/dist/diagnostics/useAthenaDiagnostics.cjs.map +1 -1
  544. package/dist/dictation/audio-level-history.cjs +3 -3
  545. package/dist/dictation/audio-level-history.cjs.map +1 -1
  546. package/dist/dictation/dictation-controls.cjs +24 -20
  547. package/dist/dictation/dictation-controls.cjs.map +1 -1
  548. package/dist/dictation/dictation-controls.d.ts +6 -1
  549. package/dist/dictation/dictation-controls.js +24 -20
  550. package/dist/dictation/dictation-controls.js.map +1 -1
  551. package/dist/dictation/use-athena-dictation-engine.cjs +3 -3
  552. package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
  553. package/dist/dictation/use-dictation.cjs +22 -22
  554. package/dist/dictation/use-dictation.cjs.map +1 -1
  555. package/dist/index.cjs +29 -2
  556. package/dist/index.cjs.map +1 -1
  557. package/dist/index.d.ts +18 -4
  558. package/dist/index.js +30 -3
  559. package/dist/index.js.map +1 -1
  560. package/dist/keryx-http/src/receive-only-socket.cjs +40 -0
  561. package/dist/keryx-http/src/receive-only-socket.cjs.map +1 -0
  562. package/dist/keryx-http/src/receive-only-socket.d.ts +27 -0
  563. package/dist/keryx-http/src/receive-only-socket.js +40 -0
  564. package/dist/keryx-http/src/receive-only-socket.js.map +1 -0
  565. package/dist/keryx-http/src/unconfirmed-update-attributions.cjs +190 -0
  566. package/dist/keryx-http/src/unconfirmed-update-attributions.cjs.map +1 -0
  567. package/dist/keryx-http/src/unconfirmed-update-attributions.d.ts +132 -0
  568. package/dist/keryx-http/src/unconfirmed-update-attributions.js +190 -0
  569. package/dist/keryx-http/src/unconfirmed-update-attributions.js.map +1 -0
  570. package/dist/keryx-http/src/update-attributions.cjs +141 -0
  571. package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
  572. package/dist/keryx-http/src/update-attributions.d.ts +107 -0
  573. package/dist/keryx-http/src/update-attributions.js +141 -0
  574. package/dist/keryx-http/src/update-attributions.js.map +1 -0
  575. package/dist/lib/owner-document.cjs +6 -6
  576. package/dist/lib/owner-document.cjs.map +1 -1
  577. package/dist/lib/use-athena-rest-query.cjs +4 -4
  578. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  579. package/dist/lib/use-document-active.cjs +4 -4
  580. package/dist/lib/use-document-active.cjs.map +1 -1
  581. package/dist/lib/use-prefers-reduced-motion.cjs +2 -2
  582. package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -1
  583. package/dist/offline/offline-history.cjs +7 -7
  584. package/dist/offline/offline-history.cjs.map +1 -1
  585. package/dist/provider/AthenaContext.cjs +3 -3
  586. package/dist/provider/AthenaContext.cjs.map +1 -1
  587. package/dist/provider/AthenaProvider.cjs +120 -79
  588. package/dist/provider/AthenaProvider.cjs.map +1 -1
  589. package/dist/provider/AthenaProvider.d.ts +11 -1
  590. package/dist/provider/AthenaProvider.js +44 -3
  591. package/dist/provider/AthenaProvider.js.map +1 -1
  592. package/dist/provider/PostHogProvider.cjs +2 -2
  593. package/dist/provider/PostHogProvider.cjs.map +1 -1
  594. package/dist/provider/agent-selection-context.cjs +2 -2
  595. package/dist/provider/agent-selection-context.cjs.map +1 -1
  596. package/dist/provider/chat-mode-context.cjs +2 -2
  597. package/dist/provider/chat-mode-context.cjs.map +1 -1
  598. package/dist/provider/session-persistence-context.cjs +10 -0
  599. package/dist/provider/session-persistence-context.cjs.map +1 -0
  600. package/dist/provider/session-persistence-context.d.ts +15 -0
  601. package/dist/provider/session-persistence-context.js +10 -0
  602. package/dist/provider/session-persistence-context.js.map +1 -0
  603. package/dist/provider/statewire-history-context.cjs +4 -4
  604. package/dist/provider/statewire-history-context.cjs.map +1 -1
  605. package/dist/provider/statewire-lifecycle-context.cjs +3 -3
  606. package/dist/provider/statewire-lifecycle-context.cjs.map +1 -1
  607. package/dist/provider/statewire-window-context.cjs +3 -3
  608. package/dist/provider/statewire-window-context.cjs.map +1 -1
  609. package/dist/provider/theme-style-context.cjs +3 -3
  610. package/dist/provider/theme-style-context.cjs.map +1 -1
  611. package/dist/react/package.json.cjs +1 -1
  612. package/dist/react/package.json.js +1 -1
  613. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +10 -10
  614. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  615. package/dist/runtime/auth-refusal-restart.cjs +7 -7
  616. package/dist/runtime/auth-refusal-restart.cjs.map +1 -1
  617. package/dist/runtime/auth.cjs +13 -13
  618. package/dist/runtime/auth.cjs.map +1 -1
  619. package/dist/runtime/statewire-lifecycle.cjs +1 -0
  620. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  621. package/dist/runtime/statewire-lifecycle.d.ts +3 -1
  622. package/dist/runtime/statewire-lifecycle.js +2 -1
  623. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  624. package/dist/runtime/statewire-server-lane-context.cjs +2 -2
  625. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
  626. package/dist/runtime/statewire-session-lane.cjs +4 -4
  627. package/dist/runtime/statewire-session-lane.cjs.map +1 -1
  628. package/dist/runtime/useAthenaStatewireRuntime.cjs +10 -8
  629. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  630. package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
  631. package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
  632. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  633. package/dist/styles.css +1 -1
  634. package/dist/threads/Inbox.cjs +8 -8
  635. package/dist/threads/Inbox.cjs.map +1 -1
  636. package/dist/threads/SessionList.cjs +9 -9
  637. package/dist/threads/SessionList.cjs.map +1 -1
  638. package/dist/threads/SessionsPage.cjs +11 -11
  639. package/dist/threads/SessionsPage.cjs.map +1 -1
  640. package/dist/threads/api.cjs.map +1 -1
  641. package/dist/threads/api.d.ts +15 -0
  642. package/dist/threads/api.js.map +1 -1
  643. package/dist/threads/conversation-list-fetcher.cjs +13 -5
  644. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  645. package/dist/threads/conversation-list-fetcher.d.ts +4 -1
  646. package/dist/threads/conversation-list-fetcher.js +13 -5
  647. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  648. package/dist/threads/index-triggered-refresh.cjs +10 -10
  649. package/dist/threads/index-triggered-refresh.cjs.map +1 -1
  650. package/dist/threads/mark-viewed-thread-read.cjs +12 -12
  651. package/dist/threads/mark-viewed-thread-read.cjs.map +1 -1
  652. package/dist/threads/offline-session-list.cjs +3 -3
  653. package/dist/threads/offline-session-list.cjs.map +1 -1
  654. package/dist/threads/session-list-tab-share.cjs +5 -5
  655. package/dist/threads/session-list-tab-share.cjs.map +1 -1
  656. package/dist/threads/statewire-thread-list.cjs +79 -57
  657. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  658. package/dist/threads/statewire-thread-list.d.ts +20 -8
  659. package/dist/threads/statewire-thread-list.js +28 -6
  660. package/dist/threads/statewire-thread-list.js.map +1 -1
  661. package/dist/threads/thread-id-context.cjs +5 -5
  662. package/dist/threads/thread-id-context.cjs.map +1 -1
  663. package/dist/threads/use-athena-session-attention.cjs +2 -2
  664. package/dist/threads/use-athena-session-attention.cjs.map +1 -1
  665. package/dist/threads/use-athena-sessions.cjs +37 -15
  666. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  667. package/dist/threads/use-athena-sessions.d.ts +10 -5
  668. package/dist/threads/use-athena-sessions.js +28 -6
  669. package/dist/threads/use-athena-sessions.js.map +1 -1
  670. package/dist/threads/use-athena-thread-model.cjs +3 -3
  671. package/dist/threads/use-athena-thread-model.cjs.map +1 -1
  672. package/dist/threads/use-rest-conversation-history.cjs +3 -3
  673. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  674. package/dist/threads/use-rest-conversation-history.d.ts +1 -0
  675. package/dist/threads/use-statewire-conversation-history.cjs +8 -8
  676. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  677. package/dist/threads/use-thread-archive.cjs +9 -9
  678. package/dist/threads/use-thread-archive.cjs.map +1 -1
  679. package/dist/threads/use-thread-favorite.cjs +2 -2
  680. package/dist/threads/use-thread-favorite.cjs.map +1 -1
  681. package/dist/threads/use-thread-field-override.cjs +20 -20
  682. package/dist/threads/use-thread-field-override.cjs.map +1 -1
  683. package/dist/threads/use-thread-read-state.cjs +4 -4
  684. package/dist/threads/use-thread-read-state.cjs.map +1 -1
  685. package/dist/threads/use-thread-rename.cjs +2 -2
  686. package/dist/threads/use-thread-rename.cjs.map +1 -1
  687. package/dist/threads/useAthenaThreadManager.cjs +2 -2
  688. package/dist/threads/useAthenaThreadManager.cjs.map +1 -1
  689. package/dist/tools/NestedPtcMessages.cjs +6 -6
  690. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  691. package/dist/tools/append-document-tool-ui.cjs +7 -7
  692. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  693. package/dist/tools/file-tool-uis.cjs +2 -2
  694. package/dist/tools/file-tool-uis.cjs.map +1 -1
  695. package/dist/tools/misc-tool-uis.cjs +2 -2
  696. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  697. package/dist/tools/primitives.cjs +6 -6
  698. package/dist/tools/primitives.cjs.map +1 -1
  699. package/dist/tools/read-asset-tool-ui.cjs +6 -6
  700. package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
  701. package/dist/tools/subagent-task-tool-ui.cjs +21 -21
  702. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  703. package/dist/tools/test-recording-tool-uis.cjs +16 -16
  704. package/dist/tools/test-recording-tool-uis.cjs.map +1 -1
  705. package/dist/tools/todo-plan-store.cjs +4 -4
  706. package/dist/tools/todo-plan-store.cjs.map +1 -1
  707. package/dist/tools/tool-appearance.cjs +3 -3
  708. package/dist/tools/tool-appearance.cjs.map +1 -1
  709. package/dist/tools/tool-fallback.cjs +14 -14
  710. package/dist/tools/tool-fallback.cjs.map +1 -1
  711. package/dist/tools/tool-uis.cjs +74 -74
  712. package/dist/tools/tool-uis.cjs.map +1 -1
  713. package/dist/tools/use-elapsed-seconds.cjs +3 -3
  714. package/dist/tools/use-elapsed-seconds.cjs.map +1 -1
  715. package/dist/tools/write-todos-tool-ui.cjs +9 -9
  716. package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
  717. package/dist/ui/image-viewer.cjs +382 -0
  718. package/dist/ui/image-viewer.cjs.map +1 -0
  719. package/dist/ui/image-viewer.d.ts +50 -0
  720. package/dist/ui/image-viewer.js +382 -0
  721. package/dist/ui/image-viewer.js.map +1 -0
  722. package/dist/voice/chat.cjs +6 -0
  723. package/dist/voice/chat.cjs.map +1 -1
  724. package/dist/voice/chat.d.ts +1 -1
  725. package/dist/voice/chat.js +8 -2
  726. package/dist/voice/livekit-join.cjs +52 -101
  727. package/dist/voice/livekit-join.cjs.map +1 -1
  728. package/dist/voice/livekit-join.d.ts +1 -6
  729. package/dist/voice/livekit-join.js +52 -101
  730. package/dist/voice/livekit-join.js.map +1 -1
  731. package/dist/voice/livekit.cjs.map +1 -1
  732. package/dist/voice/livekit.d.ts +11 -1
  733. package/dist/voice/livekit.js.map +1 -1
  734. package/dist/voice/use-athena-voice-session.cjs +34 -34
  735. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  736. package/dist/workbench/ComputerLiveDesktop.cjs +13 -13
  737. package/dist/workbench/ComputerLiveDesktop.cjs.map +1 -1
  738. package/dist/workbench/SessionWorkbench.cjs +22 -22
  739. package/dist/workbench/SessionWorkbench.cjs.map +1 -1
  740. package/dist/workbench/session-workbench-context.cjs +3 -3
  741. package/dist/workbench/session-workbench-context.cjs.map +1 -1
  742. package/dist/workbench/session-workbench-panes.cjs +8 -8
  743. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  744. package/dist/workbench/workbench-layout-context.cjs +3 -3
  745. package/dist/workbench/workbench-layout-context.cjs.map +1 -1
  746. package/package.json +2 -1
@@ -1 +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 {\n Fragment,\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { useAthenaLinkClickHandler } from \"../../chat/athena-citation-links\";\nimport { type OpenFence, splitChatBlocks } from \"./chat-blocks\";\nimport { ChatLink } from \"./chat-link\";\nimport {\n ChatCodeBlock,\n ChatMention,\n StreamingCodeBlock,\n} from \"./chat-node-views\";\nimport {\n CHAT_TEXT_CLASS,\n parseChatText,\n parseTypedChatText,\n} from \"./chat-text-schema\";\nimport { renderDOMOutputSpec } from \"./dom-output-spec\";\n\nconst subscribe = () => () => {};\nconst browserSnapshot = () => true;\nconst serverSnapshot = () => false;\n\n/**\n * Render the composer's document schema through its own node/mark serializers.\n *\n * The text is split into its top-level blocks (`splitChatBlocks`), each parsed\n * and drawn by its own memoized component under one `CHAT_TEXT_CLASS`\n * wrapper. While a reply streams, only the trailing block re-parses with each\n * token; every finished block keeps its parse and its DOM. The trailing block\n * reveals its newest words with a settle tint and a caret, and a fenced code\n * block still being written renders as plain code until its fence closes.\n *\n * `typed` reads the text as a person typed it (`parseTypedChatText`: raw HTML\n * and underscore emphasis stay the characters they were typed with), for the\n * user bubble; assistant text keeps the full reading.\n */\nexport function ChatMessageBody({\n text,\n isRunning = false,\n typed = false,\n}: {\n text: string;\n isRunning?: boolean;\n typed?: boolean;\n}) {\n const hasDom = useSyncExternalStore(\n subscribe,\n browserSnapshot,\n serverSnapshot,\n );\n const onClick = useChatLinkClick();\n const { blocks, definitions } = useMemo(\n () => splitChatBlocks(text, { streaming: isRunning }),\n [text, isRunning],\n );\n return (\n // The click handler only delegates for the anchors inside, which are\n // themselves focusable and keyboard-operable; the wrapper is not a control.\n <div\n className={CHAT_TEXT_CLASS}\n data-chat-text=\"\"\n data-status={isRunning ? \"running\" : \"complete\"}\n onClick={onClick}\n >\n {hasDom\n ? blocks.map((block, index) => (\n <ChatBlock\n key={index}\n text={block.text}\n definitions={definitions}\n openFence={block.openFence}\n streaming={isRunning && index === blocks.length - 1}\n typed={typed}\n />\n ))\n : text}\n </div>\n );\n}\n\n/**\n * One top-level block. Memoized on its inputs: a finished block's `text` never\n * changes again, so React skips it on every token that lands in the block\n * after it. Only the trailing block carries `streaming` (and, while its code\n * fence is open, `openFence`).\n */\nconst ChatBlock = memo(function ChatBlock({\n text,\n definitions,\n openFence,\n streaming,\n typed,\n}: {\n text: string;\n definitions: string;\n openFence: OpenFence | null;\n streaming: boolean;\n typed: boolean;\n}) {\n // A fence is only \"open\" while the part streams. A message that ended\n // mid-fence parses as the code block it is (markdown-it closes it at the\n // end), copy action and all, with no caret.\n const open = streaming ? openFence : null;\n const doc = useMemo(() => {\n if (open) return null;\n const markdown = definitions ? `${text}\\n\\n${definitions}` : text;\n return typed ? parseTypedChatText(markdown) : parseChatText(markdown);\n }, [text, definitions, open, typed]);\n if (open) {\n return (\n <StreamingCodeBlock\n language={open.language}\n code={open.code}\n caret={<StreamingCaret />}\n />\n );\n }\n // A block of nothing but reference definitions parses to one empty\n // paragraph (the schema's default content); draw nothing for it.\n if (!doc || isEmptyDoc(doc)) return null;\n return <>{renderContent(doc, streaming ? findStreamingTail(doc) : null)}</>;\n});\n\nfunction isEmptyDoc(doc: ProseMirrorNode): boolean {\n if (doc.childCount === 0) return true;\n const only = doc.firstChild;\n return doc.childCount === 1 && only !== null && only.isTextblock && only.content.size === 0;\n}\n\n/**\n * One delegated click handler per body: a click on any rendered anchor —\n * source chip, asset chip, plain link — goes through the SDK's link-click\n * path (`linkClicks` on the provider, then the asset panel for an Athena\n * citation) and is cancelled when that path handled it; otherwise the\n * anchor's own `target=\"_blank\"` navigation runs. Only the native `click`\n * can be cancelled — a `mouseup` handler cannot stop the navigation. A\n * modified click (Cmd/Ctrl for a new tab, Shift for a new window, Alt for a\n * download) is the browser's and is never intercepted.\n */\nfunction useChatLinkClick() {\n const handleLinkClick = useAthenaLinkClickHandler();\n return useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (\n event.button !== 0 ||\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n const target = event.target;\n const element =\n target instanceof Element\n ? target\n : target instanceof Node\n ? target.parentElement\n : null;\n const anchor = element?.closest(\"a[href]\");\n if (\n !(anchor instanceof HTMLAnchorElement) ||\n !event.currentTarget.contains(anchor)\n ) {\n return;\n }\n const handled = handleLinkClick({\n href: anchor.getAttribute(\"href\") ?? anchor.href,\n // A citation chip's text ends with its place (`p.10`); the asset is named without it.\n linkText: anchor.getAttribute(\"data-mention-name\") ?? anchor.textContent,\n target: anchor.target,\n nativeEvent: event.nativeEvent,\n });\n if (handled) event.preventDefault();\n },\n [handleLinkClick],\n );\n}\n\n/** Where the block still being written ends: its last text block, and that block's last text node (none inside code). */\ninterface StreamingTail {\n textblock: ProseMirrorNode | null;\n text: ProseMirrorNode | null;\n}\n\nfunction findStreamingTail(doc: ProseMirrorNode): StreamingTail {\n const tail: StreamingTail = { textblock: null, text: null };\n doc.descendants((node) => {\n if (node.isTextblock) {\n tail.textblock = node;\n tail.text = null;\n } else if (\n node.isText &&\n tail.textblock &&\n tail.textblock.type.name !== \"codeBlock\"\n ) {\n tail.text = node;\n }\n return true;\n });\n return tail;\n}\n\n/** How many trailing words keep their own span, so a word's settle animation outlives the tokens after it. */\nconst FRESH_WORD_WINDOW = 6;\nconst WORD = /\\s*\\S+/g;\n\n/**\n * The newest words of the streaming block, each in a span keyed by its\n * position so the same element persists while the word grows and the words\n * after it arrive; a span mounts tinted and settles to ink through\n * `animate-chat-word-settle`. Words that leave the window render as text.\n */\nfunction renderFreshWords(text: string): ReactNode {\n const words = [...text.matchAll(WORD)];\n if (words.length === 0) return text;\n const from = Math.max(0, words.length - FRESH_WORD_WINDOW);\n const first = words[from]!;\n const last = words[words.length - 1]!;\n return (\n <>\n {text.slice(0, first.index)}\n {words.slice(from).map((word, offset) => (\n <span\n key={from + offset}\n className=\"animate-chat-word-settle motion-reduce:animate-none\"\n data-chat-fresh=\"\"\n >\n {word[0]}\n </span>\n ))}\n {text.slice(last.index + last[0].length)}\n </>\n );\n}\n\n/** A thin blinking caret after the newest text while the part streams; no layout of its own beyond a hairline. */\nfunction StreamingCaret() {\n return (\n <span\n aria-hidden=\"true\"\n data-chat-caret=\"\"\n className=\"ml-0.5 inline-block h-[1em] w-0.5 rounded-full bg-primary align-[-0.125em] animate-chat-caret-blink motion-reduce:animate-none\"\n />\n );\n}\n\nfunction renderNode(\n node: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode {\n if (node.isText) {\n return tail?.text === node ? renderFreshWords(node.text ?? \"\") : node.text;\n }\n if (node.type.name === \"mention\") return <ChatMention node={node} />;\n if (node.type.name === \"codeBlock\") {\n return (\n <ChatCodeBlock node={node}>\n <code>\n {node.textContent}\n {tail?.textblock === node ? <StreamingCaret /> : null}\n </code>\n </ChatCodeBlock>\n );\n }\n const toDOM = node.type.spec.toDOM;\n if (!toDOM) return null;\n if (node.isLeaf) return renderDOMOutputSpec(toDOM(node), null);\n const content = renderContent(node, tail);\n if (tail?.textblock === node) content.push(<StreamingCaret key=\"caret\" />);\n return renderDOMOutputSpec(toDOM(node), content);\n}\n\nfunction renderContent(\n parent: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode[] {\n const nodes: ProseMirrorNode[] = [];\n parent.forEach((node) => {\n nodes.push(node);\n });\n return renderMarkRuns(nodes, 0, tail);\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 tail: StreamingTail | null,\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, tail)}</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, tail);\n const rendered =\n mark.type.name === \"link\" ? (\n <ChatLink href={mark.attrs.href} excerpt={mark.attrs.excerpt}>\n {content}\n </ChatLink>\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","splitChatBlocks","jsx","CHAT_TEXT_CLASS","memo","ChatBlock","parseTypedChatText","parseChatText","StreamingCodeBlock","Fragment","useAthenaLinkClickHandler","useCallback","jsxs","ChatMention","ChatCodeBlock","renderDOMOutputSpec","ChatLink"],"mappings":"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"}
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 {\n Fragment,\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { useAthenaLinkClickHandler } from \"../../chat/athena-citation-links\";\nimport { type OpenFence, splitChatBlocks } from \"./chat-blocks\";\nimport { ChatLink } from \"./chat-link\";\nimport {\n ChatCodeBlock,\n ChatMention,\n StreamingCodeBlock,\n} from \"./chat-node-views\";\nimport {\n CHAT_TEXT_CLASS,\n parseChatText,\n parseTypedChatText,\n} from \"./chat-text-schema\";\nimport { renderDOMOutputSpec } from \"./dom-output-spec\";\n\nconst subscribe = () => () => {};\nconst browserSnapshot = () => true;\nconst serverSnapshot = () => false;\n\n/**\n * Render the composer's document schema through its own node/mark serializers.\n *\n * The text is split into its top-level blocks (`splitChatBlocks`), each parsed\n * and drawn by its own memoized component under one `CHAT_TEXT_CLASS`\n * wrapper. While a reply streams, only the trailing block re-parses with each\n * token; every finished block keeps its parse and its DOM. The trailing block\n * reveals its newest words with a settle tint and a caret, and a fenced code\n * block still being written renders as plain code until its fence closes.\n *\n * `typed` reads the text as a person typed it (`parseTypedChatText`: raw HTML\n * and underscore emphasis stay the characters they were typed with), for the\n * user bubble; assistant text keeps the full reading.\n */\nexport function ChatMessageBody({\n text,\n isRunning = false,\n typed = false,\n}: {\n text: string;\n isRunning?: boolean;\n typed?: boolean;\n}) {\n const hasDom = useSyncExternalStore(\n subscribe,\n browserSnapshot,\n serverSnapshot,\n );\n const onClick = useChatLinkClick();\n const { blocks, definitions } = useMemo(\n () => splitChatBlocks(text, { streaming: isRunning }),\n [text, isRunning],\n );\n return (\n // The click handler only delegates for the anchors inside, which are\n // themselves focusable and keyboard-operable; the wrapper is not a control.\n <div\n className={CHAT_TEXT_CLASS}\n data-chat-text=\"\"\n data-status={isRunning ? \"running\" : \"complete\"}\n onClick={onClick}\n >\n {hasDom\n ? blocks.map((block, index) => (\n <ChatBlock\n key={index}\n text={block.text}\n definitions={definitions}\n openFence={block.openFence}\n streaming={isRunning && index === blocks.length - 1}\n typed={typed}\n />\n ))\n : text}\n </div>\n );\n}\n\n/**\n * One top-level block. Memoized on its inputs: a finished block's `text` never\n * changes again, so React skips it on every token that lands in the block\n * after it. Only the trailing block carries `streaming` (and, while its code\n * fence is open, `openFence`).\n */\nconst ChatBlock = memo(function ChatBlock({\n text,\n definitions,\n openFence,\n streaming,\n typed,\n}: {\n text: string;\n definitions: string;\n openFence: OpenFence | null;\n streaming: boolean;\n typed: boolean;\n}) {\n // A fence is only \"open\" while the part streams. A message that ended\n // mid-fence parses as the code block it is (markdown-it closes it at the\n // end), copy action and all, with no caret.\n const open = streaming ? openFence : null;\n const doc = useMemo(() => {\n if (open) return null;\n const markdown = definitions ? `${text}\\n\\n${definitions}` : text;\n return typed ? parseTypedChatText(markdown) : parseChatText(markdown);\n }, [text, definitions, open, typed]);\n if (open) {\n return (\n <StreamingCodeBlock\n language={open.language}\n code={open.code}\n caret={<StreamingCaret />}\n />\n );\n }\n // A block of nothing but reference definitions parses to one empty\n // paragraph (the schema's default content); draw nothing for it.\n if (!doc || isEmptyDoc(doc)) return null;\n return <>{renderContent(doc, streaming ? findStreamingTail(doc) : null)}</>;\n});\n\nfunction isEmptyDoc(doc: ProseMirrorNode): boolean {\n if (doc.childCount === 0) return true;\n const only = doc.firstChild;\n return doc.childCount === 1 && only !== null && only.isTextblock && only.content.size === 0;\n}\n\n/**\n * One delegated click handler per body: a click on any rendered anchor —\n * source chip, asset chip, plain link — goes through the SDK's link-click\n * path (`linkClicks` on the provider, then the asset panel for an Athena\n * citation) and is cancelled when that path handled it; otherwise the\n * anchor's own `target=\"_blank\"` navigation runs. Only the native `click`\n * can be cancelled — a `mouseup` handler cannot stop the navigation. A\n * modified click (Cmd/Ctrl for a new tab, Shift for a new window, Alt for a\n * download) is the browser's and is never intercepted.\n */\nexport function useChatLinkClick() {\n const handleLinkClick = useAthenaLinkClickHandler();\n return useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (\n event.button !== 0 ||\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n const target = event.target;\n const element =\n target instanceof Element\n ? target\n : target instanceof Node\n ? target.parentElement\n : null;\n const anchor = element?.closest(\"a[href]\");\n if (\n !(anchor instanceof HTMLAnchorElement) ||\n !event.currentTarget.contains(anchor)\n ) {\n return;\n }\n const handled = handleLinkClick({\n href: anchor.getAttribute(\"href\") ?? anchor.href,\n // A citation chip's text ends with its place (`p.10`); the asset is named without it.\n linkText: anchor.getAttribute(\"data-mention-name\") ?? anchor.textContent,\n target: anchor.target,\n nativeEvent: event.nativeEvent,\n });\n if (handled) event.preventDefault();\n },\n [handleLinkClick],\n );\n}\n\n/** Where the block still being written ends: its last text block, and that block's last text node (none inside code). */\ninterface StreamingTail {\n textblock: ProseMirrorNode | null;\n text: ProseMirrorNode | null;\n}\n\nfunction findStreamingTail(doc: ProseMirrorNode): StreamingTail {\n const tail: StreamingTail = { textblock: null, text: null };\n doc.descendants((node) => {\n if (node.isTextblock) {\n tail.textblock = node;\n tail.text = null;\n } else if (\n node.isText &&\n tail.textblock &&\n tail.textblock.type.name !== \"codeBlock\"\n ) {\n tail.text = node;\n }\n return true;\n });\n return tail;\n}\n\n/** How many trailing words keep their own span, so a word's settle animation outlives the tokens after it. */\nconst FRESH_WORD_WINDOW = 6;\nconst WORD = /\\s*\\S+/g;\n\n/**\n * The newest words of the streaming block, each in a span keyed by its\n * position so the same element persists while the word grows and the words\n * after it arrive; a span mounts tinted and settles to ink through\n * `animate-chat-word-settle`. Words that leave the window render as text.\n */\nfunction renderFreshWords(text: string): ReactNode {\n const words = [...text.matchAll(WORD)];\n if (words.length === 0) return text;\n const from = Math.max(0, words.length - FRESH_WORD_WINDOW);\n const first = words[from]!;\n const last = words[words.length - 1]!;\n return (\n <>\n {text.slice(0, first.index)}\n {words.slice(from).map((word, offset) => (\n <span\n key={from + offset}\n className=\"animate-chat-word-settle motion-reduce:animate-none\"\n data-chat-fresh=\"\"\n >\n {word[0]}\n </span>\n ))}\n {text.slice(last.index + last[0].length)}\n </>\n );\n}\n\n/** A thin blinking caret after the newest text while the part streams; no layout of its own beyond a hairline. */\nfunction StreamingCaret() {\n return (\n <span\n aria-hidden=\"true\"\n data-chat-caret=\"\"\n className=\"ml-0.5 inline-block h-[1em] w-0.5 rounded-full bg-primary align-[-0.125em] animate-chat-caret-blink motion-reduce:animate-none\"\n />\n );\n}\n\nfunction renderNode(\n node: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode {\n if (node.isText) {\n return tail?.text === node ? renderFreshWords(node.text ?? \"\") : node.text;\n }\n if (node.type.name === \"mention\") return <ChatMention node={node} />;\n if (node.type.name === \"codeBlock\") {\n return (\n <ChatCodeBlock node={node}>\n <code>\n {node.textContent}\n {tail?.textblock === node ? <StreamingCaret /> : null}\n </code>\n </ChatCodeBlock>\n );\n }\n const toDOM = node.type.spec.toDOM;\n if (!toDOM) return null;\n if (node.isLeaf) return renderDOMOutputSpec(toDOM(node), null);\n const content = renderContent(node, tail);\n if (tail?.textblock === node) content.push(<StreamingCaret key=\"caret\" />);\n return renderDOMOutputSpec(toDOM(node), content);\n}\n\nfunction renderContent(\n parent: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode[] {\n const nodes: ProseMirrorNode[] = [];\n parent.forEach((node) => {\n nodes.push(node);\n });\n return renderMarkRuns(nodes, 0, tail);\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 tail: StreamingTail | null,\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, tail)}</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, tail);\n const rendered =\n mark.type.name === \"link\" ? (\n <ChatLink href={mark.attrs.href} excerpt={mark.attrs.excerpt}>\n {content}\n </ChatLink>\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","splitChatBlocks","jsx","CHAT_TEXT_CLASS","memo","ChatBlock","parseTypedChatText","parseChatText","StreamingCodeBlock","Fragment","useAthenaLinkClickHandler","useCallback","jsxs","ChatMention","ChatCodeBlock","renderDOMOutputSpec","ChatLink"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type MouseEvent } from "react";
1
2
  /**
2
3
  * Render the composer's document schema through its own node/mark serializers.
3
4
  *
@@ -17,3 +18,14 @@ export declare function ChatMessageBody({ text, isRunning, typed, }: {
17
18
  isRunning?: boolean;
18
19
  typed?: boolean;
19
20
  }): import("react").JSX.Element;
21
+ /**
22
+ * One delegated click handler per body: a click on any rendered anchor —
23
+ * source chip, asset chip, plain link — goes through the SDK's link-click
24
+ * path (`linkClicks` on the provider, then the asset panel for an Athena
25
+ * citation) and is cancelled when that path handled it; otherwise the
26
+ * anchor's own `target="_blank"` navigation runs. Only the native `click`
27
+ * can be cancelled — a `mouseup` handler cannot stop the navigation. A
28
+ * modified click (Cmd/Ctrl for a new tab, Shift for a new window, Alt for a
29
+ * download) is the browser's and is never intercepted.
30
+ */
31
+ export declare function useChatLinkClick(): (event: MouseEvent<HTMLDivElement>) => void;
@@ -202,6 +202,7 @@ function renderMarkRuns(nodes, depth, tail) {
202
202
  return children;
203
203
  }
204
204
  export {
205
- ChatMessageBody
205
+ ChatMessageBody,
206
+ useChatLinkClick
206
207
  };
207
208
  //# sourceMappingURL=chat-message-body.js.map
@@ -1 +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 {\n Fragment,\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { useAthenaLinkClickHandler } from \"../../chat/athena-citation-links\";\nimport { type OpenFence, splitChatBlocks } from \"./chat-blocks\";\nimport { ChatLink } from \"./chat-link\";\nimport {\n ChatCodeBlock,\n ChatMention,\n StreamingCodeBlock,\n} from \"./chat-node-views\";\nimport {\n CHAT_TEXT_CLASS,\n parseChatText,\n parseTypedChatText,\n} from \"./chat-text-schema\";\nimport { renderDOMOutputSpec } from \"./dom-output-spec\";\n\nconst subscribe = () => () => {};\nconst browserSnapshot = () => true;\nconst serverSnapshot = () => false;\n\n/**\n * Render the composer's document schema through its own node/mark serializers.\n *\n * The text is split into its top-level blocks (`splitChatBlocks`), each parsed\n * and drawn by its own memoized component under one `CHAT_TEXT_CLASS`\n * wrapper. While a reply streams, only the trailing block re-parses with each\n * token; every finished block keeps its parse and its DOM. The trailing block\n * reveals its newest words with a settle tint and a caret, and a fenced code\n * block still being written renders as plain code until its fence closes.\n *\n * `typed` reads the text as a person typed it (`parseTypedChatText`: raw HTML\n * and underscore emphasis stay the characters they were typed with), for the\n * user bubble; assistant text keeps the full reading.\n */\nexport function ChatMessageBody({\n text,\n isRunning = false,\n typed = false,\n}: {\n text: string;\n isRunning?: boolean;\n typed?: boolean;\n}) {\n const hasDom = useSyncExternalStore(\n subscribe,\n browserSnapshot,\n serverSnapshot,\n );\n const onClick = useChatLinkClick();\n const { blocks, definitions } = useMemo(\n () => splitChatBlocks(text, { streaming: isRunning }),\n [text, isRunning],\n );\n return (\n // The click handler only delegates for the anchors inside, which are\n // themselves focusable and keyboard-operable; the wrapper is not a control.\n <div\n className={CHAT_TEXT_CLASS}\n data-chat-text=\"\"\n data-status={isRunning ? \"running\" : \"complete\"}\n onClick={onClick}\n >\n {hasDom\n ? blocks.map((block, index) => (\n <ChatBlock\n key={index}\n text={block.text}\n definitions={definitions}\n openFence={block.openFence}\n streaming={isRunning && index === blocks.length - 1}\n typed={typed}\n />\n ))\n : text}\n </div>\n );\n}\n\n/**\n * One top-level block. Memoized on its inputs: a finished block's `text` never\n * changes again, so React skips it on every token that lands in the block\n * after it. Only the trailing block carries `streaming` (and, while its code\n * fence is open, `openFence`).\n */\nconst ChatBlock = memo(function ChatBlock({\n text,\n definitions,\n openFence,\n streaming,\n typed,\n}: {\n text: string;\n definitions: string;\n openFence: OpenFence | null;\n streaming: boolean;\n typed: boolean;\n}) {\n // A fence is only \"open\" while the part streams. A message that ended\n // mid-fence parses as the code block it is (markdown-it closes it at the\n // end), copy action and all, with no caret.\n const open = streaming ? openFence : null;\n const doc = useMemo(() => {\n if (open) return null;\n const markdown = definitions ? `${text}\\n\\n${definitions}` : text;\n return typed ? parseTypedChatText(markdown) : parseChatText(markdown);\n }, [text, definitions, open, typed]);\n if (open) {\n return (\n <StreamingCodeBlock\n language={open.language}\n code={open.code}\n caret={<StreamingCaret />}\n />\n );\n }\n // A block of nothing but reference definitions parses to one empty\n // paragraph (the schema's default content); draw nothing for it.\n if (!doc || isEmptyDoc(doc)) return null;\n return <>{renderContent(doc, streaming ? findStreamingTail(doc) : null)}</>;\n});\n\nfunction isEmptyDoc(doc: ProseMirrorNode): boolean {\n if (doc.childCount === 0) return true;\n const only = doc.firstChild;\n return doc.childCount === 1 && only !== null && only.isTextblock && only.content.size === 0;\n}\n\n/**\n * One delegated click handler per body: a click on any rendered anchor —\n * source chip, asset chip, plain link — goes through the SDK's link-click\n * path (`linkClicks` on the provider, then the asset panel for an Athena\n * citation) and is cancelled when that path handled it; otherwise the\n * anchor's own `target=\"_blank\"` navigation runs. Only the native `click`\n * can be cancelled — a `mouseup` handler cannot stop the navigation. A\n * modified click (Cmd/Ctrl for a new tab, Shift for a new window, Alt for a\n * download) is the browser's and is never intercepted.\n */\nfunction useChatLinkClick() {\n const handleLinkClick = useAthenaLinkClickHandler();\n return useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (\n event.button !== 0 ||\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n const target = event.target;\n const element =\n target instanceof Element\n ? target\n : target instanceof Node\n ? target.parentElement\n : null;\n const anchor = element?.closest(\"a[href]\");\n if (\n !(anchor instanceof HTMLAnchorElement) ||\n !event.currentTarget.contains(anchor)\n ) {\n return;\n }\n const handled = handleLinkClick({\n href: anchor.getAttribute(\"href\") ?? anchor.href,\n // A citation chip's text ends with its place (`p.10`); the asset is named without it.\n linkText: anchor.getAttribute(\"data-mention-name\") ?? anchor.textContent,\n target: anchor.target,\n nativeEvent: event.nativeEvent,\n });\n if (handled) event.preventDefault();\n },\n [handleLinkClick],\n );\n}\n\n/** Where the block still being written ends: its last text block, and that block's last text node (none inside code). */\ninterface StreamingTail {\n textblock: ProseMirrorNode | null;\n text: ProseMirrorNode | null;\n}\n\nfunction findStreamingTail(doc: ProseMirrorNode): StreamingTail {\n const tail: StreamingTail = { textblock: null, text: null };\n doc.descendants((node) => {\n if (node.isTextblock) {\n tail.textblock = node;\n tail.text = null;\n } else if (\n node.isText &&\n tail.textblock &&\n tail.textblock.type.name !== \"codeBlock\"\n ) {\n tail.text = node;\n }\n return true;\n });\n return tail;\n}\n\n/** How many trailing words keep their own span, so a word's settle animation outlives the tokens after it. */\nconst FRESH_WORD_WINDOW = 6;\nconst WORD = /\\s*\\S+/g;\n\n/**\n * The newest words of the streaming block, each in a span keyed by its\n * position so the same element persists while the word grows and the words\n * after it arrive; a span mounts tinted and settles to ink through\n * `animate-chat-word-settle`. Words that leave the window render as text.\n */\nfunction renderFreshWords(text: string): ReactNode {\n const words = [...text.matchAll(WORD)];\n if (words.length === 0) return text;\n const from = Math.max(0, words.length - FRESH_WORD_WINDOW);\n const first = words[from]!;\n const last = words[words.length - 1]!;\n return (\n <>\n {text.slice(0, first.index)}\n {words.slice(from).map((word, offset) => (\n <span\n key={from + offset}\n className=\"animate-chat-word-settle motion-reduce:animate-none\"\n data-chat-fresh=\"\"\n >\n {word[0]}\n </span>\n ))}\n {text.slice(last.index + last[0].length)}\n </>\n );\n}\n\n/** A thin blinking caret after the newest text while the part streams; no layout of its own beyond a hairline. */\nfunction StreamingCaret() {\n return (\n <span\n aria-hidden=\"true\"\n data-chat-caret=\"\"\n className=\"ml-0.5 inline-block h-[1em] w-0.5 rounded-full bg-primary align-[-0.125em] animate-chat-caret-blink motion-reduce:animate-none\"\n />\n );\n}\n\nfunction renderNode(\n node: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode {\n if (node.isText) {\n return tail?.text === node ? renderFreshWords(node.text ?? \"\") : node.text;\n }\n if (node.type.name === \"mention\") return <ChatMention node={node} />;\n if (node.type.name === \"codeBlock\") {\n return (\n <ChatCodeBlock node={node}>\n <code>\n {node.textContent}\n {tail?.textblock === node ? <StreamingCaret /> : null}\n </code>\n </ChatCodeBlock>\n );\n }\n const toDOM = node.type.spec.toDOM;\n if (!toDOM) return null;\n if (node.isLeaf) return renderDOMOutputSpec(toDOM(node), null);\n const content = renderContent(node, tail);\n if (tail?.textblock === node) content.push(<StreamingCaret key=\"caret\" />);\n return renderDOMOutputSpec(toDOM(node), content);\n}\n\nfunction renderContent(\n parent: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode[] {\n const nodes: ProseMirrorNode[] = [];\n parent.forEach((node) => {\n nodes.push(node);\n });\n return renderMarkRuns(nodes, 0, tail);\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 tail: StreamingTail | null,\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, tail)}</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, tail);\n const rendered =\n mark.type.name === \"link\" ? (\n <ChatLink href={mark.attrs.href} excerpt={mark.attrs.excerpt}>\n {content}\n </ChatLink>\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":["ChatBlock","Fragment"],"mappings":"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"}
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 {\n Fragment,\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { useAthenaLinkClickHandler } from \"../../chat/athena-citation-links\";\nimport { type OpenFence, splitChatBlocks } from \"./chat-blocks\";\nimport { ChatLink } from \"./chat-link\";\nimport {\n ChatCodeBlock,\n ChatMention,\n StreamingCodeBlock,\n} from \"./chat-node-views\";\nimport {\n CHAT_TEXT_CLASS,\n parseChatText,\n parseTypedChatText,\n} from \"./chat-text-schema\";\nimport { renderDOMOutputSpec } from \"./dom-output-spec\";\n\nconst subscribe = () => () => {};\nconst browserSnapshot = () => true;\nconst serverSnapshot = () => false;\n\n/**\n * Render the composer's document schema through its own node/mark serializers.\n *\n * The text is split into its top-level blocks (`splitChatBlocks`), each parsed\n * and drawn by its own memoized component under one `CHAT_TEXT_CLASS`\n * wrapper. While a reply streams, only the trailing block re-parses with each\n * token; every finished block keeps its parse and its DOM. The trailing block\n * reveals its newest words with a settle tint and a caret, and a fenced code\n * block still being written renders as plain code until its fence closes.\n *\n * `typed` reads the text as a person typed it (`parseTypedChatText`: raw HTML\n * and underscore emphasis stay the characters they were typed with), for the\n * user bubble; assistant text keeps the full reading.\n */\nexport function ChatMessageBody({\n text,\n isRunning = false,\n typed = false,\n}: {\n text: string;\n isRunning?: boolean;\n typed?: boolean;\n}) {\n const hasDom = useSyncExternalStore(\n subscribe,\n browserSnapshot,\n serverSnapshot,\n );\n const onClick = useChatLinkClick();\n const { blocks, definitions } = useMemo(\n () => splitChatBlocks(text, { streaming: isRunning }),\n [text, isRunning],\n );\n return (\n // The click handler only delegates for the anchors inside, which are\n // themselves focusable and keyboard-operable; the wrapper is not a control.\n <div\n className={CHAT_TEXT_CLASS}\n data-chat-text=\"\"\n data-status={isRunning ? \"running\" : \"complete\"}\n onClick={onClick}\n >\n {hasDom\n ? blocks.map((block, index) => (\n <ChatBlock\n key={index}\n text={block.text}\n definitions={definitions}\n openFence={block.openFence}\n streaming={isRunning && index === blocks.length - 1}\n typed={typed}\n />\n ))\n : text}\n </div>\n );\n}\n\n/**\n * One top-level block. Memoized on its inputs: a finished block's `text` never\n * changes again, so React skips it on every token that lands in the block\n * after it. Only the trailing block carries `streaming` (and, while its code\n * fence is open, `openFence`).\n */\nconst ChatBlock = memo(function ChatBlock({\n text,\n definitions,\n openFence,\n streaming,\n typed,\n}: {\n text: string;\n definitions: string;\n openFence: OpenFence | null;\n streaming: boolean;\n typed: boolean;\n}) {\n // A fence is only \"open\" while the part streams. A message that ended\n // mid-fence parses as the code block it is (markdown-it closes it at the\n // end), copy action and all, with no caret.\n const open = streaming ? openFence : null;\n const doc = useMemo(() => {\n if (open) return null;\n const markdown = definitions ? `${text}\\n\\n${definitions}` : text;\n return typed ? parseTypedChatText(markdown) : parseChatText(markdown);\n }, [text, definitions, open, typed]);\n if (open) {\n return (\n <StreamingCodeBlock\n language={open.language}\n code={open.code}\n caret={<StreamingCaret />}\n />\n );\n }\n // A block of nothing but reference definitions parses to one empty\n // paragraph (the schema's default content); draw nothing for it.\n if (!doc || isEmptyDoc(doc)) return null;\n return <>{renderContent(doc, streaming ? findStreamingTail(doc) : null)}</>;\n});\n\nfunction isEmptyDoc(doc: ProseMirrorNode): boolean {\n if (doc.childCount === 0) return true;\n const only = doc.firstChild;\n return doc.childCount === 1 && only !== null && only.isTextblock && only.content.size === 0;\n}\n\n/**\n * One delegated click handler per body: a click on any rendered anchor —\n * source chip, asset chip, plain link — goes through the SDK's link-click\n * path (`linkClicks` on the provider, then the asset panel for an Athena\n * citation) and is cancelled when that path handled it; otherwise the\n * anchor's own `target=\"_blank\"` navigation runs. Only the native `click`\n * can be cancelled — a `mouseup` handler cannot stop the navigation. A\n * modified click (Cmd/Ctrl for a new tab, Shift for a new window, Alt for a\n * download) is the browser's and is never intercepted.\n */\nexport function useChatLinkClick() {\n const handleLinkClick = useAthenaLinkClickHandler();\n return useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (\n event.button !== 0 ||\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n const target = event.target;\n const element =\n target instanceof Element\n ? target\n : target instanceof Node\n ? target.parentElement\n : null;\n const anchor = element?.closest(\"a[href]\");\n if (\n !(anchor instanceof HTMLAnchorElement) ||\n !event.currentTarget.contains(anchor)\n ) {\n return;\n }\n const handled = handleLinkClick({\n href: anchor.getAttribute(\"href\") ?? anchor.href,\n // A citation chip's text ends with its place (`p.10`); the asset is named without it.\n linkText: anchor.getAttribute(\"data-mention-name\") ?? anchor.textContent,\n target: anchor.target,\n nativeEvent: event.nativeEvent,\n });\n if (handled) event.preventDefault();\n },\n [handleLinkClick],\n );\n}\n\n/** Where the block still being written ends: its last text block, and that block's last text node (none inside code). */\ninterface StreamingTail {\n textblock: ProseMirrorNode | null;\n text: ProseMirrorNode | null;\n}\n\nfunction findStreamingTail(doc: ProseMirrorNode): StreamingTail {\n const tail: StreamingTail = { textblock: null, text: null };\n doc.descendants((node) => {\n if (node.isTextblock) {\n tail.textblock = node;\n tail.text = null;\n } else if (\n node.isText &&\n tail.textblock &&\n tail.textblock.type.name !== \"codeBlock\"\n ) {\n tail.text = node;\n }\n return true;\n });\n return tail;\n}\n\n/** How many trailing words keep their own span, so a word's settle animation outlives the tokens after it. */\nconst FRESH_WORD_WINDOW = 6;\nconst WORD = /\\s*\\S+/g;\n\n/**\n * The newest words of the streaming block, each in a span keyed by its\n * position so the same element persists while the word grows and the words\n * after it arrive; a span mounts tinted and settles to ink through\n * `animate-chat-word-settle`. Words that leave the window render as text.\n */\nfunction renderFreshWords(text: string): ReactNode {\n const words = [...text.matchAll(WORD)];\n if (words.length === 0) return text;\n const from = Math.max(0, words.length - FRESH_WORD_WINDOW);\n const first = words[from]!;\n const last = words[words.length - 1]!;\n return (\n <>\n {text.slice(0, first.index)}\n {words.slice(from).map((word, offset) => (\n <span\n key={from + offset}\n className=\"animate-chat-word-settle motion-reduce:animate-none\"\n data-chat-fresh=\"\"\n >\n {word[0]}\n </span>\n ))}\n {text.slice(last.index + last[0].length)}\n </>\n );\n}\n\n/** A thin blinking caret after the newest text while the part streams; no layout of its own beyond a hairline. */\nfunction StreamingCaret() {\n return (\n <span\n aria-hidden=\"true\"\n data-chat-caret=\"\"\n className=\"ml-0.5 inline-block h-[1em] w-0.5 rounded-full bg-primary align-[-0.125em] animate-chat-caret-blink motion-reduce:animate-none\"\n />\n );\n}\n\nfunction renderNode(\n node: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode {\n if (node.isText) {\n return tail?.text === node ? renderFreshWords(node.text ?? \"\") : node.text;\n }\n if (node.type.name === \"mention\") return <ChatMention node={node} />;\n if (node.type.name === \"codeBlock\") {\n return (\n <ChatCodeBlock node={node}>\n <code>\n {node.textContent}\n {tail?.textblock === node ? <StreamingCaret /> : null}\n </code>\n </ChatCodeBlock>\n );\n }\n const toDOM = node.type.spec.toDOM;\n if (!toDOM) return null;\n if (node.isLeaf) return renderDOMOutputSpec(toDOM(node), null);\n const content = renderContent(node, tail);\n if (tail?.textblock === node) content.push(<StreamingCaret key=\"caret\" />);\n return renderDOMOutputSpec(toDOM(node), content);\n}\n\nfunction renderContent(\n parent: ProseMirrorNode,\n tail: StreamingTail | null,\n): ReactNode[] {\n const nodes: ProseMirrorNode[] = [];\n parent.forEach((node) => {\n nodes.push(node);\n });\n return renderMarkRuns(nodes, 0, tail);\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 tail: StreamingTail | null,\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, tail)}</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, tail);\n const rendered =\n mark.type.name === \"link\" ? (\n <ChatLink href={mark.attrs.href} excerpt={mark.attrs.excerpt}>\n {content}\n </ChatLink>\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":["ChatBlock","Fragment"],"mappings":"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"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const react = require("@tiptap/react");
5
5
  const lucideReact = require("lucide-react");
6
- const react$1 = require("react");
6
+ const require$$0 = require("react");
7
7
  const mentionChip = require("../mentions/mention-chip.cjs");
8
8
  const mentionExtension = require("../mentions/mention-extension.cjs");
9
9
  const cnfast = require("cnfast");
@@ -38,20 +38,20 @@ function ChatMentionNodeView({ node, editor }) {
38
38
  }
39
39
  const COPIED_RESET_MS = 1500;
40
40
  function CodeBlockCopyButton({ node }) {
41
- const [status, setStatus] = react$1.useState("idle");
42
- const resetTimer = react$1.useRef(null);
43
- react$1.useEffect(
41
+ const [status, setStatus] = require$$0.useState("idle");
42
+ const resetTimer = require$$0.useRef(null);
43
+ require$$0.useEffect(
44
44
  () => () => {
45
45
  if (resetTimer.current) clearTimeout(resetTimer.current);
46
46
  },
47
47
  []
48
48
  );
49
- const flash = react$1.useCallback((next) => {
49
+ const flash = require$$0.useCallback((next) => {
50
50
  setStatus(next);
51
51
  if (resetTimer.current) clearTimeout(resetTimer.current);
52
52
  resetTimer.current = setTimeout(() => setStatus("idle"), COPIED_RESET_MS);
53
53
  }, []);
54
- const onCopy = react$1.useCallback(() => {
54
+ const onCopy = require$$0.useCallback(() => {
55
55
  if (typeof navigator === "undefined" || !navigator.clipboard) {
56
56
  flash("failed");
57
57
  return;
@@ -1 +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 { CheckIcon, CopyIcon, XIcon } from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\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 // The chip inside draws the pill; the host draws no box of its own (styles.css).\n data-chip-host=\"\"\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\nconst COPIED_RESET_MS = 1500;\n\n/**\n * Copies the block's source. Reads `node.textContent` at click time so a\n * still-streaming block copies what is on screen, not a stale snapshot.\n */\nfunction CodeBlockCopyButton({ node }: { node: ProseMirrorNode }) {\n const [status, setStatus] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\");\n const resetTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(\n () => () => {\n if (resetTimer.current) clearTimeout(resetTimer.current);\n },\n [],\n );\n const flash = useCallback((next: \"copied\" | \"failed\") => {\n setStatus(next);\n if (resetTimer.current) clearTimeout(resetTimer.current);\n resetTimer.current = setTimeout(() => setStatus(\"idle\"), COPIED_RESET_MS);\n }, []);\n const onCopy = useCallback(() => {\n // writeText rejects when clipboard-write is denied (permissions, an\n // embedding iframe without the allow attribute); surface that instead of\n // leaving an unhandled rejection and a button that looks like it worked.\n if (typeof navigator === \"undefined\" || !navigator.clipboard) {\n flash(\"failed\");\n return;\n }\n navigator.clipboard.writeText(node.textContent).then(\n () => flash(\"copied\"),\n () => flash(\"failed\"),\n );\n }, [node, flash]);\n const label =\n status === \"copied\" ? \"Copied\" : status === \"failed\" ? \"Copy failed\" : \"Copy code\";\n return (\n <button\n type=\"button\"\n title={label}\n aria-label={label}\n onClick={onCopy}\n className={cn(\n \"inline-flex size-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n \"opacity-0 transition-opacity group-hover/code-block:opacity-100 focus-visible:opacity-100\",\n status !== \"idle\" && \"opacity-100\",\n status === \"failed\" && \"text-destructive\",\n )}\n >\n {status === \"copied\" ? (\n <CheckIcon className=\"size-3.5\" />\n ) : status === \"failed\" ? (\n <XIcon className=\"size-3.5\" />\n ) : (\n <CopyIcon className=\"size-3.5\" />\n )}\n </button>\n );\n}\n\n/** The frame both code renderings share: language label, an optional corner action, the `<pre>`. */\nfunction CodeBlockFrame({\n language,\n action,\n children,\n ...attributes\n}: {\n language: string | null | undefined;\n action?: ReactNode;\n children: ReactNode;\n \"data-chat-open-fence\"?: string;\n}) {\n return (\n <div\n className=\"not-prose group/code-block relative my-2 overflow-hidden rounded-lg border border-border bg-muted/30\"\n {...attributes}\n >\n {language && (\n <div className=\"border-b border-border bg-muted/50 px-3 py-1 text-[10px] font-medium text-muted-foreground\">\n {language}\n </div>\n )}\n {action && (\n <div className=\"absolute top-1 right-1\" contentEditable={false}>\n {action}\n </div>\n )}\n <pre className=\"overflow-x-auto p-3 pr-9 font-mono text-xs leading-relaxed text-foreground\">\n {children}\n </pre>\n </div>\n );\n}\n\nexport function ChatCodeBlock({\n node,\n children,\n}: {\n node: ProseMirrorNode;\n children: ReactNode;\n}) {\n return (\n <CodeBlockFrame\n language={node.attrs.language}\n action={<CodeBlockCopyButton node={node} />}\n >\n {children}\n </CodeBlockFrame>\n );\n}\n\n/**\n * A fenced block whose closing fence has not arrived: the same frame with the\n * code as plain text and no copy action (there is no settled source to copy\n * yet). Anything that decorates code — highlighting, a language pick — belongs\n * after the fence closes, when the block parses into a `codeBlock` node.\n */\nexport function StreamingCodeBlock({\n language,\n code,\n caret,\n}: {\n language: string;\n code: string;\n caret?: ReactNode;\n}) {\n return (\n <CodeBlockFrame language={language || null} data-chat-open-fence=\"\">\n <code>\n {code}\n {caret}\n </code>\n </CodeBlockFrame>\n );\n}\n\nexport function ChatCodeBlockNodeView({ node }: NodeViewProps) {\n return (\n <NodeViewWrapper>\n <ChatCodeBlock node={node}>\n <NodeViewContent<\"code\"> as=\"code\" />\n </ChatCodeBlock>\n </NodeViewWrapper>\n );\n}\n"],"names":["jsx","MentionLink","makeMentionUrl","NodeViewWrapper","useState","useRef","useEffect","useCallback","cn","CheckIcon","XIcon","CopyIcon","jsxs","NodeViewContent"],"mappings":"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"}
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 { CheckIcon, CopyIcon, XIcon } from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\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 // The chip inside draws the pill; the host draws no box of its own (styles.css).\n data-chip-host=\"\"\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\nconst COPIED_RESET_MS = 1500;\n\n/**\n * Copies the block's source. Reads `node.textContent` at click time so a\n * still-streaming block copies what is on screen, not a stale snapshot.\n */\nfunction CodeBlockCopyButton({ node }: { node: ProseMirrorNode }) {\n const [status, setStatus] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\");\n const resetTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(\n () => () => {\n if (resetTimer.current) clearTimeout(resetTimer.current);\n },\n [],\n );\n const flash = useCallback((next: \"copied\" | \"failed\") => {\n setStatus(next);\n if (resetTimer.current) clearTimeout(resetTimer.current);\n resetTimer.current = setTimeout(() => setStatus(\"idle\"), COPIED_RESET_MS);\n }, []);\n const onCopy = useCallback(() => {\n // writeText rejects when clipboard-write is denied (permissions, an\n // embedding iframe without the allow attribute); surface that instead of\n // leaving an unhandled rejection and a button that looks like it worked.\n if (typeof navigator === \"undefined\" || !navigator.clipboard) {\n flash(\"failed\");\n return;\n }\n navigator.clipboard.writeText(node.textContent).then(\n () => flash(\"copied\"),\n () => flash(\"failed\"),\n );\n }, [node, flash]);\n const label =\n status === \"copied\" ? \"Copied\" : status === \"failed\" ? \"Copy failed\" : \"Copy code\";\n return (\n <button\n type=\"button\"\n title={label}\n aria-label={label}\n onClick={onCopy}\n className={cn(\n \"inline-flex size-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n \"opacity-0 transition-opacity group-hover/code-block:opacity-100 focus-visible:opacity-100\",\n status !== \"idle\" && \"opacity-100\",\n status === \"failed\" && \"text-destructive\",\n )}\n >\n {status === \"copied\" ? (\n <CheckIcon className=\"size-3.5\" />\n ) : status === \"failed\" ? (\n <XIcon className=\"size-3.5\" />\n ) : (\n <CopyIcon className=\"size-3.5\" />\n )}\n </button>\n );\n}\n\n/** The frame both code renderings share: language label, an optional corner action, the `<pre>`. */\nfunction CodeBlockFrame({\n language,\n action,\n children,\n ...attributes\n}: {\n language: string | null | undefined;\n action?: ReactNode;\n children: ReactNode;\n \"data-chat-open-fence\"?: string;\n}) {\n return (\n <div\n className=\"not-prose group/code-block relative my-2 overflow-hidden rounded-lg border border-border bg-muted/30\"\n {...attributes}\n >\n {language && (\n <div className=\"border-b border-border bg-muted/50 px-3 py-1 text-[10px] font-medium text-muted-foreground\">\n {language}\n </div>\n )}\n {action && (\n <div className=\"absolute top-1 right-1\" contentEditable={false}>\n {action}\n </div>\n )}\n <pre className=\"overflow-x-auto p-3 pr-9 font-mono text-xs leading-relaxed text-foreground\">\n {children}\n </pre>\n </div>\n );\n}\n\nexport function ChatCodeBlock({\n node,\n children,\n}: {\n node: ProseMirrorNode;\n children: ReactNode;\n}) {\n return (\n <CodeBlockFrame\n language={node.attrs.language}\n action={<CodeBlockCopyButton node={node} />}\n >\n {children}\n </CodeBlockFrame>\n );\n}\n\n/**\n * A fenced block whose closing fence has not arrived: the same frame with the\n * code as plain text and no copy action (there is no settled source to copy\n * yet). Anything that decorates code — highlighting, a language pick — belongs\n * after the fence closes, when the block parses into a `codeBlock` node.\n */\nexport function StreamingCodeBlock({\n language,\n code,\n caret,\n}: {\n language: string;\n code: string;\n caret?: ReactNode;\n}) {\n return (\n <CodeBlockFrame language={language || null} data-chat-open-fence=\"\">\n <code>\n {code}\n {caret}\n </code>\n </CodeBlockFrame>\n );\n}\n\nexport function ChatCodeBlockNodeView({ node }: NodeViewProps) {\n return (\n <NodeViewWrapper>\n <ChatCodeBlock node={node}>\n <NodeViewContent<\"code\"> as=\"code\" />\n </ChatCodeBlock>\n </NodeViewWrapper>\n );\n}\n"],"names":["jsx","MentionLink","makeMentionUrl","NodeViewWrapper","useState","useRef","useEffect","useCallback","cn","CheckIcon","XIcon","CopyIcon","jsxs","NodeViewContent"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const react = require("react");
3
+ const require$$0 = require("react");
4
4
  const ATTRIBUTE_PROPS = {
5
5
  class: "className",
6
6
  for: "htmlFor",
@@ -75,7 +75,7 @@ function renderDOMOutputSpec(spec, content, key) {
75
75
  const props = attributesToProps(attrs);
76
76
  if (tagName === "input") props.disabled = true;
77
77
  if (key !== void 0) props.key = key;
78
- return react.createElement(tagName, props, ...rendered);
78
+ return require$$0.createElement(tagName, props, ...rendered);
79
79
  }
80
80
  exports.attributesToProps = attributesToProps;
81
81
  exports.renderDOMOutputSpec = renderDOMOutputSpec;
@@ -1 +1 @@
1
- {"version":3,"file":"dom-output-spec.cjs","sources":["../../../src/chat-ui/rich-text/dom-output-spec.tsx"],"sourcesContent":["import type { DOMOutputSpec } from \"@tiptap/pm/model\";\nimport { type CSSProperties, createElement, type ReactNode } from \"react\";\n\n/**\n * ProseMirror's `DOMOutputSpec` (what every node and mark's `renderHTML`\n * returns) rendered as React elements, so the static message body draws a\n * node exactly as the editor's DOM serializer would — same tag, same\n * attributes, same nesting — with the node's content placed at the spec's hole.\n *\n * Only the array form is supported. A spec that hands back a live DOM node\n * belongs to a node view, and those nodes never reach this renderer (the parser\n * reports them as unsupported).\n */\n\n/** HTML attribute names whose React prop is spelled differently. */\nconst ATTRIBUTE_PROPS: Readonly<Record<string, string>> = {\n class: \"className\",\n for: \"htmlFor\",\n tabindex: \"tabIndex\",\n contenteditable: \"contentEditable\",\n spellcheck: \"spellCheck\",\n colspan: \"colSpan\",\n rowspan: \"rowSpan\",\n readonly: \"readOnly\",\n maxlength: \"maxLength\",\n autocomplete: \"autoComplete\",\n crossorigin: \"crossOrigin\",\n srcset: \"srcSet\",\n datetime: \"dateTime\",\n};\n\n/** `text-align: center; --x: 1` → `{ textAlign: 'center', '--x': '1' }`. */\nexport function styleTextToObject(style: string): CSSProperties {\n const result: Record<string, string> = {};\n for (const declaration of style.split(\";\")) {\n const separator = declaration.indexOf(\":\");\n if (separator === -1) continue;\n const property = declaration.slice(0, separator).trim();\n const value = declaration.slice(separator + 1).trim();\n if (property === \"\" || value === \"\") continue;\n const key = property.startsWith(\"--\")\n ? property\n : property.replace(/-([a-z])/g, (_match, letter: string) =>\n letter.toUpperCase(),\n );\n result[key] = value;\n }\n return result as CSSProperties;\n}\n\n/** A spec's attribute object as React props. `null`/`undefined` values are dropped, like the serializer drops them. */\nexport function attributesToProps(\n attrs: Record<string, unknown>,\n): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(attrs)) {\n if (value === null || value === undefined) continue;\n if (name === \"style\" && typeof value === \"string\") {\n props.style = styleTextToObject(value);\n continue;\n }\n // A checkbox spec carries `checked: 'checked'` (or null): an uncontrolled input.\n if (name === \"checked\") {\n props.defaultChecked = value !== false;\n continue;\n }\n props[ATTRIBUTE_PROPS[name] ?? name] = value;\n }\n return props;\n}\n\nfunction isAttributeObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(typeof Node !== \"undefined\" && value instanceof Node)\n );\n}\n\n/**\n * Render a spec, placing `content` at its hole (`0`). Throws for a spec the\n * array grammar cannot express (a DOM node, a `{ dom, contentDOM }` pair).\n */\nexport function renderDOMOutputSpec(\n spec: DOMOutputSpec,\n content: ReactNode,\n key?: string | number,\n): ReactNode {\n if (typeof spec === \"string\") return spec;\n if (!Array.isArray(spec)) {\n throw new Error(\n \"static message body: DOMOutputSpec must use the array form\",\n );\n }\n const [tag, ...rest] = spec;\n if (typeof tag !== \"string\") {\n throw new Error(\"static message body: DOMOutputSpec tag must be a string\");\n }\n // A namespaced tag (`svg:...`) is never produced by the message schema.\n const tagName = tag.includes(\" \") ? tag.slice(tag.lastIndexOf(\" \") + 1) : tag;\n let attrs: Record<string, unknown> = {};\n let children: unknown[] = rest;\n if (rest.length > 0 && isAttributeObject(rest[0])) {\n attrs = rest[0];\n children = rest.slice(1);\n }\n const rendered = children.map((child, index) =>\n child === 0\n ? content\n : renderDOMOutputSpec(child as DOMOutputSpec, content, index),\n );\n const props = attributesToProps(attrs);\n if (tagName === \"input\") props.disabled = true;\n if (key !== undefined) props.key = key;\n return createElement(tagName, props, ...rendered);\n}\n"],"names":["createElement"],"mappings":";;;AAeA,MAAM,kBAAoD;AAAA,EACxD,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,UAAU;AACZ;AAGO,SAAS,kBAAkB,OAA8B;AAC9D,QAAM,SAAiC,CAAA;AACvC,aAAW,eAAe,MAAM,MAAM,GAAG,GAAG;AAC1C,UAAM,YAAY,YAAY,QAAQ,GAAG;AACzC,QAAI,cAAc,GAAI;AACtB,UAAM,WAAW,YAAY,MAAM,GAAG,SAAS,EAAE,KAAA;AACjD,UAAM,QAAQ,YAAY,MAAM,YAAY,CAAC,EAAE,KAAA;AAC/C,QAAI,aAAa,MAAM,UAAU,GAAI;AACrC,UAAM,MAAM,SAAS,WAAW,IAAI,IAChC,WACA,SAAS;AAAA,MAAQ;AAAA,MAAa,CAAC,QAAQ,WACrC,OAAO,YAAA;AAAA,IAAY;AAEzB,WAAO,GAAG,IAAI;AAAA,EAChB;AACA,SAAO;AACT;AAGO,SAAS,kBACd,OACyB;AACzB,QAAM,QAAiC,CAAA;AACvC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,QAAI,UAAU,QAAQ,UAAU,OAAW;AAC3C,QAAI,SAAS,WAAW,OAAO,UAAU,UAAU;AACjD,YAAM,QAAQ,kBAAkB,KAAK;AACrC;AAAA,IACF;AAEA,QAAI,SAAS,WAAW;AACtB,YAAM,iBAAiB,UAAU;AACjC;AAAA,IACF;AACA,UAAM,gBAAgB,IAAI,KAAK,IAAI,IAAI;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAkD;AAC3E,SACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,KAAK,KACpB,EAAE,OAAO,SAAS,eAAe,iBAAiB;AAEtD;AAMO,SAAS,oBACd,MACA,SACA,KACW;AACX,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,QAAM,UAAU,IAAI,SAAS,GAAG,IAAI,IAAI,MAAM,IAAI,YAAY,GAAG,IAAI,CAAC,IAAI;AAC1E,MAAI,QAAiC,CAAA;AACrC,MAAI,WAAsB;AAC1B,MAAI,KAAK,SAAS,KAAK,kBAAkB,KAAK,CAAC,CAAC,GAAG;AACjD,YAAQ,KAAK,CAAC;AACd,eAAW,KAAK,MAAM,CAAC;AAAA,EACzB;AACA,QAAM,WAAW,SAAS;AAAA,IAAI,CAAC,OAAO,UACpC,UAAU,IACN,UACA,oBAAoB,OAAwB,SAAS,KAAK;AAAA,EAAA;AAEhE,QAAM,QAAQ,kBAAkB,KAAK;AACrC,MAAI,YAAY,QAAS,OAAM,WAAW;AAC1C,MAAI,QAAQ,OAAW,OAAM,MAAM;AACnC,SAAOA,oBAAc,SAAS,OAAO,GAAG,QAAQ;AAClD;;;;"}
1
+ {"version":3,"file":"dom-output-spec.cjs","sources":["../../../src/chat-ui/rich-text/dom-output-spec.tsx"],"sourcesContent":["import type { DOMOutputSpec } from \"@tiptap/pm/model\";\nimport { type CSSProperties, createElement, type ReactNode } from \"react\";\n\n/**\n * ProseMirror's `DOMOutputSpec` (what every node and mark's `renderHTML`\n * returns) rendered as React elements, so the static message body draws a\n * node exactly as the editor's DOM serializer would — same tag, same\n * attributes, same nesting — with the node's content placed at the spec's hole.\n *\n * Only the array form is supported. A spec that hands back a live DOM node\n * belongs to a node view, and those nodes never reach this renderer (the parser\n * reports them as unsupported).\n */\n\n/** HTML attribute names whose React prop is spelled differently. */\nconst ATTRIBUTE_PROPS: Readonly<Record<string, string>> = {\n class: \"className\",\n for: \"htmlFor\",\n tabindex: \"tabIndex\",\n contenteditable: \"contentEditable\",\n spellcheck: \"spellCheck\",\n colspan: \"colSpan\",\n rowspan: \"rowSpan\",\n readonly: \"readOnly\",\n maxlength: \"maxLength\",\n autocomplete: \"autoComplete\",\n crossorigin: \"crossOrigin\",\n srcset: \"srcSet\",\n datetime: \"dateTime\",\n};\n\n/** `text-align: center; --x: 1` → `{ textAlign: 'center', '--x': '1' }`. */\nexport function styleTextToObject(style: string): CSSProperties {\n const result: Record<string, string> = {};\n for (const declaration of style.split(\";\")) {\n const separator = declaration.indexOf(\":\");\n if (separator === -1) continue;\n const property = declaration.slice(0, separator).trim();\n const value = declaration.slice(separator + 1).trim();\n if (property === \"\" || value === \"\") continue;\n const key = property.startsWith(\"--\")\n ? property\n : property.replace(/-([a-z])/g, (_match, letter: string) =>\n letter.toUpperCase(),\n );\n result[key] = value;\n }\n return result as CSSProperties;\n}\n\n/** A spec's attribute object as React props. `null`/`undefined` values are dropped, like the serializer drops them. */\nexport function attributesToProps(\n attrs: Record<string, unknown>,\n): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(attrs)) {\n if (value === null || value === undefined) continue;\n if (name === \"style\" && typeof value === \"string\") {\n props.style = styleTextToObject(value);\n continue;\n }\n // A checkbox spec carries `checked: 'checked'` (or null): an uncontrolled input.\n if (name === \"checked\") {\n props.defaultChecked = value !== false;\n continue;\n }\n props[ATTRIBUTE_PROPS[name] ?? name] = value;\n }\n return props;\n}\n\nfunction isAttributeObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(typeof Node !== \"undefined\" && value instanceof Node)\n );\n}\n\n/**\n * Render a spec, placing `content` at its hole (`0`). Throws for a spec the\n * array grammar cannot express (a DOM node, a `{ dom, contentDOM }` pair).\n */\nexport function renderDOMOutputSpec(\n spec: DOMOutputSpec,\n content: ReactNode,\n key?: string | number,\n): ReactNode {\n if (typeof spec === \"string\") return spec;\n if (!Array.isArray(spec)) {\n throw new Error(\n \"static message body: DOMOutputSpec must use the array form\",\n );\n }\n const [tag, ...rest] = spec;\n if (typeof tag !== \"string\") {\n throw new Error(\"static message body: DOMOutputSpec tag must be a string\");\n }\n // A namespaced tag (`svg:...`) is never produced by the message schema.\n const tagName = tag.includes(\" \") ? tag.slice(tag.lastIndexOf(\" \") + 1) : tag;\n let attrs: Record<string, unknown> = {};\n let children: unknown[] = rest;\n if (rest.length > 0 && isAttributeObject(rest[0])) {\n attrs = rest[0];\n children = rest.slice(1);\n }\n const rendered = children.map((child, index) =>\n child === 0\n ? content\n : renderDOMOutputSpec(child as DOMOutputSpec, content, index),\n );\n const props = attributesToProps(attrs);\n if (tagName === \"input\") props.disabled = true;\n if (key !== undefined) props.key = key;\n return createElement(tagName, props, ...rendered);\n}\n"],"names":["createElement"],"mappings":";;;AAeA,MAAM,kBAAoD;AAAA,EACxD,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,UAAU;AACZ;AAGO,SAAS,kBAAkB,OAA8B;AAC9D,QAAM,SAAiC,CAAA;AACvC,aAAW,eAAe,MAAM,MAAM,GAAG,GAAG;AAC1C,UAAM,YAAY,YAAY,QAAQ,GAAG;AACzC,QAAI,cAAc,GAAI;AACtB,UAAM,WAAW,YAAY,MAAM,GAAG,SAAS,EAAE,KAAA;AACjD,UAAM,QAAQ,YAAY,MAAM,YAAY,CAAC,EAAE,KAAA;AAC/C,QAAI,aAAa,MAAM,UAAU,GAAI;AACrC,UAAM,MAAM,SAAS,WAAW,IAAI,IAChC,WACA,SAAS;AAAA,MAAQ;AAAA,MAAa,CAAC,QAAQ,WACrC,OAAO,YAAA;AAAA,IAAY;AAEzB,WAAO,GAAG,IAAI;AAAA,EAChB;AACA,SAAO;AACT;AAGO,SAAS,kBACd,OACyB;AACzB,QAAM,QAAiC,CAAA;AACvC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,QAAI,UAAU,QAAQ,UAAU,OAAW;AAC3C,QAAI,SAAS,WAAW,OAAO,UAAU,UAAU;AACjD,YAAM,QAAQ,kBAAkB,KAAK;AACrC;AAAA,IACF;AAEA,QAAI,SAAS,WAAW;AACtB,YAAM,iBAAiB,UAAU;AACjC;AAAA,IACF;AACA,UAAM,gBAAgB,IAAI,KAAK,IAAI,IAAI;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAkD;AAC3E,SACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,KAAK,KACpB,EAAE,OAAO,SAAS,eAAe,iBAAiB;AAEtD;AAMO,SAAS,oBACd,MACA,SACA,KACW;AACX,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,QAAM,UAAU,IAAI,SAAS,GAAG,IAAI,IAAI,MAAM,IAAI,YAAY,GAAG,IAAI,CAAC,IAAI;AAC1E,MAAI,QAAiC,CAAA;AACrC,MAAI,WAAsB;AAC1B,MAAI,KAAK,SAAS,KAAK,kBAAkB,KAAK,CAAC,CAAC,GAAG;AACjD,YAAQ,KAAK,CAAC;AACd,eAAW,KAAK,MAAM,CAAC;AAAA,EACzB;AACA,QAAM,WAAW,SAAS;AAAA,IAAI,CAAC,OAAO,UACpC,UAAU,IACN,UACA,oBAAoB,OAAwB,SAAS,KAAK;AAAA,EAAA;AAEhE,QAAM,QAAQ,kBAAkB,KAAK;AACrC,MAAI,YAAY,QAAS,OAAM,WAAW;AAC1C,MAAI,QAAQ,OAAW,OAAM,MAAM;AACnC,SAAOA,yBAAc,SAAS,OAAO,GAAG,QAAQ;AAClD;;;;"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const StatewireApprovalCard = require("../chat/StatewireApprovalCard.cjs");
4
+ const browserDecisionCheck = require("../chat/browser-decision-check.cjs");
4
5
  const useStatewireApprovalRequest = require("../chat/use-statewire-approval-request.cjs");
5
6
  const StatewireRunRefusalNotice = require("../chat/StatewireRunRefusalNotice.cjs");
6
7
  const StatewireQueuedMessages = require("../chat/StatewireQueuedMessages.cjs");
@@ -13,6 +14,8 @@ const WaitingOnYouBanner = require("../chat/WaitingOnYouBanner.cjs");
13
14
  const statewireContinueRun = require("./messages/statewire-continue-run.cjs");
14
15
  const interrupts = require("../agent-runtime/src/interrupts.cjs");
15
16
  exports.StatewireApprovalCard = StatewireApprovalCard.StatewireApprovalCard;
17
+ exports.useAthenaBrowserDecisionConfirmer = browserDecisionCheck.useAthenaBrowserDecisionConfirmer;
18
+ exports.useBrowserDecisionConfirmer = browserDecisionCheck.useBrowserDecisionConfirmer;
16
19
  exports.useStatewireApprovalRequest = useStatewireApprovalRequest.useStatewireApprovalRequest;
17
20
  exports.useStatewireApprovalWait = useStatewireApprovalRequest.useStatewireApprovalWait;
18
21
  exports.RUN_START_REFUSAL_FALLBACK_MESSAGE = StatewireRunRefusalNotice.RUN_START_REFUSAL_FALLBACK_MESSAGE;
@@ -1 +1 @@
1
- {"version":3,"file":"statewire.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"statewire.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -9,7 +9,8 @@
9
9
  *
10
10
  * Published as the `@athenaintel/react/chat-ui/statewire` sub-path.
11
11
  */
12
- export { StatewireApprovalCard, type StatewireApprovalCardProps, type StatewireApprovalEditorContext, type StatewireApprovalRequestContext, } from "../chat/StatewireApprovalCard";
12
+ export { StatewireApprovalCard, type StatewireApprovalCardProps, type StatewireApprovalEditorContext, type StatewireApprovalRequestContext, type StatewireDecisionAnswer, type StatewireDecisionConfirmer, } from "../chat/StatewireApprovalCard";
13
+ export { type AthenaBrowserDecisionConfirmerOptions, type BrowserDecisionConfirmerOptions, type PendingBrowserDecisionConfirm, useAthenaBrowserDecisionConfirmer, useBrowserDecisionConfirmer, } from "../chat/browser-decision-check";
13
14
  export { type StatewireApprovalRequest, type StatewireApprovalWait, type StatewireInterruptPredicate, type UseStatewireApprovalRequestOptions, useStatewireApprovalRequest, useStatewireApprovalWait, } from "../chat/use-statewire-approval-request";
14
15
  export { RUN_START_REFUSAL_FALLBACK_MESSAGE, StatewireRunRefusalNotice, type StatewireRunRefusalNoticeProps, } from "../chat/StatewireRunRefusalNotice";
15
16
  export { StatewireQueuedMessages, type StatewireQueueEditorContext, type StatewireQueueEvent, type StatewireQueueRowContentContext, type StatewireQueueRowMarkerContext, type StatewireQueuedMessagesProps, } from "../chat/StatewireQueuedMessages";
@@ -1,4 +1,5 @@
1
1
  import { StatewireApprovalCard } from "../chat/StatewireApprovalCard.js";
2
+ import { useAthenaBrowserDecisionConfirmer, useBrowserDecisionConfirmer } from "../chat/browser-decision-check.js";
2
3
  import { useStatewireApprovalRequest, useStatewireApprovalWait } from "../chat/use-statewire-approval-request.js";
3
4
  import { RUN_START_REFUSAL_FALLBACK_MESSAGE, StatewireRunRefusalNotice } from "../chat/StatewireRunRefusalNotice.js";
4
5
  import { StatewireQueuedMessages } from "../chat/StatewireQueuedMessages.js";
@@ -28,6 +29,8 @@ export {
28
29
  WaitingOnYouBannerView,
29
30
  WakeMarkerCard,
30
31
  WakeMarkerMessage,
32
+ useAthenaBrowserDecisionConfirmer,
33
+ useBrowserDecisionConfirmer,
31
34
  useStatewireApprovalRequest,
32
35
  useStatewireApprovalWait,
33
36
  useStatewireToolOutputs
@@ -1 +1 @@
1
- {"version":3,"file":"statewire.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"statewire.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -1,19 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
- const react$1 = require("@assistant-ui/react");
4
+ const react = require("@assistant-ui/react");
5
5
  const lucideReact = require("lucide-react");
6
- const react = require("react");
6
+ const require$$0 = require("react");
7
7
  const messageComponents = require("../messages/message-components.cjs");
8
+ const answerLabel = require("../messages/answer-label.cjs");
8
9
  const messageActionsConfig = require("../messages/message-actions-config.cjs");
9
10
  const userEditComposer = require("../messages/user-edit-composer.cjs");
10
11
  const runningIndicator = require("../messages/running-indicator.cjs");
12
+ const handoffArrivalDivider = require("../messages/handoff-arrival-divider.cjs");
13
+ const fromTheCallCard = require("../messages/from-the-call-card.cjs");
11
14
  const threadChrome = require("../messages/thread-chrome.cjs");
15
+ const messages = require("../../agent-runtime/src/messages.cjs");
16
+ const withArrivalDivider = /* @__PURE__ */ (() => {
17
+ const wrapped = /* @__PURE__ */ new WeakMap();
18
+ return (Message) => {
19
+ const existing = wrapped.get(Message);
20
+ if (existing) return existing;
21
+ const WithArrivalDivider = () => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
22
+ /* @__PURE__ */ jsxRuntime.jsx(Message, {}),
23
+ /* @__PURE__ */ jsxRuntime.jsx(fromTheCallCard.FromTheCallAfterMessage, {}),
24
+ /* @__PURE__ */ jsxRuntime.jsx(handoffArrivalDivider.HandoffArrivalAfterMessage, {})
25
+ ] });
26
+ wrapped.set(Message, WithArrivalDivider);
27
+ return WithArrivalDivider;
28
+ };
29
+ })();
30
+ const ROW_KEY_SEPARATOR = "\0";
31
+ const ThreadRows = ({ components }) => {
32
+ const joinedKeys = react.useAuiState(
33
+ (s) => s.thread.messages.map((message) => messages.deepAgentRowKey(message)).join(ROW_KEY_SEPARATOR)
34
+ );
35
+ const rowKeys = require$$0.useMemo(
36
+ () => joinedKeys === "" ? [] : joinedKeys.split(ROW_KEY_SEPARATOR),
37
+ [joinedKeys]
38
+ );
39
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: rowKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.MessageByIndex, { index, components }, key)) });
40
+ };
12
41
  const DEFAULT_VIEWPORT_CLASS = "relative flex flex-1 flex-col overflow-y-auto scroll-smooth";
13
42
  const DEFAULT_CONTENT_CLASS = "w-full flex-1 px-3 pt-3";
14
43
  const DEFAULT_VIEWPORT_FOOTER_CLASS = "sticky bottom-0";
15
- const DefaultScrollToBottom = () => /* @__PURE__ */ jsxRuntime.jsx(react$1.AuiIf, { condition: (state) => !state.thread.isEmpty, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pb-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
16
- react$1.ThreadPrimitive.ScrollToBottom,
44
+ const DefaultScrollToBottom = () => /* @__PURE__ */ jsxRuntime.jsx(react.AuiIf, { condition: (state) => !state.thread.isEmpty, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pb-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
45
+ react.ThreadPrimitive.ScrollToBottom,
17
46
  {
18
47
  "aria-label": "Scroll to bottom",
19
48
  title: "Scroll to bottom",
@@ -41,24 +70,26 @@ function ChatThreadShell({
41
70
  scrollToBottom = /* @__PURE__ */ jsxRuntime.jsx(DefaultScrollToBottom, {}),
42
71
  viewportFooter,
43
72
  viewportFooterClassName,
44
- readOnly = false
73
+ readOnly = false,
74
+ arrivalThreadId = null,
75
+ viewerUserId = null
45
76
  }) {
46
77
  const {
47
78
  UserMessage,
48
79
  AssistantMessage,
49
80
  UserEditComposer: UserEditComposerComponent = userEditComposer.UserEditComposer
50
81
  } = components;
51
- const messageComponents2 = react.useMemo(
82
+ const messageComponents2 = require$$0.useMemo(
52
83
  () => ({
53
- UserMessage,
54
- AssistantMessage,
84
+ UserMessage: withArrivalDivider(UserMessage),
85
+ AssistantMessage: withArrivalDivider(AssistantMessage),
55
86
  UserEditComposer: UserEditComposerComponent
56
87
  }),
57
88
  [UserMessage, AssistantMessage, UserEditComposerComponent]
58
89
  );
59
- const messages = /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Messages, { components: messageComponents2 });
90
+ const messages2 = /* @__PURE__ */ jsxRuntime.jsx(handoffArrivalDivider.HandoffArrivalScope, { threadId: arrivalThreadId, children: /* @__PURE__ */ jsxRuntime.jsx(answerLabel.AnswerLabelScope, { viewerUserId, children: /* @__PURE__ */ jsxRuntime.jsx(ThreadRows, { components: messageComponents2 }) }) });
60
91
  return /* @__PURE__ */ jsxRuntime.jsx(messageActionsConfig.MessageActionsReadOnlyProvider, { readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs(
61
- react$1.ThreadPrimitive.Root,
92
+ react.ThreadPrimitive.Root,
62
93
  {
63
94
  className: panelClassName ?? threadChrome.THREAD_PANEL_CLASS,
64
95
  style: { "--thread-max-width": maxWidth },
@@ -67,7 +98,7 @@ function ChatThreadShell({
67
98
  header,
68
99
  banners,
69
100
  /* @__PURE__ */ jsxRuntime.jsxs(
70
- react$1.ThreadPrimitive.Viewport,
101
+ react.ThreadPrimitive.Viewport,
71
102
  {
72
103
  turnAnchor,
73
104
  className: viewportClassName ?? DEFAULT_VIEWPORT_CLASS,
@@ -75,13 +106,13 @@ function ChatThreadShell({
75
106
  children: [
76
107
  viewportOverlay,
77
108
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: contentClassName ?? DEFAULT_CONTENT_CLASS, children: [
78
- welcome != null ? /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Empty, { children: welcome }) : null,
109
+ welcome != null ? /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.Empty, { children: welcome }) : null,
79
110
  beforeMessages,
80
- renderMessages ? renderMessages(messages) : messages,
111
+ renderMessages ? renderMessages(messages2) : messages2,
81
112
  runningIndicator$1
82
113
  ] }) }),
83
114
  /* @__PURE__ */ jsxRuntime.jsxs(
84
- react$1.ThreadPrimitive.ViewportFooter,
115
+ react.ThreadPrimitive.ViewportFooter,
85
116
  {
86
117
  className: viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS,
87
118
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"chat-thread-shell.cjs","sources":["../../../src/chat-ui/thread/chat-thread-shell.tsx"],"sourcesContent":["import { AuiIf, ThreadPrimitive } from \"@assistant-ui/react\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport {\n THREAD_PANEL_CLASS,\n THREAD_SCROLL_TO_BOTTOM_CLASS,\n} from \"../messages/message-components\";\nimport { MessageActionsReadOnlyProvider } from \"../messages/message-actions-config\";\nimport { UserEditComposer } from \"../messages/user-edit-composer\";\nimport { ThreadRunningIndicator } from \"../messages/running-indicator\";\n\nexport interface ChatThreadMessageComponents {\n UserMessage: FC;\n AssistantMessage: FC;\n /**\n * Rendered in place of a user message while it is being edited (the action\n * bar's Edit control). Defaults to the shared UserEditComposer.\n */\n UserEditComposer?: FC;\n}\n\nconst DEFAULT_VIEWPORT_CLASS =\n \"relative flex flex-1 flex-col overflow-y-auto scroll-smooth\";\nconst DEFAULT_CONTENT_CLASS = \"w-full flex-1 px-3 pt-3\";\nconst DEFAULT_VIEWPORT_FOOTER_CLASS = \"sticky bottom-0\";\n\nconst DefaultScrollToBottom: FC = () => (\n <AuiIf condition={(state) => !state.thread.isEmpty}>\n <div className=\"flex justify-center pb-0.5\">\n <ThreadPrimitive.ScrollToBottom\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className={THREAD_SCROLL_TO_BOTTOM_CLASS}\n >\n <ChevronDownIcon className=\"size-3.5\" />\n </ThreadPrimitive.ScrollToBottom>\n </div>\n </AuiIf>\n);\n\nexport interface ChatThreadShellProps {\n /**\n * Rendered as the first child of the panel — for absolutely-positioned\n * scrims that must cover the whole panel (AthenaChat's thread-loading\n * overlay). The shell does not force a positioning context; hosts include\n * `relative` in `panelClassName` when the scrim anchors to the panel.\n */\n overlay?: ReactNode;\n /**\n * Rendered above the viewport, inside the panel: header rows, slide-over\n * panels, and anything else the host docks at the top.\n */\n header?: ReactNode;\n /** Status/approval banners rendered between the header and the viewport. */\n banners?: ReactNode;\n /**\n * Nodes rendered inside the scroll viewport before the message column —\n * absolutely/sticky-positioned overlays (thread-switch skeletons,\n * scroll-to-top controls) and invisible observers (read receipts).\n */\n viewportOverlay?: ReactNode;\n /** Empty-thread state, rendered via ThreadPrimitive.Empty when provided. */\n welcome?: ReactNode;\n /**\n * Rendered inside the message column right above the messages — the\n * windowed wire's history edge (`StatewireHistoryEdge`): the \"N earlier\n * messages\" row that pages older history in and fetches cut tool outputs.\n */\n beforeMessages?: ReactNode;\n /** Message renderers for ThreadPrimitive.Messages. */\n components: ChatThreadMessageComponents;\n /**\n * Wraps the messages element — for hosts that provide message-scoped\n * context (e.g. activity-grouping providers). Must render its argument.\n */\n renderMessages?: (messages: ReactNode) => ReactNode;\n /**\n * Rendered between the viewport and the composer: connection banners,\n * queued-message trays.\n */\n belowViewport?: ReactNode;\n /** The composer dock (or a read-only notice replacing it). */\n composer?: ReactNode;\n /**\n * Replaces the docked-panel card chrome — for hosts that render a\n * full-page column (AthenaChat's `aui-*` surface) instead of the\n * side-panel/task-pane card.\n */\n panelClassName?: string;\n /**\n * Value of the `--thread-max-width` variable read by width-capped\n * message/welcome/footer columns. Panels fill their width (the default,\n * \"100%\"); full-page hosts cap the column (AthenaChat defaults to 44rem).\n */\n maxWidth?: string;\n /**\n * Anchors the latest turn to the top of the viewport instead of pinning\n * scroll to the bottom (AthenaChat). Omitted = the primitive's default.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Replaces the scroll-viewport chrome (padding, overflow tuning). */\n viewportClassName?: string;\n /**\n * Replaces the message-column chrome. Hosts whose welcome screen centers\n * vertically make this a flex column so the welcome node can grow.\n */\n contentClassName?: string;\n /**\n * Thread-level \"Thinking...\" indicator rendered after the messages. Hosts\n * whose message components render their own per-message indicators pass\n * null so the two never double up.\n */\n runningIndicator?: ReactNode;\n /**\n * Replaces the default centered scroll-to-bottom pill inside the sticky\n * viewport footer (AthenaChat floats a circular button above its composer).\n */\n scrollToBottom?: ReactNode;\n /**\n * Content docked inside the sticky viewport footer, after the\n * scroll-to-bottom control — for hosts whose banners + composer float over\n * the scrolling messages (AthenaChat) instead of sitting below the\n * viewport via `belowViewport`/`composer`.\n */\n viewportFooter?: ReactNode;\n /** Replaces the sticky viewport-footer chrome. */\n viewportFooterClassName?: string;\n /**\n * Marks the transcript read-only: mutating message actions (Edit,\n * Regenerate) hide while Copy stays available. For threads whose server\n * rejects dispatch (e.g. legacy pre-cutover conversations) — the runtime's\n * static capability flags cannot express a per-thread fence.\n */\n readOnly?: boolean;\n}\n\n/**\n * The shared thread layout: panel chrome, scroll viewport with welcome +\n * messages + running indicator, the sticky scroll-to-bottom control, and the\n * host-supplied composer dock.\n *\n * Hosts express their genuine divergences through the slots above; the\n * layout, scroll behaviour, and empty/running states stay identical across\n * surfaces so fixes land once.\n */\nexport function ChatThreadShell({\n overlay,\n header,\n banners,\n viewportOverlay,\n welcome,\n beforeMessages,\n components,\n renderMessages,\n belowViewport,\n composer,\n panelClassName,\n maxWidth = \"100%\",\n turnAnchor,\n viewportClassName,\n contentClassName,\n runningIndicator = <ThreadRunningIndicator />,\n scrollToBottom = <DefaultScrollToBottom />,\n viewportFooter,\n viewportFooterClassName,\n readOnly = false,\n}: ChatThreadShellProps) {\n const {\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent = UserEditComposer,\n } = components;\n // ThreadPrimitive.Messages resolves per-message renderers by component\n // identity, so keep the merged map referentially stable across renders.\n const messageComponents = useMemo(\n () => ({\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent,\n }),\n [UserMessage, AssistantMessage, UserEditComposerComponent],\n );\n const messages = <ThreadPrimitive.Messages components={messageComponents} />;\n return (\n <MessageActionsReadOnlyProvider readOnly={readOnly}>\n <ThreadPrimitive.Root\n className={panelClassName ?? THREAD_PANEL_CLASS}\n style={{ \"--thread-max-width\": maxWidth } as CSSProperties}\n >\n {overlay}\n {header}\n {banners}\n <ThreadPrimitive.Viewport\n turnAnchor={turnAnchor}\n className={viewportClassName ?? DEFAULT_VIEWPORT_CLASS}\n data-aui-thread-viewport=\"\"\n >\n {viewportOverlay}\n {/* No min-h-0 here: the column's automatic minimum height is what\n lets it extend past one screen, keeping the sticky footer's flow\n position after the full message list. Capping it detaches the\n footer (scroll pill, docked composers) as soon as the thread\n scrolls — proven in a live-browser probe of both structures. */}\n <div className=\"flex flex-1 flex-col items-center\">\n <div className={contentClassName ?? DEFAULT_CONTENT_CLASS}>\n {welcome != null ? (\n <ThreadPrimitive.Empty>{welcome}</ThreadPrimitive.Empty>\n ) : null}\n {beforeMessages}\n {renderMessages ? renderMessages(messages) : messages}\n {runningIndicator}\n </div>\n </div>\n <ThreadPrimitive.ViewportFooter\n className={viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS}\n >\n {scrollToBottom}\n {viewportFooter}\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n {belowViewport}\n {composer}\n </ThreadPrimitive.Root>\n </MessageActionsReadOnlyProvider>\n );\n}\n"],"names":["jsx","AuiIf","ThreadPrimitive","THREAD_SCROLL_TO_BOTTOM_CLASS","ChevronDownIcon","runningIndicator","ThreadRunningIndicator","UserEditComposer","messageComponents","useMemo","MessageActionsReadOnlyProvider","jsxs","THREAD_PANEL_CLASS"],"mappings":";;;;;;;;;;;AAsBA,MAAM,yBACJ;AACF,MAAM,wBAAwB;AAC9B,MAAM,gCAAgC;AAEtC,MAAM,wBAA4B,MAChCA,2BAAAA,IAACC,QAAAA,OAAA,EAAM,WAAW,CAAC,UAAU,CAAC,MAAM,OAAO,SACzC,UAAAD,+BAAC,OAAA,EAAI,WAAU,8BACb,UAAAA,2BAAAA;AAAAA,EAACE,QAAAA,gBAAgB;AAAA,EAAhB;AAAA,IACC,cAAW;AAAA,IACX,OAAM;AAAA,IACN,WAAWC,kBAAAA;AAAAA,IAEX,UAAAH,2BAAAA,IAACI,YAAAA,iBAAA,EAAgB,WAAU,WAAA,CAAW;AAAA,EAAA;AACxC,EAAA,CACF,EAAA,CACF;AA4GK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EAAA,kBACAC,oDAAoBC,iBAAAA,wBAAA,EAAuB;AAAA,EAC3C,gDAAkB,uBAAA,EAAsB;AAAA,EACxC;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAyB;AACvB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,kBAAkB,4BAA4BC,iBAAAA;AAAAA,EAAA,IAC5C;AAGJ,QAAMC,qBAAoBC,MAAAA;AAAAA,IACxB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IAAA;AAAA,IAEpB,CAAC,aAAa,kBAAkB,yBAAyB;AAAA,EAAA;AAE3D,QAAM,WAAWT,2BAAAA,IAACE,QAAAA,gBAAgB,UAAhB,EAAyB,YAAYM,oBAAmB;AAC1E,SACER,2BAAAA,IAACU,qBAAAA,kCAA+B,UAC9B,UAAAC,2BAAAA;AAAAA,IAACT,QAAAA,gBAAgB;AAAA,IAAhB;AAAA,MACC,WAAW,kBAAkBU,aAAAA;AAAAA,MAC7B,OAAO,EAAE,sBAAsB,SAAA;AAAA,MAE9B,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,QACA;AAAA,QACDD,2BAAAA;AAAAA,UAACT,QAAAA,gBAAgB;AAAA,UAAhB;AAAA,YACC;AAAA,YACA,WAAW,qBAAqB;AAAA,YAChC,4BAAyB;AAAA,YAExB,UAAA;AAAA,cAAA;AAAA,cAMDF,2BAAAA,IAAC,SAAI,WAAU,qCACb,0CAAC,OAAA,EAAI,WAAW,oBAAoB,uBACjC,UAAA;AAAA,gBAAA,WAAW,OACVA,2BAAAA,IAACE,QAAAA,gBAAgB,OAAhB,EAAuB,mBAAQ,IAC9B;AAAA,gBACH;AAAA,gBACA,iBAAiB,eAAe,QAAQ,IAAI;AAAA,gBAC5CG;AAAAA,cAAA,EAAA,CACH,EAAA,CACF;AAAA,cACAM,2BAAAA;AAAAA,gBAACT,QAAAA,gBAAgB;AAAA,gBAAhB;AAAA,kBACC,WAAW,2BAA2B;AAAA,kBAErC,UAAA;AAAA,oBAAA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH;AAAA,UAAA;AAAA,QAAA;AAAA,QAED;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;;"}
1
+ {"version":3,"file":"chat-thread-shell.cjs","sources":["../../../src/chat-ui/thread/chat-thread-shell.tsx"],"sourcesContent":["import { AuiIf, ThreadPrimitive, useAuiState } from \"@assistant-ui/react\";\nimport { deepAgentRowKey } from \"@athenaintel/agent-runtime\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { ComponentProps, CSSProperties, FC, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport {\n THREAD_PANEL_CLASS,\n THREAD_SCROLL_TO_BOTTOM_CLASS,\n} from \"../messages/message-components\";\nimport { AnswerLabelScope } from \"../messages/answer-label\";\nimport { MessageActionsReadOnlyProvider } from \"../messages/message-actions-config\";\nimport { UserEditComposer } from \"../messages/user-edit-composer\";\nimport { ThreadRunningIndicator } from \"../messages/running-indicator\";\nimport {\n HandoffArrivalAfterMessage,\n HandoffArrivalScope,\n} from \"../messages/handoff-arrival-divider\";\nimport { FromTheCallAfterMessage } from \"../messages/from-the-call-card\";\n\nexport interface ChatThreadMessageComponents {\n UserMessage: FC;\n AssistantMessage: FC;\n /**\n * Rendered in place of a user message while it is being edited (the action\n * bar's Edit control). Defaults to the shared UserEditComposer.\n */\n UserEditComposer?: FC;\n}\n\n// One wrapper per message renderer, so a renderer keeps its identity across\n// shells and renders: a row renders its message through the component it is\n// handed, and a new component identity would remount every row.\nconst withArrivalDivider = (() => {\n const wrapped = new WeakMap<FC, FC>();\n return (Message: FC): FC => {\n const existing = wrapped.get(Message);\n if (existing) return existing;\n // After the message: the \"From the call\" card where a call's stretch\n // ends, then the arrival divider (the arrival came after the call).\n const WithArrivalDivider: FC = () => (\n <>\n <Message />\n <FromTheCallAfterMessage />\n <HandoffArrivalAfterMessage />\n </>\n );\n wrapped.set(Message, WithArrivalDivider);\n return WithArrivalDivider;\n };\n})();\n\ntype ThreadRowComponents = ComponentProps<typeof ThreadPrimitive.MessageByIndex>[\"components\"];\n\nconst ROW_KEY_SEPARATOR = \"\\u0000\";\n\n/**\n * The thread's messages, one row each under its row key (`deepAgentRowKey`).\n *\n * `ThreadPrimitive.Messages` keys a row by its message id. A page of older\n * history that folds into the first loaded turn (a long run's earlier steps)\n * gives that turn a new id on every page, so keyed by id the turn's row\n * remounted once per page: it flashed through its entrance animation, closed\n * what the person had opened in it and took the browser's scroll anchor with\n * it. The row key stays with the row the turn continues, so the page lands in\n * the mounted row. A message from another runtime keys by its id, as before.\n */\nconst ThreadRows: FC<{ components: ThreadRowComponents }> = ({ components }) => {\n const joinedKeys = useAuiState((s) =>\n s.thread.messages.map((message) => deepAgentRowKey(message)).join(ROW_KEY_SEPARATOR),\n );\n const rowKeys = useMemo(\n () => (joinedKeys === \"\" ? [] : joinedKeys.split(ROW_KEY_SEPARATOR)),\n [joinedKeys],\n );\n return (\n <>\n {rowKeys.map((key, index) => (\n <ThreadPrimitive.MessageByIndex key={key} index={index} components={components} />\n ))}\n </>\n );\n};\n\nconst DEFAULT_VIEWPORT_CLASS =\n \"relative flex flex-1 flex-col overflow-y-auto scroll-smooth\";\nconst DEFAULT_CONTENT_CLASS = \"w-full flex-1 px-3 pt-3\";\nconst DEFAULT_VIEWPORT_FOOTER_CLASS = \"sticky bottom-0\";\n\nconst DefaultScrollToBottom: FC = () => (\n <AuiIf condition={(state) => !state.thread.isEmpty}>\n <div className=\"flex justify-center pb-0.5\">\n <ThreadPrimitive.ScrollToBottom\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className={THREAD_SCROLL_TO_BOTTOM_CLASS}\n >\n <ChevronDownIcon className=\"size-3.5\" />\n </ThreadPrimitive.ScrollToBottom>\n </div>\n </AuiIf>\n);\n\nexport interface ChatThreadShellProps {\n /**\n * Rendered as the first child of the panel — for absolutely-positioned\n * scrims that must cover the whole panel (AthenaChat's thread-loading\n * overlay). The shell does not force a positioning context; hosts include\n * `relative` in `panelClassName` when the scrim anchors to the panel.\n */\n overlay?: ReactNode;\n /**\n * Rendered above the viewport, inside the panel: header rows, slide-over\n * panels, and anything else the host docks at the top.\n */\n header?: ReactNode;\n /** Status/approval banners rendered between the header and the viewport. */\n banners?: ReactNode;\n /**\n * Nodes rendered inside the scroll viewport before the message column —\n * absolutely/sticky-positioned overlays (thread-switch skeletons,\n * scroll-to-top controls) and invisible observers (read receipts).\n */\n viewportOverlay?: ReactNode;\n /** Empty-thread state, rendered via ThreadPrimitive.Empty when provided. */\n welcome?: ReactNode;\n /**\n * Rendered inside the message column right above the messages — the\n * windowed wire's history edge (`StatewireHistoryEdge`): the \"N earlier\n * messages\" row that pages older history in and fetches cut tool outputs.\n */\n beforeMessages?: ReactNode;\n /** Message renderers for the thread's rows. */\n components: ChatThreadMessageComponents;\n /**\n * Wraps the messages element — for hosts that provide message-scoped\n * context (e.g. activity-grouping providers). Must render its argument.\n */\n renderMessages?: (messages: ReactNode) => ReactNode;\n /**\n * Rendered between the viewport and the composer: connection banners,\n * queued-message trays.\n */\n belowViewport?: ReactNode;\n /** The composer dock (or a read-only notice replacing it). */\n composer?: ReactNode;\n /**\n * Replaces the docked-panel card chrome — for hosts that render a\n * full-page column (AthenaChat's `aui-*` surface) instead of the\n * side-panel/task-pane card.\n */\n panelClassName?: string;\n /**\n * Value of the `--thread-max-width` variable read by width-capped\n * message/welcome/footer columns. Panels fill their width (the default,\n * \"100%\"); full-page hosts cap the column (AthenaChat defaults to 44rem).\n */\n maxWidth?: string;\n /**\n * Anchors the latest turn to the top of the viewport instead of pinning\n * scroll to the bottom (AthenaChat). Omitted = the primitive's default.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Replaces the scroll-viewport chrome (padding, overflow tuning). */\n viewportClassName?: string;\n /**\n * Replaces the message-column chrome. Hosts whose welcome screen centers\n * vertically make this a flex column so the welcome node can grow.\n */\n contentClassName?: string;\n /**\n * Thread-level \"Thinking...\" indicator rendered after the messages. Hosts\n * whose message components render their own per-message indicators pass\n * null so the two never double up.\n */\n runningIndicator?: ReactNode;\n /**\n * Replaces the default centered scroll-to-bottom pill inside the sticky\n * viewport footer (AthenaChat floats a circular button above its composer).\n */\n scrollToBottom?: ReactNode;\n /**\n * Content docked inside the sticky viewport footer, after the\n * scroll-to-bottom control — for hosts whose banners + composer float over\n * the scrolling messages (AthenaChat) instead of sitting below the\n * viewport via `belowViewport`/`composer`.\n */\n viewportFooter?: ReactNode;\n /** Replaces the sticky viewport-footer chrome. */\n viewportFooterClassName?: string;\n /**\n * Marks the transcript read-only: mutating message actions (Edit,\n * Regenerate) hide while Copy stays available. For threads whose server\n * rejects dispatch (e.g. legacy pre-cutover conversations) — the runtime's\n * static capability flags cannot express a per-thread fence.\n */\n readOnly?: boolean;\n /**\n * The backend id of the thread on screen. When this surface picked the\n * conversation up from another one (`recordHandoffArrival`), the transcript\n * shows \"Continued from …\" after the last message that was already there.\n */\n arrivalThreadId?: string | null;\n /**\n * The signed-in viewer's Athena user id (`user_…`), for the answer labels\n * (`AnswerLabel`): their own answers read \"for you\", and an answer for\n * another person is labelled even in a 1:1 chat. Omitted, answers name the\n * person by name and are labelled only once the thread holds several agents\n * or several people.\n */\n viewerUserId?: string | null;\n}\n\n/**\n * The shared thread layout: panel chrome, scroll viewport with welcome +\n * messages + running indicator, the sticky scroll-to-bottom control, and the\n * host-supplied composer dock.\n *\n * Hosts express their genuine divergences through the slots above; the\n * layout, scroll behaviour, and empty/running states stay identical across\n * surfaces so fixes land once.\n */\nexport function ChatThreadShell({\n overlay,\n header,\n banners,\n viewportOverlay,\n welcome,\n beforeMessages,\n components,\n renderMessages,\n belowViewport,\n composer,\n panelClassName,\n maxWidth = \"100%\",\n turnAnchor,\n viewportClassName,\n contentClassName,\n runningIndicator = <ThreadRunningIndicator />,\n scrollToBottom = <DefaultScrollToBottom />,\n viewportFooter,\n viewportFooterClassName,\n readOnly = false,\n arrivalThreadId = null,\n viewerUserId = null,\n}: ChatThreadShellProps) {\n const {\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent = UserEditComposer,\n } = components;\n // A row resolves its renderer by component identity, so keep the merged map\n // referentially stable across renders.\n const messageComponents = useMemo(\n () => ({\n UserMessage: withArrivalDivider(UserMessage),\n AssistantMessage: withArrivalDivider(AssistantMessage),\n UserEditComposer: UserEditComposerComponent,\n }),\n [UserMessage, AssistantMessage, UserEditComposerComponent],\n );\n const messages = (\n <HandoffArrivalScope threadId={arrivalThreadId}>\n <AnswerLabelScope viewerUserId={viewerUserId}>\n <ThreadRows components={messageComponents} />\n </AnswerLabelScope>\n </HandoffArrivalScope>\n );\n return (\n <MessageActionsReadOnlyProvider readOnly={readOnly}>\n <ThreadPrimitive.Root\n className={panelClassName ?? THREAD_PANEL_CLASS}\n style={{ \"--thread-max-width\": maxWidth } as CSSProperties}\n >\n {overlay}\n {header}\n {banners}\n <ThreadPrimitive.Viewport\n turnAnchor={turnAnchor}\n className={viewportClassName ?? DEFAULT_VIEWPORT_CLASS}\n data-aui-thread-viewport=\"\"\n >\n {viewportOverlay}\n {/* No min-h-0 here: the column's automatic minimum height is what\n lets it extend past one screen, keeping the sticky footer's flow\n position after the full message list. Capping it detaches the\n footer (scroll pill, docked composers) as soon as the thread\n scrolls — proven in a live-browser probe of both structures. */}\n <div className=\"flex flex-1 flex-col items-center\">\n <div className={contentClassName ?? DEFAULT_CONTENT_CLASS}>\n {welcome != null ? (\n <ThreadPrimitive.Empty>{welcome}</ThreadPrimitive.Empty>\n ) : null}\n {beforeMessages}\n {renderMessages ? renderMessages(messages) : messages}\n {runningIndicator}\n </div>\n </div>\n <ThreadPrimitive.ViewportFooter\n className={viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS}\n >\n {scrollToBottom}\n {viewportFooter}\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n {belowViewport}\n {composer}\n </ThreadPrimitive.Root>\n </MessageActionsReadOnlyProvider>\n );\n}\n"],"names":["jsxs","Fragment","jsx","FromTheCallAfterMessage","HandoffArrivalAfterMessage","useAuiState","deepAgentRowKey","useMemo","ThreadPrimitive","AuiIf","THREAD_SCROLL_TO_BOTTOM_CLASS","ChevronDownIcon","runningIndicator","ThreadRunningIndicator","UserEditComposer","messageComponents","messages","HandoffArrivalScope","AnswerLabelScope","MessageActionsReadOnlyProvider","THREAD_PANEL_CLASS"],"mappings":"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"}
@@ -37,7 +37,7 @@ export interface ChatThreadShellProps {
37
37
  * messages" row that pages older history in and fetches cut tool outputs.
38
38
  */
39
39
  beforeMessages?: ReactNode;
40
- /** Message renderers for ThreadPrimitive.Messages. */
40
+ /** Message renderers for the thread's rows. */
41
41
  components: ChatThreadMessageComponents;
42
42
  /**
43
43
  * Wraps the messages element — for hosts that provide message-scoped
@@ -102,6 +102,20 @@ export interface ChatThreadShellProps {
102
102
  * static capability flags cannot express a per-thread fence.
103
103
  */
104
104
  readOnly?: boolean;
105
+ /**
106
+ * The backend id of the thread on screen. When this surface picked the
107
+ * conversation up from another one (`recordHandoffArrival`), the transcript
108
+ * shows "Continued from …" after the last message that was already there.
109
+ */
110
+ arrivalThreadId?: string | null;
111
+ /**
112
+ * The signed-in viewer's Athena user id (`user_…`), for the answer labels
113
+ * (`AnswerLabel`): their own answers read "for you", and an answer for
114
+ * another person is labelled even in a 1:1 chat. Omitted, answers name the
115
+ * person by name and are labelled only once the thread holds several agents
116
+ * or several people.
117
+ */
118
+ viewerUserId?: string | null;
105
119
  }
106
120
  /**
107
121
  * The shared thread layout: panel chrome, scroll viewport with welcome +
@@ -112,4 +126,4 @@ export interface ChatThreadShellProps {
112
126
  * layout, scroll behaviour, and empty/running states stay identical across
113
127
  * surfaces so fixes land once.
114
128
  */
115
- export declare function ChatThreadShell({ overlay, header, banners, viewportOverlay, welcome, beforeMessages, components, renderMessages, belowViewport, composer, panelClassName, maxWidth, turnAnchor, viewportClassName, contentClassName, runningIndicator, scrollToBottom, viewportFooter, viewportFooterClassName, readOnly, }: ChatThreadShellProps): import("react").JSX.Element;
129
+ export declare function ChatThreadShell({ overlay, header, banners, viewportOverlay, welcome, beforeMessages, components, renderMessages, belowViewport, composer, panelClassName, maxWidth, turnAnchor, viewportClassName, contentClassName, runningIndicator, scrollToBottom, viewportFooter, viewportFooterClassName, readOnly, arrivalThreadId, viewerUserId, }: ChatThreadShellProps): import("react").JSX.Element;