@athenaintel/react 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/README.md +74 -0
  2. package/dist/assets/use-asset-embed.cjs +8 -0
  3. package/dist/assets/use-asset-embed.cjs.map +1 -1
  4. package/dist/assets/use-asset-embed.js +8 -0
  5. package/dist/assets/use-asset-embed.js.map +1 -1
  6. package/dist/chat/StatewireApprovalCard.cjs +22 -4
  7. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  8. package/dist/chat/StatewireApprovalCard.d.ts +14 -0
  9. package/dist/chat/StatewireApprovalCard.js +23 -5
  10. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  11. package/dist/chat/StatewireClientToolBridge.cjs +2 -1
  12. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  13. package/dist/chat/StatewireClientToolBridge.js +2 -1
  14. package/dist/chat/StatewireClientToolBridge.js.map +1 -1
  15. package/dist/chat/StatewireQueuedMessages.cjs +2 -1
  16. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  17. package/dist/chat/StatewireQueuedMessages.js +2 -1
  18. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  19. package/dist/chat/athena-citation-links.cjs +17 -1
  20. package/dist/chat/athena-citation-links.cjs.map +1 -1
  21. package/dist/chat/athena-citation-links.js +17 -1
  22. package/dist/chat/athena-citation-links.js.map +1 -1
  23. package/dist/chat/statewire-client-tools.cjs +2 -1
  24. package/dist/chat/statewire-client-tools.cjs.map +1 -1
  25. package/dist/chat/statewire-client-tools.js +2 -1
  26. package/dist/chat/statewire-client-tools.js.map +1 -1
  27. package/dist/chat/super-grouping/SuperGroupingCard.cjs +69 -187
  28. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  29. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +10 -6
  30. package/dist/chat/super-grouping/SuperGroupingCard.js +73 -191
  31. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  32. package/dist/chat/super-grouping/ToolTimeline.cjs +131 -0
  33. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -0
  34. package/dist/chat/super-grouping/ToolTimeline.d.ts +16 -0
  35. package/dist/chat/super-grouping/ToolTimeline.js +131 -0
  36. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -0
  37. package/dist/chat/super-grouping/activity-timeline.cjs +14 -8
  38. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  39. package/dist/chat/super-grouping/activity-timeline.d.ts +3 -0
  40. package/dist/chat/super-grouping/activity-timeline.js +14 -8
  41. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  42. package/dist/chat/super-grouping/timeline-step.cjs +65 -0
  43. package/dist/chat/super-grouping/timeline-step.cjs.map +1 -0
  44. package/dist/chat/super-grouping/timeline-step.d.ts +17 -0
  45. package/dist/chat/super-grouping/timeline-step.js +65 -0
  46. package/dist/chat/super-grouping/timeline-step.js.map +1 -0
  47. package/dist/chat/tiptap-text.cjs +8 -8
  48. package/dist/chat/tiptap-text.cjs.map +1 -1
  49. package/dist/chat/use-athena-run-live.cjs +2 -1
  50. package/dist/chat/use-athena-run-live.cjs.map +1 -1
  51. package/dist/chat/use-athena-run-live.js +2 -1
  52. package/dist/chat/use-athena-run-live.js.map +1 -1
  53. package/dist/chat/use-statewire-approval-request.cjs +7 -2
  54. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  55. package/dist/chat/use-statewire-approval-request.d.ts +12 -2
  56. package/dist/chat/use-statewire-approval-request.js +8 -3
  57. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  58. package/dist/chat-ui/composer/tiptap-composer.cjs +24 -65
  59. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  60. package/dist/chat-ui/composer/tiptap-composer.js +24 -65
  61. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  62. package/dist/chat-ui/index.cjs +2 -1
  63. package/dist/chat-ui/index.cjs.map +1 -1
  64. package/dist/chat-ui/index.js +2 -1
  65. package/dist/chat-ui/index.js.map +1 -1
  66. package/dist/chat-ui/mentions/mention-chip.cjs +49 -4
  67. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  68. package/dist/chat-ui/mentions/mention-chip.d.ts +11 -0
  69. package/dist/chat-ui/mentions/mention-chip.js +50 -5
  70. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  71. package/dist/chat-ui/mentions/mention-extension.cjs +18 -6
  72. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  73. package/dist/chat-ui/mentions/mention-extension.d.ts +2 -0
  74. package/dist/chat-ui/mentions/mention-extension.js +18 -6
  75. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  76. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +1 -1
  77. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  78. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +1 -1
  79. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  80. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs +9 -6
  81. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs.map +1 -1
  82. package/dist/chat-ui/mentions/suggestions/components/menu-item.d.ts +2 -2
  83. package/dist/chat-ui/mentions/suggestions/components/menu-item.js +10 -7
  84. package/dist/chat-ui/mentions/suggestions/components/menu-item.js.map +1 -1
  85. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +2 -2
  86. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  87. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +2 -2
  88. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +2 -2
  89. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  90. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +2 -1
  91. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  92. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +3 -2
  93. package/dist/chat-ui/mentions/suggestions/data/api-client.js +2 -1
  94. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  95. package/dist/chat-ui/messages/message-components.cjs +6 -29
  96. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  97. package/dist/chat-ui/messages/message-components.d.ts +1 -13
  98. package/dist/chat-ui/messages/message-components.js +8 -31
  99. package/dist/chat-ui/messages/message-components.js.map +1 -1
  100. package/dist/chat-ui/messages/runtime-message.cjs +3 -2
  101. package/dist/chat-ui/messages/runtime-message.cjs.map +1 -1
  102. package/dist/chat-ui/messages/runtime-message.js +3 -2
  103. package/dist/chat-ui/messages/runtime-message.js.map +1 -1
  104. package/dist/chat-ui/messages/statewire-continue-run.cjs +23 -8
  105. package/dist/chat-ui/messages/statewire-continue-run.cjs.map +1 -1
  106. package/dist/chat-ui/messages/statewire-continue-run.d.ts +14 -4
  107. package/dist/chat-ui/messages/statewire-continue-run.js +23 -8
  108. package/dist/chat-ui/messages/statewire-continue-run.js.map +1 -1
  109. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -1
  110. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  111. package/dist/chat-ui/messages/user-edit-composer.js +2 -1
  112. package/dist/chat-ui/messages/user-edit-composer.js.map +1 -1
  113. package/dist/chat-ui/rich-text/chat-message-body.cjs +76 -0
  114. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -0
  115. package/dist/chat-ui/rich-text/chat-message-body.d.ts +5 -0
  116. package/dist/chat-ui/rich-text/chat-message-body.js +76 -0
  117. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -0
  118. package/dist/chat-ui/rich-text/chat-node-views.cjs +51 -0
  119. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -0
  120. package/dist/chat-ui/rich-text/chat-node-views.d.ts +13 -0
  121. package/dist/chat-ui/rich-text/chat-node-views.js +51 -0
  122. package/dist/chat-ui/rich-text/chat-node-views.js.map +1 -0
  123. package/dist/chat-ui/rich-text/chat-text-schema.cjs +70 -0
  124. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -0
  125. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +7 -0
  126. package/dist/chat-ui/rich-text/chat-text-schema.js +70 -0
  127. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -0
  128. package/dist/chat-ui/rich-text/dom-output-spec.cjs +83 -0
  129. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -0
  130. package/dist/chat-ui/rich-text/dom-output-spec.d.ts +11 -0
  131. package/dist/chat-ui/rich-text/dom-output-spec.js +83 -0
  132. package/dist/chat-ui/rich-text/dom-output-spec.js.map +1 -0
  133. package/dist/chat-ui/statewire.cjs +2 -1
  134. package/dist/chat-ui/statewire.cjs.map +1 -1
  135. package/dist/chat-ui/statewire.js +2 -1
  136. package/dist/chat-ui/statewire.js.map +1 -1
  137. package/dist/chat-ui/thread/statewire-history-edge.cjs +2 -1
  138. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  139. package/dist/chat-ui/thread/statewire-history-edge.js +2 -1
  140. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  141. package/dist/index.cjs +2 -1
  142. package/dist/index.cjs.map +1 -1
  143. package/dist/index.js +2 -1
  144. package/dist/index.js.map +1 -1
  145. package/dist/node_modules/qrcode-generator/dist/qrcode.cjs +32 -0
  146. package/dist/node_modules/qrcode-generator/dist/qrcode.cjs.map +1 -0
  147. package/dist/node_modules/qrcode-generator/dist/qrcode.js +31 -0
  148. package/dist/node_modules/qrcode-generator/dist/qrcode.js.map +1 -0
  149. package/dist/node_modules/zod/v4/classic/errors.cjs +44 -0
  150. package/dist/node_modules/zod/v4/classic/errors.cjs.map +1 -0
  151. package/dist/node_modules/zod/v4/classic/errors.js +44 -0
  152. package/dist/node_modules/zod/v4/classic/errors.js.map +1 -0
  153. package/dist/node_modules/zod/v4/classic/iso.cjs +43 -0
  154. package/dist/node_modules/zod/v4/classic/iso.cjs.map +1 -0
  155. package/dist/node_modules/zod/v4/classic/iso.js +43 -0
  156. package/dist/node_modules/zod/v4/classic/iso.js.map +1 -0
  157. package/dist/node_modules/zod/v4/classic/parse.cjs +29 -0
  158. package/dist/node_modules/zod/v4/classic/parse.cjs.map +1 -0
  159. package/dist/node_modules/zod/v4/classic/parse.js +29 -0
  160. package/dist/node_modules/zod/v4/classic/parse.js.map +1 -0
  161. package/dist/node_modules/zod/v4/classic/schemas.cjs +871 -0
  162. package/dist/node_modules/zod/v4/classic/schemas.cjs.map +1 -0
  163. package/dist/node_modules/zod/v4/classic/schemas.js +871 -0
  164. package/dist/node_modules/zod/v4/classic/schemas.js.map +1 -0
  165. package/dist/node_modules/zod/v4/core/api.cjs +570 -0
  166. package/dist/node_modules/zod/v4/core/api.cjs.map +1 -0
  167. package/dist/node_modules/zod/v4/core/api.js +570 -0
  168. package/dist/node_modules/zod/v4/core/api.js.map +1 -0
  169. package/dist/node_modules/zod/v4/core/checks.cjs +411 -0
  170. package/dist/node_modules/zod/v4/core/checks.cjs.map +1 -0
  171. package/dist/node_modules/zod/v4/core/checks.js +411 -0
  172. package/dist/node_modules/zod/v4/core/checks.js.map +1 -0
  173. package/dist/node_modules/zod/v4/core/core.cjs +77 -0
  174. package/dist/node_modules/zod/v4/core/core.cjs.map +1 -0
  175. package/dist/node_modules/zod/v4/core/core.js +77 -0
  176. package/dist/node_modules/zod/v4/core/core.js.map +1 -0
  177. package/dist/node_modules/zod/v4/core/doc.cjs +38 -0
  178. package/dist/node_modules/zod/v4/core/doc.cjs.map +1 -0
  179. package/dist/node_modules/zod/v4/core/doc.js +38 -0
  180. package/dist/node_modules/zod/v4/core/doc.js.map +1 -0
  181. package/dist/node_modules/zod/v4/core/errors.cjs +76 -0
  182. package/dist/node_modules/zod/v4/core/errors.cjs.map +1 -0
  183. package/dist/node_modules/zod/v4/core/errors.js +76 -0
  184. package/dist/node_modules/zod/v4/core/errors.js.map +1 -0
  185. package/dist/node_modules/zod/v4/core/json-schema-processors.cjs +312 -0
  186. package/dist/node_modules/zod/v4/core/json-schema-processors.cjs.map +1 -0
  187. package/dist/node_modules/zod/v4/core/json-schema-processors.js +312 -0
  188. package/dist/node_modules/zod/v4/core/json-schema-processors.js.map +1 -0
  189. package/dist/node_modules/zod/v4/core/parse.cjs +96 -0
  190. package/dist/node_modules/zod/v4/core/parse.cjs.map +1 -0
  191. package/dist/node_modules/zod/v4/core/parse.js +96 -0
  192. package/dist/node_modules/zod/v4/core/parse.js.map +1 -0
  193. package/dist/node_modules/zod/v4/core/regexes.cjs +86 -0
  194. package/dist/node_modules/zod/v4/core/regexes.cjs.map +1 -0
  195. package/dist/node_modules/zod/v4/core/regexes.js +86 -0
  196. package/dist/node_modules/zod/v4/core/regexes.js.map +1 -0
  197. package/dist/node_modules/zod/v4/core/registries.cjs +52 -0
  198. package/dist/node_modules/zod/v4/core/registries.cjs.map +1 -0
  199. package/dist/node_modules/zod/v4/core/registries.js +52 -0
  200. package/dist/node_modules/zod/v4/core/registries.js.map +1 -0
  201. package/dist/node_modules/zod/v4/core/schemas.cjs +1412 -0
  202. package/dist/node_modules/zod/v4/core/schemas.cjs.map +1 -0
  203. package/dist/node_modules/zod/v4/core/schemas.js +1413 -0
  204. package/dist/node_modules/zod/v4/core/schemas.js.map +1 -0
  205. package/dist/node_modules/zod/v4/core/to-json-schema.cjs +370 -0
  206. package/dist/node_modules/zod/v4/core/to-json-schema.cjs.map +1 -0
  207. package/dist/node_modules/zod/v4/core/to-json-schema.js +370 -0
  208. package/dist/node_modules/zod/v4/core/to-json-schema.js.map +1 -0
  209. package/dist/node_modules/zod/v4/core/util.cjs +444 -0
  210. package/dist/node_modules/zod/v4/core/util.cjs.map +1 -0
  211. package/dist/node_modules/zod/v4/core/util.js +444 -0
  212. package/dist/node_modules/zod/v4/core/util.js.map +1 -0
  213. package/dist/node_modules/zod/v4/core/versions.cjs +9 -0
  214. package/dist/node_modules/zod/v4/core/versions.cjs.map +1 -0
  215. package/dist/node_modules/zod/v4/core/versions.js +9 -0
  216. package/dist/node_modules/zod/v4/core/versions.js.map +1 -0
  217. package/dist/packages/agent-runtime/src/client-tool-bridge.cjs +7 -1
  218. package/dist/packages/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  219. package/dist/packages/agent-runtime/src/client-tool-bridge.js +7 -1
  220. package/dist/packages/agent-runtime/src/client-tool-bridge.js.map +1 -1
  221. package/dist/packages/agent-runtime/src/conversation-list.cjs +4 -0
  222. package/dist/packages/agent-runtime/src/conversation-list.cjs.map +1 -1
  223. package/dist/packages/agent-runtime/src/conversation-list.js +4 -0
  224. package/dist/packages/agent-runtime/src/conversation-list.js.map +1 -1
  225. package/dist/packages/agent-runtime/src/edit-command.cjs.map +1 -1
  226. package/dist/packages/agent-runtime/src/edit-command.js.map +1 -1
  227. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -0
  228. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  229. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -0
  230. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  231. package/dist/packages/agent-runtime/src/interrupts.cjs +31 -7
  232. package/dist/packages/agent-runtime/src/interrupts.cjs.map +1 -1
  233. package/dist/packages/agent-runtime/src/interrupts.js +31 -7
  234. package/dist/packages/agent-runtime/src/interrupts.js.map +1 -1
  235. package/dist/packages/agent-runtime/src/messages.cjs +35 -5
  236. package/dist/packages/agent-runtime/src/messages.cjs.map +1 -1
  237. package/dist/packages/agent-runtime/src/messages.js +35 -5
  238. package/dist/packages/agent-runtime/src/messages.js.map +1 -1
  239. package/dist/packages/agent-runtime/src/protocol.cjs +4 -6
  240. package/dist/packages/agent-runtime/src/protocol.cjs.map +1 -1
  241. package/dist/packages/agent-runtime/src/protocol.js +4 -6
  242. package/dist/packages/agent-runtime/src/protocol.js.map +1 -1
  243. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs +296 -14
  244. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  245. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js +293 -11
  246. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  247. package/dist/packages/agent-runtime/src/screen-point.cjs +68 -0
  248. package/dist/packages/agent-runtime/src/screen-point.cjs.map +1 -0
  249. package/dist/packages/agent-runtime/src/screen-point.js +68 -0
  250. package/dist/packages/agent-runtime/src/screen-point.js.map +1 -0
  251. package/dist/packages/agent-runtime/src/statewire-transport.cjs +6 -1
  252. package/dist/packages/agent-runtime/src/statewire-transport.cjs.map +1 -1
  253. package/dist/packages/agent-runtime/src/statewire-transport.js +6 -1
  254. package/dist/packages/agent-runtime/src/statewire-transport.js.map +1 -1
  255. package/dist/packages/agent-runtime/src/thread-handoff.cjs +85 -0
  256. package/dist/packages/agent-runtime/src/thread-handoff.cjs.map +1 -0
  257. package/dist/packages/agent-runtime/src/thread-handoff.js +85 -0
  258. package/dist/packages/agent-runtime/src/thread-handoff.js.map +1 -0
  259. package/dist/packages/agent-runtime/src/thread-snapshot-cache.cjs +1 -1
  260. package/dist/packages/agent-runtime/src/thread-snapshot-cache.cjs.map +1 -1
  261. package/dist/packages/agent-runtime/src/thread-snapshot-cache.js +1 -1
  262. package/dist/packages/agent-runtime/src/thread-snapshot-cache.js.map +1 -1
  263. package/dist/packages/agent-runtime/src/tool-metadata.cjs +0 -8
  264. package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +1 -1
  265. package/dist/packages/agent-runtime/src/tool-metadata.js +0 -8
  266. package/dist/packages/agent-runtime/src/tool-metadata.js.map +1 -1
  267. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs +14 -0
  268. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs.map +1 -0
  269. package/dist/packages/agent-runtime/src/use-deep-agent-config.js +14 -0
  270. package/dist/packages/agent-runtime/src/use-deep-agent-config.js.map +1 -0
  271. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs +21 -5
  272. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  273. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js +21 -5
  274. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -1
  275. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.cjs +13 -3
  276. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  277. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.js +14 -4
  278. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  279. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs +35 -15
  280. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  281. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js +35 -15
  282. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  283. package/dist/packages/agent-runtime/src/voice-presentation.cjs.map +1 -1
  284. package/dist/packages/agent-runtime/src/voice-presentation.js.map +1 -1
  285. package/dist/packages/react/package.json.cjs +1 -1
  286. package/dist/packages/react/package.json.js +1 -1
  287. package/dist/provider/AthenaProvider.cjs +2 -1
  288. package/dist/provider/AthenaProvider.cjs.map +1 -1
  289. package/dist/provider/AthenaProvider.js +2 -1
  290. package/dist/provider/AthenaProvider.js.map +1 -1
  291. package/dist/runtime/statewire-lifecycle.cjs +2 -1
  292. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  293. package/dist/runtime/statewire-lifecycle.js +2 -1
  294. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  295. package/dist/runtime/useAthenaStatewireRuntime.cjs +2 -1
  296. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  297. package/dist/runtime/useAthenaStatewireRuntime.js +2 -1
  298. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  299. package/dist/styles.css +1 -1
  300. package/dist/threads/conversation-list-fetcher.cjs +4 -0
  301. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  302. package/dist/threads/conversation-list-fetcher.js +4 -0
  303. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  304. package/dist/threads/statewire-thread-list.cjs +2 -1
  305. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  306. package/dist/threads/statewire-thread-list.js +2 -1
  307. package/dist/threads/statewire-thread-list.js.map +1 -1
  308. package/dist/threads/use-rest-conversation-history.cjs +2 -1
  309. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  310. package/dist/threads/use-rest-conversation-history.js +2 -1
  311. package/dist/threads/use-rest-conversation-history.js.map +1 -1
  312. package/dist/threads/use-statewire-conversation-history.cjs +2 -1
  313. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  314. package/dist/threads/use-statewire-conversation-history.d.ts +1 -0
  315. package/dist/threads/use-statewire-conversation-history.js +2 -1
  316. package/dist/threads/use-statewire-conversation-history.js.map +1 -1
  317. package/dist/tools/index.cjs +2 -1
  318. package/dist/tools/index.cjs.map +1 -1
  319. package/dist/tools/index.js +2 -1
  320. package/dist/tools/index.js.map +1 -1
  321. package/dist/tools/misc-tool-uis.cjs +2 -1
  322. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  323. package/dist/tools/misc-tool-uis.js +2 -1
  324. package/dist/tools/misc-tool-uis.js.map +1 -1
  325. package/dist/tools/primitives.cjs +2 -1
  326. package/dist/tools/primitives.cjs.map +1 -1
  327. package/dist/tools/primitives.js +2 -1
  328. package/dist/tools/primitives.js.map +1 -1
  329. package/dist/tools/tool-fallback.cjs +2 -1
  330. package/dist/tools/tool-fallback.cjs.map +1 -1
  331. package/dist/tools/tool-fallback.js +2 -1
  332. package/dist/tools/tool-fallback.js.map +1 -1
  333. package/dist/tools/voice-update-tool-ui.cjs +2 -1
  334. package/dist/tools/voice-update-tool-ui.cjs.map +1 -1
  335. package/dist/tools/voice-update-tool-ui.js +2 -1
  336. package/dist/tools/voice-update-tool-ui.js.map +1 -1
  337. package/dist/voice/index.cjs +6 -0
  338. package/dist/voice/index.cjs.map +1 -0
  339. package/dist/voice/index.d.ts +2 -0
  340. package/dist/voice/index.js +6 -0
  341. package/dist/voice/index.js.map +1 -0
  342. package/dist/voice/use-athena-voice-session.cjs +315 -0
  343. package/dist/voice/use-athena-voice-session.cjs.map +1 -0
  344. package/dist/voice/use-athena-voice-session.d.ts +145 -0
  345. package/dist/voice/use-athena-voice-session.js +315 -0
  346. package/dist/voice/use-athena-voice-session.js.map +1 -0
  347. package/package.json +17 -3
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const react = require("react");
4
+ const livekitClient = require("livekit-client");
5
+ const auth = require("../runtime/auth.cjs");
6
+ const toError = (value) => value instanceof Error ? value : new Error(String(value));
7
+ const NO_BRIDGE = {
8
+ token: null,
9
+ statewireSyncUrl: null,
10
+ backendBaseUrl: null,
11
+ appUrl: null,
12
+ hostAnswered: false,
13
+ ready: true
14
+ };
15
+ const useNoBridge = () => NO_BRIDGE;
16
+ const NO_VIEWER_TOKEN_MESSAGE = "useAthenaVoiceSession: no Athena viewer token. Either serve the app from a Marathon computer-asset URL (which mints one via /_athena/auth) or pass `createSession` to create the session through your own server.";
17
+ const createAthenaVoiceSession = async ({
18
+ backendBaseUrl,
19
+ token,
20
+ session = {},
21
+ signal
22
+ }) => {
23
+ const url = `${backendBaseUrl.replace(/\/+$/, "")}/api/orpheus/create-session`;
24
+ const response = await fetch(url, {
25
+ method: "POST",
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ Authorization: `Bearer ${token}`
29
+ },
30
+ body: JSON.stringify(session),
31
+ signal
32
+ });
33
+ if (!response.ok) {
34
+ const detail = await response.text().catch(() => "");
35
+ throw new Error(
36
+ `Orpheus create-session failed (${response.status})${detail ? `: ${detail}` : ""}`
37
+ );
38
+ }
39
+ return await response.json();
40
+ };
41
+ const speakerOf = (participant, room) => participant !== void 0 && participant.identity === room.localParticipant.identity ? "user" : "agent";
42
+ const useAthenaVoiceSession = (options = {}) => {
43
+ const {
44
+ createSession,
45
+ session,
46
+ onTranscript,
47
+ onInterimTranscript,
48
+ onError,
49
+ audioElement,
50
+ autoEnableMicrophone = true,
51
+ createRoom,
52
+ useBridge = createSession ? useNoBridge : auth.useParentBridge
53
+ } = options;
54
+ const bridge = useBridge();
55
+ const bridgeRef = react.useRef(bridge);
56
+ bridgeRef.current = bridge;
57
+ const bridgeReadyWaitersRef = react.useRef([]);
58
+ react.useEffect(() => {
59
+ if (!bridge.ready) return;
60
+ const waiters = bridgeReadyWaitersRef.current;
61
+ bridgeReadyWaitersRef.current = [];
62
+ for (const resolve of waiters) resolve();
63
+ }, [bridge.ready]);
64
+ const sessionRef = react.useRef(session);
65
+ sessionRef.current = session;
66
+ const createSessionAsViewer = react.useCallback(
67
+ async (signal) => {
68
+ if (!bridgeRef.current.ready) {
69
+ await new Promise((resolve) => {
70
+ bridgeReadyWaitersRef.current.push(resolve);
71
+ signal.addEventListener("abort", () => resolve(), { once: true });
72
+ });
73
+ if (signal.aborted) throw new Error("aborted");
74
+ }
75
+ const { token, backendBaseUrl } = bridgeRef.current;
76
+ if (!token || !backendBaseUrl) throw new Error(NO_VIEWER_TOKEN_MESSAGE);
77
+ return createAthenaVoiceSession({
78
+ backendBaseUrl,
79
+ token,
80
+ session: sessionRef.current,
81
+ signal
82
+ });
83
+ },
84
+ []
85
+ );
86
+ const [status, setStatus] = react.useState("idle");
87
+ const [activeSpeaker, setActiveSpeaker] = react.useState(
88
+ null
89
+ );
90
+ const [isMuted, setIsMuted] = react.useState(false);
91
+ const [transcript, setTranscript] = react.useState([]);
92
+ const [sessionId, setSessionId] = react.useState(null);
93
+ const [roomName, setRoomName] = react.useState(null);
94
+ const [error, setError] = react.useState(null);
95
+ const callbacksRef = react.useRef({
96
+ createSession: createSession ?? createSessionAsViewer,
97
+ onTranscript,
98
+ onInterimTranscript,
99
+ onError
100
+ });
101
+ callbacksRef.current = {
102
+ createSession: createSession ?? createSessionAsViewer,
103
+ onTranscript,
104
+ onInterimTranscript,
105
+ onError
106
+ };
107
+ const roomRef = react.useRef(null);
108
+ const abortRef = react.useRef(null);
109
+ const attachedElementsRef = react.useRef([]);
110
+ const ownedAudioRef = react.useRef(null);
111
+ const committedSegmentIdsRef = react.useRef(/* @__PURE__ */ new Set());
112
+ const startingRef = react.useRef(false);
113
+ const fail = react.useCallback((cause) => {
114
+ var _a, _b;
115
+ const err = toError(cause);
116
+ setError(err);
117
+ setStatus("error");
118
+ (_b = (_a = callbacksRef.current).onError) == null ? void 0 : _b.call(_a, err);
119
+ }, []);
120
+ const detachAudio = react.useCallback(() => {
121
+ for (const element of attachedElementsRef.current) {
122
+ element.srcObject = null;
123
+ if (element === ownedAudioRef.current) element.remove();
124
+ }
125
+ attachedElementsRef.current = [];
126
+ ownedAudioRef.current = null;
127
+ }, []);
128
+ const teardown = react.useCallback(async () => {
129
+ var _a;
130
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
131
+ abortRef.current = null;
132
+ const room = roomRef.current;
133
+ roomRef.current = null;
134
+ startingRef.current = false;
135
+ detachAudio();
136
+ if (room) {
137
+ room.removeAllListeners();
138
+ await room.disconnect(true);
139
+ }
140
+ }, [detachAudio]);
141
+ const stop = react.useCallback(async () => {
142
+ const hadRoom = roomRef.current !== null || abortRef.current !== null;
143
+ await teardown();
144
+ setActiveSpeaker(null);
145
+ if (hadRoom) setStatus("ended");
146
+ }, [teardown]);
147
+ const attachTrack = react.useCallback(
148
+ (track) => {
149
+ if (track.kind !== livekitClient.Track.Kind.Audio) return;
150
+ if (audioElement) {
151
+ track.attach(audioElement);
152
+ attachedElementsRef.current.push(audioElement);
153
+ return;
154
+ }
155
+ const element = track.attach();
156
+ element.setAttribute("data-athena-voice-audio", "");
157
+ document.body.appendChild(element);
158
+ ownedAudioRef.current = element;
159
+ attachedElementsRef.current.push(element);
160
+ },
161
+ [audioElement]
162
+ );
163
+ const handleTranscription = react.useCallback(
164
+ (segments, participant, room) => {
165
+ var _a, _b, _c, _d;
166
+ const speaker = speakerOf(participant, room);
167
+ const committed = [];
168
+ for (const segment of segments) {
169
+ if (!segment.final) {
170
+ (_b = (_a = callbacksRef.current).onInterimTranscript) == null ? void 0 : _b.call(_a, speaker, segment.text);
171
+ continue;
172
+ }
173
+ if (committedSegmentIdsRef.current.has(segment.id)) continue;
174
+ committedSegmentIdsRef.current.add(segment.id);
175
+ committed.push({
176
+ id: segment.id,
177
+ speaker,
178
+ text: segment.text,
179
+ startTime: segment.startTime,
180
+ endTime: segment.endTime,
181
+ language: segment.language
182
+ });
183
+ }
184
+ if (committed.length === 0) return;
185
+ setTranscript((previous) => [...previous, ...committed]);
186
+ for (const turn of committed) (_d = (_c = callbacksRef.current).onTranscript) == null ? void 0 : _d.call(_c, turn);
187
+ },
188
+ []
189
+ );
190
+ const start = react.useCallback(async () => {
191
+ if (startingRef.current || roomRef.current) return;
192
+ startingRef.current = true;
193
+ setError(null);
194
+ setSessionId(null);
195
+ setRoomName(null);
196
+ setStatus("connecting");
197
+ const controller = new AbortController();
198
+ abortRef.current = controller;
199
+ let credentials;
200
+ try {
201
+ credentials = await callbacksRef.current.createSession(controller.signal);
202
+ } catch (cause) {
203
+ if (controller.signal.aborted) return;
204
+ abortRef.current = null;
205
+ startingRef.current = false;
206
+ fail(cause);
207
+ return;
208
+ }
209
+ if (controller.signal.aborted) return;
210
+ setSessionId(credentials.asset_id ?? null);
211
+ setRoomName(credentials.room_name ?? null);
212
+ const room = createRoom ? createRoom() : new livekitClient.Room();
213
+ roomRef.current = room;
214
+ room.on(livekitClient.RoomEvent.TrackSubscribed, attachTrack).on(livekitClient.RoomEvent.ActiveSpeakersChanged, (speakers) => {
215
+ const first = speakers[0];
216
+ setActiveSpeaker(first ? speakerOf(first, room) : null);
217
+ }).on(
218
+ livekitClient.RoomEvent.TranscriptionReceived,
219
+ (segments, participant) => handleTranscription(segments, participant, room)
220
+ ).on(livekitClient.RoomEvent.Reconnecting, () => setStatus("reconnecting")).on(livekitClient.RoomEvent.Reconnected, () => setStatus("connected")).on(livekitClient.RoomEvent.Disconnected, () => {
221
+ if (roomRef.current !== room) return;
222
+ roomRef.current = null;
223
+ startingRef.current = false;
224
+ detachAudio();
225
+ setActiveSpeaker(null);
226
+ setStatus("ended");
227
+ }).on(livekitClient.RoomEvent.MediaDevicesError, fail);
228
+ try {
229
+ await room.connect(credentials.server_url, credentials.token);
230
+ if (controller.signal.aborted) return;
231
+ if (autoEnableMicrophone) {
232
+ await room.localParticipant.setMicrophoneEnabled(true);
233
+ setIsMuted(false);
234
+ } else {
235
+ setIsMuted(true);
236
+ }
237
+ if (controller.signal.aborted) return;
238
+ abortRef.current = null;
239
+ startingRef.current = false;
240
+ setStatus("connected");
241
+ } catch (cause) {
242
+ if (controller.signal.aborted) return;
243
+ await teardown();
244
+ fail(cause);
245
+ }
246
+ }, [
247
+ attachTrack,
248
+ autoEnableMicrophone,
249
+ createRoom,
250
+ detachAudio,
251
+ fail,
252
+ handleTranscription,
253
+ teardown
254
+ ]);
255
+ const setMicrophone = react.useCallback(async (enabled) => {
256
+ const room = roomRef.current;
257
+ if (!room) return;
258
+ await room.localParticipant.setMicrophoneEnabled(enabled);
259
+ setIsMuted(!enabled);
260
+ }, []);
261
+ const mute = react.useCallback(() => setMicrophone(false), [setMicrophone]);
262
+ const unmute = react.useCallback(() => setMicrophone(true), [setMicrophone]);
263
+ const clearTranscript = react.useCallback(() => {
264
+ committedSegmentIdsRef.current.clear();
265
+ setTranscript([]);
266
+ }, []);
267
+ const unmountTimerRef = react.useRef(null);
268
+ react.useEffect(() => {
269
+ if (unmountTimerRef.current !== null) {
270
+ clearTimeout(unmountTimerRef.current);
271
+ unmountTimerRef.current = null;
272
+ }
273
+ return () => {
274
+ unmountTimerRef.current = setTimeout(() => {
275
+ unmountTimerRef.current = null;
276
+ void teardown();
277
+ }, 0);
278
+ };
279
+ }, [teardown]);
280
+ return react.useMemo(
281
+ () => ({
282
+ status,
283
+ isConnecting: status === "connecting",
284
+ isConnected: status === "connected" || status === "reconnecting",
285
+ activeSpeaker,
286
+ isMuted,
287
+ transcript,
288
+ sessionId,
289
+ roomName,
290
+ error,
291
+ start,
292
+ stop,
293
+ mute,
294
+ unmute,
295
+ clearTranscript
296
+ }),
297
+ [
298
+ status,
299
+ activeSpeaker,
300
+ isMuted,
301
+ transcript,
302
+ sessionId,
303
+ roomName,
304
+ error,
305
+ start,
306
+ stop,
307
+ mute,
308
+ unmute,
309
+ clearTranscript
310
+ ]
311
+ );
312
+ };
313
+ exports.createAthenaVoiceSession = createAthenaVoiceSession;
314
+ exports.useAthenaVoiceSession = useAthenaVoiceSession;
315
+ //# sourceMappingURL=use-athena-voice-session.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-voice-session.cjs","sources":["../../src/voice/use-athena-voice-session.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Room,\n RoomEvent,\n Track,\n type Participant,\n type RemoteTrack,\n type TranscriptionSegment,\n} from 'livekit-client';\nimport { useParentBridge, type ParentBridgeState } from '../runtime/auth';\n\n/**\n * LiveKit connection details for one Athena voice session. This is the shape\n * Orpheus returns from `POST /api/orpheus/create-session`; the hook only reads\n * these fields, so any server that proxies that call can hand it straight back.\n */\nexport interface AthenaVoiceSessionCredentials {\n /** LiveKit signalling URL (`wss://…`). */\n server_url: string;\n /** Short-lived LiveKit participant JWT scoped to `room_name`. */\n token: string;\n room_name?: string;\n /**\n * Athena session asset the voice run is persisted into. Use it with\n * `GET /api/v0/sessions/{asset_id}/download` to retrieve the transcript\n * after the call.\n */\n asset_id?: string;\n}\n\nexport type AthenaVoiceSessionStatus =\n | 'idle'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'ended'\n | 'error';\n\nexport type AthenaVoiceSpeaker = 'user' | 'agent';\n\n/** One committed (final) transcription segment from either side of the call. */\nexport interface AthenaVoiceTranscriptTurn {\n id: string;\n speaker: AthenaVoiceSpeaker;\n text: string;\n /** Segment start, in ms since the LiveKit room's epoch. */\n startTime: number;\n endTime: number;\n language: string;\n}\n\n/**\n * Orpheus agent configuration for a session the hook creates itself (see\n * `UseAthenaVoiceSessionOptions.session`). Mirrors the body of\n * `POST /api/orpheus/create-session`; every field is optional and falls back\n * to the server default.\n */\nexport interface AthenaVoiceSessionConfig {\n /** Persona / instructions for the voice agent. */\n system_prompt?: string;\n /** Realtime provider, e.g. `'openai'` or `'google'`. */\n provider?: string;\n /** Provider model id, e.g. `'gpt-realtime-2'`. */\n model?: string;\n /** Provider voice id, e.g. `'marin'` (OpenAI) or `'Aoede'` (Google). */\n voice?: string;\n temperature?: number;\n /** BCP-47 language tag; default `'en'`. */\n language?: string;\n /** Athena tool ids the agent may call; default none. */\n enabled_tools?: string[];\n /** IANA timezone of the speaker, e.g. `'America/New_York'`. */\n timezone?: string;\n}\n\nexport interface UseAthenaVoiceSessionOptions {\n /**\n * Creates the LiveKit session. Omit it when the app is served from a\n * Marathon computer-asset URL: the hook then calls\n * `POST {backendBaseUrl}/api/orpheus/create-session` itself with the\n * viewer's bearer token from `/_athena/auth`, so the session is created as\n * — and shows up in the sessions of — whoever is using the app.\n *\n * Works for workspace members and external SSO viewers alike: the scoped\n * `athview_` viewer credential is authorized for the Orpheus route and\n * `agents/general/invoke` the same way it is for `/api/v0/sessions`.\n *\n * Supply it when the app runs anywhere else (standalone, custom auth): it\n * should run on the caller's own server so the Athena API key never reaches\n * the browser. The hook only reads the returned credentials.\n *\n * Decide once: switching between supplying and omitting it across renders\n * of the same component is not supported.\n */\n createSession?: (\n signal: AbortSignal,\n ) => Promise<AthenaVoiceSessionCredentials>;\n /**\n * Agent configuration for sessions the hook creates itself. Ignored when\n * `createSession` is supplied.\n */\n session?: AthenaVoiceSessionConfig;\n /** Called once per committed transcript turn, in arrival order. */\n onTranscript?: (turn: AthenaVoiceTranscriptTurn) => void;\n /** Called with interim (non-final) transcript text as it streams in. */\n onInterimTranscript?: (speaker: AthenaVoiceSpeaker, text: string) => void;\n onError?: (error: Error) => void;\n /**\n * Where to play the agent's audio. Defaults to a detached `<audio>` element\n * the hook creates and removes itself.\n */\n audioElement?: HTMLMediaElement | null;\n /** Enable the microphone as soon as the room connects. Default `true`. */\n autoEnableMicrophone?: boolean;\n /** @internal Overrides `new Room()`; used by tests. */\n createRoom?: () => Room;\n /** @internal Overrides `useParentBridge()`; used by tests. */\n useBridge?: () => ParentBridgeState;\n}\n\nexport interface UseAthenaVoiceSessionReturn {\n status: AthenaVoiceSessionStatus;\n /** True between `start()` resolving the session and the room connecting. */\n isConnecting: boolean;\n isConnected: boolean;\n /** Who is speaking right now, or `null` when the room is quiet. */\n activeSpeaker: AthenaVoiceSpeaker | null;\n isMuted: boolean;\n /** Committed transcript turns so far, in arrival order. */\n transcript: AthenaVoiceTranscriptTurn[];\n /** Athena session asset id, once the session has been created. */\n sessionId: string | null;\n roomName: string | null;\n error: Error | null;\n /** Creates a session and joins the room. No-op while a session is live. */\n start: () => Promise<void>;\n /** Leaves the room and stops local tracks. Safe to call at any time. */\n stop: () => Promise<void>;\n mute: () => Promise<void>;\n unmute: () => Promise<void>;\n /** Clears `transcript`; does not affect the live session. */\n clearTranscript: () => void;\n}\n\nconst toError = (value: unknown): Error =>\n value instanceof Error ? value : new Error(String(value));\n\nconst NO_BRIDGE: ParentBridgeState = {\n token: null,\n statewireSyncUrl: null,\n backendBaseUrl: null,\n appUrl: null,\n hostAnswered: false,\n ready: true,\n};\n// Stands in for `useParentBridge` when the caller creates sessions itself, so\n// the hook never fetches `/_athena/auth` it would not use.\nconst useNoBridge = (): ParentBridgeState => NO_BRIDGE;\n\nconst NO_VIEWER_TOKEN_MESSAGE =\n 'useAthenaVoiceSession: no Athena viewer token. Either serve the app from ' +\n 'a Marathon computer-asset URL (which mints one via /_athena/auth) or pass ' +\n '`createSession` to create the session through your own server.';\n\n/**\n * `POST /api/orpheus/create-session` as the current viewer. Exported so apps\n * with their own bridge state (or a server proxy holding a user bearer) can\n * reuse the exact request the hook makes.\n */\nexport const createAthenaVoiceSession = async ({\n backendBaseUrl,\n token,\n session = {},\n signal,\n}: {\n /** Bare Agora API base, e.g. `https://api.athenaintel.com`. */\n backendBaseUrl: string;\n /** Bearer token for the user the session belongs to. */\n token: string;\n session?: AthenaVoiceSessionConfig;\n signal?: AbortSignal;\n}): Promise<AthenaVoiceSessionCredentials> => {\n const url: string = `${backendBaseUrl.replace(/\\/+$/, '')}/api/orpheus/create-session`;\n const response: Response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(session),\n signal,\n });\n if (!response.ok) {\n const detail: string = await response.text().catch(() => '');\n throw new Error(\n `Orpheus create-session failed (${response.status})${detail ? `: ${detail}` : ''}`,\n );\n }\n return (await response.json()) as AthenaVoiceSessionCredentials;\n};\n\nconst speakerOf = (\n participant: Participant | undefined,\n room: Room,\n): AthenaVoiceSpeaker =>\n participant !== undefined &&\n participant.identity === room.localParticipant.identity\n ? 'user'\n : 'agent';\n\n/**\n * Runs one Athena voice session (Orpheus agent over LiveKit) from React.\n *\n * Owns the whole browser-side lifecycle the Orpheus API leaves to the caller:\n * creating the session through the app's own server, joining the LiveKit room,\n * publishing the microphone, playing the agent's audio, tracking who is\n * speaking, committing transcript turns from LiveKit transcription events, and\n * tearing everything down on `stop()` or unmount. A second `start()` while a\n * session is live (or still connecting) is ignored, so React StrictMode's\n * double-invoked effects cannot dispatch two agents into one room.\n */\nexport const useAthenaVoiceSession = (\n options: UseAthenaVoiceSessionOptions = {},\n): UseAthenaVoiceSessionReturn => {\n const {\n createSession,\n session,\n onTranscript,\n onInterimTranscript,\n onError,\n audioElement,\n autoEnableMicrophone = true,\n createRoom,\n useBridge = createSession ? useNoBridge : useParentBridge,\n } = options;\n\n // Viewer identity minted by Marathon (`/_athena/auth`) or the Olympus iframe\n // bridge. Only consulted when the caller did not supply `createSession`.\n const bridge: ParentBridgeState = useBridge();\n const bridgeRef = useRef<ParentBridgeState>(bridge);\n bridgeRef.current = bridge;\n const bridgeReadyWaitersRef = useRef<Array<() => void>>([]);\n useEffect(() => {\n if (!bridge.ready) return;\n const waiters: Array<() => void> = bridgeReadyWaitersRef.current;\n bridgeReadyWaitersRef.current = [];\n for (const resolve of waiters) resolve();\n }, [bridge.ready]);\n\n const sessionRef = useRef<AthenaVoiceSessionConfig | undefined>(session);\n sessionRef.current = session;\n\n const createSessionAsViewer = useCallback(\n async (signal: AbortSignal): Promise<AthenaVoiceSessionCredentials> => {\n if (!bridgeRef.current.ready) {\n await new Promise<void>((resolve) => {\n bridgeReadyWaitersRef.current.push(resolve);\n signal.addEventListener('abort', () => resolve(), { once: true });\n });\n if (signal.aborted) throw new Error('aborted');\n }\n const { token, backendBaseUrl } = bridgeRef.current;\n if (!token || !backendBaseUrl) throw new Error(NO_VIEWER_TOKEN_MESSAGE);\n return createAthenaVoiceSession({\n backendBaseUrl,\n token,\n session: sessionRef.current,\n signal,\n });\n },\n [],\n );\n\n const [status, setStatus] = useState<AthenaVoiceSessionStatus>('idle');\n const [activeSpeaker, setActiveSpeaker] = useState<AthenaVoiceSpeaker | null>(\n null,\n );\n const [isMuted, setIsMuted] = useState<boolean>(false);\n const [transcript, setTranscript] = useState<AthenaVoiceTranscriptTurn[]>([]);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [roomName, setRoomName] = useState<string | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n // Latest callbacks without re-subscribing room listeners on every render.\n const callbacksRef = useRef({\n createSession: createSession ?? createSessionAsViewer,\n onTranscript,\n onInterimTranscript,\n onError,\n });\n callbacksRef.current = {\n createSession: createSession ?? createSessionAsViewer,\n onTranscript,\n onInterimTranscript,\n onError,\n };\n\n const roomRef = useRef<Room | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const attachedElementsRef = useRef<HTMLMediaElement[]>([]);\n const ownedAudioRef = useRef<HTMLMediaElement | null>(null);\n const committedSegmentIdsRef = useRef<Set<string>>(new Set());\n // Guards `start()` against re-entry from the moment it is called, before any\n // state update lands — a StrictMode double effect fires both calls\n // synchronously in the same tick.\n const startingRef = useRef<boolean>(false);\n\n const fail = useCallback((cause: unknown) => {\n const err: Error = toError(cause);\n setError(err);\n setStatus('error');\n callbacksRef.current.onError?.(err);\n }, []);\n\n const detachAudio = useCallback(() => {\n for (const element of attachedElementsRef.current) {\n element.srcObject = null;\n if (element === ownedAudioRef.current) element.remove();\n }\n attachedElementsRef.current = [];\n ownedAudioRef.current = null;\n }, []);\n\n const teardown = useCallback(async () => {\n abortRef.current?.abort();\n abortRef.current = null;\n const room: Room | null = roomRef.current;\n roomRef.current = null;\n startingRef.current = false;\n detachAudio();\n if (room) {\n room.removeAllListeners();\n await room.disconnect(true);\n }\n }, [detachAudio]);\n\n const stop = useCallback(async () => {\n const hadRoom: boolean =\n roomRef.current !== null || abortRef.current !== null;\n await teardown();\n setActiveSpeaker(null);\n if (hadRoom) setStatus('ended');\n }, [teardown]);\n\n const attachTrack = useCallback(\n (track: RemoteTrack) => {\n if (track.kind !== Track.Kind.Audio) return;\n if (audioElement) {\n track.attach(audioElement);\n attachedElementsRef.current.push(audioElement);\n return;\n }\n const element: HTMLMediaElement = track.attach();\n element.setAttribute('data-athena-voice-audio', '');\n document.body.appendChild(element);\n ownedAudioRef.current = element;\n attachedElementsRef.current.push(element);\n },\n [audioElement],\n );\n\n const handleTranscription = useCallback(\n (\n segments: TranscriptionSegment[],\n participant: Participant | undefined,\n room: Room,\n ) => {\n const speaker: AthenaVoiceSpeaker = speakerOf(participant, room);\n const committed: AthenaVoiceTranscriptTurn[] = [];\n for (const segment of segments) {\n if (!segment.final) {\n callbacksRef.current.onInterimTranscript?.(speaker, segment.text);\n continue;\n }\n if (committedSegmentIdsRef.current.has(segment.id)) continue;\n committedSegmentIdsRef.current.add(segment.id);\n committed.push({\n id: segment.id,\n speaker,\n text: segment.text,\n startTime: segment.startTime,\n endTime: segment.endTime,\n language: segment.language,\n });\n }\n if (committed.length === 0) return;\n setTranscript((previous) => [...previous, ...committed]);\n for (const turn of committed) callbacksRef.current.onTranscript?.(turn);\n },\n [],\n );\n\n const start = useCallback(async () => {\n if (startingRef.current || roomRef.current) return;\n startingRef.current = true;\n setError(null);\n setSessionId(null);\n setRoomName(null);\n setStatus('connecting');\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n let credentials: AthenaVoiceSessionCredentials;\n try {\n credentials = await callbacksRef.current.createSession(controller.signal);\n } catch (cause) {\n if (controller.signal.aborted) return;\n abortRef.current = null;\n startingRef.current = false;\n fail(cause);\n return;\n }\n if (controller.signal.aborted) return;\n\n setSessionId(credentials.asset_id ?? null);\n setRoomName(credentials.room_name ?? null);\n\n const room: Room = createRoom ? createRoom() : new Room();\n roomRef.current = room;\n\n room\n .on(RoomEvent.TrackSubscribed, attachTrack)\n .on(RoomEvent.ActiveSpeakersChanged, (speakers: Participant[]) => {\n const first: Participant | undefined = speakers[0];\n setActiveSpeaker(first ? speakerOf(first, room) : null);\n })\n .on(RoomEvent.TranscriptionReceived, (segments, participant) =>\n handleTranscription(segments, participant, room),\n )\n .on(RoomEvent.Reconnecting, () => setStatus('reconnecting'))\n .on(RoomEvent.Reconnected, () => setStatus('connected'))\n .on(RoomEvent.Disconnected, () => {\n if (roomRef.current !== room) return;\n roomRef.current = null;\n startingRef.current = false;\n detachAudio();\n setActiveSpeaker(null);\n setStatus('ended');\n })\n .on(RoomEvent.MediaDevicesError, fail);\n\n try {\n await room.connect(credentials.server_url, credentials.token);\n if (controller.signal.aborted) return;\n if (autoEnableMicrophone) {\n await room.localParticipant.setMicrophoneEnabled(true);\n setIsMuted(false);\n } else {\n setIsMuted(true);\n }\n if (controller.signal.aborted) return;\n abortRef.current = null;\n startingRef.current = false;\n setStatus('connected');\n } catch (cause) {\n if (controller.signal.aborted) return;\n await teardown();\n fail(cause);\n }\n }, [\n attachTrack,\n autoEnableMicrophone,\n createRoom,\n detachAudio,\n fail,\n handleTranscription,\n teardown,\n ]);\n\n const setMicrophone = useCallback(async (enabled: boolean) => {\n const room: Room | null = roomRef.current;\n if (!room) return;\n await room.localParticipant.setMicrophoneEnabled(enabled);\n setIsMuted(!enabled);\n }, []);\n const mute = useCallback(() => setMicrophone(false), [setMicrophone]);\n const unmute = useCallback(() => setMicrophone(true), [setMicrophone]);\n\n const clearTranscript = useCallback(() => {\n committedSegmentIdsRef.current.clear();\n setTranscript([]);\n }, []);\n\n // Unmount teardown is deferred one tick so StrictMode's synchronous\n // unmount/remount of the same instance does not abort an in-flight\n // `createSession` (which would dispatch a second Orpheus agent on remount).\n const unmountTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(() => {\n if (unmountTimerRef.current !== null) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n return () => {\n unmountTimerRef.current = setTimeout(() => {\n unmountTimerRef.current = null;\n void teardown();\n }, 0);\n };\n }, [teardown]);\n\n return useMemo<UseAthenaVoiceSessionReturn>(\n () => ({\n status,\n isConnecting: status === 'connecting',\n isConnected: status === 'connected' || status === 'reconnecting',\n activeSpeaker,\n isMuted,\n transcript,\n sessionId,\n roomName,\n error,\n start,\n stop,\n mute,\n unmute,\n clearTranscript,\n }),\n [\n status,\n activeSpeaker,\n isMuted,\n transcript,\n sessionId,\n roomName,\n error,\n start,\n stop,\n mute,\n unmute,\n clearTranscript,\n ],\n );\n};\n"],"names":["useParentBridge","useRef","useEffect","useCallback","useState","Track","Room","RoomEvent","useMemo"],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import { Room } from 'livekit-client';
2
+ import { type ParentBridgeState } from '../runtime/auth';
3
+ /**
4
+ * LiveKit connection details for one Athena voice session. This is the shape
5
+ * Orpheus returns from `POST /api/orpheus/create-session`; the hook only reads
6
+ * these fields, so any server that proxies that call can hand it straight back.
7
+ */
8
+ export interface AthenaVoiceSessionCredentials {
9
+ /** LiveKit signalling URL (`wss://…`). */
10
+ server_url: string;
11
+ /** Short-lived LiveKit participant JWT scoped to `room_name`. */
12
+ token: string;
13
+ room_name?: string;
14
+ /**
15
+ * Athena session asset the voice run is persisted into. Use it with
16
+ * `GET /api/v0/sessions/{asset_id}/download` to retrieve the transcript
17
+ * after the call.
18
+ */
19
+ asset_id?: string;
20
+ }
21
+ export type AthenaVoiceSessionStatus = 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'ended' | 'error';
22
+ export type AthenaVoiceSpeaker = 'user' | 'agent';
23
+ /** One committed (final) transcription segment from either side of the call. */
24
+ export interface AthenaVoiceTranscriptTurn {
25
+ id: string;
26
+ speaker: AthenaVoiceSpeaker;
27
+ text: string;
28
+ /** Segment start, in ms since the LiveKit room's epoch. */
29
+ startTime: number;
30
+ endTime: number;
31
+ language: string;
32
+ }
33
+ /**
34
+ * Orpheus agent configuration for a session the hook creates itself (see
35
+ * `UseAthenaVoiceSessionOptions.session`). Mirrors the body of
36
+ * `POST /api/orpheus/create-session`; every field is optional and falls back
37
+ * to the server default.
38
+ */
39
+ export interface AthenaVoiceSessionConfig {
40
+ /** Persona / instructions for the voice agent. */
41
+ system_prompt?: string;
42
+ /** Realtime provider, e.g. `'openai'` or `'google'`. */
43
+ provider?: string;
44
+ /** Provider model id, e.g. `'gpt-realtime-2'`. */
45
+ model?: string;
46
+ /** Provider voice id, e.g. `'marin'` (OpenAI) or `'Aoede'` (Google). */
47
+ voice?: string;
48
+ temperature?: number;
49
+ /** BCP-47 language tag; default `'en'`. */
50
+ language?: string;
51
+ /** Athena tool ids the agent may call; default none. */
52
+ enabled_tools?: string[];
53
+ /** IANA timezone of the speaker, e.g. `'America/New_York'`. */
54
+ timezone?: string;
55
+ }
56
+ export interface UseAthenaVoiceSessionOptions {
57
+ /**
58
+ * Creates the LiveKit session. Omit it when the app is served from a
59
+ * Marathon computer-asset URL: the hook then calls
60
+ * `POST {backendBaseUrl}/api/orpheus/create-session` itself with the
61
+ * viewer's bearer token from `/_athena/auth`, so the session is created as
62
+ * — and shows up in the sessions of — whoever is using the app.
63
+ *
64
+ * Works for workspace members and external SSO viewers alike: the scoped
65
+ * `athview_` viewer credential is authorized for the Orpheus route and
66
+ * `agents/general/invoke` the same way it is for `/api/v0/sessions`.
67
+ *
68
+ * Supply it when the app runs anywhere else (standalone, custom auth): it
69
+ * should run on the caller's own server so the Athena API key never reaches
70
+ * the browser. The hook only reads the returned credentials.
71
+ *
72
+ * Decide once: switching between supplying and omitting it across renders
73
+ * of the same component is not supported.
74
+ */
75
+ createSession?: (signal: AbortSignal) => Promise<AthenaVoiceSessionCredentials>;
76
+ /**
77
+ * Agent configuration for sessions the hook creates itself. Ignored when
78
+ * `createSession` is supplied.
79
+ */
80
+ session?: AthenaVoiceSessionConfig;
81
+ /** Called once per committed transcript turn, in arrival order. */
82
+ onTranscript?: (turn: AthenaVoiceTranscriptTurn) => void;
83
+ /** Called with interim (non-final) transcript text as it streams in. */
84
+ onInterimTranscript?: (speaker: AthenaVoiceSpeaker, text: string) => void;
85
+ onError?: (error: Error) => void;
86
+ /**
87
+ * Where to play the agent's audio. Defaults to a detached `<audio>` element
88
+ * the hook creates and removes itself.
89
+ */
90
+ audioElement?: HTMLMediaElement | null;
91
+ /** Enable the microphone as soon as the room connects. Default `true`. */
92
+ autoEnableMicrophone?: boolean;
93
+ /** @internal Overrides `new Room()`; used by tests. */
94
+ createRoom?: () => Room;
95
+ /** @internal Overrides `useParentBridge()`; used by tests. */
96
+ useBridge?: () => ParentBridgeState;
97
+ }
98
+ export interface UseAthenaVoiceSessionReturn {
99
+ status: AthenaVoiceSessionStatus;
100
+ /** True between `start()` resolving the session and the room connecting. */
101
+ isConnecting: boolean;
102
+ isConnected: boolean;
103
+ /** Who is speaking right now, or `null` when the room is quiet. */
104
+ activeSpeaker: AthenaVoiceSpeaker | null;
105
+ isMuted: boolean;
106
+ /** Committed transcript turns so far, in arrival order. */
107
+ transcript: AthenaVoiceTranscriptTurn[];
108
+ /** Athena session asset id, once the session has been created. */
109
+ sessionId: string | null;
110
+ roomName: string | null;
111
+ error: Error | null;
112
+ /** Creates a session and joins the room. No-op while a session is live. */
113
+ start: () => Promise<void>;
114
+ /** Leaves the room and stops local tracks. Safe to call at any time. */
115
+ stop: () => Promise<void>;
116
+ mute: () => Promise<void>;
117
+ unmute: () => Promise<void>;
118
+ /** Clears `transcript`; does not affect the live session. */
119
+ clearTranscript: () => void;
120
+ }
121
+ /**
122
+ * `POST /api/orpheus/create-session` as the current viewer. Exported so apps
123
+ * with their own bridge state (or a server proxy holding a user bearer) can
124
+ * reuse the exact request the hook makes.
125
+ */
126
+ export declare const createAthenaVoiceSession: ({ backendBaseUrl, token, session, signal, }: {
127
+ /** Bare Agora API base, e.g. `https://api.athenaintel.com`. */
128
+ backendBaseUrl: string;
129
+ /** Bearer token for the user the session belongs to. */
130
+ token: string;
131
+ session?: AthenaVoiceSessionConfig;
132
+ signal?: AbortSignal;
133
+ }) => Promise<AthenaVoiceSessionCredentials>;
134
+ /**
135
+ * Runs one Athena voice session (Orpheus agent over LiveKit) from React.
136
+ *
137
+ * Owns the whole browser-side lifecycle the Orpheus API leaves to the caller:
138
+ * creating the session through the app's own server, joining the LiveKit room,
139
+ * publishing the microphone, playing the agent's audio, tracking who is
140
+ * speaking, committing transcript turns from LiveKit transcription events, and
141
+ * tearing everything down on `stop()` or unmount. A second `start()` while a
142
+ * session is live (or still connecting) is ignored, so React StrictMode's
143
+ * double-invoked effects cannot dispatch two agents into one room.
144
+ */
145
+ export declare const useAthenaVoiceSession: (options?: UseAthenaVoiceSessionOptions) => UseAthenaVoiceSessionReturn;