@athenaintel/react 0.23.3 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +17 -4
  2. package/dist/assets/AssetPanel.cjs +1 -1
  3. package/dist/assets/AssetPanel.cjs.map +1 -1
  4. package/dist/assets/AssetPanel.js +1 -1
  5. package/dist/assets/AssetPanel.js.map +1 -1
  6. package/dist/assets/AthenaAssetEmbed.cjs +1 -1
  7. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  8. package/dist/assets/AthenaAssetEmbed.js +1 -1
  9. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  10. package/dist/chat/AthenaChat.cjs +15 -23
  11. package/dist/chat/AthenaChat.cjs.map +1 -1
  12. package/dist/chat/AthenaChat.d.ts +9 -4
  13. package/dist/chat/AthenaChat.js +15 -23
  14. package/dist/chat/AthenaChat.js.map +1 -1
  15. package/dist/chat/StatewireApprovalCard.cjs +34 -24
  16. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  17. package/dist/chat/StatewireApprovalCard.d.ts +34 -4
  18. package/dist/chat/StatewireApprovalCard.js +34 -24
  19. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  20. package/dist/chat/StatewireClientToolBridge.cjs +2 -16
  21. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  22. package/dist/chat/StatewireClientToolBridge.js +2 -16
  23. package/dist/chat/StatewireClientToolBridge.js.map +1 -1
  24. package/dist/chat/StatewireQueuedMessages.cjs +5 -16
  25. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  26. package/dist/chat/StatewireQueuedMessages.js +5 -16
  27. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  28. package/dist/chat/WaitingOnYouBanner.cjs +3 -18
  29. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
  30. package/dist/chat/WaitingOnYouBanner.js +3 -18
  31. package/dist/chat/WaitingOnYouBanner.js.map +1 -1
  32. package/dist/chat/run-activity.cjs +0 -16
  33. package/dist/chat/run-activity.cjs.map +1 -1
  34. package/dist/chat/run-activity.js +0 -16
  35. package/dist/chat/run-activity.js.map +1 -1
  36. package/dist/chat/statewire-client-tools.cjs +1 -17
  37. package/dist/chat/statewire-client-tools.cjs.map +1 -1
  38. package/dist/chat/statewire-client-tools.js +1 -17
  39. package/dist/chat/statewire-client-tools.js.map +1 -1
  40. package/dist/chat/super-grouping/activity-timeline.cjs +0 -16
  41. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  42. package/dist/chat/super-grouping/activity-timeline.js +0 -16
  43. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  44. package/dist/chat/tiptap-text.cjs +1 -17
  45. package/dist/chat/tiptap-text.cjs.map +1 -1
  46. package/dist/chat/tiptap-text.js +1 -17
  47. package/dist/chat/tiptap-text.js.map +1 -1
  48. package/dist/chat/use-athena-run-live.cjs +0 -15
  49. package/dist/chat/use-athena-run-live.cjs.map +1 -1
  50. package/dist/chat/use-athena-run-live.js +0 -15
  51. package/dist/chat/use-athena-run-live.js.map +1 -1
  52. package/dist/chat/use-statewire-approval-request.cjs +4 -16
  53. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  54. package/dist/chat/use-statewire-approval-request.d.ts +2 -0
  55. package/dist/chat/use-statewire-approval-request.js +4 -16
  56. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  57. package/dist/chat-ui/composer/tiptap-composer.cjs +1 -16
  58. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  59. package/dist/chat-ui/composer/tiptap-composer.js +1 -16
  60. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  61. package/dist/chat-ui/index.cjs +0 -16
  62. package/dist/chat-ui/index.cjs.map +1 -1
  63. package/dist/chat-ui/index.d.ts +1 -1
  64. package/dist/chat-ui/index.js +0 -16
  65. package/dist/chat-ui/index.js.map +1 -1
  66. package/dist/chat-ui/mentions/mention-chip.cjs +1 -16
  67. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  68. package/dist/chat-ui/mentions/mention-chip.js +1 -16
  69. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  70. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs +4 -6
  71. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs.map +1 -1
  72. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js +4 -6
  73. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js.map +1 -1
  74. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +2 -9
  75. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  76. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +2 -9
  77. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  78. package/dist/chat-ui/messages/message-components.cjs +5 -19
  79. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  80. package/dist/chat-ui/messages/message-components.js +5 -19
  81. package/dist/chat-ui/messages/message-components.js.map +1 -1
  82. package/dist/chat-ui/messages/runtime-message.cjs +1 -16
  83. package/dist/chat-ui/messages/runtime-message.cjs.map +1 -1
  84. package/dist/chat-ui/messages/runtime-message.js +1 -16
  85. package/dist/chat-ui/messages/runtime-message.js.map +1 -1
  86. package/dist/chat-ui/messages/statewire-continue-run.cjs +3 -15
  87. package/dist/chat-ui/messages/statewire-continue-run.cjs.map +1 -1
  88. package/dist/chat-ui/messages/statewire-continue-run.js +3 -15
  89. package/dist/chat-ui/messages/statewire-continue-run.js.map +1 -1
  90. package/dist/chat-ui/messages/user-edit-composer.cjs +0 -16
  91. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  92. package/dist/chat-ui/messages/user-edit-composer.js +0 -16
  93. package/dist/chat-ui/messages/user-edit-composer.js.map +1 -1
  94. package/dist/chat-ui/messages/wake-marker.cjs +1 -16
  95. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  96. package/dist/chat-ui/messages/wake-marker.js +1 -16
  97. package/dist/chat-ui/messages/wake-marker.js.map +1 -1
  98. package/dist/chat-ui/statewire.cjs +0 -16
  99. package/dist/chat-ui/statewire.cjs.map +1 -1
  100. package/dist/chat-ui/statewire.d.ts +1 -1
  101. package/dist/chat-ui/statewire.js +0 -16
  102. package/dist/chat-ui/statewire.js.map +1 -1
  103. package/dist/chat-ui/thread/statewire-history-edge.cjs +2 -17
  104. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  105. package/dist/chat-ui/thread/statewire-history-edge.js +2 -17
  106. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  107. package/dist/dictation/DictationStrip.cjs +2 -1
  108. package/dist/dictation/DictationStrip.cjs.map +1 -1
  109. package/dist/dictation/DictationStrip.d.ts +2 -0
  110. package/dist/dictation/DictationStrip.js +2 -1
  111. package/dist/dictation/DictationStrip.js.map +1 -1
  112. package/dist/dictation/dictation-engine.cjs.map +1 -1
  113. package/dist/dictation/dictation-engine.d.ts +8 -0
  114. package/dist/dictation/dictation-engine.js.map +1 -1
  115. package/dist/dictation/recorded-dictation-engine.cjs +153 -0
  116. package/dist/dictation/recorded-dictation-engine.cjs.map +1 -0
  117. package/dist/dictation/recorded-dictation-engine.d.ts +66 -0
  118. package/dist/dictation/recorded-dictation-engine.js +153 -0
  119. package/dist/dictation/recorded-dictation-engine.js.map +1 -0
  120. package/dist/dictation/use-athena-dictation-engine.cjs +64 -0
  121. package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -0
  122. package/dist/dictation/use-athena-dictation-engine.d.ts +25 -0
  123. package/dist/dictation/use-athena-dictation-engine.js +64 -0
  124. package/dist/dictation/use-athena-dictation-engine.js.map +1 -0
  125. package/dist/dictation/use-dictation.cjs +17 -6
  126. package/dist/dictation/use-dictation.cjs.map +1 -1
  127. package/dist/dictation/use-dictation.d.ts +20 -4
  128. package/dist/dictation/use-dictation.js +17 -6
  129. package/dist/dictation/use-dictation.js.map +1 -1
  130. package/dist/index.cjs +29 -39
  131. package/dist/index.cjs.map +1 -1
  132. package/dist/index.d.ts +6 -3
  133. package/dist/index.js +12 -22
  134. package/dist/index.js.map +1 -1
  135. package/dist/packages/agent-runtime/src/conversation-list.cjs.map +1 -1
  136. package/dist/packages/agent-runtime/src/conversation-list.js.map +1 -1
  137. package/dist/packages/agent-runtime/src/edit-command.cjs.map +1 -1
  138. package/dist/packages/agent-runtime/src/edit-command.js.map +1 -1
  139. package/dist/packages/agent-runtime/src/errors.cjs +18 -0
  140. package/dist/packages/agent-runtime/src/errors.cjs.map +1 -1
  141. package/dist/packages/agent-runtime/src/errors.js +19 -1
  142. package/dist/packages/agent-runtime/src/errors.js.map +1 -1
  143. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -0
  144. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  145. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -0
  146. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  147. package/dist/packages/agent-runtime/src/interrupts.cjs +83 -14
  148. package/dist/packages/agent-runtime/src/interrupts.cjs.map +1 -1
  149. package/dist/packages/agent-runtime/src/interrupts.js +83 -14
  150. package/dist/packages/agent-runtime/src/interrupts.js.map +1 -1
  151. package/dist/packages/agent-runtime/src/messages.cjs +2 -1
  152. package/dist/packages/agent-runtime/src/messages.cjs.map +1 -1
  153. package/dist/packages/agent-runtime/src/messages.js +2 -1
  154. package/dist/packages/agent-runtime/src/messages.js.map +1 -1
  155. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs +49 -0
  156. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  157. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js +49 -0
  158. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  159. package/dist/packages/agent-runtime/src/thread-status.js +1 -1
  160. package/dist/packages/agent-runtime/src/tool-metadata.cjs +1 -37
  161. package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +1 -1
  162. package/dist/packages/agent-runtime/src/tool-metadata.js +1 -37
  163. package/dist/packages/agent-runtime/src/tool-metadata.js.map +1 -1
  164. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs +0 -1
  165. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  166. package/dist/packages/agent-runtime/src/use-deep-agent-config.js +0 -1
  167. package/dist/packages/agent-runtime/src/use-deep-agent-config.js.map +1 -1
  168. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  169. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  170. package/dist/packages/agent-runtime/src/voice-presentation.cjs +6 -0
  171. package/dist/packages/agent-runtime/src/voice-presentation.cjs.map +1 -1
  172. package/dist/packages/agent-runtime/src/voice-presentation.js +6 -0
  173. package/dist/packages/agent-runtime/src/voice-presentation.js.map +1 -1
  174. package/dist/packages/agent-runtime/src/voice-turn-grouping.cjs +68 -0
  175. package/dist/packages/agent-runtime/src/voice-turn-grouping.cjs.map +1 -0
  176. package/dist/packages/agent-runtime/src/voice-turn-grouping.js +68 -0
  177. package/dist/packages/agent-runtime/src/voice-turn-grouping.js.map +1 -0
  178. package/dist/packages/react/package.json.cjs +1 -1
  179. package/dist/packages/react/package.json.js +1 -1
  180. package/dist/provider/AthenaProvider.cjs +5 -18
  181. package/dist/provider/AthenaProvider.cjs.map +1 -1
  182. package/dist/provider/AthenaProvider.js +5 -18
  183. package/dist/provider/AthenaProvider.js.map +1 -1
  184. package/dist/provider/theme-style-context.cjs +12 -0
  185. package/dist/provider/theme-style-context.cjs.map +1 -0
  186. package/dist/provider/theme-style-context.d.ts +8 -0
  187. package/dist/provider/theme-style-context.js +12 -0
  188. package/dist/provider/theme-style-context.js.map +1 -0
  189. package/dist/runtime/statewire-lifecycle.cjs +0 -16
  190. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  191. package/dist/runtime/statewire-lifecycle.js +0 -16
  192. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  193. package/dist/runtime/useAthenaStatewireRuntime.cjs +3 -17
  194. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  195. package/dist/runtime/useAthenaStatewireRuntime.js +3 -17
  196. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  197. package/dist/styles.css +1 -1
  198. package/dist/threads/SessionList.cjs +87 -16
  199. package/dist/threads/SessionList.cjs.map +1 -1
  200. package/dist/threads/SessionList.js +88 -17
  201. package/dist/threads/SessionList.js.map +1 -1
  202. package/dist/threads/session-list-model.cjs +13 -5
  203. package/dist/threads/session-list-model.cjs.map +1 -1
  204. package/dist/threads/session-list-model.d.ts +10 -3
  205. package/dist/threads/session-list-model.js +13 -5
  206. package/dist/threads/session-list-model.js.map +1 -1
  207. package/dist/threads/statewire-thread-list.cjs +4 -17
  208. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  209. package/dist/threads/statewire-thread-list.js +4 -17
  210. package/dist/threads/statewire-thread-list.js.map +1 -1
  211. package/dist/threads/use-rest-conversation-history.cjs +2 -16
  212. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  213. package/dist/threads/use-rest-conversation-history.js +2 -16
  214. package/dist/threads/use-rest-conversation-history.js.map +1 -1
  215. package/dist/threads/use-statewire-conversation-history.cjs +2 -16
  216. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  217. package/dist/threads/use-statewire-conversation-history.js +2 -16
  218. package/dist/threads/use-statewire-conversation-history.js.map +1 -1
  219. package/dist/toolkits/index.cjs +0 -7
  220. package/dist/toolkits/index.cjs.map +1 -1
  221. package/dist/toolkits/index.d.ts +0 -2
  222. package/dist/toolkits/index.js +0 -7
  223. package/dist/toolkits/index.js.map +1 -1
  224. package/dist/tools/index.cjs +4 -20
  225. package/dist/tools/index.cjs.map +1 -1
  226. package/dist/tools/index.js +1 -17
  227. package/dist/tools/index.js.map +1 -1
  228. package/dist/tools/misc-tool-uis.cjs +2 -17
  229. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  230. package/dist/tools/misc-tool-uis.js +2 -17
  231. package/dist/tools/misc-tool-uis.js.map +1 -1
  232. package/dist/tools/primitives.cjs +1 -16
  233. package/dist/tools/primitives.cjs.map +1 -1
  234. package/dist/tools/primitives.js +1 -16
  235. package/dist/tools/primitives.js.map +1 -1
  236. package/dist/tools/tool-fallback.cjs +2 -17
  237. package/dist/tools/tool-fallback.cjs.map +1 -1
  238. package/dist/tools/tool-fallback.js +2 -17
  239. package/dist/tools/tool-fallback.js.map +1 -1
  240. package/dist/tools/voice-update-tool-ui.cjs +1 -17
  241. package/dist/tools/voice-update-tool-ui.cjs.map +1 -1
  242. package/dist/tools/voice-update-tool-ui.js +1 -17
  243. package/dist/tools/voice-update-tool-ui.js.map +1 -1
  244. package/dist/ui/popover.cjs +46 -0
  245. package/dist/ui/popover.cjs.map +1 -0
  246. package/dist/ui/popover.d.ts +6 -0
  247. package/dist/ui/popover.js +46 -0
  248. package/dist/ui/popover.js.map +1 -0
  249. package/package.json +2 -2
  250. package/dist/node_modules/qrcode-generator/dist/qrcode.cjs +0 -32
  251. package/dist/node_modules/qrcode-generator/dist/qrcode.cjs.map +0 -1
  252. package/dist/node_modules/qrcode-generator/dist/qrcode.js +0 -31
  253. package/dist/node_modules/qrcode-generator/dist/qrcode.js.map +0 -1
  254. package/dist/node_modules/zod/v4/classic/errors.cjs +0 -44
  255. package/dist/node_modules/zod/v4/classic/errors.cjs.map +0 -1
  256. package/dist/node_modules/zod/v4/classic/errors.js +0 -44
  257. package/dist/node_modules/zod/v4/classic/errors.js.map +0 -1
  258. package/dist/node_modules/zod/v4/classic/iso.cjs +0 -43
  259. package/dist/node_modules/zod/v4/classic/iso.cjs.map +0 -1
  260. package/dist/node_modules/zod/v4/classic/iso.js +0 -43
  261. package/dist/node_modules/zod/v4/classic/iso.js.map +0 -1
  262. package/dist/node_modules/zod/v4/classic/parse.cjs +0 -29
  263. package/dist/node_modules/zod/v4/classic/parse.cjs.map +0 -1
  264. package/dist/node_modules/zod/v4/classic/parse.js +0 -29
  265. package/dist/node_modules/zod/v4/classic/parse.js.map +0 -1
  266. package/dist/node_modules/zod/v4/classic/schemas.cjs +0 -871
  267. package/dist/node_modules/zod/v4/classic/schemas.cjs.map +0 -1
  268. package/dist/node_modules/zod/v4/classic/schemas.js +0 -871
  269. package/dist/node_modules/zod/v4/classic/schemas.js.map +0 -1
  270. package/dist/node_modules/zod/v4/core/api.cjs +0 -570
  271. package/dist/node_modules/zod/v4/core/api.cjs.map +0 -1
  272. package/dist/node_modules/zod/v4/core/api.js +0 -570
  273. package/dist/node_modules/zod/v4/core/api.js.map +0 -1
  274. package/dist/node_modules/zod/v4/core/checks.cjs +0 -411
  275. package/dist/node_modules/zod/v4/core/checks.cjs.map +0 -1
  276. package/dist/node_modules/zod/v4/core/checks.js +0 -411
  277. package/dist/node_modules/zod/v4/core/checks.js.map +0 -1
  278. package/dist/node_modules/zod/v4/core/core.cjs +0 -77
  279. package/dist/node_modules/zod/v4/core/core.cjs.map +0 -1
  280. package/dist/node_modules/zod/v4/core/core.js +0 -77
  281. package/dist/node_modules/zod/v4/core/core.js.map +0 -1
  282. package/dist/node_modules/zod/v4/core/doc.cjs +0 -38
  283. package/dist/node_modules/zod/v4/core/doc.cjs.map +0 -1
  284. package/dist/node_modules/zod/v4/core/doc.js +0 -38
  285. package/dist/node_modules/zod/v4/core/doc.js.map +0 -1
  286. package/dist/node_modules/zod/v4/core/errors.cjs +0 -76
  287. package/dist/node_modules/zod/v4/core/errors.cjs.map +0 -1
  288. package/dist/node_modules/zod/v4/core/errors.js +0 -76
  289. package/dist/node_modules/zod/v4/core/errors.js.map +0 -1
  290. package/dist/node_modules/zod/v4/core/json-schema-processors.cjs +0 -312
  291. package/dist/node_modules/zod/v4/core/json-schema-processors.cjs.map +0 -1
  292. package/dist/node_modules/zod/v4/core/json-schema-processors.js +0 -312
  293. package/dist/node_modules/zod/v4/core/json-schema-processors.js.map +0 -1
  294. package/dist/node_modules/zod/v4/core/parse.cjs +0 -96
  295. package/dist/node_modules/zod/v4/core/parse.cjs.map +0 -1
  296. package/dist/node_modules/zod/v4/core/parse.js +0 -96
  297. package/dist/node_modules/zod/v4/core/parse.js.map +0 -1
  298. package/dist/node_modules/zod/v4/core/regexes.cjs +0 -86
  299. package/dist/node_modules/zod/v4/core/regexes.cjs.map +0 -1
  300. package/dist/node_modules/zod/v4/core/regexes.js +0 -86
  301. package/dist/node_modules/zod/v4/core/regexes.js.map +0 -1
  302. package/dist/node_modules/zod/v4/core/registries.cjs +0 -52
  303. package/dist/node_modules/zod/v4/core/registries.cjs.map +0 -1
  304. package/dist/node_modules/zod/v4/core/registries.js +0 -52
  305. package/dist/node_modules/zod/v4/core/registries.js.map +0 -1
  306. package/dist/node_modules/zod/v4/core/schemas.cjs +0 -1412
  307. package/dist/node_modules/zod/v4/core/schemas.cjs.map +0 -1
  308. package/dist/node_modules/zod/v4/core/schemas.js +0 -1413
  309. package/dist/node_modules/zod/v4/core/schemas.js.map +0 -1
  310. package/dist/node_modules/zod/v4/core/to-json-schema.cjs +0 -370
  311. package/dist/node_modules/zod/v4/core/to-json-schema.cjs.map +0 -1
  312. package/dist/node_modules/zod/v4/core/to-json-schema.js +0 -370
  313. package/dist/node_modules/zod/v4/core/to-json-schema.js.map +0 -1
  314. package/dist/node_modules/zod/v4/core/util.cjs +0 -444
  315. package/dist/node_modules/zod/v4/core/util.cjs.map +0 -1
  316. package/dist/node_modules/zod/v4/core/util.js +0 -444
  317. package/dist/node_modules/zod/v4/core/util.js.map +0 -1
  318. package/dist/node_modules/zod/v4/core/versions.cjs +0 -9
  319. package/dist/node_modules/zod/v4/core/versions.cjs.map +0 -1
  320. package/dist/node_modules/zod/v4/core/versions.js +0 -9
  321. package/dist/node_modules/zod/v4/core/versions.js.map +0 -1
  322. package/dist/packages/agent-runtime/src/thread-handoff.cjs +0 -85
  323. package/dist/packages/agent-runtime/src/thread-handoff.cjs.map +0 -1
  324. package/dist/packages/agent-runtime/src/thread-handoff.js +0 -85
  325. package/dist/packages/agent-runtime/src/thread-handoff.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"voice-presentation.cjs","sources":["../../../../../agent-runtime/src/voice-presentation.ts"],"sourcesContent":["/**\n * How voice-mode transcript entries present, shared by every chat surface\n * (Olympus, the Chrome side panel, the mobile app) so a spoken turn, a\n * delegation the live voice model handed off, and an interim spoken update\n * read the same everywhere. The wire contract is the deep-agent host's\n * `additional_kwargs.metadata` (exposed as `message.metadata.custom`):\n *\n * - `source: \"voice\"` — a spoken turn; `voice_live: true` while it is still\n * being heard or spoken (the ephemeral entry the durable row replaces);\n * - `source: \"text\"` — a message typed into the live conversation;\n * - `source: \"voice_delegation\"` (id prefix `voicetask_`) — the unit of work\n * the live voice model delegated to the thread.\n */\n\n/** `metadata.custom.source` of a spoken turn. */\nexport const VOICE_SOURCE_SPOKEN = 'voice';\n/** `metadata.custom.source` of a message typed into the live conversation. */\nexport const VOICE_SOURCE_TYPED = 'text';\n/** `metadata.custom.source` of a voice delegation's anchor message. */\nexport const VOICE_SOURCE_DELEGATION = 'voice_delegation';\n/** Id prefix of a voice delegation's anchor message (the working signal on\n * hosts that drop the command's metadata). */\nexport const VOICE_DELEGATION_ID_PREFIX = 'voicetask_';\n/** `metadata.custom` flag on a spoken turn still in flight. */\nexport const VOICE_LIVE_KEY = 'voice_live';\n\n/** The delegated run's interim-update tool (agora `send_voice_update`). */\nexport const VOICE_UPDATE_TOOL_NAME = 'send_voice_update';\n\n/** Trailing hint on the live-session strip, worded once for every surface. */\nexport const VOICE_LIVE_TYPED_HINT = 'typed messages go to the voice conversation';\n\nexport interface VoiceMessageMarker {\n /** The thread message id; a host may not have assigned one yet. */\n messageId: string | undefined;\n /** The thread message's `metadata.custom`, when any. */\n custom: Record<string, unknown> | undefined;\n}\n\n/** Whether a thread message is a voice delegation's anchor (the ask the live\n * voice model handed to the thread), by source or by id prefix. */\nexport function isVoiceDelegationMessage({ messageId, custom }: VoiceMessageMarker): boolean {\n return (\n custom?.source === VOICE_SOURCE_DELEGATION ||\n (typeof messageId === 'string' && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX))\n );\n}\n\nexport interface VoiceProvenance {\n /** Chip copy: \"Listening\", \"Speaking\", \"Spoken\", or \"Delegated from voice\". */\n readonly label: string;\n /** True while the turn is still being heard or spoken. */\n readonly live: boolean;\n}\n\n// These values are read directly by useAuiState/useSyncExternalStore selectors.\n// Equal presentation must retain its identity, even when a transport replaces\n// the message metadata. Fresh objects here cause React's update-depth crash.\nconst SPOKEN_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Spoken',\n live: false,\n});\nconst LISTENING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Listening',\n live: true,\n});\nconst SPEAKING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Speaking',\n live: true,\n});\nconst DELEGATED_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Delegated from voice',\n live: false,\n});\n\n/**\n * The provenance chip for a message, or `null` for ordinary chat messages so\n * the chip is free to mount on every row. A spoken turn still in flight reads\n * as what is happening (\"Listening\" for the user, \"Speaking\" for the\n * assistant) rather than as a finished \"Spoken\" turn; a typed-in-voice turn\n * is a normal message and gets no chip. Results are immutable and stable for\n * equal presentation, so all surfaces can use this function as a selector.\n */\nexport function voiceProvenanceLabel({\n messageId,\n custom,\n role,\n}: VoiceMessageMarker & { role: 'user' | 'assistant' | string }): VoiceProvenance | null {\n const source = custom?.source;\n if (source === VOICE_SOURCE_SPOKEN) {\n if (custom?.[VOICE_LIVE_KEY] === true) {\n return role === 'user' ? LISTENING_PROVENANCE : SPEAKING_PROVENANCE;\n }\n return SPOKEN_PROVENANCE;\n }\n if (isVoiceDelegationMessage({ messageId, custom })) {\n return DELEGATED_PROVENANCE;\n }\n return null;\n}\n\nexport interface VoiceUpdateToolCall {\n /** `mode: \"speak\"` — read aloud to the user; otherwise a silent progress note. */\n spoken: boolean;\n /** The update's words. */\n text: string;\n /** Whether the live session took it; `null` while the call is still running. */\n delivered: boolean | null;\n}\n\n/**\n * What a `send_voice_update` tool call did, from its arguments and the tool's\n * teaching-text result (agora returns prose, not JSON, so the run can read it).\n */\nexport function describeVoiceUpdateToolCall({\n args,\n result,\n}: {\n args: Record<string, unknown> | undefined;\n result: unknown;\n}): VoiceUpdateToolCall {\n const text = typeof args?.text === 'string' ? args.text.trim() : '';\n const spoken = args?.mode === 'speak';\n if (typeof result !== 'string' || result.trim() === '') {\n return { spoken, text, delivered: null };\n }\n const outcome = result.toLowerCase();\n const failed =\n outcome.includes('could not be delivered') ||\n outcome.includes('was not delivered') ||\n outcome.includes('rejected the update') ||\n outcome.includes('has ended') ||\n outcome.includes('not configured') ||\n outcome.includes('no voice session');\n return { spoken, text, delivered: !failed };\n}\n\n/** The card's status line for a voice update in a given tool-call state. */\nexport function voiceUpdateStatusLabel(\n call: VoiceUpdateToolCall,\n status: 'running' | 'complete' | 'incomplete' | 'requires-action' | undefined\n): string {\n if (status === 'running' || (call.delivered === null && status !== 'incomplete')) {\n return call.spoken ? 'Saying to you…' : 'Noting progress…';\n }\n if (call.delivered === false || status === 'incomplete') {\n return call.spoken ? 'Could not say this to you' : 'Progress note not delivered';\n }\n return call.spoken ? 'Said aloud' : 'Progress noted silently';\n}\n"],"names":[],"mappings":";;AAmBO,MAAM,0BAA0B;AAGhC,MAAM,6BAA6B;AAKnC,MAAM,yBAAyB;AAc/B,SAAS,yBAAyB,EAAE,WAAW,UAAuC;AAC3F,UACE,iCAAQ,YAAW,2BAClB,OAAO,cAAc,YAAY,UAAU,WAAW,0BAA0B;AAErF;AAoEO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAGwB;AACtB,QAAM,OAAO,QAAO,6BAAM,UAAS,WAAW,KAAK,KAAK,SAAS;AACjE,QAAM,UAAS,6BAAM,UAAS;AAC9B,MAAI,OAAO,WAAW,YAAY,OAAO,KAAA,MAAW,IAAI;AACtD,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAA;AAAA,EACpC;AACA,QAAM,UAAU,OAAO,YAAA;AACvB,QAAM,SACJ,QAAQ,SAAS,wBAAwB,KACzC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,qBAAqB,KACtC,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,kBAAkB;AACrC,SAAO,EAAE,QAAQ,MAAM,WAAW,CAAC,OAAA;AACrC;AAGO,SAAS,uBACd,MACA,QACQ;AACR,MAAI,WAAW,aAAc,KAAK,cAAc,QAAQ,WAAW,cAAe;AAChF,WAAO,KAAK,SAAS,mBAAmB;AAAA,EAC1C;AACA,MAAI,KAAK,cAAc,SAAS,WAAW,cAAc;AACvD,WAAO,KAAK,SAAS,8BAA8B;AAAA,EACrD;AACA,SAAO,KAAK,SAAS,eAAe;AACtC;;;;;;;"}
1
+ {"version":3,"file":"voice-presentation.cjs","sources":["../../../../../agent-runtime/src/voice-presentation.ts"],"sourcesContent":["/**\n * How voice-mode transcript entries present, shared by every chat surface\n * (Olympus, the Chrome side panel, the mobile app) so a spoken turn, a\n * delegation the live voice model handed off, and an interim spoken update\n * read the same everywhere. The wire contract is the deep-agent host's\n * `additional_kwargs.metadata` (exposed as `message.metadata.custom`):\n *\n * - `source: \"voice\"` — a spoken turn; `voice_live: true` while it is still\n * being heard or spoken (the ephemeral entry the durable row replaces);\n * - `source: \"text\"` — a message typed into the live conversation;\n * - `source: \"voice_delegation\"` (id prefix `voicetask_`) — the unit of work\n * the live voice model delegated to the thread.\n */\n\n/** `metadata.custom.source` of a spoken turn. */\nexport const VOICE_SOURCE_SPOKEN = 'voice';\n/** `metadata.custom.source` of a message typed into the live conversation. */\nexport const VOICE_SOURCE_TYPED = 'text';\n/** `metadata.custom.source` of a voice delegation's anchor message. */\nexport const VOICE_SOURCE_DELEGATION = 'voice_delegation';\n/** Id prefix of a voice delegation's anchor message (the working signal on\n * hosts that drop the command's metadata). */\nexport const VOICE_DELEGATION_ID_PREFIX = 'voicetask_';\n/** `metadata.custom` flag on a spoken turn still in flight. */\nexport const VOICE_LIVE_KEY = 'voice_live';\n/** `metadata.custom` list of the wire ids a grouped spoken bubble stands for\n * (see `groupSpokenUserTurns`), so id-keyed lookups such as checkpoint markers\n * can resolve any member to the bubble. */\nexport const VOICE_TURN_IDS_KEY = 'voice_turn_ids';\n\n/** The delegated run's interim-update tool (agora `send_voice_update`). */\nexport const VOICE_UPDATE_TOOL_NAME = 'send_voice_update';\n\n/** Trailing hint on the live-session strip, worded once for every surface. */\nexport const VOICE_LIVE_TYPED_HINT = 'typed messages go to the voice conversation';\n\nexport interface VoiceMessageMarker {\n /** The thread message id; a host may not have assigned one yet. */\n messageId: string | undefined;\n /** The thread message's `metadata.custom`, when any. */\n custom: Record<string, unknown> | undefined;\n}\n\n/** Whether a thread message is a voice delegation's anchor (the ask the live\n * voice model handed to the thread), by source or by id prefix. */\nexport function isVoiceDelegationMessage({ messageId, custom }: VoiceMessageMarker): boolean {\n return (\n custom?.source === VOICE_SOURCE_DELEGATION ||\n (typeof messageId === 'string' && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX))\n );\n}\n\nexport interface VoiceProvenance {\n /** Chip copy: \"Listening\", \"Speaking\", \"Spoken\", or \"Delegated from voice\". */\n readonly label: string;\n /** True while the turn is still being heard or spoken. */\n readonly live: boolean;\n}\n\n// These values are read directly by useAuiState/useSyncExternalStore selectors.\n// Equal presentation must retain its identity, even when a transport replaces\n// the message metadata. Fresh objects here cause React's update-depth crash.\nconst SPOKEN_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Spoken',\n live: false,\n});\nconst LISTENING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Listening',\n live: true,\n});\nconst SPEAKING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Speaking',\n live: true,\n});\nconst DELEGATED_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Delegated from voice',\n live: false,\n});\n\n/**\n * The provenance chip for a message, or `null` for ordinary chat messages so\n * the chip is free to mount on every row. A spoken turn still in flight reads\n * as what is happening (\"Listening\" for the user, \"Speaking\" for the\n * assistant) rather than as a finished \"Spoken\" turn; a typed-in-voice turn\n * is a normal message and gets no chip. Results are immutable and stable for\n * equal presentation, so all surfaces can use this function as a selector.\n */\nexport function voiceProvenanceLabel({\n messageId,\n custom,\n role,\n}: VoiceMessageMarker & { role: 'user' | 'assistant' | string }): VoiceProvenance | null {\n const source = custom?.source;\n if (source === VOICE_SOURCE_SPOKEN) {\n if (custom?.[VOICE_LIVE_KEY] === true) {\n return role === 'user' ? LISTENING_PROVENANCE : SPEAKING_PROVENANCE;\n }\n return SPOKEN_PROVENANCE;\n }\n if (isVoiceDelegationMessage({ messageId, custom })) {\n return DELEGATED_PROVENANCE;\n }\n return null;\n}\n\nexport interface VoiceUpdateToolCall {\n /** `mode: \"speak\"` — read aloud to the user; otherwise a silent progress note. */\n spoken: boolean;\n /** The update's words. */\n text: string;\n /** Whether the live session took it; `null` while the call is still running. */\n delivered: boolean | null;\n}\n\n/**\n * What a `send_voice_update` tool call did, from its arguments and the tool's\n * teaching-text result (agora returns prose, not JSON, so the run can read it).\n */\nexport function describeVoiceUpdateToolCall({\n args,\n result,\n}: {\n args: Record<string, unknown> | undefined;\n result: unknown;\n}): VoiceUpdateToolCall {\n const text = typeof args?.text === 'string' ? args.text.trim() : '';\n const spoken = args?.mode === 'speak';\n if (typeof result !== 'string' || result.trim() === '') {\n return { spoken, text, delivered: null };\n }\n const outcome = result.toLowerCase();\n const failed =\n outcome.includes('could not be delivered') ||\n outcome.includes('was not delivered') ||\n outcome.includes('rejected the update') ||\n outcome.includes('has ended') ||\n outcome.includes('not configured') ||\n outcome.includes('no voice session');\n return { spoken, text, delivered: !failed };\n}\n\n/** The card's status line for a voice update in a given tool-call state. */\nexport function voiceUpdateStatusLabel(\n call: VoiceUpdateToolCall,\n status: 'running' | 'complete' | 'incomplete' | 'requires-action' | undefined\n): string {\n if (status === 'running' || (call.delivered === null && status !== 'incomplete')) {\n return call.spoken ? 'Saying to you…' : 'Noting progress…';\n }\n if (call.delivered === false || status === 'incomplete') {\n return call.spoken ? 'Could not say this to you' : 'Progress note not delivered';\n }\n return call.spoken ? 'Said aloud' : 'Progress noted silently';\n}\n"],"names":[],"mappings":";;AAeO,MAAM,sBAAsB;AAI5B,MAAM,0BAA0B;AAGhC,MAAM,6BAA6B;AAEnC,MAAM,iBAAiB;AAIvB,MAAM,qBAAqB;AAG3B,MAAM,yBAAyB;AAc/B,SAAS,yBAAyB,EAAE,WAAW,UAAuC;AAC3F,UACE,iCAAQ,YAAW,2BAClB,OAAO,cAAc,YAAY,UAAU,WAAW,0BAA0B;AAErF;AAoEO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAGwB;AACtB,QAAM,OAAO,QAAO,6BAAM,UAAS,WAAW,KAAK,KAAK,SAAS;AACjE,QAAM,UAAS,6BAAM,UAAS;AAC9B,MAAI,OAAO,WAAW,YAAY,OAAO,KAAA,MAAW,IAAI;AACtD,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAA;AAAA,EACpC;AACA,QAAM,UAAU,OAAO,YAAA;AACvB,QAAM,SACJ,QAAQ,SAAS,wBAAwB,KACzC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,qBAAqB,KACtC,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,kBAAkB;AACrC,SAAO,EAAE,QAAQ,MAAM,WAAW,CAAC,OAAA;AACrC;AAGO,SAAS,uBACd,MACA,QACQ;AACR,MAAI,WAAW,aAAc,KAAK,cAAc,QAAQ,WAAW,cAAe;AAChF,WAAO,KAAK,SAAS,mBAAmB;AAAA,EAC1C;AACA,MAAI,KAAK,cAAc,SAAS,WAAW,cAAc;AACvD,WAAO,KAAK,SAAS,8BAA8B;AAAA,EACrD;AACA,SAAO,KAAK,SAAS,eAAe;AACtC;;;;;;;;;;"}
@@ -1,5 +1,8 @@
1
+ const VOICE_SOURCE_SPOKEN = "voice";
1
2
  const VOICE_SOURCE_DELEGATION = "voice_delegation";
2
3
  const VOICE_DELEGATION_ID_PREFIX = "voicetask_";
4
+ const VOICE_LIVE_KEY = "voice_live";
5
+ const VOICE_TURN_IDS_KEY = "voice_turn_ids";
3
6
  const VOICE_UPDATE_TOOL_NAME = "send_voice_update";
4
7
  function isVoiceDelegationMessage({ messageId, custom }) {
5
8
  return (custom == null ? void 0 : custom.source) === VOICE_SOURCE_DELEGATION || typeof messageId === "string" && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX);
@@ -28,7 +31,10 @@ function voiceUpdateStatusLabel(call, status) {
28
31
  }
29
32
  export {
30
33
  VOICE_DELEGATION_ID_PREFIX,
34
+ VOICE_LIVE_KEY,
31
35
  VOICE_SOURCE_DELEGATION,
36
+ VOICE_SOURCE_SPOKEN,
37
+ VOICE_TURN_IDS_KEY,
32
38
  VOICE_UPDATE_TOOL_NAME,
33
39
  describeVoiceUpdateToolCall,
34
40
  isVoiceDelegationMessage,
@@ -1 +1 @@
1
- {"version":3,"file":"voice-presentation.js","sources":["../../../../../agent-runtime/src/voice-presentation.ts"],"sourcesContent":["/**\n * How voice-mode transcript entries present, shared by every chat surface\n * (Olympus, the Chrome side panel, the mobile app) so a spoken turn, a\n * delegation the live voice model handed off, and an interim spoken update\n * read the same everywhere. The wire contract is the deep-agent host's\n * `additional_kwargs.metadata` (exposed as `message.metadata.custom`):\n *\n * - `source: \"voice\"` — a spoken turn; `voice_live: true` while it is still\n * being heard or spoken (the ephemeral entry the durable row replaces);\n * - `source: \"text\"` — a message typed into the live conversation;\n * - `source: \"voice_delegation\"` (id prefix `voicetask_`) — the unit of work\n * the live voice model delegated to the thread.\n */\n\n/** `metadata.custom.source` of a spoken turn. */\nexport const VOICE_SOURCE_SPOKEN = 'voice';\n/** `metadata.custom.source` of a message typed into the live conversation. */\nexport const VOICE_SOURCE_TYPED = 'text';\n/** `metadata.custom.source` of a voice delegation's anchor message. */\nexport const VOICE_SOURCE_DELEGATION = 'voice_delegation';\n/** Id prefix of a voice delegation's anchor message (the working signal on\n * hosts that drop the command's metadata). */\nexport const VOICE_DELEGATION_ID_PREFIX = 'voicetask_';\n/** `metadata.custom` flag on a spoken turn still in flight. */\nexport const VOICE_LIVE_KEY = 'voice_live';\n\n/** The delegated run's interim-update tool (agora `send_voice_update`). */\nexport const VOICE_UPDATE_TOOL_NAME = 'send_voice_update';\n\n/** Trailing hint on the live-session strip, worded once for every surface. */\nexport const VOICE_LIVE_TYPED_HINT = 'typed messages go to the voice conversation';\n\nexport interface VoiceMessageMarker {\n /** The thread message id; a host may not have assigned one yet. */\n messageId: string | undefined;\n /** The thread message's `metadata.custom`, when any. */\n custom: Record<string, unknown> | undefined;\n}\n\n/** Whether a thread message is a voice delegation's anchor (the ask the live\n * voice model handed to the thread), by source or by id prefix. */\nexport function isVoiceDelegationMessage({ messageId, custom }: VoiceMessageMarker): boolean {\n return (\n custom?.source === VOICE_SOURCE_DELEGATION ||\n (typeof messageId === 'string' && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX))\n );\n}\n\nexport interface VoiceProvenance {\n /** Chip copy: \"Listening\", \"Speaking\", \"Spoken\", or \"Delegated from voice\". */\n readonly label: string;\n /** True while the turn is still being heard or spoken. */\n readonly live: boolean;\n}\n\n// These values are read directly by useAuiState/useSyncExternalStore selectors.\n// Equal presentation must retain its identity, even when a transport replaces\n// the message metadata. Fresh objects here cause React's update-depth crash.\nconst SPOKEN_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Spoken',\n live: false,\n});\nconst LISTENING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Listening',\n live: true,\n});\nconst SPEAKING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Speaking',\n live: true,\n});\nconst DELEGATED_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Delegated from voice',\n live: false,\n});\n\n/**\n * The provenance chip for a message, or `null` for ordinary chat messages so\n * the chip is free to mount on every row. A spoken turn still in flight reads\n * as what is happening (\"Listening\" for the user, \"Speaking\" for the\n * assistant) rather than as a finished \"Spoken\" turn; a typed-in-voice turn\n * is a normal message and gets no chip. Results are immutable and stable for\n * equal presentation, so all surfaces can use this function as a selector.\n */\nexport function voiceProvenanceLabel({\n messageId,\n custom,\n role,\n}: VoiceMessageMarker & { role: 'user' | 'assistant' | string }): VoiceProvenance | null {\n const source = custom?.source;\n if (source === VOICE_SOURCE_SPOKEN) {\n if (custom?.[VOICE_LIVE_KEY] === true) {\n return role === 'user' ? LISTENING_PROVENANCE : SPEAKING_PROVENANCE;\n }\n return SPOKEN_PROVENANCE;\n }\n if (isVoiceDelegationMessage({ messageId, custom })) {\n return DELEGATED_PROVENANCE;\n }\n return null;\n}\n\nexport interface VoiceUpdateToolCall {\n /** `mode: \"speak\"` — read aloud to the user; otherwise a silent progress note. */\n spoken: boolean;\n /** The update's words. */\n text: string;\n /** Whether the live session took it; `null` while the call is still running. */\n delivered: boolean | null;\n}\n\n/**\n * What a `send_voice_update` tool call did, from its arguments and the tool's\n * teaching-text result (agora returns prose, not JSON, so the run can read it).\n */\nexport function describeVoiceUpdateToolCall({\n args,\n result,\n}: {\n args: Record<string, unknown> | undefined;\n result: unknown;\n}): VoiceUpdateToolCall {\n const text = typeof args?.text === 'string' ? args.text.trim() : '';\n const spoken = args?.mode === 'speak';\n if (typeof result !== 'string' || result.trim() === '') {\n return { spoken, text, delivered: null };\n }\n const outcome = result.toLowerCase();\n const failed =\n outcome.includes('could not be delivered') ||\n outcome.includes('was not delivered') ||\n outcome.includes('rejected the update') ||\n outcome.includes('has ended') ||\n outcome.includes('not configured') ||\n outcome.includes('no voice session');\n return { spoken, text, delivered: !failed };\n}\n\n/** The card's status line for a voice update in a given tool-call state. */\nexport function voiceUpdateStatusLabel(\n call: VoiceUpdateToolCall,\n status: 'running' | 'complete' | 'incomplete' | 'requires-action' | undefined\n): string {\n if (status === 'running' || (call.delivered === null && status !== 'incomplete')) {\n return call.spoken ? 'Saying to you…' : 'Noting progress…';\n }\n if (call.delivered === false || status === 'incomplete') {\n return call.spoken ? 'Could not say this to you' : 'Progress note not delivered';\n }\n return call.spoken ? 'Said aloud' : 'Progress noted silently';\n}\n"],"names":[],"mappings":"AAmBO,MAAM,0BAA0B;AAGhC,MAAM,6BAA6B;AAKnC,MAAM,yBAAyB;AAc/B,SAAS,yBAAyB,EAAE,WAAW,UAAuC;AAC3F,UACE,iCAAQ,YAAW,2BAClB,OAAO,cAAc,YAAY,UAAU,WAAW,0BAA0B;AAErF;AAoEO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAGwB;AACtB,QAAM,OAAO,QAAO,6BAAM,UAAS,WAAW,KAAK,KAAK,SAAS;AACjE,QAAM,UAAS,6BAAM,UAAS;AAC9B,MAAI,OAAO,WAAW,YAAY,OAAO,KAAA,MAAW,IAAI;AACtD,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAA;AAAA,EACpC;AACA,QAAM,UAAU,OAAO,YAAA;AACvB,QAAM,SACJ,QAAQ,SAAS,wBAAwB,KACzC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,qBAAqB,KACtC,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,kBAAkB;AACrC,SAAO,EAAE,QAAQ,MAAM,WAAW,CAAC,OAAA;AACrC;AAGO,SAAS,uBACd,MACA,QACQ;AACR,MAAI,WAAW,aAAc,KAAK,cAAc,QAAQ,WAAW,cAAe;AAChF,WAAO,KAAK,SAAS,mBAAmB;AAAA,EAC1C;AACA,MAAI,KAAK,cAAc,SAAS,WAAW,cAAc;AACvD,WAAO,KAAK,SAAS,8BAA8B;AAAA,EACrD;AACA,SAAO,KAAK,SAAS,eAAe;AACtC;"}
1
+ {"version":3,"file":"voice-presentation.js","sources":["../../../../../agent-runtime/src/voice-presentation.ts"],"sourcesContent":["/**\n * How voice-mode transcript entries present, shared by every chat surface\n * (Olympus, the Chrome side panel, the mobile app) so a spoken turn, a\n * delegation the live voice model handed off, and an interim spoken update\n * read the same everywhere. The wire contract is the deep-agent host's\n * `additional_kwargs.metadata` (exposed as `message.metadata.custom`):\n *\n * - `source: \"voice\"` — a spoken turn; `voice_live: true` while it is still\n * being heard or spoken (the ephemeral entry the durable row replaces);\n * - `source: \"text\"` — a message typed into the live conversation;\n * - `source: \"voice_delegation\"` (id prefix `voicetask_`) — the unit of work\n * the live voice model delegated to the thread.\n */\n\n/** `metadata.custom.source` of a spoken turn. */\nexport const VOICE_SOURCE_SPOKEN = 'voice';\n/** `metadata.custom.source` of a message typed into the live conversation. */\nexport const VOICE_SOURCE_TYPED = 'text';\n/** `metadata.custom.source` of a voice delegation's anchor message. */\nexport const VOICE_SOURCE_DELEGATION = 'voice_delegation';\n/** Id prefix of a voice delegation's anchor message (the working signal on\n * hosts that drop the command's metadata). */\nexport const VOICE_DELEGATION_ID_PREFIX = 'voicetask_';\n/** `metadata.custom` flag on a spoken turn still in flight. */\nexport const VOICE_LIVE_KEY = 'voice_live';\n/** `metadata.custom` list of the wire ids a grouped spoken bubble stands for\n * (see `groupSpokenUserTurns`), so id-keyed lookups such as checkpoint markers\n * can resolve any member to the bubble. */\nexport const VOICE_TURN_IDS_KEY = 'voice_turn_ids';\n\n/** The delegated run's interim-update tool (agora `send_voice_update`). */\nexport const VOICE_UPDATE_TOOL_NAME = 'send_voice_update';\n\n/** Trailing hint on the live-session strip, worded once for every surface. */\nexport const VOICE_LIVE_TYPED_HINT = 'typed messages go to the voice conversation';\n\nexport interface VoiceMessageMarker {\n /** The thread message id; a host may not have assigned one yet. */\n messageId: string | undefined;\n /** The thread message's `metadata.custom`, when any. */\n custom: Record<string, unknown> | undefined;\n}\n\n/** Whether a thread message is a voice delegation's anchor (the ask the live\n * voice model handed to the thread), by source or by id prefix. */\nexport function isVoiceDelegationMessage({ messageId, custom }: VoiceMessageMarker): boolean {\n return (\n custom?.source === VOICE_SOURCE_DELEGATION ||\n (typeof messageId === 'string' && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX))\n );\n}\n\nexport interface VoiceProvenance {\n /** Chip copy: \"Listening\", \"Speaking\", \"Spoken\", or \"Delegated from voice\". */\n readonly label: string;\n /** True while the turn is still being heard or spoken. */\n readonly live: boolean;\n}\n\n// These values are read directly by useAuiState/useSyncExternalStore selectors.\n// Equal presentation must retain its identity, even when a transport replaces\n// the message metadata. Fresh objects here cause React's update-depth crash.\nconst SPOKEN_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Spoken',\n live: false,\n});\nconst LISTENING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Listening',\n live: true,\n});\nconst SPEAKING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Speaking',\n live: true,\n});\nconst DELEGATED_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Delegated from voice',\n live: false,\n});\n\n/**\n * The provenance chip for a message, or `null` for ordinary chat messages so\n * the chip is free to mount on every row. A spoken turn still in flight reads\n * as what is happening (\"Listening\" for the user, \"Speaking\" for the\n * assistant) rather than as a finished \"Spoken\" turn; a typed-in-voice turn\n * is a normal message and gets no chip. Results are immutable and stable for\n * equal presentation, so all surfaces can use this function as a selector.\n */\nexport function voiceProvenanceLabel({\n messageId,\n custom,\n role,\n}: VoiceMessageMarker & { role: 'user' | 'assistant' | string }): VoiceProvenance | null {\n const source = custom?.source;\n if (source === VOICE_SOURCE_SPOKEN) {\n if (custom?.[VOICE_LIVE_KEY] === true) {\n return role === 'user' ? LISTENING_PROVENANCE : SPEAKING_PROVENANCE;\n }\n return SPOKEN_PROVENANCE;\n }\n if (isVoiceDelegationMessage({ messageId, custom })) {\n return DELEGATED_PROVENANCE;\n }\n return null;\n}\n\nexport interface VoiceUpdateToolCall {\n /** `mode: \"speak\"` — read aloud to the user; otherwise a silent progress note. */\n spoken: boolean;\n /** The update's words. */\n text: string;\n /** Whether the live session took it; `null` while the call is still running. */\n delivered: boolean | null;\n}\n\n/**\n * What a `send_voice_update` tool call did, from its arguments and the tool's\n * teaching-text result (agora returns prose, not JSON, so the run can read it).\n */\nexport function describeVoiceUpdateToolCall({\n args,\n result,\n}: {\n args: Record<string, unknown> | undefined;\n result: unknown;\n}): VoiceUpdateToolCall {\n const text = typeof args?.text === 'string' ? args.text.trim() : '';\n const spoken = args?.mode === 'speak';\n if (typeof result !== 'string' || result.trim() === '') {\n return { spoken, text, delivered: null };\n }\n const outcome = result.toLowerCase();\n const failed =\n outcome.includes('could not be delivered') ||\n outcome.includes('was not delivered') ||\n outcome.includes('rejected the update') ||\n outcome.includes('has ended') ||\n outcome.includes('not configured') ||\n outcome.includes('no voice session');\n return { spoken, text, delivered: !failed };\n}\n\n/** The card's status line for a voice update in a given tool-call state. */\nexport function voiceUpdateStatusLabel(\n call: VoiceUpdateToolCall,\n status: 'running' | 'complete' | 'incomplete' | 'requires-action' | undefined\n): string {\n if (status === 'running' || (call.delivered === null && status !== 'incomplete')) {\n return call.spoken ? 'Saying to you…' : 'Noting progress…';\n }\n if (call.delivered === false || status === 'incomplete') {\n return call.spoken ? 'Could not say this to you' : 'Progress note not delivered';\n }\n return call.spoken ? 'Said aloud' : 'Progress noted silently';\n}\n"],"names":[],"mappings":"AAeO,MAAM,sBAAsB;AAI5B,MAAM,0BAA0B;AAGhC,MAAM,6BAA6B;AAEnC,MAAM,iBAAiB;AAIvB,MAAM,qBAAqB;AAG3B,MAAM,yBAAyB;AAc/B,SAAS,yBAAyB,EAAE,WAAW,UAAuC;AAC3F,UACE,iCAAQ,YAAW,2BAClB,OAAO,cAAc,YAAY,UAAU,WAAW,0BAA0B;AAErF;AAoEO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAGwB;AACtB,QAAM,OAAO,QAAO,6BAAM,UAAS,WAAW,KAAK,KAAK,SAAS;AACjE,QAAM,UAAS,6BAAM,UAAS;AAC9B,MAAI,OAAO,WAAW,YAAY,OAAO,KAAA,MAAW,IAAI;AACtD,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAA;AAAA,EACpC;AACA,QAAM,UAAU,OAAO,YAAA;AACvB,QAAM,SACJ,QAAQ,SAAS,wBAAwB,KACzC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,qBAAqB,KACtC,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,kBAAkB;AACrC,SAAO,EAAE,QAAQ,MAAM,WAAW,CAAC,OAAA;AACrC;AAGO,SAAS,uBACd,MACA,QACQ;AACR,MAAI,WAAW,aAAc,KAAK,cAAc,QAAQ,WAAW,cAAe;AAChF,WAAO,KAAK,SAAS,mBAAmB;AAAA,EAC1C;AACA,MAAI,KAAK,cAAc,SAAS,WAAW,cAAc;AACvD,WAAO,KAAK,SAAS,8BAA8B;AAAA,EACrD;AACA,SAAO,KAAK,SAAS,eAAe;AACtC;"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const voicePresentation = require("./voice-presentation.cjs");
4
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5
+ function readVoiceMetadata(message) {
6
+ var _a;
7
+ if (!("additional_kwargs" in message)) return void 0;
8
+ const metadata = (_a = message.additional_kwargs) == null ? void 0 : _a.metadata;
9
+ return isRecord(metadata) ? metadata : void 0;
10
+ }
11
+ function isBranchForkPoint(message) {
12
+ var _a;
13
+ const branch = (_a = readVoiceMetadata(message)) == null ? void 0 : _a.branch;
14
+ return isRecord(branch) && Array.isArray(branch.siblings) && branch.siblings.length > 1;
15
+ }
16
+ function isSpokenUserTurn(message) {
17
+ var _a;
18
+ return message.type === "human" && typeof message.content === "string" && ((_a = readVoiceMetadata(message)) == null ? void 0 : _a.source) === voicePresentation.VOICE_SOURCE_SPOKEN;
19
+ }
20
+ const spokenGroupCache = /* @__PURE__ */ new WeakMap();
21
+ function sameTurns(a, b) {
22
+ return a.length === b.length && a.every((turn, index) => turn === b[index]);
23
+ }
24
+ function mergeSpokenTurns(turns) {
25
+ const first = turns[0];
26
+ if (first === void 0) throw new Error("mergeSpokenTurns: empty group");
27
+ if (turns.length === 1) return first;
28
+ const cached = spokenGroupCache.get(first);
29
+ if (cached !== void 0 && sameTurns(cached.turns, turns)) return cached.merged;
30
+ const live = turns.some((turn) => {
31
+ var _a;
32
+ return ((_a = readVoiceMetadata(turn)) == null ? void 0 : _a[voicePresentation.VOICE_LIVE_KEY]) === true;
33
+ });
34
+ const firstMetadata = readVoiceMetadata(first) ?? {};
35
+ const metadata = live ? { ...firstMetadata, [voicePresentation.VOICE_LIVE_KEY]: true } : Object.fromEntries(Object.entries(firstMetadata).filter(([key]) => key !== voicePresentation.VOICE_LIVE_KEY));
36
+ metadata[voicePresentation.VOICE_TURN_IDS_KEY] = turns.flatMap((turn) => turn.id === void 0 ? [] : [turn.id]);
37
+ const content = turns.map((turn) => turn.content.trim()).filter((text) => text.length > 0).join(" ");
38
+ const merged = {
39
+ ...first,
40
+ content,
41
+ additional_kwargs: { ...first.additional_kwargs, metadata }
42
+ };
43
+ spokenGroupCache.set(first, { turns, merged });
44
+ return merged;
45
+ }
46
+ function groupSpokenUserTurns(messages) {
47
+ const grouped = [];
48
+ let run = [];
49
+ const flush = () => {
50
+ if (run.length === 0) return;
51
+ grouped.push(mergeSpokenTurns(run));
52
+ run = [];
53
+ };
54
+ for (const message of messages) {
55
+ if (isSpokenUserTurn(message)) {
56
+ if (isBranchForkPoint(message)) flush();
57
+ run.push(message);
58
+ continue;
59
+ }
60
+ flush();
61
+ grouped.push(message);
62
+ }
63
+ flush();
64
+ return grouped;
65
+ }
66
+ exports.groupSpokenUserTurns = groupSpokenUserTurns;
67
+ exports.isSpokenUserTurn = isSpokenUserTurn;
68
+ //# sourceMappingURL=voice-turn-grouping.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-turn-grouping.cjs","sources":["../../../../../agent-runtime/src/voice-turn-grouping.ts"],"sourcesContent":["import type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { VOICE_LIVE_KEY, VOICE_SOURCE_SPOKEN, VOICE_TURN_IDS_KEY } from './voice-presentation';\n\n/**\n * A live voice session commits a spoken turn per utterance, so one breath of\n * speech reaches the wire as several short human rows. Every chat surface\n * renders consecutive spoken user turns as ONE user message: the run stays\n * grouped until something other than a spoken user turn (the assistant's\n * reply, a typed message, a delegation anchor) closes it. There is no pause\n * threshold on purpose — the transcript is easier to read and reason about as\n * one bubble per exchange.\n *\n * The merged message keeps the FIRST turn's id and metadata, so message\n * actions (edit, retry) anchor where the user started speaking; lists every\n * member's id under `voice_turn_ids`, so a checkpoint written after a later\n * member still finds the bubble; and reads live while any member is still\n * being heard. A turn the history forks at (its branch fan-out lists siblings)\n * always starts a group: the branch picker reads `metadata.custom.branch` off\n * the presented message, so a fork buried inside a group would be unreachable.\n */\n\ntype SpokenUserTurn = Extract<LangChainMessage, { type: 'human' }> & { content: string };\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nfunction readVoiceMetadata(message: LangChainMessage): Record<string, unknown> | undefined {\n if (!('additional_kwargs' in message)) return undefined;\n const metadata = message.additional_kwargs?.metadata;\n return isRecord(metadata) ? metadata : undefined;\n}\n\n/** Whether the history fans out at this turn (`branch.siblings` beyond itself). */\nfunction isBranchForkPoint(message: LangChainMessage): boolean {\n const branch = readVoiceMetadata(message)?.branch;\n return isRecord(branch) && Array.isArray(branch.siblings) && branch.siblings.length > 1;\n}\n\n/** A spoken (not typed, not delegated) user turn with plain text content. */\nexport function isSpokenUserTurn(message: LangChainMessage): message is SpokenUserTurn {\n return (\n message.type === 'human' &&\n typeof message.content === 'string' &&\n readVoiceMetadata(message)?.source === VOICE_SOURCE_SPOKEN\n );\n}\n\ninterface SpokenGroup {\n readonly turns: readonly SpokenUserTurn[];\n readonly merged: LangChainMessage;\n}\n\n/**\n * Keyed by the group's first turn (identity-stable per wire object, see the\n * lift cache in `messages.ts`): an unchanged group returns the IDENTICAL\n * merged object, so the converter's per-source cache and assistant-ui's\n * selectors see no churn between passes.\n */\nconst spokenGroupCache = new WeakMap<LangChainMessage, SpokenGroup>();\n\nfunction sameTurns(a: readonly SpokenUserTurn[], b: readonly SpokenUserTurn[]): boolean {\n return a.length === b.length && a.every((turn, index) => turn === b[index]);\n}\n\nfunction mergeSpokenTurns(turns: readonly SpokenUserTurn[]): LangChainMessage {\n const first = turns[0];\n if (first === undefined) throw new Error('mergeSpokenTurns: empty group');\n if (turns.length === 1) return first;\n const cached = spokenGroupCache.get(first);\n if (cached !== undefined && sameTurns(cached.turns, turns)) return cached.merged;\n\n const live = turns.some((turn) => readVoiceMetadata(turn)?.[VOICE_LIVE_KEY] === true);\n const firstMetadata = readVoiceMetadata(first) ?? {};\n const metadata: Record<string, unknown> = live\n ? { ...firstMetadata, [VOICE_LIVE_KEY]: true }\n : Object.fromEntries(Object.entries(firstMetadata).filter(([key]) => key !== VOICE_LIVE_KEY));\n metadata[VOICE_TURN_IDS_KEY] = turns.flatMap((turn) => (turn.id === undefined ? [] : [turn.id]));\n const content = turns\n .map((turn) => turn.content.trim())\n .filter((text) => text.length > 0)\n .join(' ');\n const merged: LangChainMessage = {\n ...first,\n content,\n additional_kwargs: { ...first.additional_kwargs, metadata },\n };\n spokenGroupCache.set(first, { turns, merged });\n return merged;\n}\n\n/** Collapse each run of consecutive spoken user turns into one human message. */\nexport function groupSpokenUserTurns(messages: readonly LangChainMessage[]): LangChainMessage[] {\n const grouped: LangChainMessage[] = [];\n let run: SpokenUserTurn[] = [];\n const flush = () => {\n if (run.length === 0) return;\n grouped.push(mergeSpokenTurns(run));\n run = [];\n };\n for (const message of messages) {\n if (isSpokenUserTurn(message)) {\n if (isBranchForkPoint(message)) flush();\n run.push(message);\n continue;\n }\n flush();\n grouped.push(message);\n }\n flush();\n return grouped;\n}\n"],"names":["VOICE_SOURCE_SPOKEN","VOICE_LIVE_KEY","VOICE_TURN_IDS_KEY"],"mappings":";;;AAuBA,MAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,SAAS,kBAAkB,SAAgE;;AACzF,MAAI,EAAE,uBAAuB,SAAU,QAAO;AAC9C,QAAM,YAAW,aAAQ,sBAAR,mBAA2B;AAC5C,SAAO,SAAS,QAAQ,IAAI,WAAW;AACzC;AAGA,SAAS,kBAAkB,SAAoC;;AAC7D,QAAM,UAAS,uBAAkB,OAAO,MAAzB,mBAA4B;AAC3C,SAAO,SAAS,MAAM,KAAK,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS,SAAS;AACxF;AAGO,SAAS,iBAAiB,SAAsD;;AACrF,SACE,QAAQ,SAAS,WACjB,OAAO,QAAQ,YAAY,cAC3B,uBAAkB,OAAO,MAAzB,mBAA4B,YAAWA,kBAAAA;AAE3C;AAaA,MAAM,uCAAuB,QAAA;AAE7B,SAAS,UAAU,GAA8B,GAAuC;AACtF,SAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,UAAU,SAAS,EAAE,KAAK,CAAC;AAC5E;AAEA,SAAS,iBAAiB,OAAoD;AAC5E,QAAM,QAAQ,MAAM,CAAC;AACrB,MAAI,UAAU,OAAW,OAAM,IAAI,MAAM,+BAA+B;AACxE,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,SAAS,iBAAiB,IAAI,KAAK;AACzC,MAAI,WAAW,UAAa,UAAU,OAAO,OAAO,KAAK,UAAU,OAAO;AAE1E,QAAM,OAAO,MAAM,KAAK,CAAC;;AAAS,oCAAkB,IAAI,MAAtB,mBAA0BC,uCAAoB;AAAA,GAAI;AACpF,QAAM,gBAAgB,kBAAkB,KAAK,KAAK,CAAA;AAClD,QAAM,WAAoC,OACtC,EAAE,GAAG,eAAe,CAACA,gCAAc,GAAG,KAAA,IACtC,OAAO,YAAY,OAAO,QAAQ,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQA,kBAAAA,cAAc,CAAC;AAC9F,WAASC,kBAAAA,kBAAkB,IAAI,MAAM,QAAQ,CAAC,SAAU,KAAK,OAAO,SAAY,CAAA,IAAK,CAAC,KAAK,EAAE,CAAE;AAC/F,QAAM,UAAU,MACb,IAAI,CAAC,SAAS,KAAK,QAAQ,KAAA,CAAM,EACjC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,GAAG;AACX,QAAM,SAA2B;AAAA,IAC/B,GAAG;AAAA,IACH;AAAA,IACA,mBAAmB,EAAE,GAAG,MAAM,mBAAmB,SAAA;AAAA,EAAS;AAE5D,mBAAiB,IAAI,OAAO,EAAE,OAAO,QAAQ;AAC7C,SAAO;AACT;AAGO,SAAS,qBAAqB,UAA2D;AAC9F,QAAM,UAA8B,CAAA;AACpC,MAAI,MAAwB,CAAA;AAC5B,QAAM,QAAQ,MAAM;AAClB,QAAI,IAAI,WAAW,EAAG;AACtB,YAAQ,KAAK,iBAAiB,GAAG,CAAC;AAClC,UAAM,CAAA;AAAA,EACR;AACA,aAAW,WAAW,UAAU;AAC9B,QAAI,iBAAiB,OAAO,GAAG;AAC7B,UAAI,kBAAkB,OAAO,EAAG,OAAA;AAChC,UAAI,KAAK,OAAO;AAChB;AAAA,IACF;AACA,UAAA;AACA,YAAQ,KAAK,OAAO;AAAA,EACtB;AACA,QAAA;AACA,SAAO;AACT;;;"}
@@ -0,0 +1,68 @@
1
+ import { VOICE_SOURCE_SPOKEN, VOICE_LIVE_KEY, VOICE_TURN_IDS_KEY } from "./voice-presentation.js";
2
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ function readVoiceMetadata(message) {
4
+ var _a;
5
+ if (!("additional_kwargs" in message)) return void 0;
6
+ const metadata = (_a = message.additional_kwargs) == null ? void 0 : _a.metadata;
7
+ return isRecord(metadata) ? metadata : void 0;
8
+ }
9
+ function isBranchForkPoint(message) {
10
+ var _a;
11
+ const branch = (_a = readVoiceMetadata(message)) == null ? void 0 : _a.branch;
12
+ return isRecord(branch) && Array.isArray(branch.siblings) && branch.siblings.length > 1;
13
+ }
14
+ function isSpokenUserTurn(message) {
15
+ var _a;
16
+ return message.type === "human" && typeof message.content === "string" && ((_a = readVoiceMetadata(message)) == null ? void 0 : _a.source) === VOICE_SOURCE_SPOKEN;
17
+ }
18
+ const spokenGroupCache = /* @__PURE__ */ new WeakMap();
19
+ function sameTurns(a, b) {
20
+ return a.length === b.length && a.every((turn, index) => turn === b[index]);
21
+ }
22
+ function mergeSpokenTurns(turns) {
23
+ const first = turns[0];
24
+ if (first === void 0) throw new Error("mergeSpokenTurns: empty group");
25
+ if (turns.length === 1) return first;
26
+ const cached = spokenGroupCache.get(first);
27
+ if (cached !== void 0 && sameTurns(cached.turns, turns)) return cached.merged;
28
+ const live = turns.some((turn) => {
29
+ var _a;
30
+ return ((_a = readVoiceMetadata(turn)) == null ? void 0 : _a[VOICE_LIVE_KEY]) === true;
31
+ });
32
+ const firstMetadata = readVoiceMetadata(first) ?? {};
33
+ const metadata = live ? { ...firstMetadata, [VOICE_LIVE_KEY]: true } : Object.fromEntries(Object.entries(firstMetadata).filter(([key]) => key !== VOICE_LIVE_KEY));
34
+ metadata[VOICE_TURN_IDS_KEY] = turns.flatMap((turn) => turn.id === void 0 ? [] : [turn.id]);
35
+ const content = turns.map((turn) => turn.content.trim()).filter((text) => text.length > 0).join(" ");
36
+ const merged = {
37
+ ...first,
38
+ content,
39
+ additional_kwargs: { ...first.additional_kwargs, metadata }
40
+ };
41
+ spokenGroupCache.set(first, { turns, merged });
42
+ return merged;
43
+ }
44
+ function groupSpokenUserTurns(messages) {
45
+ const grouped = [];
46
+ let run = [];
47
+ const flush = () => {
48
+ if (run.length === 0) return;
49
+ grouped.push(mergeSpokenTurns(run));
50
+ run = [];
51
+ };
52
+ for (const message of messages) {
53
+ if (isSpokenUserTurn(message)) {
54
+ if (isBranchForkPoint(message)) flush();
55
+ run.push(message);
56
+ continue;
57
+ }
58
+ flush();
59
+ grouped.push(message);
60
+ }
61
+ flush();
62
+ return grouped;
63
+ }
64
+ export {
65
+ groupSpokenUserTurns,
66
+ isSpokenUserTurn
67
+ };
68
+ //# sourceMappingURL=voice-turn-grouping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-turn-grouping.js","sources":["../../../../../agent-runtime/src/voice-turn-grouping.ts"],"sourcesContent":["import type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { VOICE_LIVE_KEY, VOICE_SOURCE_SPOKEN, VOICE_TURN_IDS_KEY } from './voice-presentation';\n\n/**\n * A live voice session commits a spoken turn per utterance, so one breath of\n * speech reaches the wire as several short human rows. Every chat surface\n * renders consecutive spoken user turns as ONE user message: the run stays\n * grouped until something other than a spoken user turn (the assistant's\n * reply, a typed message, a delegation anchor) closes it. There is no pause\n * threshold on purpose — the transcript is easier to read and reason about as\n * one bubble per exchange.\n *\n * The merged message keeps the FIRST turn's id and metadata, so message\n * actions (edit, retry) anchor where the user started speaking; lists every\n * member's id under `voice_turn_ids`, so a checkpoint written after a later\n * member still finds the bubble; and reads live while any member is still\n * being heard. A turn the history forks at (its branch fan-out lists siblings)\n * always starts a group: the branch picker reads `metadata.custom.branch` off\n * the presented message, so a fork buried inside a group would be unreachable.\n */\n\ntype SpokenUserTurn = Extract<LangChainMessage, { type: 'human' }> & { content: string };\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nfunction readVoiceMetadata(message: LangChainMessage): Record<string, unknown> | undefined {\n if (!('additional_kwargs' in message)) return undefined;\n const metadata = message.additional_kwargs?.metadata;\n return isRecord(metadata) ? metadata : undefined;\n}\n\n/** Whether the history fans out at this turn (`branch.siblings` beyond itself). */\nfunction isBranchForkPoint(message: LangChainMessage): boolean {\n const branch = readVoiceMetadata(message)?.branch;\n return isRecord(branch) && Array.isArray(branch.siblings) && branch.siblings.length > 1;\n}\n\n/** A spoken (not typed, not delegated) user turn with plain text content. */\nexport function isSpokenUserTurn(message: LangChainMessage): message is SpokenUserTurn {\n return (\n message.type === 'human' &&\n typeof message.content === 'string' &&\n readVoiceMetadata(message)?.source === VOICE_SOURCE_SPOKEN\n );\n}\n\ninterface SpokenGroup {\n readonly turns: readonly SpokenUserTurn[];\n readonly merged: LangChainMessage;\n}\n\n/**\n * Keyed by the group's first turn (identity-stable per wire object, see the\n * lift cache in `messages.ts`): an unchanged group returns the IDENTICAL\n * merged object, so the converter's per-source cache and assistant-ui's\n * selectors see no churn between passes.\n */\nconst spokenGroupCache = new WeakMap<LangChainMessage, SpokenGroup>();\n\nfunction sameTurns(a: readonly SpokenUserTurn[], b: readonly SpokenUserTurn[]): boolean {\n return a.length === b.length && a.every((turn, index) => turn === b[index]);\n}\n\nfunction mergeSpokenTurns(turns: readonly SpokenUserTurn[]): LangChainMessage {\n const first = turns[0];\n if (first === undefined) throw new Error('mergeSpokenTurns: empty group');\n if (turns.length === 1) return first;\n const cached = spokenGroupCache.get(first);\n if (cached !== undefined && sameTurns(cached.turns, turns)) return cached.merged;\n\n const live = turns.some((turn) => readVoiceMetadata(turn)?.[VOICE_LIVE_KEY] === true);\n const firstMetadata = readVoiceMetadata(first) ?? {};\n const metadata: Record<string, unknown> = live\n ? { ...firstMetadata, [VOICE_LIVE_KEY]: true }\n : Object.fromEntries(Object.entries(firstMetadata).filter(([key]) => key !== VOICE_LIVE_KEY));\n metadata[VOICE_TURN_IDS_KEY] = turns.flatMap((turn) => (turn.id === undefined ? [] : [turn.id]));\n const content = turns\n .map((turn) => turn.content.trim())\n .filter((text) => text.length > 0)\n .join(' ');\n const merged: LangChainMessage = {\n ...first,\n content,\n additional_kwargs: { ...first.additional_kwargs, metadata },\n };\n spokenGroupCache.set(first, { turns, merged });\n return merged;\n}\n\n/** Collapse each run of consecutive spoken user turns into one human message. */\nexport function groupSpokenUserTurns(messages: readonly LangChainMessage[]): LangChainMessage[] {\n const grouped: LangChainMessage[] = [];\n let run: SpokenUserTurn[] = [];\n const flush = () => {\n if (run.length === 0) return;\n grouped.push(mergeSpokenTurns(run));\n run = [];\n };\n for (const message of messages) {\n if (isSpokenUserTurn(message)) {\n if (isBranchForkPoint(message)) flush();\n run.push(message);\n continue;\n }\n flush();\n grouped.push(message);\n }\n flush();\n return grouped;\n}\n"],"names":[],"mappings":";AAuBA,MAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,SAAS,kBAAkB,SAAgE;;AACzF,MAAI,EAAE,uBAAuB,SAAU,QAAO;AAC9C,QAAM,YAAW,aAAQ,sBAAR,mBAA2B;AAC5C,SAAO,SAAS,QAAQ,IAAI,WAAW;AACzC;AAGA,SAAS,kBAAkB,SAAoC;;AAC7D,QAAM,UAAS,uBAAkB,OAAO,MAAzB,mBAA4B;AAC3C,SAAO,SAAS,MAAM,KAAK,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS,SAAS;AACxF;AAGO,SAAS,iBAAiB,SAAsD;;AACrF,SACE,QAAQ,SAAS,WACjB,OAAO,QAAQ,YAAY,cAC3B,uBAAkB,OAAO,MAAzB,mBAA4B,YAAW;AAE3C;AAaA,MAAM,uCAAuB,QAAA;AAE7B,SAAS,UAAU,GAA8B,GAAuC;AACtF,SAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,UAAU,SAAS,EAAE,KAAK,CAAC;AAC5E;AAEA,SAAS,iBAAiB,OAAoD;AAC5E,QAAM,QAAQ,MAAM,CAAC;AACrB,MAAI,UAAU,OAAW,OAAM,IAAI,MAAM,+BAA+B;AACxE,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,SAAS,iBAAiB,IAAI,KAAK;AACzC,MAAI,WAAW,UAAa,UAAU,OAAO,OAAO,KAAK,UAAU,OAAO;AAE1E,QAAM,OAAO,MAAM,KAAK,CAAC;;AAAS,oCAAkB,IAAI,MAAtB,mBAA0B,qBAAoB;AAAA,GAAI;AACpF,QAAM,gBAAgB,kBAAkB,KAAK,KAAK,CAAA;AAClD,QAAM,WAAoC,OACtC,EAAE,GAAG,eAAe,CAAC,cAAc,GAAG,KAAA,IACtC,OAAO,YAAY,OAAO,QAAQ,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQ,cAAc,CAAC;AAC9F,WAAS,kBAAkB,IAAI,MAAM,QAAQ,CAAC,SAAU,KAAK,OAAO,SAAY,CAAA,IAAK,CAAC,KAAK,EAAE,CAAE;AAC/F,QAAM,UAAU,MACb,IAAI,CAAC,SAAS,KAAK,QAAQ,KAAA,CAAM,EACjC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,GAAG;AACX,QAAM,SAA2B;AAAA,IAC/B,GAAG;AAAA,IACH;AAAA,IACA,mBAAmB,EAAE,GAAG,MAAM,mBAAmB,SAAA;AAAA,EAAS;AAE5D,mBAAiB,IAAI,OAAO,EAAE,OAAO,QAAQ;AAC7C,SAAO;AACT;AAGO,SAAS,qBAAqB,UAA2D;AAC9F,QAAM,UAA8B,CAAA;AACpC,MAAI,MAAwB,CAAA;AAC5B,QAAM,QAAQ,MAAM;AAClB,QAAI,IAAI,WAAW,EAAG;AACtB,YAAQ,KAAK,iBAAiB,GAAG,CAAC;AAClC,UAAM,CAAA;AAAA,EACR;AACA,aAAW,WAAW,UAAU;AAC9B,QAAI,iBAAiB,OAAO,GAAG;AAC7B,UAAI,kBAAkB,OAAO,EAAG,OAAA;AAChC,UAAI,KAAK,OAAO;AAChB;AAAA,IACF;AACA,UAAA;AACA,YAAQ,KAAK,OAAO;AAAA,EACtB;AACA,QAAA;AACA,SAAO;AACT;"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const version = "0.23.3";
3
+ const version = "0.24.1";
4
4
  const packageJson = {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
- const version = "0.23.3";
1
+ const version = "0.24.1";
2
2
  const packageJson = {
3
3
  version
4
4
  };
@@ -3,23 +3,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const react$1 = require("@assistant-ui/react");
5
5
  const react = require("react");
6
- require("../packages/agent-runtime/src/generated/runconfig-contract.cjs");
7
- require("@assistant-ui/tap");
8
- require("statewire");
9
- require("../packages/agent-runtime/src/statewire-suspended.cjs");
10
- require("../packages/agent-runtime/src/conversation-list.cjs");
11
- require("@tanstack/react-query");
12
- require("../packages/agent-runtime/src/statewire-state.cjs");
13
- require("../packages/agent-runtime/src/messages.cjs");
14
- require("@assistant-ui/store");
15
- const toolOutputs = require("../packages/agent-runtime/src/tool-outputs.cjs");
16
- require("../packages/agent-runtime/src/quota-safe-local-storage-session.cjs");
17
- const threadSnapshotCache = require("../packages/agent-runtime/src/thread-snapshot-cache.cjs");
18
- require("../packages/agent-runtime/src/statewire-attach-observer.cjs");
19
- const threadStatus = require("../packages/agent-runtime/src/thread-status.cjs");
20
- require("@assistant-ui/react-statewire");
21
- require("@assistant-ui/core");
22
- require("../packages/agent-runtime/src/thread-handoff.cjs");
23
6
  const athenaUrls = require("../lib/athena-urls.cjs");
24
7
  const mint = require("../collab/mint.cjs");
25
8
  const auth = require("../runtime/auth.cjs");
@@ -42,7 +25,11 @@ const threadIdContext = require("../threads/thread-id-context.cjs");
42
25
  const statewireThreadList = require("../threads/statewire-thread-list.cjs");
43
26
  const assetPanelStore = require("../assets/asset-panel-store.cjs");
44
27
  const index = require("../theme/index.cjs");
28
+ const themeStyleContext = require("./theme-style-context.cjs");
45
29
  const PostHogProvider = require("./PostHogProvider.cjs");
30
+ const threadSnapshotCache = require("../packages/agent-runtime/src/thread-snapshot-cache.cjs");
31
+ const toolOutputs = require("../packages/agent-runtime/src/tool-outputs.cjs");
32
+ const threadStatus = require("../packages/agent-runtime/src/thread-status.cjs");
46
33
  const resolveTokenOverride = ({
47
34
  config,
48
35
  token
@@ -483,7 +470,7 @@ function AthenaProvider({
483
470
  {
484
471
  className: themeStyleVars ? "athena-sdk athena-themed" : "athena-sdk",
485
472
  style: themeStyleVars,
486
- children: /* @__PURE__ */ jsxRuntime.jsx(PostHogProvider.PostHogProvider, { config: posthogConfig, children: /* @__PURE__ */ jsxRuntime.jsx(composerHandoff.ComposerHandoffContext.Provider, { value: composerHandoff$1, children: inner }) })
473
+ children: /* @__PURE__ */ jsxRuntime.jsx(PostHogProvider.PostHogProvider, { config: posthogConfig, children: /* @__PURE__ */ jsxRuntime.jsx(composerHandoff.ComposerHandoffContext.Provider, { value: composerHandoff$1, children: /* @__PURE__ */ jsxRuntime.jsx(themeStyleContext.AthenaThemeStyleContext.Provider, { value: themeStyleVars, children: inner }) }) })
487
474
  }
488
475
  );
489
476
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaProvider.cjs","sources":["../../src/provider/AthenaProvider.tsx"],"sourcesContent":["import { AuiProvider, useAui } from '@assistant-ui/react';\nimport {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport type { AssistantClient, Toolkit } from '@assistant-ui/react';\nimport {\n createDeepAgentThreadSnapshotCache,\n createDeepAgentToolOutputStore,\n DeepAgentConnectionContext,\n type DeepAgentThreadSnapshotCache,\n type DeepAgentToolOutputStore,\n} from '@athenaintel/agent-runtime';\nimport {\n assertHostMintedStatewireMount,\n deriveAthenaAppUrl,\n getAthenaEnvironmentUrls,\n resolveStatewireSyncUrl,\n type AthenaEnvironment,\n} from '../lib/athena-urls';\nimport { getAthenaApiBaseUrl } from '../collab/mint';\nimport { useParentBridge } from '../runtime/auth';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport {\n useAthenaStatewireRuntime,\n useStatewireClientTools,\n} from '../runtime/useAthenaStatewireRuntime';\nimport {\n athenaStatewireErrorNotice,\n type AthenaStatewireLifecycleState,\n initialStatewireLifecycle,\n statewireLifecycleReducer,\n} from '../runtime/statewire-lifecycle';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { resolveAgentProp } from '../runtime/statewire-run-config';\nimport { mintThreadId } from '../threads/mint-thread-id';\nimport { AthenaStatewireLifecycleContext } from './statewire-lifecycle-context';\nimport {\n ComposerHandoffContext,\n clearComposerHandoff,\n createComposerHandoffStore,\n drainComposerHandoff,\n useComposerHandoffStore,\n useComposerReady,\n} from '../composer/composer-handoff';\nimport { StatewireToolOutputsContext } from './statewire-window-context';\nimport { StatewireClientToolBridge } from '../chat/StatewireClientToolBridge';\nimport {\n athenaDiagnostics,\n debugPropToDiagnosticsConfig,\n installAthenaDiagnosticsGlobal,\n type AthenaDiagnosticEvent,\n type AthenaDiagnosticLevel,\n type AthenaDiagnosticsConfig,\n} from '../diagnostics/athena-diagnostics';\nimport { AthenaSdkError } from '../diagnostics/errors';\nimport {\n backendDeclaredFrontendToolIds,\n resolveClientToolSurface,\n} from '../chat/statewire-client-tools';\nimport { TooltipProvider } from '../ui/tooltip';\nimport { DEFAULT_AUTO_OPEN_TOOLS } from '../tools/auto-open-tools';\nimport { AthenaContext, type AthenaConfig } from './AthenaContext';\nimport type { AthenaProviderConfig } from './config';\nimport type {\n AthenaCitationLinkOptions,\n AthenaLinkClickOptions,\n} from './citation-links';\nimport {\n AthenaStatewireThreadIdContext,\n AthenaThreadIdContext,\n useAthenaStatewireThreadId,\n} from '../threads/thread-id-context';\nimport {\n AthenaStatewireThreadListProvider,\n StatewireThreadTitlePoller,\n useAthenaStatewireThreadList,\n} from '../threads/statewire-thread-list';\nimport { useAssetPanelStore } from '../assets/asset-panel-store';\nimport { themeToStyleVars, type AthenaTheme } from '../theme';\nimport { PostHogProvider, type PostHogConfig } from './PostHogProvider';\n\nexport interface AthenaProviderProps {\n children: ReactNode;\n\n /** Preferred structured config for auth and Athena endpoint settings. */\n config?: AthenaProviderConfig;\n\n /** @deprecated Prefer `config.apiKey`. API key for authentication in standalone mode. */\n apiKey?: string;\n\n /** @deprecated Prefer `config.token`. PropelAuth token. If provided, takes priority over apiKey. If omitted, the SDK\n * will automatically listen for a token from the parent window via PostMessage. */\n token?: string | null;\n\n /** Run the thread AS a published collab agent. The only accepted shape is\n * `collab_agent:<asset_id>`: the thread then uses that agent's prompt,\n * tools, and model default, and the caller must have view access to the\n * agent asset. Omit it (or pass a blank string) to run the Athena deep agent.\n *\n * Any other non-blank value throws at render — the statewire host cannot\n * honour named agents, and a selector that is silently dropped would let a\n * misconfigured deployment answer as the wrong agent. */\n agent?: string;\n\n /** Collab-agent channel id — a built-in channel (`email`, `sms`, …) or a\n * user-defined custom channel id from the agent's Channels tab. Selects\n * that channel's configuration overrides and stamps the session's origin.\n * Only meaningful together with a `collab_agent:<asset_id>` `agent`; sent\n * as `collab_channel_id`. An unknown or disabled channel rejects the run\n * with a structured, teaching error. */\n channel?: string;\n\n /** LLM model identifier. Defaults to the deep-agent default model\n * (`DEFAULT_STATEWIRE_MODEL`) — or, when a collab agent is selected, to\n * the model its author configured. */\n model?: string;\n\n /** Backend toolkit IDs to enable (e.g. 'document_toolkit', 'web_search_browse_toolkit'). */\n tools?: string[];\n\n /** Frontend tools that execute in the browser. The agent can invoke these.\n * Merged on top of the SDK's default auto-open tools; entries here take\n * precedence over defaults with the same name. Tools with a local\n * `execute` are declared to the backend as `client_tools` and run through\n * the statewire client-tool bridge. */\n frontendTools?: Toolkit;\n\n /** Disable the SDK's default auto-open behavior for created/touched assets. */\n disableAutoOpen?: boolean;\n\n /** @deprecated Prefer `config.apiUrl`. URL on the Iris host fronting the\n * deployment; its origin derives the statewire sync mount when\n * `statewireSyncUrl` is not set. */\n apiUrl?: string;\n\n /** @deprecated Prefer `config.backendUrl`. URL for the Athena backend API. */\n backendUrl?: string;\n\n /** @deprecated Prefer `config.appUrl`. URL for the Athena frontend app origin. */\n appUrl?: string;\n\n /** @deprecated Prefer `config.environment`. Athena environment preset used when URLs are not explicitly provided. */\n environment?: AthenaEnvironment;\n\n /** Resolve the latest auth token immediately before a request (for\n * expiring clients). Takes priority over `token` when it resolves.\n * Prefer `config.getToken` (see its `force` contract for refused\n * credentials). */\n getToken?: AthenaStatewireTokenGetter;\n\n /** Additional fields merged into runConfig.custom. Prefer\n * `config.extraRunConfig`. */\n extraRunConfig?: Record<string, unknown>;\n\n /** Statewire sync base URL override (the `…/v2/threads` mount). Defaults to\n * the mount a Marathon host mints, then the effective `apiUrl` host +\n * `/v2/threads`. Prefer `config.statewireSyncUrl`. */\n statewireSyncUrl?: string;\n\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n\n /** System prompt override. */\n systemPrompt?: string;\n\n /** Client app identifier for session filtering.\n * Sessions created with this ID can be filtered in the thread list.\n * E.g. \"olympus\", \"athena-app\", or a computer asset ID like \"asset_<uuid>\". */\n appId?: string;\n\n /** Thread ID override. Auto-generated if not provided. */\n threadId?: string;\n\n /** Enable thread list management (sidebar thread switching). */\n enableThreadList?: boolean;\n\n /** Ask the thread list for live pull-request state on each session\n * (`include_pull_requests`), which `SessionList` renders as chips.\n * Defaults to `true` in thread-list mode; turn it off in a host that never\n * shows them to spare the server the lookup. */\n threadListIncludePullRequests?: boolean;\n\n /** Theme configuration. Pass a preset from `themes` or a custom `AthenaTheme` object.\n * Injects CSS variables on a wrapper element — no CSS files needed.\n *\n * @example\n * import { themes } from '@athenaintel/react';\n * <AthenaProvider theme={themes.dark}>\n *\n * @example\n * <AthenaProvider theme={{ primary: '#8b5cf6', radius: '1rem' }}>\n *\n * @example\n * <AthenaProvider theme={{ ...themes.dark, primary: '#22c55e' }}>\n */\n theme?: AthenaTheme;\n\n /** Customize how rendered chat links behave. */\n linkClicks?: AthenaLinkClickOptions;\n\n /** @deprecated Prefer `linkClicks`. Customize how Athena citation links rendered in chat messages behave. */\n citationLinks?: AthenaCitationLinkOptions;\n\n /** PostHog analytics configuration. When omitted or keys are missing, PostHog is silently disabled.\n * Prefer `config.posthog` for structured configuration. */\n posthog?: PostHogConfig;\n\n /** SDK diagnostics.\n *\n * - `true` / a level: echo structured `[AthenaSDK]` events to the console\n * at that level (`true` = 'debug').\n * - An object: full diagnostics config (console level, PostHog timing\n * forwarding, buffer size).\n *\n * Independent of the prop, `localStorage.setItem('athena:debug','debug')`\n * (or `window.__ATHENA_SDK__.diagnostics.enableConsole()`) turns console\n * echo on at runtime without a rebuild. Errors log once even when off. */\n debug?: boolean | AthenaDiagnosticLevel | Partial<AthenaDiagnosticsConfig>;\n\n /** Receives every diagnostics event (timings, warnings, errors) — the hook\n * for shipping SDK telemetry to the host app's own pipeline. */\n onDiagnostic?: (event: AthenaDiagnosticEvent) => void;\n\n /** Receives every SDK error as a typed `AthenaSdkError` (stable `code`,\n * `hint`, structured server `detail`). Fires in addition to the UI's own\n * error handling, so integrations never fail silently. */\n onError?: (error: AthenaSdkError, event: AthenaDiagnosticEvent) => void;\n}\n\nconst resolveTokenOverride = ({\n config,\n token,\n}: {\n config?: AthenaProviderConfig;\n token?: string | null;\n}): string | null | undefined => {\n if (config?.token !== undefined) {\n return config.token;\n }\n return token;\n};\n\nconst useAthenaConfigValue = ({\n backendUrl,\n appUrl,\n apiKey,\n token,\n getToken,\n enabledToolkits,\n linkClicks,\n citationLinks,\n}: {\n backendUrl: string;\n appUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}): AthenaConfig => {\n const linkClicksRef = useRef(linkClicks);\n linkClicksRef.current = linkClicks;\n const citationLinksRef = useRef(citationLinks);\n citationLinksRef.current = citationLinks;\n // Keep token in a ref so its value can update without invalidating the\n // config object identity. PropelAuth rotates tokens on window focus —\n // if token were a memo dep, every rotation would publish a new config\n // object to context and force every consumer (e.g. AssetIframe) to\n // re-render, causing asset panel flicker.\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const getTokenRef = useRef(getToken);\n getTokenRef.current = getToken;\n\n return useMemo(\n () => ({\n backendUrl,\n appUrl,\n apiKey,\n enabledToolkits,\n get token() {\n return tokenRef.current;\n },\n get getToken() {\n return getTokenRef.current;\n },\n get linkClicks() {\n return linkClicksRef.current;\n },\n get citationLinks() {\n return citationLinksRef.current;\n },\n }),\n [backendUrl, appUrl, apiKey, enabledToolkits],\n );\n};\n\n/**\n * Delivers composer writes that were made before this mount was ready\n * (`useAppendToComposer` / `useSendMessage` queue them in the provider-level\n * store, which outlives the keyed per-thread mount). Lives under the\n * `AuiProvider` so it can read the thread's own loading state.\n */\nfunction ComposerHandoffDrain(): null {\n const aui = useAui();\n const store = useComposerHandoffStore();\n const threadId = useContext(AthenaStatewireThreadIdContext);\n const ready = useComposerReady();\n useEffect(() => {\n if (!ready || !store) return;\n // Writes bound to another thread are dropped here, not applied.\n drainComposerHandoff({ store, target: aui, threadId });\n }, [aui, ready, store, threadId]);\n return null;\n}\n\n// ─── Standalone Mode ──────────────────────────────────────────────────\n\n/** Everything the per-thread runtime needs to attach and run a thread. */\ninterface AthenaStatewireRuntimeProps {\n syncUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n model?: string;\n agent?: string;\n channel?: string;\n tools: string[];\n frontendToolIds: string[];\n frontendTools: Toolkit;\n workbench?: string[];\n knowledgeBase?: string[];\n systemPrompt?: string;\n appId?: string;\n extraRunConfig?: Record<string, unknown>;\n /** The provider-owned snapshot cache (see `AthenaProvider`). */\n snapshotCache: DeepAgentThreadSnapshotCache;\n /** The provider-owned store of fetched-back cut tool outputs (see `AthenaProvider`). */\n toolOutputs: DeepAgentToolOutputStore;\n}\n\ninterface AthenaStatewireStandaloneProps extends AthenaStatewireRuntimeProps {\n children: ReactNode;\n backendUrl: string;\n appUrl: string;\n threadId?: string;\n /**\n * Thread-list mode. The list owns the active id and alone knows whether the\n * backend has listed it yet: `isNewChat` overrides the \"new chat\"\n * derivation (the list mints ids for brand-new chats, which must still load\n * as new), and the scope publishes `AthenaThreadIdContext` — the backend id,\n * withheld while the chat is unpersisted. Absent outside thread-list mode,\n * where that context stays untouched.\n */\n threadList?: { isNewChat: boolean };\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\n/**\n * What one per-thread runtime mount hands to the stable scope around the\n * host's children: the assistant client attached to `threadId` and the\n * transport lifecycle observed on that attach. Published as ONE value so the\n * scope can never pair a thread's id with another thread's client.\n */\ninterface AthenaStatewireRuntimeSnapshot {\n threadId: string;\n isNewChat: boolean;\n client: AssistantClient;\n lifecycle: AthenaStatewireLifecycleState;\n}\n\n/**\n * The per-thread half of the statewire lane: owns the runtime hook (statewire\n * client, pending-message lane, `useAui` client) and the lifecycle reducer\n * behind the connection/error banners, and renders nothing itself. Mounted\n * under `key={threadId}` so a switch — or a new chat — gets a fresh instance\n * of everything here, exactly as when the whole provider subtree was keyed,\n * without remounting the host's UI.\n *\n * An assistant client's readable state only advances when its tap fibers\n * commit (in effects), so an in-place `threadId` change on one mounted hook\n * would leave a commit in which the new id is published but `useAuiState`\n * still reads the previous thread's committed state; a fresh mount publishes\n * its own state on its first render. That is why the runtime is remounted per\n * thread rather than switched in place.\n *\n * The snapshot is published from a layout effect: React flushes the state\n * update a layout effect schedules synchronously, before the browser paints,\n * so the scope re-renders against this client in the same task as this\n * mount's commit — the previous client is never painted under the new id.\n */\nfunction AthenaStatewireRuntimeMount({\n threadId,\n isNewChat,\n onPublish,\n syncUrl,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n}: AthenaStatewireRuntimeProps & {\n threadId: string;\n isNewChat: boolean;\n onPublish: (snapshot: AthenaStatewireRuntimeSnapshot) => void;\n}): null {\n const [lifecycle, dispatchLifecycle] = useReducer(\n statewireLifecycleReducer,\n initialStatewireLifecycle,\n );\n\n const client = useAthenaStatewireRuntime({\n syncUrl,\n threadId,\n isNewChat,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendToolkit: frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n // The runtime already records every transport error on the diagnostics\n // bus (with the channel-teardown split), so this layer only maps it to\n // the banner notice.\n onError: (error) => {\n const notice = athenaStatewireErrorNotice(error);\n if (notice) dispatchLifecycle({ type: 'error', error: notice });\n },\n onConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'connection', connection });\n },\n onRawConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'raw-connection', reconnect: connection.reconnect });\n },\n });\n\n const dismissError = useCallback(\n () => dispatchLifecycle({ type: 'error', error: null }),\n [],\n );\n const lifecycleValue = useMemo<AthenaStatewireLifecycleState>(\n () => ({\n connection: lifecycle.connection,\n error: lifecycle.error,\n reconnect: lifecycle.reconnect,\n dismissError,\n }),\n [lifecycle, dismissError],\n );\n\n const snapshot = useMemo<AthenaStatewireRuntimeSnapshot>(\n () => ({ threadId, isNewChat, client, lifecycle: lifecycleValue }),\n [threadId, isNewChat, client, lifecycleValue],\n );\n useLayoutEffect(() => {\n onPublish(snapshot);\n }, [onPublish, snapshot]);\n\n return null;\n}\n\n/**\n * The stable half of the statewire lane: the scope around the host's\n * `children`. It mounts one `AthenaStatewireRuntimeMount` per thread beside\n * them and provides whatever that mount last published — client, thread ids,\n * lifecycle — so a thread switch swaps the client under the host's UI instead\n * of remounting it. Until the first mount has published, the children are\n * withheld: they need a client, and the first publication lands in the same\n * task as the mount's commit.\n *\n * A server render runs no effects, so it would withhold the children too.\n * That changes nothing today: `AthenaProvider` renders `null` until the parent\n * bridge reports ready, which only ever happens in an effect (`useParentBridge`\n * starts `ready: false`), so the SDK has never server-rendered the host UI —\n * it hydrates it. A future SSR-ready bridge would need the first publication\n * to happen in render as well.\n */\nfunction AthenaStatewireStandalone({\n children,\n backendUrl,\n appUrl,\n threadId: threadIdProp,\n threadList,\n linkClicks,\n citationLinks,\n ...runtimeProps\n}: AthenaStatewireStandaloneProps) {\n // Statewire attaches to `${syncUrl}/${threadId}`, so a thread ID must exist\n // up front. An auto-generated ID is by definition a never-started local chat.\n const generatedIdRef = useRef<string | null>(null);\n if (generatedIdRef.current === null) {\n generatedIdRef.current = mintThreadId();\n }\n const threadId = threadIdProp ?? generatedIdRef.current;\n const isNewChat = threadList?.isNewChat ?? !threadIdProp;\n\n const [published, setPublished] = useState<AthenaStatewireRuntimeSnapshot | null>(null);\n\n const clientTools = useStatewireClientTools(runtimeProps.frontendTools);\n\n // The runtime binds `client_tools` only for a recognised `app_id`; with none\n // it drops every declaration without telling the client, and the model then\n // sees \"not a valid tool\". Say so here, once per configuration, as an error\n // so it reaches `onError` and the console even with diagnostics off.\n const clientToolNamesKey = clientTools.map((tool) => tool.definition.name).join(',');\n const clientToolAppId = runtimeProps.appId;\n useEffect(() => {\n if (clientTools.length === 0 || resolveClientToolSurface(clientToolAppId) !== null) return;\n athenaDiagnostics.emit('sdk.config.warning', {\n level: 'error',\n error: new AthenaSdkError({\n code: 'config_invalid',\n message: `frontendTools with an execute() need a recognised appId; ${clientTools.length} tool(s) will not be bound.`,\n hint:\n \"Pass appId={publicAppId} on <AthenaProvider> (a computer-asset app reads it from athena-public-config.json as computer_asset_<uuid>). Without it the deep-agent runtime drops every client tool.\",\n context: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n }),\n data: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n });\n // clientToolNamesKey is the value-stable form of the tool list.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [clientToolAppId, clientToolNamesKey]);\n\n const athenaConfig = useAthenaConfigValue({\n backendUrl,\n appUrl,\n apiKey: runtimeProps.apiKey,\n token: runtimeProps.token,\n getToken: runtimeProps.getToken,\n enabledToolkits: runtimeProps.tools,\n linkClicks,\n citationLinks,\n });\n\n const scope = published && (\n <AuiProvider value={published.client}>\n <AthenaContext.Provider value={athenaConfig}>\n <AthenaStatewireThreadIdContext.Provider value={published.threadId}>\n <AthenaStatewireLifecycleContext.Provider value={published.lifecycle}>\n <DeepAgentConnectionContext.Provider value={published.lifecycle.connection}>\n <StatewireToolOutputsContext.Provider value={runtimeProps.toolOutputs}>\n <TooltipProvider>\n <StatewireClientToolBridge tools={clientTools} threadId={published.threadId} />\n <ComposerHandoffDrain />\n {children}\n </TooltipProvider>\n </StatewireToolOutputsContext.Provider>\n </DeepAgentConnectionContext.Provider>\n </AthenaStatewireLifecycleContext.Provider>\n </AthenaStatewireThreadIdContext.Provider>\n </AthenaContext.Provider>\n </AuiProvider>\n );\n\n return (\n <>\n <AthenaStatewireRuntimeMount\n key={threadId}\n threadId={threadId}\n isNewChat={isNewChat}\n onPublish={setPublished}\n {...runtimeProps}\n />\n {/* The backend id rides the same snapshot as the client, so\n history-gated UI (e.g. the loading overlay) never judges one thread\n by another's state; it is undefined for a never-started chat, which\n must not read as pending history. */}\n {threadList && published ? (\n <AthenaThreadIdContext.Provider\n value={published.isNewChat ? undefined : published.threadId}\n >\n {scope}\n </AthenaThreadIdContext.Provider>\n ) : (\n scope\n )}\n </>\n );\n}\n\n// ─── Thread List Mode ─────────────────────────────────────────────────\n\nfunction AthenaStatewireWithThreadList({\n children,\n backendUrl,\n syncUrl,\n appId,\n apiKey,\n token,\n getToken,\n initialThreadId,\n includePullRequests,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'> & {\n initialThreadId?: string;\n includePullRequests?: boolean;\n}) {\n return (\n <AthenaStatewireThreadListProvider\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n appId={appId}\n initialThreadId={initialThreadId}\n includePullRequests={includePullRequests}\n // The list's hover prefetch warms the same cache the active-thread\n // mount seeds from, so a hovered-then-selected session paints at once.\n snapshotCache={standaloneProps.snapshotCache}\n >\n <AthenaStatewireActiveThreadHost\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n appId={appId}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n {...standaloneProps}\n >\n {children}\n </AthenaStatewireActiveThreadHost>\n </AthenaStatewireThreadListProvider>\n );\n}\n\nfunction AthenaStatewireActiveThreadHost({\n children,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'>) {\n const list = useAthenaStatewireThreadList();\n if (!list) return null;\n\n // Not keyed: the scope keeps the host's children mounted across a switch\n // and remounts only its per-thread runtime against the new\n // `…/v2/threads/{id}` URL (see `AthenaStatewireStandalone`).\n return (\n <AthenaStatewireStandalone\n threadId={list.activeThreadId}\n threadList={{ isNewChat: list.isNewChat }}\n {...standaloneProps}\n >\n <StatewireThreadTitlePoller />\n <AssetPanelThreadSync />\n {children}\n </AthenaStatewireStandalone>\n );\n}\n\n/**\n * Syncs the active thread ID into the asset panel store so that open asset\n * tabs are scoped per-thread automatically.\n *\n * Scoped by the attached thread's minted id from creation onward — NOT by\n * `useAthenaThreadManager().activeThreadId`, which is deliberately `null`\n * while a new chat is unpersisted (so URL sync never names it). The minted id\n * is the id the thread persists under, so tabs opened in a brand-new chat\n * stay put when the backend first lists it instead of being left behind in a\n * `null` scope the store never restores. Read from the statewire scope (the\n * id published with its client) rather than the list's selection, which runs\n * one commit ahead of the client during a switch.\n */\nfunction AssetPanelThreadSync() {\n const threadId = useAthenaStatewireThreadId();\n const setCurrentThread = useAssetPanelStore((s) => s.setCurrentThread);\n\n useEffect(() => {\n setCurrentThread(threadId);\n }, [threadId, setCurrentThread]);\n\n return null;\n}\n\n// ─── Main Provider ────────────────────────────────────────────────────\n\nexport function AthenaProvider({\n children,\n config,\n apiKey,\n token: tokenProp,\n agent,\n channel,\n model,\n tools = [],\n frontendTools = {},\n disableAutoOpen = false,\n apiUrl,\n backendUrl,\n appUrl,\n environment,\n statewireSyncUrl,\n getToken,\n extraRunConfig,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n threadId: threadIdProp,\n enableThreadList = false,\n threadListIncludePullRequests = true,\n theme,\n linkClicks,\n citationLinks,\n posthog: posthogProp,\n debug,\n onDiagnostic,\n onError,\n}: AthenaProviderProps) {\n // Fail loud before any effect, bridge wait, or network call: an `agent`\n // outside the collab_agent namespace can never apply, so a misconfigured\n // deployment must die at first render rather than answer as the wrong agent.\n resolveAgentProp({ agent });\n\n // Diagnostics wiring first, so everything below is observable. Callbacks\n // ride refs: a per-render closure must not re-register the consumer. Each\n // provider registers its OWN consumer (additive, cleaned up on unmount), so\n // two mounted providers never clobber each other's onDiagnostic/onError —\n // only the console/PostHog/buffer settings are global (last writer wins).\n const onDiagnosticRef = useRef(onDiagnostic);\n onDiagnosticRef.current = onDiagnostic;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n useEffect(() => {\n installAthenaDiagnosticsGlobal();\n return athenaDiagnostics.addConsumer({\n onEvent: (event) => onDiagnosticRef.current?.(event),\n onError: (error, event) => onErrorRef.current?.(error, event),\n });\n }, []);\n const debugKey = JSON.stringify(debugPropToDiagnosticsConfig(debug));\n useEffect(() => {\n athenaDiagnostics.configure(debugPropToDiagnosticsConfig(debug));\n // debugKey is the value-stable form of `debug` (consumers pass literals).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debugKey]);\n // Only declarations WITHOUT a local `execute` ride `enabled_tools`: they name\n // registry tools the backend binds itself. Executable tools are declared\n // through `client_tools` instead — listing them here too would switch on a\n // backend toolkit owning a tool of the same name, and the backend wins that\n // collision (the client tool is silently dropped).\n const frontendToolNames = useMemo(\n () => backendDeclaredFrontendToolIds(frontendTools),\n [frontendTools],\n );\n // Merge SDK auto-open defaults under the consumer's frontendTools. Consumer\n // entries win on name collision; auto-open tool names are NOT added to\n // frontendToolIds (they are already backend-advertised by their toolkits).\n const effectiveFrontendTools = useMemo<Toolkit>(\n () => (disableAutoOpen ? frontendTools : { ...DEFAULT_AUTO_OPEN_TOOLS, ...frontendTools }),\n [disableAutoOpen, frontendTools],\n );\n const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : undefined, [theme]);\n const configuredEnvironment = config?.environment ?? environment;\n const environmentUrls = useMemo(\n () => getAthenaEnvironmentUrls({ environment: configuredEnvironment }),\n [configuredEnvironment],\n );\n const configuredApiKey = config?.apiKey ?? apiKey;\n const configuredToken = resolveTokenOverride({ config, token: tokenProp });\n const configuredApiUrl = config?.apiUrl ?? apiUrl;\n const configuredBackendUrl = config?.backendUrl ?? backendUrl;\n const configuredAppUrl = config?.appUrl ?? appUrl;\n const configuredStatewireSyncUrl = config?.statewireSyncUrl ?? statewireSyncUrl;\n const configuredGetToken = config?.getToken ?? getToken;\n const configuredExtraRunConfig = config?.extraRunConfig ?? extraRunConfig;\n const configuredTrustedParentOrigins = config?.trustedParentOrigins;\n const posthogConfig: PostHogConfig | undefined = config?.posthog ?? posthogProp;\n\n // Statewire is the SDK's only chat transport; the gauge/event stay on the\n // diagnostics contract so dashboards keyed on them keep reading a value.\n useEffect(() => {\n athenaDiagnostics.gauge('sdk.transport', 'statewire');\n athenaDiagnostics.emit('sdk.transport', {\n level: 'debug',\n data: { transport: 'statewire', thread_list: enableThreadList },\n });\n }, [enableThreadList]);\n\n const bridge = useParentBridge({\n trustedOrigins: configuredTrustedParentOrigins,\n });\n\n // If an AthenaAuthProvider is present above us, use its access token automatically.\n const authContext = useContext(AthenaAuthContext);\n const authProviderToken = authContext?.accessToken ?? null;\n\n // Per-provider snapshot cache: a switch back to a recently-visited thread\n // mounts with its last-known snapshot instead of a loading spinner. Owned\n // here, above the per-thread keyed mount, so it survives switches; cleared\n // when the acting identity changes so a snapshot captured under one account\n // never seeds a mount under another.\n const [snapshotCache] = useState(() => createDeepAgentThreadSnapshotCache());\n // Composer writes that arrive before the per-thread mount is ready wait\n // here, above that mount, so a thread-list remount cannot drop them.\n const [composerHandoff] = useState(createComposerHandoffStore);\n // The windowed wire's fetched-back tool outputs, owned alongside the cache\n // for the same reasons: shared across the provider's thread switches (a\n // tool message id is unique across threads), dropped with the identity.\n const [toolOutputs] = useState(() => createDeepAgentToolOutputStore());\n const principal = authContext?.user?.userId ?? '';\n useEffect(() => {\n snapshotCache.clear();\n toolOutputs.clear();\n // A draft or send queued under the previous identity must never land in\n // this one's composer.\n clearComposerHandoff({ store: composerHandoff, reason: 'the signed-in identity changed' });\n }, [snapshotCache, toolOutputs, composerHandoff, principal, configuredApiKey]);\n // Nothing drains after the provider is gone: settle what still waits so no\n // `useSendMessage` caller hangs.\n useEffect(\n () => () => clearComposerHandoff({ store: composerHandoff, reason: 'the chat provider unmounted' }),\n [composerHandoff],\n );\n\n const effectiveToken = configuredToken !== undefined\n ? configuredToken\n : authProviderToken ?? bridge.token;\n // Explicit config wins. A Marathon host mints the statewire mount, the bare\n // Agora base and the app origin outright (`/_athena/auth`, or a trusted\n // parent's `athena-config`); the environment preset is the last resort, and\n // the sync mount derives from the `apiUrl` host when no host minted one.\n const effectiveApiUrl = configuredApiUrl ?? environmentUrls.apiUrl;\n // Published as the bare Agora base: a historical `…/api/assistant-ui` value\n // is trimmed here once rather than by each REST helper.\n const effectiveBackendUrl = getAthenaApiBaseUrl(\n configuredBackendUrl ?? bridge.backendBaseUrl ?? environmentUrls.backendUrl,\n );\n const hostStatewireSyncUrl = configuredStatewireSyncUrl ?? bridge.statewireSyncUrl ?? undefined;\n const effectiveAppUrl = configuredAppUrl\n ?? bridge.appUrl\n ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl })\n ?? environmentUrls.appUrl;\n\n // Wait for the parent bridge to deliver config/auth before rendering.\n // This prevents the thread list from fetching with wrong URLs or no token.\n // Falls back after a short timeout (2s) if no bridge responds.\n if (!bridge.ready) {\n return null;\n }\n\n // Both throw on an unresolvable configuration instead of falling back to an\n // Athena default — a custom deployment's credentials must never be sent to\n // a host the consumer didn't configure. A host that answered the bridge\n // without minting the statewire mount is that case: its token would\n // otherwise ride the environment preset.\n assertHostMintedStatewireMount({\n hostAnswered: bridge.hostAnswered,\n hostStatewireSyncUrl: bridge.statewireSyncUrl,\n statewireSyncUrl: configuredStatewireSyncUrl,\n apiUrl: configuredApiUrl,\n });\n const effectiveStatewireSyncUrl = resolveStatewireSyncUrl({\n statewireSyncUrl: hostStatewireSyncUrl,\n apiUrl: effectiveApiUrl,\n });\n\n const statewireProps = {\n syncUrl: effectiveStatewireSyncUrl,\n backendUrl: effectiveBackendUrl,\n appUrl: effectiveAppUrl,\n apiKey: configuredApiKey,\n token: effectiveToken,\n getToken: configuredGetToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds: frontendToolNames,\n frontendTools: effectiveFrontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig: configuredExtraRunConfig,\n snapshotCache,\n toolOutputs,\n linkClicks,\n citationLinks,\n };\n\n const inner: ReactNode = enableThreadList ? (\n <AthenaStatewireWithThreadList\n {...statewireProps}\n initialThreadId={threadIdProp}\n includePullRequests={threadListIncludePullRequests}\n >\n {children}\n </AthenaStatewireWithThreadList>\n ) : (\n <AthenaStatewireStandalone {...statewireProps} threadId={threadIdProp}>\n {children}\n </AthenaStatewireStandalone>\n );\n\n // The .athena-sdk wrapper (display: contents) anchors the SDK's design\n // tokens and scoped preflight from styles.css, so the stylesheet works\n // in hosts without their own Tailwind build. PostHog gracefully no-ops\n // when its config is missing.\n return (\n <div\n className={themeStyleVars ? \"athena-sdk athena-themed\" : \"athena-sdk\"}\n style={themeStyleVars as React.CSSProperties | undefined}\n >\n <PostHogProvider config={posthogConfig}>\n <ComposerHandoffContext.Provider value={composerHandoff}>\n {inner}\n </ComposerHandoffContext.Provider>\n </PostHogProvider>\n </div>\n );\n}\n"],"names":["useRef","useMemo","useAui","useComposerHandoffStore","useContext","AthenaStatewireThreadIdContext","useComposerReady","useEffect","drainComposerHandoff","toolOutputs","useReducer","statewireLifecycleReducer","initialStatewireLifecycle","useAthenaStatewireRuntime","athenaStatewireErrorNotice","useCallback","useLayoutEffect","mintThreadId","useState","useStatewireClientTools","resolveClientToolSurface","athenaDiagnostics","AthenaSdkError","jsx","AuiProvider","AthenaContext","AthenaStatewireLifecycleContext","DeepAgentConnectionContext","StatewireToolOutputsContext","TooltipProvider","StatewireClientToolBridge","jsxs","Fragment","AthenaThreadIdContext","AthenaStatewireThreadListProvider","useAthenaStatewireThreadList","StatewireThreadTitlePoller","useAthenaStatewireThreadId","useAssetPanelStore","resolveAgentProp","installAthenaDiagnosticsGlobal","_a","debugPropToDiagnosticsConfig","backendDeclaredFrontendToolIds","DEFAULT_AUTO_OPEN_TOOLS","themeToStyleVars","getAthenaEnvironmentUrls","useParentBridge","AthenaAuthContext","createDeepAgentThreadSnapshotCache","composerHandoff","createComposerHandoffStore","createDeepAgentToolOutputStore","clearComposerHandoff","getAthenaApiBaseUrl","deriveAthenaAppUrl","assertHostMintedStatewireMount","resolveStatewireSyncUrl","PostHogProvider","ComposerHandoffContext"],"mappings":"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"}
1
+ {"version":3,"file":"AthenaProvider.cjs","sources":["../../src/provider/AthenaProvider.tsx"],"sourcesContent":["import { AuiProvider, useAui } from '@assistant-ui/react';\nimport {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport type { AssistantClient, Toolkit } from '@assistant-ui/react';\nimport {\n createDeepAgentThreadSnapshotCache,\n createDeepAgentToolOutputStore,\n DeepAgentConnectionContext,\n type DeepAgentThreadSnapshotCache,\n type DeepAgentToolOutputStore,\n} from '@athenaintel/agent-runtime';\nimport {\n assertHostMintedStatewireMount,\n deriveAthenaAppUrl,\n getAthenaEnvironmentUrls,\n resolveStatewireSyncUrl,\n type AthenaEnvironment,\n} from '../lib/athena-urls';\nimport { getAthenaApiBaseUrl } from '../collab/mint';\nimport { useParentBridge } from '../runtime/auth';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport {\n useAthenaStatewireRuntime,\n useStatewireClientTools,\n} from '../runtime/useAthenaStatewireRuntime';\nimport {\n athenaStatewireErrorNotice,\n type AthenaStatewireLifecycleState,\n initialStatewireLifecycle,\n statewireLifecycleReducer,\n} from '../runtime/statewire-lifecycle';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { resolveAgentProp } from '../runtime/statewire-run-config';\nimport { mintThreadId } from '../threads/mint-thread-id';\nimport { AthenaStatewireLifecycleContext } from './statewire-lifecycle-context';\nimport {\n ComposerHandoffContext,\n clearComposerHandoff,\n createComposerHandoffStore,\n drainComposerHandoff,\n useComposerHandoffStore,\n useComposerReady,\n} from '../composer/composer-handoff';\nimport { StatewireToolOutputsContext } from './statewire-window-context';\nimport { StatewireClientToolBridge } from '../chat/StatewireClientToolBridge';\nimport {\n athenaDiagnostics,\n debugPropToDiagnosticsConfig,\n installAthenaDiagnosticsGlobal,\n type AthenaDiagnosticEvent,\n type AthenaDiagnosticLevel,\n type AthenaDiagnosticsConfig,\n} from '../diagnostics/athena-diagnostics';\nimport { AthenaSdkError } from '../diagnostics/errors';\nimport {\n backendDeclaredFrontendToolIds,\n resolveClientToolSurface,\n} from '../chat/statewire-client-tools';\nimport { TooltipProvider } from '../ui/tooltip';\nimport { DEFAULT_AUTO_OPEN_TOOLS } from '../tools/auto-open-tools';\nimport { AthenaContext, type AthenaConfig } from './AthenaContext';\nimport type { AthenaProviderConfig } from './config';\nimport type {\n AthenaCitationLinkOptions,\n AthenaLinkClickOptions,\n} from './citation-links';\nimport {\n AthenaStatewireThreadIdContext,\n AthenaThreadIdContext,\n useAthenaStatewireThreadId,\n} from '../threads/thread-id-context';\nimport {\n AthenaStatewireThreadListProvider,\n StatewireThreadTitlePoller,\n useAthenaStatewireThreadList,\n} from '../threads/statewire-thread-list';\nimport { useAssetPanelStore } from '../assets/asset-panel-store';\nimport { themeToStyleVars, type AthenaTheme } from '../theme';\nimport { AthenaThemeStyleContext } from './theme-style-context';\nimport { PostHogProvider, type PostHogConfig } from './PostHogProvider';\n\nexport interface AthenaProviderProps {\n children: ReactNode;\n\n /** Preferred structured config for auth and Athena endpoint settings. */\n config?: AthenaProviderConfig;\n\n /** @deprecated Prefer `config.apiKey`. API key for authentication in standalone mode. */\n apiKey?: string;\n\n /** @deprecated Prefer `config.token`. PropelAuth token. If provided, takes priority over apiKey. If omitted, the SDK\n * will automatically listen for a token from the parent window via PostMessage. */\n token?: string | null;\n\n /** Run the thread AS a published collab agent. The only accepted shape is\n * `collab_agent:<asset_id>`: the thread then uses that agent's prompt,\n * tools, and model default, and the caller must have view access to the\n * agent asset. Omit it (or pass a blank string) to run the Athena deep agent.\n *\n * Any other non-blank value throws at render — the statewire host cannot\n * honour named agents, and a selector that is silently dropped would let a\n * misconfigured deployment answer as the wrong agent. */\n agent?: string;\n\n /** Collab-agent channel id — a built-in channel (`email`, `sms`, …) or a\n * user-defined custom channel id from the agent's Channels tab. Selects\n * that channel's configuration overrides and stamps the session's origin.\n * Only meaningful together with a `collab_agent:<asset_id>` `agent`; sent\n * as `collab_channel_id`. An unknown or disabled channel rejects the run\n * with a structured, teaching error. */\n channel?: string;\n\n /** LLM model identifier. Defaults to the deep-agent default model\n * (`DEFAULT_STATEWIRE_MODEL`) — or, when a collab agent is selected, to\n * the model its author configured. */\n model?: string;\n\n /** Backend toolkit IDs to enable (e.g. 'document_toolkit', 'web_search_browse_toolkit'). */\n tools?: string[];\n\n /** Frontend tools that execute in the browser. The agent can invoke these.\n * Merged on top of the SDK's default auto-open tools; entries here take\n * precedence over defaults with the same name. Tools with a local\n * `execute` are declared to the backend as `client_tools` and run through\n * the statewire client-tool bridge. */\n frontendTools?: Toolkit;\n\n /** Disable the SDK's default auto-open behavior for created/touched assets. */\n disableAutoOpen?: boolean;\n\n /** @deprecated Prefer `config.apiUrl`. URL on the Iris host fronting the\n * deployment; its origin derives the statewire sync mount when\n * `statewireSyncUrl` is not set. */\n apiUrl?: string;\n\n /** @deprecated Prefer `config.backendUrl`. URL for the Athena backend API. */\n backendUrl?: string;\n\n /** @deprecated Prefer `config.appUrl`. URL for the Athena frontend app origin. */\n appUrl?: string;\n\n /** @deprecated Prefer `config.environment`. Athena environment preset used when URLs are not explicitly provided. */\n environment?: AthenaEnvironment;\n\n /** Resolve the latest auth token immediately before a request (for\n * expiring clients). Takes priority over `token` when it resolves.\n * Prefer `config.getToken` (see its `force` contract for refused\n * credentials). */\n getToken?: AthenaStatewireTokenGetter;\n\n /** Additional fields merged into runConfig.custom. Prefer\n * `config.extraRunConfig`. */\n extraRunConfig?: Record<string, unknown>;\n\n /** Statewire sync base URL override (the `…/v2/threads` mount). Defaults to\n * the mount a Marathon host mints, then the effective `apiUrl` host +\n * `/v2/threads`. Prefer `config.statewireSyncUrl`. */\n statewireSyncUrl?: string;\n\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n\n /** System prompt override. */\n systemPrompt?: string;\n\n /** Client app identifier for session filtering.\n * Sessions created with this ID can be filtered in the thread list.\n * E.g. \"olympus\", \"athena-app\", or a computer asset ID like \"asset_<uuid>\". */\n appId?: string;\n\n /** Thread ID override. Auto-generated if not provided. */\n threadId?: string;\n\n /** Enable thread list management (sidebar thread switching). */\n enableThreadList?: boolean;\n\n /** Ask the thread list for live pull-request state on each session\n * (`include_pull_requests`), which `SessionList` renders as chips.\n * Defaults to `true` in thread-list mode; turn it off in a host that never\n * shows them to spare the server the lookup. */\n threadListIncludePullRequests?: boolean;\n\n /** Theme configuration. Pass a preset from `themes` or a custom `AthenaTheme` object.\n * Injects CSS variables on a wrapper element — no CSS files needed.\n *\n * @example\n * import { themes } from '@athenaintel/react';\n * <AthenaProvider theme={themes.dark}>\n *\n * @example\n * <AthenaProvider theme={{ primary: '#8b5cf6', radius: '1rem' }}>\n *\n * @example\n * <AthenaProvider theme={{ ...themes.dark, primary: '#22c55e' }}>\n */\n theme?: AthenaTheme;\n\n /** Customize how rendered chat links behave. */\n linkClicks?: AthenaLinkClickOptions;\n\n /** @deprecated Prefer `linkClicks`. Customize how Athena citation links rendered in chat messages behave. */\n citationLinks?: AthenaCitationLinkOptions;\n\n /** PostHog analytics configuration. When omitted or keys are missing, PostHog is silently disabled.\n * Prefer `config.posthog` for structured configuration. */\n posthog?: PostHogConfig;\n\n /** SDK diagnostics.\n *\n * - `true` / a level: echo structured `[AthenaSDK]` events to the console\n * at that level (`true` = 'debug').\n * - An object: full diagnostics config (console level, PostHog timing\n * forwarding, buffer size).\n *\n * Independent of the prop, `localStorage.setItem('athena:debug','debug')`\n * (or `window.__ATHENA_SDK__.diagnostics.enableConsole()`) turns console\n * echo on at runtime without a rebuild. Errors log once even when off. */\n debug?: boolean | AthenaDiagnosticLevel | Partial<AthenaDiagnosticsConfig>;\n\n /** Receives every diagnostics event (timings, warnings, errors) — the hook\n * for shipping SDK telemetry to the host app's own pipeline. */\n onDiagnostic?: (event: AthenaDiagnosticEvent) => void;\n\n /** Receives every SDK error as a typed `AthenaSdkError` (stable `code`,\n * `hint`, structured server `detail`). Fires in addition to the UI's own\n * error handling, so integrations never fail silently. */\n onError?: (error: AthenaSdkError, event: AthenaDiagnosticEvent) => void;\n}\n\nconst resolveTokenOverride = ({\n config,\n token,\n}: {\n config?: AthenaProviderConfig;\n token?: string | null;\n}): string | null | undefined => {\n if (config?.token !== undefined) {\n return config.token;\n }\n return token;\n};\n\nconst useAthenaConfigValue = ({\n backendUrl,\n appUrl,\n apiKey,\n token,\n getToken,\n enabledToolkits,\n linkClicks,\n citationLinks,\n}: {\n backendUrl: string;\n appUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}): AthenaConfig => {\n const linkClicksRef = useRef(linkClicks);\n linkClicksRef.current = linkClicks;\n const citationLinksRef = useRef(citationLinks);\n citationLinksRef.current = citationLinks;\n // Keep token in a ref so its value can update without invalidating the\n // config object identity. PropelAuth rotates tokens on window focus —\n // if token were a memo dep, every rotation would publish a new config\n // object to context and force every consumer (e.g. AssetIframe) to\n // re-render, causing asset panel flicker.\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const getTokenRef = useRef(getToken);\n getTokenRef.current = getToken;\n\n return useMemo(\n () => ({\n backendUrl,\n appUrl,\n apiKey,\n enabledToolkits,\n get token() {\n return tokenRef.current;\n },\n get getToken() {\n return getTokenRef.current;\n },\n get linkClicks() {\n return linkClicksRef.current;\n },\n get citationLinks() {\n return citationLinksRef.current;\n },\n }),\n [backendUrl, appUrl, apiKey, enabledToolkits],\n );\n};\n\n/**\n * Delivers composer writes that were made before this mount was ready\n * (`useAppendToComposer` / `useSendMessage` queue them in the provider-level\n * store, which outlives the keyed per-thread mount). Lives under the\n * `AuiProvider` so it can read the thread's own loading state.\n */\nfunction ComposerHandoffDrain(): null {\n const aui = useAui();\n const store = useComposerHandoffStore();\n const threadId = useContext(AthenaStatewireThreadIdContext);\n const ready = useComposerReady();\n useEffect(() => {\n if (!ready || !store) return;\n // Writes bound to another thread are dropped here, not applied.\n drainComposerHandoff({ store, target: aui, threadId });\n }, [aui, ready, store, threadId]);\n return null;\n}\n\n// ─── Standalone Mode ──────────────────────────────────────────────────\n\n/** Everything the per-thread runtime needs to attach and run a thread. */\ninterface AthenaStatewireRuntimeProps {\n syncUrl: string;\n apiKey?: string;\n token?: string | null;\n getToken?: AthenaStatewireTokenGetter;\n model?: string;\n agent?: string;\n channel?: string;\n tools: string[];\n frontendToolIds: string[];\n frontendTools: Toolkit;\n workbench?: string[];\n knowledgeBase?: string[];\n systemPrompt?: string;\n appId?: string;\n extraRunConfig?: Record<string, unknown>;\n /** The provider-owned snapshot cache (see `AthenaProvider`). */\n snapshotCache: DeepAgentThreadSnapshotCache;\n /** The provider-owned store of fetched-back cut tool outputs (see `AthenaProvider`). */\n toolOutputs: DeepAgentToolOutputStore;\n}\n\ninterface AthenaStatewireStandaloneProps extends AthenaStatewireRuntimeProps {\n children: ReactNode;\n backendUrl: string;\n appUrl: string;\n threadId?: string;\n /**\n * Thread-list mode. The list owns the active id and alone knows whether the\n * backend has listed it yet: `isNewChat` overrides the \"new chat\"\n * derivation (the list mints ids for brand-new chats, which must still load\n * as new), and the scope publishes `AthenaThreadIdContext` — the backend id,\n * withheld while the chat is unpersisted. Absent outside thread-list mode,\n * where that context stays untouched.\n */\n threadList?: { isNewChat: boolean };\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\n/**\n * What one per-thread runtime mount hands to the stable scope around the\n * host's children: the assistant client attached to `threadId` and the\n * transport lifecycle observed on that attach. Published as ONE value so the\n * scope can never pair a thread's id with another thread's client.\n */\ninterface AthenaStatewireRuntimeSnapshot {\n threadId: string;\n isNewChat: boolean;\n client: AssistantClient;\n lifecycle: AthenaStatewireLifecycleState;\n}\n\n/**\n * The per-thread half of the statewire lane: owns the runtime hook (statewire\n * client, pending-message lane, `useAui` client) and the lifecycle reducer\n * behind the connection/error banners, and renders nothing itself. Mounted\n * under `key={threadId}` so a switch — or a new chat — gets a fresh instance\n * of everything here, exactly as when the whole provider subtree was keyed,\n * without remounting the host's UI.\n *\n * An assistant client's readable state only advances when its tap fibers\n * commit (in effects), so an in-place `threadId` change on one mounted hook\n * would leave a commit in which the new id is published but `useAuiState`\n * still reads the previous thread's committed state; a fresh mount publishes\n * its own state on its first render. That is why the runtime is remounted per\n * thread rather than switched in place.\n *\n * The snapshot is published from a layout effect: React flushes the state\n * update a layout effect schedules synchronously, before the browser paints,\n * so the scope re-renders against this client in the same task as this\n * mount's commit — the previous client is never painted under the new id.\n */\nfunction AthenaStatewireRuntimeMount({\n threadId,\n isNewChat,\n onPublish,\n syncUrl,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n}: AthenaStatewireRuntimeProps & {\n threadId: string;\n isNewChat: boolean;\n onPublish: (snapshot: AthenaStatewireRuntimeSnapshot) => void;\n}): null {\n const [lifecycle, dispatchLifecycle] = useReducer(\n statewireLifecycleReducer,\n initialStatewireLifecycle,\n );\n\n const client = useAthenaStatewireRuntime({\n syncUrl,\n threadId,\n isNewChat,\n apiKey,\n token,\n getToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds,\n frontendToolkit: frontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig,\n snapshotCache,\n toolOutputs,\n // The runtime already records every transport error on the diagnostics\n // bus (with the channel-teardown split), so this layer only maps it to\n // the banner notice.\n onError: (error) => {\n const notice = athenaStatewireErrorNotice(error);\n if (notice) dispatchLifecycle({ type: 'error', error: notice });\n },\n onConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'connection', connection });\n },\n onRawConnectionChange: (connection) => {\n dispatchLifecycle({ type: 'raw-connection', reconnect: connection.reconnect });\n },\n });\n\n const dismissError = useCallback(\n () => dispatchLifecycle({ type: 'error', error: null }),\n [],\n );\n const lifecycleValue = useMemo<AthenaStatewireLifecycleState>(\n () => ({\n connection: lifecycle.connection,\n error: lifecycle.error,\n reconnect: lifecycle.reconnect,\n dismissError,\n }),\n [lifecycle, dismissError],\n );\n\n const snapshot = useMemo<AthenaStatewireRuntimeSnapshot>(\n () => ({ threadId, isNewChat, client, lifecycle: lifecycleValue }),\n [threadId, isNewChat, client, lifecycleValue],\n );\n useLayoutEffect(() => {\n onPublish(snapshot);\n }, [onPublish, snapshot]);\n\n return null;\n}\n\n/**\n * The stable half of the statewire lane: the scope around the host's\n * `children`. It mounts one `AthenaStatewireRuntimeMount` per thread beside\n * them and provides whatever that mount last published — client, thread ids,\n * lifecycle — so a thread switch swaps the client under the host's UI instead\n * of remounting it. Until the first mount has published, the children are\n * withheld: they need a client, and the first publication lands in the same\n * task as the mount's commit.\n *\n * A server render runs no effects, so it would withhold the children too.\n * That changes nothing today: `AthenaProvider` renders `null` until the parent\n * bridge reports ready, which only ever happens in an effect (`useParentBridge`\n * starts `ready: false`), so the SDK has never server-rendered the host UI —\n * it hydrates it. A future SSR-ready bridge would need the first publication\n * to happen in render as well.\n */\nfunction AthenaStatewireStandalone({\n children,\n backendUrl,\n appUrl,\n threadId: threadIdProp,\n threadList,\n linkClicks,\n citationLinks,\n ...runtimeProps\n}: AthenaStatewireStandaloneProps) {\n // Statewire attaches to `${syncUrl}/${threadId}`, so a thread ID must exist\n // up front. An auto-generated ID is by definition a never-started local chat.\n const generatedIdRef = useRef<string | null>(null);\n if (generatedIdRef.current === null) {\n generatedIdRef.current = mintThreadId();\n }\n const threadId = threadIdProp ?? generatedIdRef.current;\n const isNewChat = threadList?.isNewChat ?? !threadIdProp;\n\n const [published, setPublished] = useState<AthenaStatewireRuntimeSnapshot | null>(null);\n\n const clientTools = useStatewireClientTools(runtimeProps.frontendTools);\n\n // The runtime binds `client_tools` only for a recognised `app_id`; with none\n // it drops every declaration without telling the client, and the model then\n // sees \"not a valid tool\". Say so here, once per configuration, as an error\n // so it reaches `onError` and the console even with diagnostics off.\n const clientToolNamesKey = clientTools.map((tool) => tool.definition.name).join(',');\n const clientToolAppId = runtimeProps.appId;\n useEffect(() => {\n if (clientTools.length === 0 || resolveClientToolSurface(clientToolAppId) !== null) return;\n athenaDiagnostics.emit('sdk.config.warning', {\n level: 'error',\n error: new AthenaSdkError({\n code: 'config_invalid',\n message: `frontendTools with an execute() need a recognised appId; ${clientTools.length} tool(s) will not be bound.`,\n hint:\n \"Pass appId={publicAppId} on <AthenaProvider> (a computer-asset app reads it from athena-public-config.json as computer_asset_<uuid>). Without it the deep-agent runtime drops every client tool.\",\n context: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n }),\n data: { appId: clientToolAppId ?? null, tools: clientToolNamesKey.split(',') },\n });\n // clientToolNamesKey is the value-stable form of the tool list.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [clientToolAppId, clientToolNamesKey]);\n\n const athenaConfig = useAthenaConfigValue({\n backendUrl,\n appUrl,\n apiKey: runtimeProps.apiKey,\n token: runtimeProps.token,\n getToken: runtimeProps.getToken,\n enabledToolkits: runtimeProps.tools,\n linkClicks,\n citationLinks,\n });\n\n const scope = published && (\n <AuiProvider value={published.client}>\n <AthenaContext.Provider value={athenaConfig}>\n <AthenaStatewireThreadIdContext.Provider value={published.threadId}>\n <AthenaStatewireLifecycleContext.Provider value={published.lifecycle}>\n <DeepAgentConnectionContext.Provider value={published.lifecycle.connection}>\n <StatewireToolOutputsContext.Provider value={runtimeProps.toolOutputs}>\n <TooltipProvider>\n <StatewireClientToolBridge tools={clientTools} threadId={published.threadId} />\n <ComposerHandoffDrain />\n {children}\n </TooltipProvider>\n </StatewireToolOutputsContext.Provider>\n </DeepAgentConnectionContext.Provider>\n </AthenaStatewireLifecycleContext.Provider>\n </AthenaStatewireThreadIdContext.Provider>\n </AthenaContext.Provider>\n </AuiProvider>\n );\n\n return (\n <>\n <AthenaStatewireRuntimeMount\n key={threadId}\n threadId={threadId}\n isNewChat={isNewChat}\n onPublish={setPublished}\n {...runtimeProps}\n />\n {/* The backend id rides the same snapshot as the client, so\n history-gated UI (e.g. the loading overlay) never judges one thread\n by another's state; it is undefined for a never-started chat, which\n must not read as pending history. */}\n {threadList && published ? (\n <AthenaThreadIdContext.Provider\n value={published.isNewChat ? undefined : published.threadId}\n >\n {scope}\n </AthenaThreadIdContext.Provider>\n ) : (\n scope\n )}\n </>\n );\n}\n\n// ─── Thread List Mode ─────────────────────────────────────────────────\n\nfunction AthenaStatewireWithThreadList({\n children,\n backendUrl,\n syncUrl,\n appId,\n apiKey,\n token,\n getToken,\n initialThreadId,\n includePullRequests,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'> & {\n initialThreadId?: string;\n includePullRequests?: boolean;\n}) {\n return (\n <AthenaStatewireThreadListProvider\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n appId={appId}\n initialThreadId={initialThreadId}\n includePullRequests={includePullRequests}\n // The list's hover prefetch warms the same cache the active-thread\n // mount seeds from, so a hovered-then-selected session paints at once.\n snapshotCache={standaloneProps.snapshotCache}\n >\n <AthenaStatewireActiveThreadHost\n backendUrl={backendUrl}\n syncUrl={syncUrl}\n appId={appId}\n apiKey={apiKey}\n token={token}\n getToken={getToken}\n {...standaloneProps}\n >\n {children}\n </AthenaStatewireActiveThreadHost>\n </AthenaStatewireThreadListProvider>\n );\n}\n\nfunction AthenaStatewireActiveThreadHost({\n children,\n ...standaloneProps\n}: Omit<AthenaStatewireStandaloneProps, 'threadId' | 'threadList'>) {\n const list = useAthenaStatewireThreadList();\n if (!list) return null;\n\n // Not keyed: the scope keeps the host's children mounted across a switch\n // and remounts only its per-thread runtime against the new\n // `…/v2/threads/{id}` URL (see `AthenaStatewireStandalone`).\n return (\n <AthenaStatewireStandalone\n threadId={list.activeThreadId}\n threadList={{ isNewChat: list.isNewChat }}\n {...standaloneProps}\n >\n <StatewireThreadTitlePoller />\n <AssetPanelThreadSync />\n {children}\n </AthenaStatewireStandalone>\n );\n}\n\n/**\n * Syncs the active thread ID into the asset panel store so that open asset\n * tabs are scoped per-thread automatically.\n *\n * Scoped by the attached thread's minted id from creation onward — NOT by\n * `useAthenaThreadManager().activeThreadId`, which is deliberately `null`\n * while a new chat is unpersisted (so URL sync never names it). The minted id\n * is the id the thread persists under, so tabs opened in a brand-new chat\n * stay put when the backend first lists it instead of being left behind in a\n * `null` scope the store never restores. Read from the statewire scope (the\n * id published with its client) rather than the list's selection, which runs\n * one commit ahead of the client during a switch.\n */\nfunction AssetPanelThreadSync() {\n const threadId = useAthenaStatewireThreadId();\n const setCurrentThread = useAssetPanelStore((s) => s.setCurrentThread);\n\n useEffect(() => {\n setCurrentThread(threadId);\n }, [threadId, setCurrentThread]);\n\n return null;\n}\n\n// ─── Main Provider ────────────────────────────────────────────────────\n\nexport function AthenaProvider({\n children,\n config,\n apiKey,\n token: tokenProp,\n agent,\n channel,\n model,\n tools = [],\n frontendTools = {},\n disableAutoOpen = false,\n apiUrl,\n backendUrl,\n appUrl,\n environment,\n statewireSyncUrl,\n getToken,\n extraRunConfig,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n threadId: threadIdProp,\n enableThreadList = false,\n threadListIncludePullRequests = true,\n theme,\n linkClicks,\n citationLinks,\n posthog: posthogProp,\n debug,\n onDiagnostic,\n onError,\n}: AthenaProviderProps) {\n // Fail loud before any effect, bridge wait, or network call: an `agent`\n // outside the collab_agent namespace can never apply, so a misconfigured\n // deployment must die at first render rather than answer as the wrong agent.\n resolveAgentProp({ agent });\n\n // Diagnostics wiring first, so everything below is observable. Callbacks\n // ride refs: a per-render closure must not re-register the consumer. Each\n // provider registers its OWN consumer (additive, cleaned up on unmount), so\n // two mounted providers never clobber each other's onDiagnostic/onError —\n // only the console/PostHog/buffer settings are global (last writer wins).\n const onDiagnosticRef = useRef(onDiagnostic);\n onDiagnosticRef.current = onDiagnostic;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n useEffect(() => {\n installAthenaDiagnosticsGlobal();\n return athenaDiagnostics.addConsumer({\n onEvent: (event) => onDiagnosticRef.current?.(event),\n onError: (error, event) => onErrorRef.current?.(error, event),\n });\n }, []);\n const debugKey = JSON.stringify(debugPropToDiagnosticsConfig(debug));\n useEffect(() => {\n athenaDiagnostics.configure(debugPropToDiagnosticsConfig(debug));\n // debugKey is the value-stable form of `debug` (consumers pass literals).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debugKey]);\n // Only declarations WITHOUT a local `execute` ride `enabled_tools`: they name\n // registry tools the backend binds itself. Executable tools are declared\n // through `client_tools` instead — listing them here too would switch on a\n // backend toolkit owning a tool of the same name, and the backend wins that\n // collision (the client tool is silently dropped).\n const frontendToolNames = useMemo(\n () => backendDeclaredFrontendToolIds(frontendTools),\n [frontendTools],\n );\n // Merge SDK auto-open defaults under the consumer's frontendTools. Consumer\n // entries win on name collision; auto-open tool names are NOT added to\n // frontendToolIds (they are already backend-advertised by their toolkits).\n const effectiveFrontendTools = useMemo<Toolkit>(\n () => (disableAutoOpen ? frontendTools : { ...DEFAULT_AUTO_OPEN_TOOLS, ...frontendTools }),\n [disableAutoOpen, frontendTools],\n );\n const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : undefined, [theme]);\n const configuredEnvironment = config?.environment ?? environment;\n const environmentUrls = useMemo(\n () => getAthenaEnvironmentUrls({ environment: configuredEnvironment }),\n [configuredEnvironment],\n );\n const configuredApiKey = config?.apiKey ?? apiKey;\n const configuredToken = resolveTokenOverride({ config, token: tokenProp });\n const configuredApiUrl = config?.apiUrl ?? apiUrl;\n const configuredBackendUrl = config?.backendUrl ?? backendUrl;\n const configuredAppUrl = config?.appUrl ?? appUrl;\n const configuredStatewireSyncUrl = config?.statewireSyncUrl ?? statewireSyncUrl;\n const configuredGetToken = config?.getToken ?? getToken;\n const configuredExtraRunConfig = config?.extraRunConfig ?? extraRunConfig;\n const configuredTrustedParentOrigins = config?.trustedParentOrigins;\n const posthogConfig: PostHogConfig | undefined = config?.posthog ?? posthogProp;\n\n // Statewire is the SDK's only chat transport; the gauge/event stay on the\n // diagnostics contract so dashboards keyed on them keep reading a value.\n useEffect(() => {\n athenaDiagnostics.gauge('sdk.transport', 'statewire');\n athenaDiagnostics.emit('sdk.transport', {\n level: 'debug',\n data: { transport: 'statewire', thread_list: enableThreadList },\n });\n }, [enableThreadList]);\n\n const bridge = useParentBridge({\n trustedOrigins: configuredTrustedParentOrigins,\n });\n\n // If an AthenaAuthProvider is present above us, use its access token automatically.\n const authContext = useContext(AthenaAuthContext);\n const authProviderToken = authContext?.accessToken ?? null;\n\n // Per-provider snapshot cache: a switch back to a recently-visited thread\n // mounts with its last-known snapshot instead of a loading spinner. Owned\n // here, above the per-thread keyed mount, so it survives switches; cleared\n // when the acting identity changes so a snapshot captured under one account\n // never seeds a mount under another.\n const [snapshotCache] = useState(() => createDeepAgentThreadSnapshotCache());\n // Composer writes that arrive before the per-thread mount is ready wait\n // here, above that mount, so a thread-list remount cannot drop them.\n const [composerHandoff] = useState(createComposerHandoffStore);\n // The windowed wire's fetched-back tool outputs, owned alongside the cache\n // for the same reasons: shared across the provider's thread switches (a\n // tool message id is unique across threads), dropped with the identity.\n const [toolOutputs] = useState(() => createDeepAgentToolOutputStore());\n const principal = authContext?.user?.userId ?? '';\n useEffect(() => {\n snapshotCache.clear();\n toolOutputs.clear();\n // A draft or send queued under the previous identity must never land in\n // this one's composer.\n clearComposerHandoff({ store: composerHandoff, reason: 'the signed-in identity changed' });\n }, [snapshotCache, toolOutputs, composerHandoff, principal, configuredApiKey]);\n // Nothing drains after the provider is gone: settle what still waits so no\n // `useSendMessage` caller hangs.\n useEffect(\n () => () => clearComposerHandoff({ store: composerHandoff, reason: 'the chat provider unmounted' }),\n [composerHandoff],\n );\n\n const effectiveToken = configuredToken !== undefined\n ? configuredToken\n : authProviderToken ?? bridge.token;\n // Explicit config wins. A Marathon host mints the statewire mount, the bare\n // Agora base and the app origin outright (`/_athena/auth`, or a trusted\n // parent's `athena-config`); the environment preset is the last resort, and\n // the sync mount derives from the `apiUrl` host when no host minted one.\n const effectiveApiUrl = configuredApiUrl ?? environmentUrls.apiUrl;\n // Published as the bare Agora base: a historical `…/api/assistant-ui` value\n // is trimmed here once rather than by each REST helper.\n const effectiveBackendUrl = getAthenaApiBaseUrl(\n configuredBackendUrl ?? bridge.backendBaseUrl ?? environmentUrls.backendUrl,\n );\n const hostStatewireSyncUrl = configuredStatewireSyncUrl ?? bridge.statewireSyncUrl ?? undefined;\n const effectiveAppUrl = configuredAppUrl\n ?? bridge.appUrl\n ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl })\n ?? environmentUrls.appUrl;\n\n // Wait for the parent bridge to deliver config/auth before rendering.\n // This prevents the thread list from fetching with wrong URLs or no token.\n // Falls back after a short timeout (2s) if no bridge responds.\n if (!bridge.ready) {\n return null;\n }\n\n // Both throw on an unresolvable configuration instead of falling back to an\n // Athena default — a custom deployment's credentials must never be sent to\n // a host the consumer didn't configure. A host that answered the bridge\n // without minting the statewire mount is that case: its token would\n // otherwise ride the environment preset.\n assertHostMintedStatewireMount({\n hostAnswered: bridge.hostAnswered,\n hostStatewireSyncUrl: bridge.statewireSyncUrl,\n statewireSyncUrl: configuredStatewireSyncUrl,\n apiUrl: configuredApiUrl,\n });\n const effectiveStatewireSyncUrl = resolveStatewireSyncUrl({\n statewireSyncUrl: hostStatewireSyncUrl,\n apiUrl: effectiveApiUrl,\n });\n\n const statewireProps = {\n syncUrl: effectiveStatewireSyncUrl,\n backendUrl: effectiveBackendUrl,\n appUrl: effectiveAppUrl,\n apiKey: configuredApiKey,\n token: effectiveToken,\n getToken: configuredGetToken,\n model,\n agent,\n channel,\n tools,\n frontendToolIds: frontendToolNames,\n frontendTools: effectiveFrontendTools,\n workbench,\n knowledgeBase,\n systemPrompt,\n appId,\n extraRunConfig: configuredExtraRunConfig,\n snapshotCache,\n toolOutputs,\n linkClicks,\n citationLinks,\n };\n\n const inner: ReactNode = enableThreadList ? (\n <AthenaStatewireWithThreadList\n {...statewireProps}\n initialThreadId={threadIdProp}\n includePullRequests={threadListIncludePullRequests}\n >\n {children}\n </AthenaStatewireWithThreadList>\n ) : (\n <AthenaStatewireStandalone {...statewireProps} threadId={threadIdProp}>\n {children}\n </AthenaStatewireStandalone>\n );\n\n // The .athena-sdk wrapper (display: contents) anchors the SDK's design\n // tokens and scoped preflight from styles.css, so the stylesheet works\n // in hosts without their own Tailwind build. PostHog gracefully no-ops\n // when its config is missing.\n return (\n <div\n className={themeStyleVars ? \"athena-sdk athena-themed\" : \"athena-sdk\"}\n style={themeStyleVars as React.CSSProperties | undefined}\n >\n <PostHogProvider config={posthogConfig}>\n <ComposerHandoffContext.Provider value={composerHandoff}>\n <AthenaThemeStyleContext.Provider value={themeStyleVars}>\n {inner}\n </AthenaThemeStyleContext.Provider>\n </ComposerHandoffContext.Provider>\n </PostHogProvider>\n </div>\n );\n}\n"],"names":["useRef","useMemo","useAui","useComposerHandoffStore","useContext","AthenaStatewireThreadIdContext","useComposerReady","useEffect","drainComposerHandoff","toolOutputs","useReducer","statewireLifecycleReducer","initialStatewireLifecycle","useAthenaStatewireRuntime","athenaStatewireErrorNotice","useCallback","useLayoutEffect","mintThreadId","useState","useStatewireClientTools","resolveClientToolSurface","athenaDiagnostics","AthenaSdkError","jsx","AuiProvider","AthenaContext","AthenaStatewireLifecycleContext","DeepAgentConnectionContext","StatewireToolOutputsContext","TooltipProvider","StatewireClientToolBridge","jsxs","Fragment","AthenaThreadIdContext","AthenaStatewireThreadListProvider","useAthenaStatewireThreadList","StatewireThreadTitlePoller","useAthenaStatewireThreadId","useAssetPanelStore","resolveAgentProp","installAthenaDiagnosticsGlobal","_a","debugPropToDiagnosticsConfig","backendDeclaredFrontendToolIds","DEFAULT_AUTO_OPEN_TOOLS","themeToStyleVars","getAthenaEnvironmentUrls","useParentBridge","AthenaAuthContext","createDeepAgentThreadSnapshotCache","composerHandoff","createComposerHandoffStore","createDeepAgentToolOutputStore","clearComposerHandoff","getAthenaApiBaseUrl","deriveAthenaAppUrl","assertHostMintedStatewireMount","resolveStatewireSyncUrl","PostHogProvider","ComposerHandoffContext","AthenaThemeStyleContext"],"mappings":"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"}