@opengeni/react 1.3.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +29 -1
  2. package/dist/accounts.js +2 -0
  3. package/dist/accounts.js.map +1 -1
  4. package/dist/artifacts-document.js +5 -4
  5. package/dist/artifacts-presentation.js +5 -4
  6. package/dist/artifacts-spreadsheet.js +4 -3
  7. package/dist/artifacts.js +14 -13
  8. package/dist/artifacts.js.map +1 -1
  9. package/dist/browser-viewer-WGJ43YGI.js +17 -0
  10. package/dist/chat-interactive-block-ZFHOKTMS.js +12 -0
  11. package/dist/{chunk-WEHMPOXK.js → chunk-2DDJ6YH6.js} +3 -1
  12. package/dist/{chunk-WEHMPOXK.js.map → chunk-2DDJ6YH6.js.map} +1 -1
  13. package/dist/{chunk-C5X5AJXK.js → chunk-2HVLQ26H.js} +5 -4
  14. package/dist/{chunk-C5X5AJXK.js.map → chunk-2HVLQ26H.js.map} +1 -1
  15. package/dist/{chunk-A4UJB2MM.js → chunk-32CGLXW2.js} +4 -3
  16. package/dist/{chunk-A4UJB2MM.js.map → chunk-32CGLXW2.js.map} +1 -1
  17. package/dist/{chunk-5CVXZA3Y.js → chunk-45NUOSXQ.js} +3 -2
  18. package/dist/{chunk-5CVXZA3Y.js.map → chunk-45NUOSXQ.js.map} +1 -1
  19. package/dist/{chunk-WUISZ3WU.js → chunk-53KJBGPZ.js} +5 -4
  20. package/dist/{chunk-WUISZ3WU.js.map → chunk-53KJBGPZ.js.map} +1 -1
  21. package/dist/{chunk-TMYGL6X5.js → chunk-55DXD22O.js} +73 -7
  22. package/dist/chunk-55DXD22O.js.map +1 -0
  23. package/dist/{chunk-JT4JW7BC.js → chunk-5I4VRWBB.js} +3 -1
  24. package/dist/{chunk-JT4JW7BC.js.map → chunk-5I4VRWBB.js.map} +1 -1
  25. package/dist/{chunk-UK4TINKT.js → chunk-B27E3V37.js} +3 -1
  26. package/dist/{chunk-UK4TINKT.js.map → chunk-B27E3V37.js.map} +1 -1
  27. package/dist/{chunk-J6DBS4T3.js → chunk-BNKV5ZLF.js} +5 -4
  28. package/dist/{chunk-J6DBS4T3.js.map → chunk-BNKV5ZLF.js.map} +1 -1
  29. package/dist/{chunk-YM2DE7BQ.js → chunk-C5BF4L26.js} +13 -12
  30. package/dist/{chunk-YM2DE7BQ.js.map → chunk-C5BF4L26.js.map} +1 -1
  31. package/dist/{chunk-YBXQDQFX.js → chunk-C7CMD56T.js} +6 -5
  32. package/dist/{chunk-YBXQDQFX.js.map → chunk-C7CMD56T.js.map} +1 -1
  33. package/dist/{chunk-UGLEYEMP.js → chunk-CM7LVUKC.js} +3 -1
  34. package/dist/{chunk-UGLEYEMP.js.map → chunk-CM7LVUKC.js.map} +1 -1
  35. package/dist/{chunk-PGSX7UCP.js → chunk-CREMJMVN.js} +1502 -833
  36. package/dist/chunk-CREMJMVN.js.map +1 -0
  37. package/dist/{chunk-JVYQRRC4.js → chunk-CVYCLFMH.js} +3 -1
  38. package/dist/{chunk-JVYQRRC4.js.map → chunk-CVYCLFMH.js.map} +1 -1
  39. package/dist/{chunk-Y2PRMYLC.js → chunk-G3U2A6GS.js} +3 -2
  40. package/dist/{chunk-Y2PRMYLC.js.map → chunk-G3U2A6GS.js.map} +1 -1
  41. package/dist/{chunk-WWEUO2PL.js → chunk-G6YRCIYJ.js} +202 -14
  42. package/dist/chunk-G6YRCIYJ.js.map +1 -0
  43. package/dist/{chunk-B3V6TG77.js → chunk-GC3PH6N7.js} +3 -1
  44. package/dist/{chunk-B3V6TG77.js.map → chunk-GC3PH6N7.js.map} +1 -1
  45. package/dist/{chunk-FZCP527Y.js → chunk-HXYOSSQO.js} +3 -2
  46. package/dist/{chunk-FZCP527Y.js.map → chunk-HXYOSSQO.js.map} +1 -1
  47. package/dist/{chunk-BRM6FVZA.js → chunk-IEE7WCLN.js} +4 -3
  48. package/dist/{chunk-BRM6FVZA.js.map → chunk-IEE7WCLN.js.map} +1 -1
  49. package/dist/{chunk-DYWBUX5Q.js → chunk-IMSUVYQB.js} +6 -5
  50. package/dist/{chunk-DYWBUX5Q.js.map → chunk-IMSUVYQB.js.map} +1 -1
  51. package/dist/{chunk-CY7WK5FD.js → chunk-IUHHPMAX.js} +203 -46
  52. package/dist/chunk-IUHHPMAX.js.map +1 -0
  53. package/dist/{chunk-SGKD2OCN.js → chunk-IYQCWGU5.js} +6 -5
  54. package/dist/{chunk-SGKD2OCN.js.map → chunk-IYQCWGU5.js.map} +1 -1
  55. package/dist/{chunk-J2QWVSQY.js → chunk-JH7V627O.js} +8 -7
  56. package/dist/{chunk-J2QWVSQY.js.map → chunk-JH7V627O.js.map} +1 -1
  57. package/dist/{chunk-EESD3PY3.js → chunk-JHTIMBOL.js} +6 -5
  58. package/dist/{chunk-EESD3PY3.js.map → chunk-JHTIMBOL.js.map} +1 -1
  59. package/dist/{chunk-LNIRAOA3.js → chunk-L2J3PU7A.js} +7 -6
  60. package/dist/{chunk-LNIRAOA3.js.map → chunk-L2J3PU7A.js.map} +1 -1
  61. package/dist/{chunk-ZYRGEKWS.js → chunk-LJUMYUBO.js} +3 -1
  62. package/dist/{chunk-ZYRGEKWS.js.map → chunk-LJUMYUBO.js.map} +1 -1
  63. package/dist/{chunk-4RVYOY4O.js → chunk-LSW2OJVV.js} +4 -3
  64. package/dist/{chunk-4RVYOY4O.js.map → chunk-LSW2OJVV.js.map} +1 -1
  65. package/dist/{chunk-UTRTG6LH.js → chunk-LVS3MH5T.js} +3 -1
  66. package/dist/{chunk-UTRTG6LH.js.map → chunk-LVS3MH5T.js.map} +1 -1
  67. package/dist/chunk-M357MHH3.js +2 -0
  68. package/dist/{chunk-GYVRFZDY.js → chunk-MDIXFKA3.js} +9 -8
  69. package/dist/{chunk-GYVRFZDY.js.map → chunk-MDIXFKA3.js.map} +1 -1
  70. package/dist/{chunk-WRHIZYZF.js → chunk-MEQM4LI3.js} +6 -5
  71. package/dist/{chunk-WRHIZYZF.js.map → chunk-MEQM4LI3.js.map} +1 -1
  72. package/dist/chunk-NX4ADH73.js +14 -0
  73. package/dist/chunk-NX4ADH73.js.map +1 -0
  74. package/dist/{chunk-XCHWDJ22.js → chunk-OGTTUYNT.js} +3 -1
  75. package/dist/{chunk-XCHWDJ22.js.map → chunk-OGTTUYNT.js.map} +1 -1
  76. package/dist/{chunk-GIMRELBW.js → chunk-OYQQJL3J.js} +3 -1
  77. package/dist/{chunk-GIMRELBW.js.map → chunk-OYQQJL3J.js.map} +1 -1
  78. package/dist/{chunk-RSI7XYXL.js → chunk-PBCZL4JP.js} +6 -5
  79. package/dist/{chunk-RSI7XYXL.js.map → chunk-PBCZL4JP.js.map} +1 -1
  80. package/dist/{chunk-I7IWRQLN.js → chunk-PHBFJCEU.js} +17 -11
  81. package/dist/chunk-PHBFJCEU.js.map +1 -0
  82. package/dist/{chunk-3CTRFMAK.js → chunk-PKCAYHDC.js} +5 -4
  83. package/dist/{chunk-3CTRFMAK.js.map → chunk-PKCAYHDC.js.map} +1 -1
  84. package/dist/{chunk-K3HQAKQX.js → chunk-PMV53IMM.js} +3 -1
  85. package/dist/{chunk-K3HQAKQX.js.map → chunk-PMV53IMM.js.map} +1 -1
  86. package/dist/{chunk-YQEAA6LT.js → chunk-QHUE7E4N.js} +3 -2
  87. package/dist/{chunk-YQEAA6LT.js.map → chunk-QHUE7E4N.js.map} +1 -1
  88. package/dist/{chunk-RC6BZ44Q.js → chunk-QMMCJGFI.js} +4 -3
  89. package/dist/{chunk-RC6BZ44Q.js.map → chunk-QMMCJGFI.js.map} +1 -1
  90. package/dist/{chunk-YV4L3ILF.js → chunk-QV3DJVRZ.js} +3 -1
  91. package/dist/{chunk-YV4L3ILF.js.map → chunk-QV3DJVRZ.js.map} +1 -1
  92. package/dist/{chunk-447JLCBU.js → chunk-S2QH6EZ5.js} +3 -1
  93. package/dist/{chunk-447JLCBU.js.map → chunk-S2QH6EZ5.js.map} +1 -1
  94. package/dist/{chunk-PNY3JKBJ.js → chunk-SFH43JT2.js} +5 -4
  95. package/dist/{chunk-PNY3JKBJ.js.map → chunk-SFH43JT2.js.map} +1 -1
  96. package/dist/{chunk-ERGYJIBB.js → chunk-T46QZH3E.js} +4 -2
  97. package/dist/{chunk-ERGYJIBB.js.map → chunk-T46QZH3E.js.map} +1 -1
  98. package/dist/{chunk-5J4FOW6Q.js → chunk-TNEZNMSN.js} +3 -1
  99. package/dist/{chunk-5J4FOW6Q.js.map → chunk-TNEZNMSN.js.map} +1 -1
  100. package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
  101. package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
  102. package/dist/{chunk-742CZ3L3.js → chunk-UDPH5SLV.js} +19 -202
  103. package/dist/chunk-UDPH5SLV.js.map +1 -0
  104. package/dist/{chunk-HDJWDK7W.js → chunk-VCSERYXH.js} +10 -9
  105. package/dist/{chunk-HDJWDK7W.js.map → chunk-VCSERYXH.js.map} +1 -1
  106. package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
  107. package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
  108. package/dist/{chunk-5F4WR7X7.js → chunk-XS67YG5R.js} +3 -1
  109. package/dist/{chunk-5F4WR7X7.js.map → chunk-XS67YG5R.js.map} +1 -1
  110. package/dist/{chunk-TKOTKRWY.js → chunk-XTD7TZHW.js} +3 -1
  111. package/dist/{chunk-TKOTKRWY.js.map → chunk-XTD7TZHW.js.map} +1 -1
  112. package/dist/{chunk-A2PI6UMY.js → chunk-YSRBFJMQ.js} +3 -1
  113. package/dist/{chunk-A2PI6UMY.js.map → chunk-YSRBFJMQ.js.map} +1 -1
  114. package/dist/chunk-YVFRBXST.js +1420 -0
  115. package/dist/chunk-YVFRBXST.js.map +1 -0
  116. package/dist/{chunk-SCOTPE2I.js → chunk-YYLBXXTE.js} +3 -1
  117. package/dist/{chunk-SCOTPE2I.js.map → chunk-YYLBXXTE.js.map} +1 -1
  118. package/dist/{chunk-RHREZ7BO.js → chunk-ZUWF4NF7.js} +3 -1
  119. package/dist/{chunk-RHREZ7BO.js.map → chunk-ZUWF4NF7.js.map} +1 -1
  120. package/dist/clipboard.js +3 -2
  121. package/dist/components/composer-transcription-control.d.ts +7 -0
  122. package/dist/components/open-geni-chat.d.ts +6 -2
  123. package/dist/components/session-conversation.d.ts +31 -19
  124. package/dist/components/session-list.d.ts +4 -1
  125. package/dist/components/tool-action-review.d.ts +29 -2
  126. package/dist/components/tool-review-history.d.ts +8 -4
  127. package/dist/composer-voice-events.d.ts +8 -0
  128. package/dist/composer.js +15 -13
  129. package/dist/computer-viewer-46UIN7F3.js +20 -0
  130. package/dist/connect.js +15 -12
  131. package/dist/connect.js.map +1 -1
  132. package/dist/desktop.js +6 -5
  133. package/dist/desktop.js.map +1 -1
  134. package/dist/diffs.js +2 -1
  135. package/dist/diffs.js.map +1 -1
  136. package/dist/editor.js +4 -3
  137. package/dist/editor.js.map +1 -1
  138. package/dist/embedded-voice-NIL4RDX3.js +69 -0
  139. package/dist/embedded-voice-NIL4RDX3.js.map +1 -0
  140. package/dist/{fleet-decision-row-YZ3ZKWMM.js → fleet-decision-row-SI63O5V4.js} +3 -1
  141. package/dist/{fleet-decision-row-YZ3ZKWMM.js.map → fleet-decision-row-SI63O5V4.js.map} +1 -1
  142. package/dist/hooks/use-client-config-flags.d.ts +43 -0
  143. package/dist/hooks/use-realtime-voice-models.d.ts +9 -0
  144. package/dist/hooks/use-voice-input.d.ts +8 -1
  145. package/dist/index.d.ts +3 -3
  146. package/dist/index.js +60 -48
  147. package/dist/index.js.map +1 -1
  148. package/dist/interaction.js +14 -13
  149. package/dist/interaction.js.map +1 -1
  150. package/dist/{latest-question-YTOBHCWR.js → latest-question-2POFPYNB.js} +5 -4
  151. package/dist/{latest-question-YTOBHCWR.js.map → latest-question-2POFPYNB.js.map} +1 -1
  152. package/dist/machines.js +8 -7
  153. package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-DQ4DRNVT.js} +3 -1
  154. package/dist/{markdown-table-layout-QXSLK4BY.js.map → markdown-table-layout-DQ4DRNVT.js.map} +1 -1
  155. package/dist/model-policy-picker-menu-WRNSRFQC.js +15 -0
  156. package/dist/model-policy.js +2 -1
  157. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
  158. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
  159. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
  160. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
  161. package/dist/{platform-activity-row-627BFZ46.js → platform-activity-row-PJJVATTZ.js} +3 -1
  162. package/dist/{platform-activity-row-627BFZ46.js.map → platform-activity-row-PJJVATTZ.js.map} +1 -1
  163. package/dist/{queue-surface-implementation-ZHFI5JBP.js → queue-surface-implementation-67FS7FUI.js} +10 -9
  164. package/dist/{queue-surface-implementation-ZHFI5JBP.js.map → queue-surface-implementation-67FS7FUI.js.map} +1 -1
  165. package/dist/realtime/embedded-voice.d.ts +20 -0
  166. package/dist/realtime/realtime-control.d.ts +2 -0
  167. package/dist/realtime.js +22 -1332
  168. package/dist/realtime.js.map +1 -1
  169. package/dist/sandbox-files-34CJJNOY.js +21 -0
  170. package/dist/session-capability-policy.d.ts +20 -1
  171. package/dist/session-ui.js +32 -30
  172. package/dist/session-ui.js.map +1 -1
  173. package/dist/session.js +12 -11
  174. package/dist/sites.js +2 -1
  175. package/dist/terminal.js +6 -5
  176. package/dist/terminal.js.map +1 -1
  177. package/dist/timeline/index.d.ts +2 -0
  178. package/dist/timeline/retained-loaders.d.ts +27 -0
  179. package/dist/{timeline-annotation-markers-GNDHTGBD.js → timeline-annotation-markers-U3G66KUD.js} +5 -4
  180. package/dist/{timeline-annotation-markers-GNDHTGBD.js.map → timeline-annotation-markers-U3G66KUD.js.map} +1 -1
  181. package/dist/{timeline-annotation-selection-DMLMM2TX.js → timeline-annotation-selection-BI7QTPTZ.js} +4 -3
  182. package/dist/{timeline-annotation-selection-DMLMM2TX.js.map → timeline-annotation-selection-BI7QTPTZ.js.map} +1 -1
  183. package/dist/{timeline-annotations-dialog-ELRDBHTS.js → timeline-annotations-dialog-FOMHSDTE.js} +7 -6
  184. package/dist/{timeline-annotations-dialog-ELRDBHTS.js.map → timeline-annotations-dialog-FOMHSDTE.js.map} +1 -1
  185. package/dist/usage.js +6 -5
  186. package/dist/usage.js.map +1 -1
  187. package/dist/voice-recording-owner.d.ts +7 -0
  188. package/package.json +3 -3
  189. package/src/components/approval-surface.tsx +190 -79
  190. package/src/components/artifacts/session-artifact-viewer.tsx +4 -2
  191. package/src/components/composer-transcription-control.tsx +121 -25
  192. package/src/components/composer.tsx +1 -0
  193. package/src/components/markdown.tsx +7 -2
  194. package/src/components/message-timeline.tsx +10 -1
  195. package/src/components/open-geni-chat.tsx +53 -13
  196. package/src/components/session-conversation.tsx +273 -63
  197. package/src/components/session-list.tsx +9 -2
  198. package/src/components/session-proxy-scope.tsx +26 -5
  199. package/src/components/tool-action-review.tsx +502 -239
  200. package/src/components/tool-review-history.tsx +18 -43
  201. package/src/composer-voice-events.ts +12 -0
  202. package/src/connection-discovery.tsx +4 -1
  203. package/src/hooks/use-client-config-flags.ts +110 -0
  204. package/src/hooks/use-goal.ts +12 -1
  205. package/src/hooks/use-realtime-voice-models.ts +67 -0
  206. package/src/hooks/use-session-events.ts +19 -16
  207. package/src/hooks/use-transcription.ts +6 -0
  208. package/src/hooks/use-voice-input.ts +115 -18
  209. package/src/index.ts +9 -0
  210. package/src/realtime/embedded-voice.tsx +81 -0
  211. package/src/realtime/realtime-control.tsx +109 -17
  212. package/src/session-capability-policy.ts +119 -6
  213. package/src/timeline/index.ts +10 -0
  214. package/src/timeline/retained-loaders.ts +86 -0
  215. package/src/timeline/tool-display-name.ts +5 -1
  216. package/src/timeline/tool-renderers.tsx +143 -10
  217. package/src/voice-recording-owner.ts +22 -0
  218. package/styles/compiled.css +135 -37
  219. package/styles/index.css +49 -0
  220. package/styles/responsive.css +61 -4
  221. package/styles/session-capability.css +1 -1
  222. package/styles/tokens.css +1 -1
  223. package/dist/browser-viewer-SHYKQRNX.js +0 -16
  224. package/dist/chat-interactive-block-UGBTNB3L.js +0 -11
  225. package/dist/chunk-742CZ3L3.js.map +0 -1
  226. package/dist/chunk-CY7WK5FD.js.map +0 -1
  227. package/dist/chunk-I7IWRQLN.js.map +0 -1
  228. package/dist/chunk-IWIDV7SB.js +0 -1
  229. package/dist/chunk-PGSX7UCP.js.map +0 -1
  230. package/dist/chunk-TMYGL6X5.js.map +0 -1
  231. package/dist/chunk-WWEUO2PL.js.map +0 -1
  232. package/dist/computer-viewer-6SRGWRUX.js +0 -19
  233. package/dist/model-policy-picker-menu-DXHUL73H.js +0 -14
  234. package/dist/sandbox-files-GORZOUUJ.js +0 -20
  235. /package/dist/{browser-viewer-SHYKQRNX.js.map → browser-viewer-WGJ43YGI.js.map} +0 -0
  236. /package/dist/{chat-interactive-block-UGBTNB3L.js.map → chat-interactive-block-ZFHOKTMS.js.map} +0 -0
  237. /package/dist/{chunk-IWIDV7SB.js.map → chunk-M357MHH3.js.map} +0 -0
  238. /package/dist/{computer-viewer-6SRGWRUX.js.map → computer-viewer-46UIN7F3.js.map} +0 -0
  239. /package/dist/{model-policy-picker-menu-DXHUL73H.js.map → model-policy-picker-menu-WRNSRFQC.js.map} +0 -0
  240. /package/dist/{sandbox-files-GORZOUUJ.js.map → sandbox-files-34CJJNOY.js.map} +0 -0
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/lib/clipboard.ts
2
4
  async function copyTextToClipboard(text) {
3
5
  const value = text.replace(/\u00a0/g, " ");
@@ -50,4 +52,4 @@ export {
50
52
  copyTextToClipboard,
51
53
  tableElementToTsv
52
54
  };
53
- //# sourceMappingURL=chunk-JVYQRRC4.js.map
55
+ //# sourceMappingURL=chunk-CVYCLFMH.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/clipboard.ts"],"sourcesContent":["/**\n * Copy plain text to the clipboard. Prefers the async Clipboard API; falls\n * back to a short-lived textarea for older embeds / denied permissions.\n */\nexport async function copyTextToClipboard(text: string): Promise<boolean> {\n const value = text.replace(/\\u00a0/g, \" \");\n if (value.length === 0) {\n return false;\n }\n try {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value);\n return true;\n }\n } catch {\n // Fall through to execCommand path.\n }\n if (typeof document === \"undefined\") {\n return false;\n }\n try {\n const area = document.createElement(\"textarea\");\n area.value = value;\n area.setAttribute(\"readonly\", \"\");\n area.style.position = \"fixed\";\n area.style.left = \"-9999px\";\n area.style.top = \"0\";\n document.body.appendChild(area);\n area.select();\n const ok = document.execCommand(\"copy\");\n document.body.removeChild(area);\n return ok;\n } catch {\n return false;\n }\n}\n\n/** Serialize an HTML table to tab-separated values (spreadsheet-friendly). */\nexport function tableElementToTsv(table: HTMLTableElement | null | undefined): string {\n if (!table) {\n return \"\";\n }\n const rows = Array.from(table.querySelectorAll(\"tr\"));\n return rows\n .map((row) =>\n Array.from(row.querySelectorAll(\"th,td\"))\n .map((cell) => {\n const raw = (cell.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (/[\\t\\n\"]/.test(raw)) {\n return `\"${raw.replace(/\"/g, '\"\"')}\"`;\n }\n return raw;\n })\n .join(\"\\t\"),\n )\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n"],"mappings":";AAIA,eAAsB,oBAAoB,MAAgC;AACxE,QAAM,QAAQ,KAAK,QAAQ,WAAW,GAAG;AACzC,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,MAAI;AACF,QAAI,OAAO,cAAc,eAAe,UAAU,WAAW,WAAW;AACtE,YAAM,UAAU,UAAU,UAAU,KAAK;AACzC,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AACA,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,OAAO,SAAS,cAAc,UAAU;AAC9C,SAAK,QAAQ;AACb,SAAK,aAAa,YAAY,EAAE;AAChC,SAAK,MAAM,WAAW;AACtB,SAAK,MAAM,OAAO;AAClB,SAAK,MAAM,MAAM;AACjB,aAAS,KAAK,YAAY,IAAI;AAC9B,SAAK,OAAO;AACZ,UAAM,KAAK,SAAS,YAAY,MAAM;AACtC,aAAS,KAAK,YAAY,IAAI;AAC9B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,kBAAkB,OAAoD;AACpF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,OAAO,MAAM,KAAK,MAAM,iBAAiB,IAAI,CAAC;AACpD,SAAO,KACJ;AAAA,IAAI,CAAC,QACJ,MAAM,KAAK,IAAI,iBAAiB,OAAO,CAAC,EACrC,IAAI,CAAC,SAAS;AACb,YAAM,OAAO,KAAK,eAAe,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/D,UAAI,UAAU,KAAK,GAAG,GAAG;AACvB,eAAO,IAAI,IAAI,QAAQ,MAAM,IAAI,CAAC;AAAA,MACpC;AACA,aAAO;AAAA,IACT,CAAC,EACA,KAAK,GAAI;AAAA,EACd,EACC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,IAAI;AACd;","names":[]}
1
+ {"version":3,"sources":["../src/lib/clipboard.ts"],"sourcesContent":["/**\n * Copy plain text to the clipboard. Prefers the async Clipboard API; falls\n * back to a short-lived textarea for older embeds / denied permissions.\n */\nexport async function copyTextToClipboard(text: string): Promise<boolean> {\n const value = text.replace(/\\u00a0/g, \" \");\n if (value.length === 0) {\n return false;\n }\n try {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(value);\n return true;\n }\n } catch {\n // Fall through to execCommand path.\n }\n if (typeof document === \"undefined\") {\n return false;\n }\n try {\n const area = document.createElement(\"textarea\");\n area.value = value;\n area.setAttribute(\"readonly\", \"\");\n area.style.position = \"fixed\";\n area.style.left = \"-9999px\";\n area.style.top = \"0\";\n document.body.appendChild(area);\n area.select();\n const ok = document.execCommand(\"copy\");\n document.body.removeChild(area);\n return ok;\n } catch {\n return false;\n }\n}\n\n/** Serialize an HTML table to tab-separated values (spreadsheet-friendly). */\nexport function tableElementToTsv(table: HTMLTableElement | null | undefined): string {\n if (!table) {\n return \"\";\n }\n const rows = Array.from(table.querySelectorAll(\"tr\"));\n return rows\n .map((row) =>\n Array.from(row.querySelectorAll(\"th,td\"))\n .map((cell) => {\n const raw = (cell.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (/[\\t\\n\"]/.test(raw)) {\n return `\"${raw.replace(/\"/g, '\"\"')}\"`;\n }\n return raw;\n })\n .join(\"\\t\"),\n )\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n"],"mappings":";;;AAIA,eAAsB,oBAAoB,MAAgC;AACxE,QAAM,QAAQ,KAAK,QAAQ,WAAW,GAAG;AACzC,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,MAAI;AACF,QAAI,OAAO,cAAc,eAAe,UAAU,WAAW,WAAW;AACtE,YAAM,UAAU,UAAU,UAAU,KAAK;AACzC,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AACA,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,OAAO,SAAS,cAAc,UAAU;AAC9C,SAAK,QAAQ;AACb,SAAK,aAAa,YAAY,EAAE;AAChC,SAAK,MAAM,WAAW;AACtB,SAAK,MAAM,OAAO;AAClB,SAAK,MAAM,MAAM;AACjB,aAAS,KAAK,YAAY,IAAI;AAC9B,SAAK,OAAO;AACZ,UAAM,KAAK,SAAS,YAAY,MAAM;AACtC,aAAS,KAAK,YAAY,IAAI;AAC9B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,kBAAkB,OAAoD;AACpF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,OAAO,MAAM,KAAK,MAAM,iBAAiB,IAAI,CAAC;AACpD,SAAO,KACJ;AAAA,IAAI,CAAC,QACJ,MAAM,KAAK,IAAI,iBAAiB,OAAO,CAAC,EACrC,IAAI,CAAC,SAAS;AACb,YAAM,OAAO,KAAK,eAAe,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/D,UAAI,UAAU,KAAK,GAAG,GAAG;AACvB,eAAO,IAAI,IAAI,QAAQ,MAAM,IAAI,CAAC;AAAA,MACpC;AACA,aAAO;AAAA,IACT,CAAC,EACA,KAAK,GAAI;AAAA,EACd,EACC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,IAAI;AACd;","names":[]}
@@ -1,6 +1,7 @@
1
+ "use client";
1
2
  import {
2
3
  cn
3
- } from "./chunk-22KP6LR5.js";
4
+ } from "./chunk-TXS65BB2.js";
4
5
 
5
6
  // src/components/artifacts/artifact-surface.tsx
6
7
  import {
@@ -159,4 +160,4 @@ export {
159
160
  EditableArtifactMessage,
160
161
  asEditableArtifactError
161
162
  };
162
- //# sourceMappingURL=chunk-Y2PRMYLC.js.map
163
+ //# sourceMappingURL=chunk-G3U2A6GS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/artifacts/artifact-surface.tsx","../src/components/artifacts/editable-artifact-ui.tsx"],"sourcesContent":["import {\n FileSpreadsheetIcon,\n FileTextIcon,\n LoaderCircleIcon,\n PresentationIcon,\n} from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport type ArtifactModality = \"spreadsheet\" | \"document\" | \"presentation\";\n\nexport type ArtifactSurfaceProps = {\n modality: ArtifactModality;\n title: string;\n /** An embedding host may already provide the artifact title and navigation. */\n showHeader?: boolean | undefined;\n subtitle?: ReactNode | undefined;\n actions?: ReactNode | undefined;\n children: ReactNode;\n footer?: ReactNode | undefined;\n busy?: boolean | undefined;\n className?: string | undefined;\n};\n\nconst MODALITY_LABEL: Record<ArtifactModality, string> = {\n spreadsheet: \"Spreadsheet\",\n document: \"Document\",\n presentation: \"Presentation\",\n};\n\nfunction ModalityIcon({ modality }: { modality: ArtifactModality }) {\n switch (modality) {\n case \"spreadsheet\":\n return <FileSpreadsheetIcon className=\"size-4\" />;\n case \"document\":\n return <FileTextIcon className=\"size-4\" />;\n case \"presentation\":\n return <PresentationIcon className=\"size-4\" />;\n }\n}\n\n/**\n * Modality-neutral artifact chrome. It deliberately owns no file, session, or\n * persistence state: hosts can use the same surface for a local draft, a\n * durable OpenGeni artifact, or a collaborative projection.\n */\nexport function ArtifactSurface({\n modality,\n title,\n showHeader = true,\n subtitle,\n actions,\n children,\n footer,\n busy = false,\n className,\n}: ArtifactSurfaceProps) {\n return (\n <section\n aria-label={`${MODALITY_LABEL[modality]}: ${title}`}\n aria-busy={busy || undefined}\n data-og-artifact-modality={modality}\n className={cn(\n \"og-root flex h-full min-h-0 min-w-0 flex-col overflow-hidden rounded-og-lg border border-og-border bg-og-surface-1 text-og-fg shadow-og-md\",\n className,\n )}\n >\n {showHeader ? (\n <header className=\"flex min-h-11 shrink-0 items-center gap-2 border-b border-og-border bg-og-surface-2 px-3\">\n <span\n aria-hidden\n className=\"grid size-7 shrink-0 place-items-center rounded-og-sm bg-og-surface-3 text-og-fg-muted\"\n >\n <ModalityIcon modality={modality} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"truncate text-og-base font-medium text-og-fg\">{title}</h2>\n {subtitle ? (\n <div className=\"truncate text-og-xs text-og-fg-muted\">{subtitle}</div>\n ) : null}\n </div>\n {busy ? (\n <LoaderCircleIcon\n aria-label=\"Updating artifact\"\n className=\"size-4 shrink-0 animate-spin text-og-fg-muted\"\n />\n ) : null}\n {actions ? <div className=\"flex shrink-0 items-center gap-1\">{actions}</div> : null}\n </header>\n ) : (\n <>\n {typeof subtitle === \"string\" || typeof subtitle === \"number\" ? (\n <span role=\"status\" className=\"sr-only\">\n {subtitle}\n </span>\n ) : null}\n {actions ? (\n <div className=\"flex shrink-0 items-center justify-end gap-1 border-b border-og-border px-3 py-1\">\n {actions}\n </div>\n ) : null}\n </>\n )}\n\n <div className=\"min-h-0 min-w-0 flex-1\">{children}</div>\n\n {footer ? (\n <footer className=\"shrink-0 border-t border-og-border bg-og-surface-2\">{footer}</footer>\n ) : null}\n </section>\n );\n}\n","import type {\n EditableArtifactSession,\n EditableArtifactSyncView,\n} from \"@opengeni/sdk/editable-artifacts\";\nimport { useEffect, useState } from \"react\";\n\nexport function useEditableArtifactView(\n session: EditableArtifactSession,\n): EditableArtifactSyncView {\n const [view, setView] = useState(() => session.getView());\n useEffect(() => {\n setView(session.getView());\n return session.subscribe(setView);\n }, [session]);\n return view;\n}\n\n/** Changes whenever the Worker-resident speculative projection may have changed. */\nexport function editableArtifactProjectionKey(view: EditableArtifactSyncView): string {\n return [\n view.state,\n view.cursor,\n view.headSequence,\n view.pendingTransactions,\n view.blockedPending.map((entry) => `${entry.clientTransactionId}:${entry.code}`).join(\",\"),\n ].join(\":\");\n}\n\nexport function editableArtifactStatusLabel(view: EditableArtifactSyncView): string {\n switch (view.state) {\n case \"idle\":\n case \"connecting\":\n return \"Connecting…\";\n case \"syncing\":\n case \"resyncing\":\n return \"Syncing…\";\n case \"reconnecting\":\n return \"Reconnecting…\";\n case \"unsupported\":\n return \"This artifact version is not supported\";\n case \"failed\":\n if (editableArtifactAccessRevoked(view)) {\n return \"You no longer have access to this artifact\";\n }\n return view.lastError?.message ?? \"Could not open this artifact\";\n case \"closed\":\n return \"Artifact session closed\";\n case \"live\":\n return view.writable ? \"Live\" : \"Live · Read only\";\n }\n}\n\n/** Revoked read authority must hide any projection retained before invalidation. */\nexport function editableArtifactAccessRevoked(view: EditableArtifactSyncView): boolean {\n if (view.state !== \"failed\" || !view.lastError) return false;\n return (view.lastError as Error & Readonly<{ code?: unknown }>).code === \"permission_changed\";\n}\n\nexport function EditableArtifactMessage({\n title,\n detail,\n retry,\n retryLabel = \"Retry\",\n}: {\n title: string;\n detail: string;\n retry?: (() => void) | undefined;\n retryLabel?: string | undefined;\n}) {\n return (\n <div className=\"grid h-full min-h-56 place-items-center bg-og-bg p-6 text-center\">\n <div>\n <p className=\"text-og-base font-medium text-og-fg\">{title}</p>\n <p className=\"mt-1 max-w-lg text-og-sm text-og-fg-muted\">{detail}</p>\n {retry ? (\n <button\n type=\"button\"\n onClick={retry}\n className=\"mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent\"\n >\n {retryLabel}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport function asEditableArtifactError(cause: unknown, fallback: string): Error {\n return cause instanceof Error ? cause : new Error(fallback);\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
1
+ {"version":3,"sources":["../src/components/artifacts/artifact-surface.tsx","../src/components/artifacts/editable-artifact-ui.tsx"],"sourcesContent":["import {\n FileSpreadsheetIcon,\n FileTextIcon,\n LoaderCircleIcon,\n PresentationIcon,\n} from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport type ArtifactModality = \"spreadsheet\" | \"document\" | \"presentation\";\n\nexport type ArtifactSurfaceProps = {\n modality: ArtifactModality;\n title: string;\n /** An embedding host may already provide the artifact title and navigation. */\n showHeader?: boolean | undefined;\n subtitle?: ReactNode | undefined;\n actions?: ReactNode | undefined;\n children: ReactNode;\n footer?: ReactNode | undefined;\n busy?: boolean | undefined;\n className?: string | undefined;\n};\n\nconst MODALITY_LABEL: Record<ArtifactModality, string> = {\n spreadsheet: \"Spreadsheet\",\n document: \"Document\",\n presentation: \"Presentation\",\n};\n\nfunction ModalityIcon({ modality }: { modality: ArtifactModality }) {\n switch (modality) {\n case \"spreadsheet\":\n return <FileSpreadsheetIcon className=\"size-4\" />;\n case \"document\":\n return <FileTextIcon className=\"size-4\" />;\n case \"presentation\":\n return <PresentationIcon className=\"size-4\" />;\n }\n}\n\n/**\n * Modality-neutral artifact chrome. It deliberately owns no file, session, or\n * persistence state: hosts can use the same surface for a local draft, a\n * durable OpenGeni artifact, or a collaborative projection.\n */\nexport function ArtifactSurface({\n modality,\n title,\n showHeader = true,\n subtitle,\n actions,\n children,\n footer,\n busy = false,\n className,\n}: ArtifactSurfaceProps) {\n return (\n <section\n aria-label={`${MODALITY_LABEL[modality]}: ${title}`}\n aria-busy={busy || undefined}\n data-og-artifact-modality={modality}\n className={cn(\n \"og-root flex h-full min-h-0 min-w-0 flex-col overflow-hidden rounded-og-lg border border-og-border bg-og-surface-1 text-og-fg shadow-og-md\",\n className,\n )}\n >\n {showHeader ? (\n <header className=\"flex min-h-11 shrink-0 items-center gap-2 border-b border-og-border bg-og-surface-2 px-3\">\n <span\n aria-hidden\n className=\"grid size-7 shrink-0 place-items-center rounded-og-sm bg-og-surface-3 text-og-fg-muted\"\n >\n <ModalityIcon modality={modality} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"truncate text-og-base font-medium text-og-fg\">{title}</h2>\n {subtitle ? (\n <div className=\"truncate text-og-xs text-og-fg-muted\">{subtitle}</div>\n ) : null}\n </div>\n {busy ? (\n <LoaderCircleIcon\n aria-label=\"Updating artifact\"\n className=\"size-4 shrink-0 animate-spin text-og-fg-muted\"\n />\n ) : null}\n {actions ? <div className=\"flex shrink-0 items-center gap-1\">{actions}</div> : null}\n </header>\n ) : (\n <>\n {typeof subtitle === \"string\" || typeof subtitle === \"number\" ? (\n <span role=\"status\" className=\"sr-only\">\n {subtitle}\n </span>\n ) : null}\n {actions ? (\n <div className=\"flex shrink-0 items-center justify-end gap-1 border-b border-og-border px-3 py-1\">\n {actions}\n </div>\n ) : null}\n </>\n )}\n\n <div className=\"min-h-0 min-w-0 flex-1\">{children}</div>\n\n {footer ? (\n <footer className=\"shrink-0 border-t border-og-border bg-og-surface-2\">{footer}</footer>\n ) : null}\n </section>\n );\n}\n","import type {\n EditableArtifactSession,\n EditableArtifactSyncView,\n} from \"@opengeni/sdk/editable-artifacts\";\nimport { useEffect, useState } from \"react\";\n\nexport function useEditableArtifactView(\n session: EditableArtifactSession,\n): EditableArtifactSyncView {\n const [view, setView] = useState(() => session.getView());\n useEffect(() => {\n setView(session.getView());\n return session.subscribe(setView);\n }, [session]);\n return view;\n}\n\n/** Changes whenever the Worker-resident speculative projection may have changed. */\nexport function editableArtifactProjectionKey(view: EditableArtifactSyncView): string {\n return [\n view.state,\n view.cursor,\n view.headSequence,\n view.pendingTransactions,\n view.blockedPending.map((entry) => `${entry.clientTransactionId}:${entry.code}`).join(\",\"),\n ].join(\":\");\n}\n\nexport function editableArtifactStatusLabel(view: EditableArtifactSyncView): string {\n switch (view.state) {\n case \"idle\":\n case \"connecting\":\n return \"Connecting…\";\n case \"syncing\":\n case \"resyncing\":\n return \"Syncing…\";\n case \"reconnecting\":\n return \"Reconnecting…\";\n case \"unsupported\":\n return \"This artifact version is not supported\";\n case \"failed\":\n if (editableArtifactAccessRevoked(view)) {\n return \"You no longer have access to this artifact\";\n }\n return view.lastError?.message ?? \"Could not open this artifact\";\n case \"closed\":\n return \"Artifact session closed\";\n case \"live\":\n return view.writable ? \"Live\" : \"Live · Read only\";\n }\n}\n\n/** Revoked read authority must hide any projection retained before invalidation. */\nexport function editableArtifactAccessRevoked(view: EditableArtifactSyncView): boolean {\n if (view.state !== \"failed\" || !view.lastError) return false;\n return (view.lastError as Error & Readonly<{ code?: unknown }>).code === \"permission_changed\";\n}\n\nexport function EditableArtifactMessage({\n title,\n detail,\n retry,\n retryLabel = \"Retry\",\n}: {\n title: string;\n detail: string;\n retry?: (() => void) | undefined;\n retryLabel?: string | undefined;\n}) {\n return (\n <div className=\"grid h-full min-h-56 place-items-center bg-og-bg p-6 text-center\">\n <div>\n <p className=\"text-og-base font-medium text-og-fg\">{title}</p>\n <p className=\"mt-1 max-w-lg text-og-sm text-og-fg-muted\">{detail}</p>\n {retry ? (\n <button\n type=\"button\"\n onClick={retry}\n className=\"mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent\"\n >\n {retryLabel}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport function asEditableArtifactError(cause: unknown, fallback: string): Error {\n return cause instanceof Error ? cause : new Error(fallback);\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
@@ -1,25 +1,27 @@
1
+ "use client";
1
2
  import {
2
3
  buildTimeline,
3
4
  groupTimeline,
4
5
  sessionStatusFromEvents
5
- } from "./chunk-RC6BZ44Q.js";
6
+ } from "./chunk-QMMCJGFI.js";
6
7
  import {
7
8
  useDebouncedCallback,
8
9
  useMutationRunner,
9
10
  usePageLiveActivity,
10
11
  usePolledValue,
11
12
  useSessionEventTrigger
12
- } from "./chunk-YQEAA6LT.js";
13
+ } from "./chunk-QHUE7E4N.js";
13
14
  import {
14
15
  normalizeError,
15
16
  useErrorMessage
16
- } from "./chunk-UGLEYEMP.js";
17
+ } from "./chunk-CM7LVUKC.js";
17
18
  import {
18
19
  useEmbeddedFileAttachments,
20
+ useEmbeddedGoal,
19
21
  useEmbeddedHumanInputSession,
20
22
  useEmbeddedSession,
21
23
  useEmbeddedSessionRead
22
- } from "./chunk-TKOTKRWY.js";
24
+ } from "./chunk-XTD7TZHW.js";
23
25
 
24
26
  // src/human-input.ts
25
27
  function isActionableHumanInputRequest(request, nowMs = Date.now()) {
@@ -580,7 +582,6 @@ function useSessionEvents(sessionId, options = {}) {
580
582
  markTailPreserved();
581
583
  return false;
582
584
  }
583
- streamAbortRef.current?.abort();
584
585
  const status = observeSessionStatus(window.events, sessionStatusRef);
585
586
  const retained = {
586
587
  ...next,
@@ -592,17 +593,21 @@ function useSessionEvents(sessionId, options = {}) {
592
593
  }
593
594
  const retainedNewest = maxResumeSequenceOrNull(retained.events);
594
595
  const previousNewest = maxResumeSequenceOrNull(current.events);
596
+ const evictedLiveTail = previousNewest !== null && retainedNewest !== null && retainedNewest < previousNewest;
597
+ if (evictedLiveTail && viewModeRef.current === "live") {
598
+ streamAbortRef.current?.abort();
599
+ }
595
600
  eventWindowRef.current = retained;
596
601
  markCommitted();
597
602
  oldestSequenceRef.current = retainedOldest;
598
603
  newestSequenceRef.current = retainedNewest;
599
- streamResumeSequenceRef.current = maxResumeSequence(retained.events);
604
+ if (evictedLiveTail) {
605
+ streamResumeSequenceRef.current = maxResumeSequence(retained.events);
606
+ }
600
607
  const olderStillAvailable = window.hasOlder;
601
608
  hasOlderRef.current = olderStillAvailable;
602
- const evictedLiveTail = previousNewest !== null && retainedNewest !== null && retainedNewest < previousNewest;
603
609
  let newer = null;
604
610
  let enterHistory = false;
605
- let reconnectLive = false;
606
611
  if (viewModeRef.current === "history" || evictedLiveTail) {
607
612
  const highWater = lastSequenceRef.current;
608
613
  newer = retainedNewest !== null && (retainedNewest < highWater || retained.truncated);
@@ -611,8 +616,6 @@ function useSessionEvents(sessionId, options = {}) {
611
616
  viewModeRef.current = "history";
612
617
  enterHistory = true;
613
618
  }
614
- } else {
615
- reconnectLive = true;
616
619
  }
617
620
  loadingOlderRef.current = false;
618
621
  startTransition(() => {
@@ -626,8 +629,6 @@ function useSessionEvents(sessionId, options = {}) {
626
629
  }
627
630
  if (enterHistory) {
628
631
  setViewMode("history");
629
- } else if (reconnectLive) {
630
- setStreamEpoch((epoch) => epoch + 1);
631
632
  }
632
633
  setLoadingOlder(false);
633
634
  });
@@ -891,7 +892,7 @@ function useSessionEvents(sessionId, options = {}) {
891
892
  let generation = navigationGenerationRef.current;
892
893
  const current = () => ownsNavigation() && generation === navigationGenerationRef.current;
893
894
  try {
894
- const { resolveLatestQuestion } = await import("./latest-question-YTOBHCWR.js");
895
+ const { resolveLatestQuestion } = await import("./latest-question-2POFPYNB.js");
895
896
  if (!current()) return null;
896
897
  const destination = await resolveLatestQuestion({
897
898
  client,
@@ -2250,6 +2251,191 @@ function useSessionControl(sessionId, options = {}) {
2250
2251
  };
2251
2252
  }
2252
2253
 
2254
+ // src/hooks/use-goal.ts
2255
+ import { OpenGeniApiError } from "@opengeni/sdk";
2256
+ import { useCallback as useCallback7, useEffect as useEffect6, useRef as useRef7, useState as useState6 } from "react";
2257
+ function isGoalEvent(event) {
2258
+ return event.type.startsWith("goal.");
2259
+ }
2260
+ function isGoalRefreshEvent(event) {
2261
+ const type = event.type;
2262
+ return isGoalEvent(event) || type.startsWith("turn.") || type.startsWith("session.") || type.startsWith("system.update.") || type.startsWith("workspace.inference.") || type.startsWith("user.");
2263
+ }
2264
+ function useGoal(sessionId, options = {}) {
2265
+ const { client, workspaceId } = useEmbeddedGoal(options);
2266
+ const enabled = (options.enabled ?? true) && Boolean(sessionId);
2267
+ const sharedEvents = options.events;
2268
+ const sharedFeed = sharedEvents !== void 0;
2269
+ const pageLive = usePageLiveActivity();
2270
+ const [goal, setGoal] = useState6(null);
2271
+ const [loading, setLoading] = useState6(enabled);
2272
+ const [error, setError] = useState6(null);
2273
+ const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
2274
+ const generation = useRef7(0);
2275
+ const targetKeyRef = useRef7(null);
2276
+ const goalAbsentRef = useRef7(false);
2277
+ const loadAbort = useRef7(null);
2278
+ const retireLoads = useCallback7(() => {
2279
+ generation.current += 1;
2280
+ loadAbort.current?.abort();
2281
+ loadAbort.current = null;
2282
+ }, []);
2283
+ const load = useCallback7(async () => {
2284
+ if (!sessionId) {
2285
+ return;
2286
+ }
2287
+ const ticket = ++generation.current;
2288
+ loadAbort.current?.abort();
2289
+ const controller = new AbortController();
2290
+ loadAbort.current = controller;
2291
+ try {
2292
+ const fetched = await client.getGoal(workspaceId, sessionId, {
2293
+ signal: controller.signal
2294
+ });
2295
+ if (ticket === generation.current) {
2296
+ goalAbsentRef.current = false;
2297
+ setGoal(fetched);
2298
+ setError(null);
2299
+ setLoading(false);
2300
+ }
2301
+ } catch (cause) {
2302
+ if (ticket !== generation.current) {
2303
+ return;
2304
+ }
2305
+ if (cause instanceof OpenGeniApiError && cause.status === 404) {
2306
+ goalAbsentRef.current = true;
2307
+ setGoal(null);
2308
+ setError(null);
2309
+ } else {
2310
+ setError(normalizeError(cause));
2311
+ }
2312
+ setLoading(false);
2313
+ } finally {
2314
+ if (loadAbort.current === controller) loadAbort.current = null;
2315
+ }
2316
+ }, [client, workspaceId, sessionId]);
2317
+ useEffect6(() => {
2318
+ const targetKey = `${workspaceId} ${sessionId ?? ""}`;
2319
+ if (targetKeyRef.current !== targetKey) {
2320
+ targetKeyRef.current = targetKey;
2321
+ goalAbsentRef.current = false;
2322
+ setGoal(null);
2323
+ setError(null);
2324
+ }
2325
+ if (!enabled || !pageLive) {
2326
+ retireLoads();
2327
+ setLoading(false);
2328
+ return;
2329
+ }
2330
+ if (sharedFeed) {
2331
+ setLoading(true);
2332
+ void load();
2333
+ return () => {
2334
+ retireLoads();
2335
+ };
2336
+ }
2337
+ setLoading(true);
2338
+ const pollIntervalMs = options.pollIntervalMs;
2339
+ if (pollIntervalMs === void 0 || pollIntervalMs <= 0) {
2340
+ void load();
2341
+ return () => {
2342
+ retireLoads();
2343
+ };
2344
+ }
2345
+ let cancelled = false;
2346
+ let timer = null;
2347
+ const schedule = () => {
2348
+ if (cancelled) return;
2349
+ timer = setTimeout(() => {
2350
+ timer = null;
2351
+ void load().finally(schedule);
2352
+ }, pollIntervalMs);
2353
+ };
2354
+ void load().finally(schedule);
2355
+ return () => {
2356
+ cancelled = true;
2357
+ if (timer !== null) clearTimeout(timer);
2358
+ retireLoads();
2359
+ };
2360
+ }, [
2361
+ load,
2362
+ enabled,
2363
+ pageLive,
2364
+ workspaceId,
2365
+ sessionId,
2366
+ options.pollIntervalMs,
2367
+ retireLoads,
2368
+ sharedFeed
2369
+ ]);
2370
+ const scheduleRefresh = useDebouncedCallback(() => void load());
2371
+ const isRefreshEvent = useCallback7(
2372
+ (event) => goalAbsentRef.current ? isGoalEvent(event) : isGoalRefreshEvent(event),
2373
+ []
2374
+ );
2375
+ useSessionEventTrigger(client, workspaceId, sessionId, isRefreshEvent, scheduleRefresh, {
2376
+ enabled,
2377
+ ...sharedEvents !== void 0 ? { events: sharedEvents } : {}
2378
+ });
2379
+ const pause = useCallback7(
2380
+ async (rationale) => {
2381
+ if (!sessionId) {
2382
+ return null;
2383
+ }
2384
+ const result = await run(
2385
+ () => client.updateGoal(workspaceId, sessionId, {
2386
+ status: "paused",
2387
+ ...rationale !== void 0 ? { rationale } : {}
2388
+ })
2389
+ );
2390
+ if (result) {
2391
+ setGoal(result);
2392
+ }
2393
+ return result;
2394
+ },
2395
+ [client, workspaceId, sessionId, run]
2396
+ );
2397
+ const resume = useCallback7(async () => {
2398
+ if (!sessionId) {
2399
+ return null;
2400
+ }
2401
+ const result = await run(() => client.updateGoal(workspaceId, sessionId, { status: "active" }));
2402
+ if (result) {
2403
+ setGoal(result);
2404
+ }
2405
+ return result;
2406
+ }, [client, workspaceId, sessionId, run]);
2407
+ const clearGoal = useCallback7(async () => {
2408
+ if (!sessionId) {
2409
+ return;
2410
+ }
2411
+ const ok = await run(async () => {
2412
+ await client.deleteGoal(workspaceId, sessionId);
2413
+ return true;
2414
+ });
2415
+ if (ok) {
2416
+ retireLoads();
2417
+ setGoal(null);
2418
+ setError(null);
2419
+ }
2420
+ }, [client, workspaceId, sessionId, run, retireLoads]);
2421
+ return {
2422
+ goal,
2423
+ isActive: goal?.status === "active",
2424
+ isPaused: goal?.status === "paused",
2425
+ isCompleted: goal?.status === "completed",
2426
+ loading,
2427
+ error,
2428
+ refresh: load,
2429
+ pause,
2430
+ resume,
2431
+ clearGoal,
2432
+ deleteGoal: clearGoal,
2433
+ updating: mutating,
2434
+ mutationError,
2435
+ clearMutationError
2436
+ };
2437
+ }
2438
+
2253
2439
  // src/conversation-timeline.ts
2254
2440
  function conversationTimeline(items, queue, composer) {
2255
2441
  const queued = new Set(
@@ -2324,6 +2510,8 @@ export {
2324
2510
  useHumanInputRequests,
2325
2511
  useFileAttachments,
2326
2512
  useSessionControl,
2513
+ isGoalEvent,
2514
+ useGoal,
2327
2515
  conversationTimeline
2328
2516
  };
2329
- //# sourceMappingURL=chunk-WWEUO2PL.js.map
2517
+ //# sourceMappingURL=chunk-G6YRCIYJ.js.map