@opengeni/react 4.4.1 → 4.5.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 (700) hide show
  1. package/dist/app/app-state.js +25 -25
  2. package/dist/app/components/Composer.js +27 -27
  3. package/dist/app/components/agent/agent-capability-picker.js +4 -4
  4. package/dist/app/components/artifacts/artifact-browse-controls.js +3 -3
  5. package/dist/app/components/artifacts/artifact-library.js +19 -19
  6. package/dist/app/components/artifacts/artifact-page-chrome.js +2 -2
  7. package/dist/app/components/artifacts/chat-interactive-block.js +15 -15
  8. package/dist/app/components/artifacts/inline-chat-image.js +30 -29
  9. package/dist/app/components/artifacts/retained-file-preview.js +34 -33
  10. package/dist/app/components/artifacts/retained-text-preview.js +5 -5
  11. package/dist/app/components/artifacts/site-audience.js +4 -4
  12. package/dist/app/components/artifacts/site-conversations.js +20 -19
  13. package/dist/app/components/artifacts/site-data.js +18 -18
  14. package/dist/app/components/artifacts/site-publishing.js +39 -39
  15. package/dist/app/components/artifacts/site-settings.js +46 -46
  16. package/dist/app/components/billing-class-mark.js +5 -5
  17. package/dist/app/components/capabilities/capability-detail-sheet.js +8 -8
  18. package/dist/app/components/capabilities/capability-logo-source.js +11 -11
  19. package/dist/app/components/capabilities/connector-tool-permissions.js +4 -4
  20. package/dist/app/components/capabilities/native-connect-setup.js +14 -14
  21. package/dist/app/components/capabilities/perform-capability-action.js +1 -1
  22. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +15 -15
  23. package/dist/app/components/capabilities/session-capability-card.js +77 -75
  24. package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
  25. package/dist/app/components/capabilities/session-chrome-card.js +35 -33
  26. package/dist/app/components/capabilities/session-custom-mcp-card.js +19 -19
  27. package/dist/app/components/capabilities/session-github-card.js +22 -22
  28. package/dist/app/components/capabilities/session-machine-card.js +34 -32
  29. package/dist/app/components/capabilities/use-capabilities-catalog.js +3 -3
  30. package/dist/app/components/capabilities/use-connection-accounts.js +1 -1
  31. package/dist/app/components/command-menu/chat-status.js +15 -14
  32. package/dist/app/components/command-menu/chat-switcher.js +16 -15
  33. package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
  34. package/dist/app/components/command-menu/command-menu.js +32 -110
  35. package/dist/app/components/command-menu/command-menu.js.map +1 -1
  36. package/dist/app/components/command-menu/shortcut-sheet.js +15 -15
  37. package/dist/app/components/composer-capabilities-menu-body.js +3 -3
  38. package/dist/app/components/composer-mobile-plus-panel.js +17 -17
  39. package/dist/app/components/composer-mobile-plus.js +1 -1
  40. package/dist/app/components/credit-required-gate.js +1 -1
  41. package/dist/app/components/credit-required-prompt.js +9 -9
  42. package/dist/app/components/credits/coupon-redeem.js +2 -2
  43. package/dist/app/components/credits/credit-refusal-notice.js +2 -2
  44. package/dist/app/components/desktop/app-shots.js +6 -6
  45. package/dist/app/components/desktop/this-computer.js +4 -4
  46. package/dist/app/components/feedback.js +4 -4
  47. package/dist/app/components/follow-up-repository-menu-body.js +4 -4
  48. package/dist/app/components/follow-up-repository-picker.js +1 -1
  49. package/dist/app/components/github-app-connect-launcher.js +2 -2
  50. package/dist/app/components/in-app-help-link.js +2 -2
  51. package/dist/app/components/knowledge/agent-learning-settings.js +3 -3
  52. package/dist/app/components/machines/connect-machine-dialog.js +18 -18
  53. package/dist/app/components/markdown.js +8 -8
  54. package/dist/app/components/message-context-pills.js +2 -2
  55. package/dist/app/components/models/models-ui.js +8 -8
  56. package/dist/app/components/new-session-starters.js +2 -2
  57. package/dist/app/components/pickers.js +8 -8
  58. package/dist/app/components/rail/rail-context.js +3 -3
  59. package/dist/app/components/rail/rail-sections.js +65 -62
  60. package/dist/app/components/rail/session-header.js +48 -47
  61. package/dist/app/components/rail/session-list.js +64 -61
  62. package/dist/app/components/rail/session-row-content.d.ts +6 -2
  63. package/dist/app/components/rail/session-row-content.js +1 -1
  64. package/dist/app/components/rail/session-row-hover-details.js +20 -19
  65. package/dist/app/components/rail/session-shell.js +104 -101
  66. package/dist/app/components/rail/site-session-group-heading.d.ts +7 -1
  67. package/dist/app/components/rail/site-session-group-heading.js +20 -3
  68. package/dist/app/components/repository-picker.js +4 -4
  69. package/dist/app/components/secrets/session-secrets-panel.js +3 -3
  70. package/dist/app/components/session/agent-configuration-panel.js +33 -33
  71. package/dist/app/components/session/artifact-link-boundary.js +2 -2
  72. package/dist/app/components/session/artifact-session-page.js +5 -5
  73. package/dist/app/components/session/banners.js +10 -10
  74. package/dist/app/components/session/codex-account-indicator.js +11 -11
  75. package/dist/app/components/session/editable-artifacts-workspace.js +44 -44
  76. package/dist/app/components/session/failed-session-banner.js +10 -10
  77. package/dist/app/components/session/human-input.js +57 -53
  78. package/dist/app/components/session/inspector.js +94 -90
  79. package/dist/app/components/session/inspector.js.map +1 -1
  80. package/dist/app/components/session/message-actions.js +4 -4
  81. package/dist/app/components/session/message-resource-attachments.js +20 -19
  82. package/dist/app/components/session/message-resource-attachments.js.map +1 -1
  83. package/dist/app/components/session/model-account-indicator.js +11 -11
  84. package/dist/app/components/session/model-context-inspector.js +2 -2
  85. package/dist/app/components/session/model-recovery-notice.js +3 -3
  86. package/dist/app/components/session/new-session-settings-menu.js +9 -9
  87. package/dist/app/components/session/sandbox-switcher.js +16 -16
  88. package/dist/app/components/session/sandbox-workspace.js +81 -77
  89. package/dist/app/components/session/search-markdown-highlight.js +9 -9
  90. package/dist/app/components/session/search-results-view.js +10 -10
  91. package/dist/app/components/session/session-admin-access.js +8 -8
  92. package/dist/app/components/session/session-admission-notice.js +6 -6
  93. package/dist/app/components/session/session-machine-access-notice.js +6 -6
  94. package/dist/app/components/session/session-retention.js +4 -4
  95. package/dist/app/components/session/session-search-dialog.js +11 -11
  96. package/dist/app/components/session/session-skill-reviews.js +1 -1
  97. package/dist/app/components/session/session-tenancy-control.d.ts +2 -0
  98. package/dist/app/components/session/session-tenancy-control.js +40 -25
  99. package/dist/app/components/session/session-tenancy-control.js.map +1 -1
  100. package/dist/app/components/session/session-usage-limit-section.js +11 -11
  101. package/dist/app/components/session/session-wait-status.js +9 -8
  102. package/dist/app/components/session/session-wait-status.js.map +1 -1
  103. package/dist/app/components/session/site-origin-link.d.ts +1 -0
  104. package/dist/app/components/session/site-origin-link.js +2 -2
  105. package/dist/app/components/session/subagents.js +16 -15
  106. package/dist/app/components/session-connectors-menu-body.js +5 -5
  107. package/dist/app/components/settings/row-select.js +3 -3
  108. package/dist/app/components/transcription-settings.js +4 -4
  109. package/dist/app/components/ui/destructive-confirm.js +6 -6
  110. package/dist/app/components/usage/usage-entry.js +8 -8
  111. package/dist/app/components/workspace-composer-plus.js +21 -21
  112. package/dist/app/embed/memory-navigation.js +2 -2
  113. package/dist/app/embed/session-app.js +256 -250
  114. package/dist/app/lib/actions/actions-provider.js +15 -15
  115. package/dist/app/lib/actions/held-modifier.d.ts +11 -0
  116. package/dist/app/lib/app-surfaces.js +2 -2
  117. package/dist/app/lib/codex-usage-query.js +6 -6
  118. package/dist/app/lib/composer-connectors.js +12 -12
  119. package/dist/app/lib/console-site.d.ts +6 -0
  120. package/dist/app/lib/console-site.js +14 -0
  121. package/dist/app/lib/console-text.js +2 -2
  122. package/dist/app/lib/events.js +17 -16
  123. package/dist/app/lib/failed-session-copy.js +3 -3
  124. package/dist/app/lib/model-access-onboarding.js +3 -3
  125. package/dist/app/lib/move-chat-to-machine.js +3 -3
  126. package/dist/app/lib/navigation.d.ts +5 -0
  127. package/dist/app/lib/navigation.js +1 -1
  128. package/dist/app/lib/routes.d.ts +17 -0
  129. package/dist/app/lib/routes.js +9 -3
  130. package/dist/app/lib/session-branch-cache.js +13 -12
  131. package/dist/app/lib/session-deep-link.js +2 -2
  132. package/dist/app/lib/session-failure-toasts.d.ts +8 -0
  133. package/dist/app/lib/session-group-pagination.js +13 -12
  134. package/dist/app/lib/session-hover-facts.js +14 -13
  135. package/dist/app/lib/session-model.js +3 -3
  136. package/dist/app/lib/session-rail.js +9 -8
  137. package/dist/app/lib/session-rename.js +3 -3
  138. package/dist/app/lib/session-ui-features.d.ts +6 -1
  139. package/dist/app/lib/session-ui-features.js +1 -1
  140. package/dist/app/lib/sessions-group.d.ts +43 -3
  141. package/dist/app/lib/sessions-group.js +21 -14
  142. package/dist/app/lib/shared-query.js +3 -3
  143. package/dist/app/lib/site-opened.d.ts +6 -0
  144. package/dist/app/lib/site-opened.js +10 -0
  145. package/dist/app/lib/turn-failure-analytics.js +4 -4
  146. package/dist/app/lib/use-duplicate-site.js +3 -3
  147. package/dist/app/lib/use-follow-up-repositories.js +4 -4
  148. package/dist/app/lib/use-session-list-hint-refresh.d.ts +20 -2
  149. package/dist/app/lib/use-session-list-hint-refresh.js +5 -1
  150. package/dist/app/lib/use-workspace-machines.js +6 -6
  151. package/dist/app/lib/use-workspace-model-catalog.js +7 -7
  152. package/dist/app/lib/use-workspace-rigs.js +8 -8
  153. package/dist/app/lib/workspace-navigation-preference.js +5 -5
  154. package/dist/app/lib/workspace-scope-context.js +4 -4
  155. package/dist/app/routes/artifacts.js +132 -149
  156. package/dist/app/routes/artifacts.js.map +1 -1
  157. package/dist/app/routes/retained-artifact.js +63 -62
  158. package/dist/app/routes/retained-artifact.js.map +1 -1
  159. package/dist/app/routes/session-unavailable.js +7 -5
  160. package/dist/app/routes/session.js +170 -166
  161. package/dist/app/routes/sessions-index.js +110 -108
  162. package/dist/app/routes/site-view.d.ts +11 -0
  163. package/dist/app/routes/site-view.js +597 -0
  164. package/dist/app/routes/site-view.js.map +1 -0
  165. package/dist/artifacts-document.js +4 -4
  166. package/dist/artifacts-presentation.js +4 -4
  167. package/dist/artifacts-spreadsheet.js +4 -4
  168. package/dist/artifacts.js +39 -39
  169. package/dist/{browser-viewer-RYYQSRTC.js → browser-viewer-QMCNV4RI.js} +9 -7
  170. package/dist/{chat-interactive-block-ABCRKXJ4.js → chat-interactive-block-PMIAUXSO.js} +6 -6
  171. package/dist/{chunk-TGVVEGZG.js → chunk-22FFOHPT.js} +9 -9
  172. package/dist/chunk-22GTC4MZ.js +15 -0
  173. package/dist/chunk-22GTC4MZ.js.map +1 -0
  174. package/dist/{chunk-Z5WMLJKI.js → chunk-22JFMNMF.js} +92 -4
  175. package/dist/chunk-22JFMNMF.js.map +1 -0
  176. package/dist/{chunk-UHFWF6ZU.js → chunk-2FPS5H2D.js} +2 -2
  177. package/dist/{chunk-NAWXARTY.js → chunk-2KO2G3RI.js} +72 -6
  178. package/dist/chunk-2KO2G3RI.js.map +1 -0
  179. package/dist/{chunk-5POTDNQT.js → chunk-2NC7NZCE.js} +6 -6
  180. package/dist/{chunk-ZKYYZH6L.js → chunk-2QBYDGWO.js} +9 -9
  181. package/dist/{chunk-TWXIFWBD.js → chunk-34EU25RL.js} +2 -2
  182. package/dist/{chunk-R63QEVPK.js → chunk-35BC2FU2.js} +16 -16
  183. package/dist/{chunk-PTGRFAMH.js → chunk-3ABPIUCK.js} +2 -2
  184. package/dist/{chunk-S4SC5SSV.js → chunk-3GU7AWG7.js} +18 -18
  185. package/dist/{chunk-722UO6YQ.js → chunk-3PEXVG4D.js} +2 -2
  186. package/dist/{chunk-63VGE4OH.js → chunk-3RMKPHBL.js} +3 -3
  187. package/dist/{chunk-6JKZILLF.js → chunk-3RQUWFZT.js} +67 -67
  188. package/dist/{chunk-6JKZILLF.js.map → chunk-3RQUWFZT.js.map} +1 -1
  189. package/dist/{chunk-RQDFYQHA.js → chunk-3STBLX4O.js} +9 -9
  190. package/dist/{chunk-S4EZ3JUB.js → chunk-3X5FKDYQ.js} +23 -23
  191. package/dist/{chunk-KTRKZRID.js → chunk-4GLLWX33.js} +11 -11
  192. package/dist/{chunk-ROQOVH4N.js → chunk-4HEXNAFI.js} +20 -20
  193. package/dist/chunk-4HEXNAFI.js.map +1 -0
  194. package/dist/{chunk-SD2K5ZN5.js → chunk-4LPA25NQ.js} +4 -4
  195. package/dist/{chunk-KWKGBGAF.js → chunk-4RMN4E2Y.js} +9 -9
  196. package/dist/{chunk-X7ASQHR6.js → chunk-4SAGYEVB.js} +2 -2
  197. package/dist/{chunk-HTT3FB7T.js → chunk-4VK2R5QC.js} +3 -3
  198. package/dist/{chunk-DDK4WFJ3.js → chunk-4XQC7VLT.js} +9 -9
  199. package/dist/{chunk-IVOA3DXA.js → chunk-4YXAQMTD.js} +12 -12
  200. package/dist/{chunk-HOJGAJAB.js → chunk-52WK2GGK.js} +8 -8
  201. package/dist/{chunk-NYZQ7LO7.js → chunk-552UYIQ7.js} +20 -20
  202. package/dist/{chunk-LEXPBQ56.js → chunk-5DSKMG2I.js} +4 -4
  203. package/dist/{chunk-WNG757ID.js → chunk-5FA455GR.js} +4 -4
  204. package/dist/{chunk-HWDGJFM4.js → chunk-5FEN3KYH.js} +11 -11
  205. package/dist/{chunk-OSVHU2WU.js → chunk-5JHRMUAZ.js} +12 -12
  206. package/dist/{chunk-PM3OSANE.js → chunk-5MJHH72T.js} +14 -3
  207. package/dist/chunk-5MJHH72T.js.map +1 -0
  208. package/dist/{chunk-RKB2Z457.js → chunk-5VGJXWQ2.js} +2 -2
  209. package/dist/{chunk-GFUUFM2O.js → chunk-5W6ZDKRR.js} +6 -6
  210. package/dist/{chunk-6PQNLL4E.js → chunk-5W7KJ5NQ.js} +37 -37
  211. package/dist/{chunk-Q35YZVDZ.js → chunk-5Y2FPLZE.js} +9 -9
  212. package/dist/{chunk-6W3LF3DB.js → chunk-5YFY4SFC.js} +2 -12
  213. package/dist/chunk-5YFY4SFC.js.map +1 -0
  214. package/dist/{chunk-F3NERYBQ.js → chunk-62VER7O4.js} +6 -6
  215. package/dist/{chunk-FBMU3VK5.js → chunk-6DCEDIF6.js} +2 -2
  216. package/dist/{chunk-LE2EDBXU.js → chunk-73WI7FL2.js} +18 -18
  217. package/dist/chunk-756MKA2J.js +45 -0
  218. package/dist/chunk-756MKA2J.js.map +1 -0
  219. package/dist/{chunk-ZRJCGBVV.js → chunk-7FJMRJDG.js} +2 -2
  220. package/dist/{chunk-7KGKDWWR.js → chunk-7HFLYNWN.js} +2 -2
  221. package/dist/{chunk-72J6C2AJ.js → chunk-7KIENXRE.js} +2 -2
  222. package/dist/{chunk-CBY5CXBD.js → chunk-7NPCEBZE.js} +5 -5
  223. package/dist/{chunk-46VBQG2D.js → chunk-7P4AQMGA.js} +13 -13
  224. package/dist/{chunk-X7L4H4VG.js → chunk-7TCT7KPQ.js} +742 -644
  225. package/dist/chunk-7TCT7KPQ.js.map +1 -0
  226. package/dist/{chunk-CVG4FILQ.js → chunk-7XO7YKPC.js} +280 -1035
  227. package/dist/chunk-7XO7YKPC.js.map +1 -0
  228. package/dist/{chunk-S7PVL7XH.js → chunk-A4BD4ZVB.js} +4 -4
  229. package/dist/{chunk-EF5SYXAY.js → chunk-ACL2V2KE.js} +30 -22
  230. package/dist/chunk-ACL2V2KE.js.map +1 -0
  231. package/dist/{chunk-73SOCVLS.js → chunk-AIEXYO2X.js} +3 -3
  232. package/dist/{chunk-U7TC2XJQ.js → chunk-AJPW3SV4.js} +3 -3
  233. package/dist/{chunk-HRJQAFKR.js → chunk-AX6YJA5U.js} +2 -2
  234. package/dist/{chunk-P5WABK2H.js → chunk-BCM7C3MJ.js} +9 -9
  235. package/dist/{chunk-DT7BORXG.js → chunk-BMJTNPWK.js} +2 -2
  236. package/dist/{chunk-HIHO2QE7.js → chunk-BT2MVGHT.js} +2 -2
  237. package/dist/{chunk-3XOISKZC.js → chunk-BXQYAAVE.js} +4 -4
  238. package/dist/{chunk-IBTXYLBW.js → chunk-CCFWY4GF.js} +2 -2
  239. package/dist/{chunk-ZOC3OP6F.js → chunk-CCR33J7L.js} +2 -2
  240. package/dist/{chunk-GTQ3SNEI.js → chunk-CD3MO3IC.js} +2 -2
  241. package/dist/{chunk-WSMYOLHG.js → chunk-CDEXRJB6.js} +5 -5
  242. package/dist/{chunk-3GLAPCVI.js → chunk-CFFNT2OY.js} +8 -8
  243. package/dist/{chunk-HO5Y2OOX.js → chunk-CMLJSF2F.js} +10 -10
  244. package/dist/{chunk-RA3FNMWF.js → chunk-CP7ZQHBW.js} +10 -10
  245. package/dist/{chunk-IOKSNX74.js → chunk-D5OWJZQR.js} +2 -2
  246. package/dist/{chunk-SQGXMHJO.js → chunk-DGLRZMXL.js} +3 -3
  247. package/dist/{chunk-GNEHAPKV.js → chunk-DJFTH2DI.js} +3 -3
  248. package/dist/{chunk-HQG4SLTE.js → chunk-DYJGYGPB.js} +2 -2
  249. package/dist/{chunk-4EAF3HSD.js → chunk-EJ7WARW7.js} +2 -2
  250. package/dist/{chunk-3AA6RNGE.js → chunk-ENS6E4RZ.js} +2 -2
  251. package/dist/{chunk-OOEO4MKY.js → chunk-EPWD4KRA.js} +2 -2
  252. package/dist/{chunk-PN66T6JA.js → chunk-EQE3MNQN.js} +5 -5
  253. package/dist/{chunk-TSBE4KOQ.js → chunk-EWL6NDOO.js} +3 -3
  254. package/dist/{chunk-OO2T63BY.js → chunk-EYS4ZOF5.js} +2 -2
  255. package/dist/{chunk-7CZTKBTI.js → chunk-FDAV72IX.js} +5 -5
  256. package/dist/{chunk-AG7VGUIW.js → chunk-FFNPUSVO.js} +7 -7
  257. package/dist/{chunk-P5T36BA3.js → chunk-FRP64DEK.js} +2 -2
  258. package/dist/{chunk-KBF3SE7G.js → chunk-FSP334UU.js} +2 -2
  259. package/dist/{chunk-BSX2R4CW.js → chunk-FTX5CNHA.js} +4 -4
  260. package/dist/{chunk-O756O2I7.js → chunk-FWOBNL2A.js} +1 -1
  261. package/dist/{chunk-6NIB2KGJ.js → chunk-FWYEZ3LE.js} +33 -33
  262. package/dist/{chunk-DLOYMWUQ.js → chunk-G4HQUBO4.js} +7 -7
  263. package/dist/{chunk-CSHBR2IZ.js → chunk-GDLDBR6B.js} +2 -2
  264. package/dist/chunk-GGV4NSG3.js +792 -0
  265. package/dist/chunk-GGV4NSG3.js.map +1 -0
  266. package/dist/{chunk-U36PO27Q.js → chunk-GHHM6WN4.js} +3 -3
  267. package/dist/{chunk-OANSIX34.js → chunk-GRSODLVO.js} +4 -4
  268. package/dist/{chunk-4R3JCVID.js → chunk-GT7JFQ4E.js} +410 -153
  269. package/dist/chunk-GT7JFQ4E.js.map +1 -0
  270. package/dist/{chunk-EU6XSQFM.js → chunk-GXW2I2M2.js} +2 -2
  271. package/dist/{chunk-5JEIDFPD.js → chunk-GZS37O3G.js} +1 -1
  272. package/dist/{chunk-XFNLU7EW.js → chunk-H5M33DAL.js} +15 -6
  273. package/dist/chunk-H5M33DAL.js.map +1 -0
  274. package/dist/{chunk-HNYJEAES.js → chunk-HQWVDQXW.js} +7 -7
  275. package/dist/{chunk-YXOKAG66.js → chunk-HU6JTNWF.js} +2 -2
  276. package/dist/{chunk-QRVNI5V6.js → chunk-I6KIQKU6.js} +3 -3
  277. package/dist/{chunk-APU42QDI.js → chunk-IBA5FMRE.js} +115 -111
  278. package/dist/chunk-IBA5FMRE.js.map +1 -0
  279. package/dist/{chunk-BNUPYHHZ.js → chunk-IDXTASGN.js} +4 -4
  280. package/dist/{chunk-KF3MF6FP.js → chunk-IECRGM6K.js} +3 -2
  281. package/dist/chunk-IECRGM6K.js.map +1 -0
  282. package/dist/chunk-IJYL5BZM.js +38 -0
  283. package/dist/chunk-IJYL5BZM.js.map +1 -0
  284. package/dist/{chunk-L6RXRRN3.js → chunk-ILDOW2IQ.js} +3 -3
  285. package/dist/{chunk-VUHPA3XQ.js → chunk-ITX2TB4K.js} +6 -6
  286. package/dist/{chunk-BXRIQZAH.js → chunk-J22HD2PB.js} +5 -5
  287. package/dist/{chunk-U47YDYLQ.js → chunk-J5MEDX7C.js} +8 -8
  288. package/dist/{chunk-F6LBGYS6.js → chunk-J7FBBLHF.js} +35 -35
  289. package/dist/{chunk-5JZYPZ72.js → chunk-JFK7NTEA.js} +4 -4
  290. package/dist/chunk-JFK7NTEA.js.map +1 -0
  291. package/dist/{chunk-QZRDCFHI.js → chunk-JM4HQPAI.js} +5 -5
  292. package/dist/{chunk-PIVGX42P.js → chunk-JNY5MT3I.js} +2 -2
  293. package/dist/{chunk-XWWXIZFP.js → chunk-JO6R5EXF.js} +7 -7
  294. package/dist/{chunk-NWZW2WHN.js → chunk-JQCGPTZ6.js} +9 -9
  295. package/dist/chunk-JRSNCSZN.js +37 -0
  296. package/dist/chunk-JRSNCSZN.js.map +1 -0
  297. package/dist/{chunk-OR37STQZ.js → chunk-KEXYBG7Q.js} +3 -3
  298. package/dist/{chunk-AZVANYMB.js → chunk-KUNFUSZ7.js} +2 -2
  299. package/dist/{chunk-DXZNDKQD.js → chunk-LEEJBZ5B.js} +2 -2
  300. package/dist/{chunk-STUCI6QA.js → chunk-LEKBNKLD.js} +1 -1
  301. package/dist/{chunk-STUCI6QA.js.map → chunk-LEKBNKLD.js.map} +1 -1
  302. package/dist/{chunk-AOLE4IRZ.js → chunk-LF5CBAOS.js} +5 -5
  303. package/dist/{chunk-BJIZ7PL7.js → chunk-LHLK7FUA.js} +145 -29
  304. package/dist/chunk-LHLK7FUA.js.map +1 -0
  305. package/dist/{chunk-RIMKJBCD.js → chunk-LMPTC4CX.js} +2 -2
  306. package/dist/{chunk-3KVWXKD6.js → chunk-LQ47YL6E.js} +2 -2
  307. package/dist/{chunk-RSNYGEVZ.js → chunk-LT4J7RHI.js} +13 -13
  308. package/dist/{chunk-U3HSFCON.js → chunk-MCTTONOW.js} +28 -28
  309. package/dist/{chunk-7DU35P5J.js → chunk-MIECLOQC.js} +9 -9
  310. package/dist/{chunk-FM4OUCC2.js → chunk-MOKYT3X3.js} +3 -3
  311. package/dist/{chunk-GZ64CASI.js → chunk-MVZYNZXE.js} +5 -4
  312. package/dist/chunk-MVZYNZXE.js.map +1 -0
  313. package/dist/{chunk-L7YURQI2.js → chunk-MXLKI7BI.js} +3 -3
  314. package/dist/{chunk-XRRSFQEV.js → chunk-NAZZLAWX.js} +2 -2
  315. package/dist/{chunk-UWJ5P5CU.js → chunk-NEK4WB5P.js} +3 -3
  316. package/dist/{chunk-6L7U46Y2.js → chunk-NKNVIO66.js} +2 -2
  317. package/dist/{chunk-JKUICTLM.js → chunk-NLAFNMPK.js} +2 -2
  318. package/dist/{chunk-4LKNIGHB.js → chunk-O2SBHS2N.js} +2 -2
  319. package/dist/{chunk-DWPOQ3S5.js → chunk-OTMWHZBY.js} +2 -2
  320. package/dist/{chunk-JTN3T4QN.js → chunk-PCFK7HKD.js} +14 -14
  321. package/dist/{chunk-VVCDB2T7.js → chunk-PCJLH45G.js} +3 -3
  322. package/dist/{chunk-PZ24CYDO.js → chunk-PFAUGEV5.js} +2 -2
  323. package/dist/{chunk-HGMWMK5K.js → chunk-PO3BH3KQ.js} +2 -2
  324. package/dist/{chunk-B74GSYR6.js → chunk-PUTS4DYW.js} +2 -2
  325. package/dist/{chunk-JSIDLTTG.js → chunk-PZ2V2XIK.js} +2 -2
  326. package/dist/{chunk-TMEQPODK.js → chunk-PZ37VDB5.js} +2 -2
  327. package/dist/{chunk-Q35DT6I6.js → chunk-QFMLAT7L.js} +234 -225
  328. package/dist/chunk-QFMLAT7L.js.map +1 -0
  329. package/dist/{chunk-LVONK3YQ.js → chunk-QRKTESVE.js} +2 -2
  330. package/dist/{chunk-HT5WSUC7.js → chunk-QXEDIDBZ.js} +3 -3
  331. package/dist/{chunk-WURSS6MP.js → chunk-R66YMYJU.js} +2 -2
  332. package/dist/{chunk-HDHK3SXK.js → chunk-RFLYID6H.js} +5 -5
  333. package/dist/{chunk-ADJJQSYC.js → chunk-RIYZFKIM.js} +39 -37
  334. package/dist/chunk-RIYZFKIM.js.map +1 -0
  335. package/dist/{chunk-JK7C5A4I.js → chunk-RQNZDTKT.js} +19 -19
  336. package/dist/{chunk-EHCUFCXM.js → chunk-RYSRFAHN.js} +32 -22
  337. package/dist/chunk-RYSRFAHN.js.map +1 -0
  338. package/dist/{chunk-I6VUUEXH.js → chunk-S2U4CDAC.js} +150 -150
  339. package/dist/chunk-S2U4CDAC.js.map +1 -0
  340. package/dist/{chunk-ST22GONV.js → chunk-S37GP7LX.js} +19 -19
  341. package/dist/{chunk-A2EWJQXX.js → chunk-SM5QX6UK.js} +4 -4
  342. package/dist/{chunk-FBE6AIIW.js → chunk-SOKNCW5U.js} +2 -2
  343. package/dist/{chunk-4W7VISE7.js → chunk-SSOO4GWN.js} +193 -194
  344. package/dist/chunk-SSOO4GWN.js.map +1 -0
  345. package/dist/{chunk-UP4BE32Y.js → chunk-SY2AAZNB.js} +5 -5
  346. package/dist/{chunk-33TPANCR.js → chunk-TFK4KFKA.js} +4 -4
  347. package/dist/{chunk-4432A3HQ.js → chunk-TIQPKOFW.js} +4 -4
  348. package/dist/{chunk-HPPKLBTJ.js → chunk-TJQDL3JH.js} +2 -2
  349. package/dist/chunk-TL7BOFFL.js +89 -0
  350. package/dist/chunk-TL7BOFFL.js.map +1 -0
  351. package/dist/{chunk-FD4Q5KFL.js → chunk-TLL22FFO.js} +2 -2
  352. package/dist/{chunk-QM5H4FPT.js → chunk-TV6BWONY.js} +3 -3
  353. package/dist/{chunk-4VKA5O7T.js → chunk-U6MPB3K6.js} +4 -4
  354. package/dist/{chunk-XOFUXMPP.js → chunk-ULJAOMJA.js} +2 -2
  355. package/dist/chunk-ULYQEFNH.js +529 -0
  356. package/dist/chunk-ULYQEFNH.js.map +1 -0
  357. package/dist/{chunk-H5EVWF6L.js → chunk-UNNJUJVD.js} +2 -2
  358. package/dist/{chunk-RGW24ZZM.js → chunk-UP7I3W6O.js} +51 -49
  359. package/dist/chunk-UP7I3W6O.js.map +1 -0
  360. package/dist/{chunk-5MZTJMZ3.js → chunk-UUGR3X5I.js} +17 -11
  361. package/dist/chunk-UUGR3X5I.js.map +1 -0
  362. package/dist/{chunk-Z6DKXQG7.js → chunk-UXXFMF4X.js} +2 -2
  363. package/dist/{chunk-OBQVTCTW.js → chunk-UYNCMZX5.js} +4 -4
  364. package/dist/{chunk-RGPYMHKI.js → chunk-V3K4RQO7.js} +9 -3
  365. package/dist/chunk-V3K4RQO7.js.map +1 -0
  366. package/dist/{chunk-KZHW27BV.js → chunk-V4QZ7UBK.js} +2 -2
  367. package/dist/{chunk-SUVEDKE2.js → chunk-VH5EGTH2.js} +3 -3
  368. package/dist/{chunk-MYNUBDU7.js → chunk-VYKW6TB2.js} +1 -1
  369. package/dist/chunk-VYKW6TB2.js.map +1 -0
  370. package/dist/{chunk-QEJTQTF5.js → chunk-W6T5HR3Z.js} +3 -3
  371. package/dist/{chunk-VP62LPLW.js → chunk-WCMG4HYI.js} +10 -10
  372. package/dist/{chunk-GZLLDA6P.js → chunk-WEFN327U.js} +2 -2
  373. package/dist/{chunk-7BST7BA6.js → chunk-WKHUZIOW.js} +1 -1
  374. package/dist/{chunk-ANHUMDJX.js → chunk-WNDTLK44.js} +2 -2
  375. package/dist/{chunk-2DS4UOYQ.js → chunk-WSZQNTVN.js} +2 -2
  376. package/dist/{chunk-GALB2G3W.js → chunk-X2AH4DRF.js} +2 -2
  377. package/dist/{chunk-Z2DAWUO3.js → chunk-XMNUZUUA.js} +6 -6
  378. package/dist/{chunk-GAIM5RNE.js → chunk-XN7NSPE6.js} +3 -3
  379. package/dist/chunk-XV6ZYRHK.js +59 -0
  380. package/dist/chunk-XV6ZYRHK.js.map +1 -0
  381. package/dist/{chunk-FLGUVRR7.js → chunk-Y5BSA3I7.js} +5 -5
  382. package/dist/{chunk-WRLWLGEF.js → chunk-Y5E3XQ2S.js} +25 -2
  383. package/dist/{chunk-WRLWLGEF.js.map → chunk-Y5E3XQ2S.js.map} +1 -1
  384. package/dist/{chunk-QCD5Y7K5.js → chunk-YEROLKOA.js} +16 -16
  385. package/dist/{chunk-NDF3SH3X.js → chunk-YJPKDRI2.js} +15 -15
  386. package/dist/{chunk-TQGJN5UZ.js → chunk-YV56F4UP.js} +318 -700
  387. package/dist/chunk-YV56F4UP.js.map +1 -0
  388. package/dist/{chunk-VAIESMPY.js → chunk-YVBHGMKC.js} +4 -4
  389. package/dist/{chunk-AD22P5X3.js → chunk-YXA2EKV3.js} +3 -3
  390. package/dist/{chunk-FDNJVZRE.js → chunk-YYCOSTUU.js} +17 -17
  391. package/dist/{chunk-NLMTNEWW.js → chunk-Z6E6TUAE.js} +2 -2
  392. package/dist/{chunk-BJW7G6EF.js → chunk-Z7IGO5EA.js} +3 -3
  393. package/dist/{chunk-NCX5SAQY.js → chunk-ZEIFJ6PX.js} +5 -5
  394. package/dist/{chunk-JRXHSVD5.js → chunk-ZS2UQ3DV.js} +65 -8
  395. package/dist/chunk-ZS2UQ3DV.js.map +1 -0
  396. package/dist/{chunk-4EONHNJU.js → chunk-ZVVT72MT.js} +2 -2
  397. package/dist/components/browser-viewer.d.ts +1 -1
  398. package/dist/composer.js +13 -13
  399. package/dist/{computer-viewer-KEDVLD42.js → computer-viewer-25AJIDYA.js} +9 -9
  400. package/dist/connect.js +10 -10
  401. package/dist/desktop.js +2 -2
  402. package/dist/editor.js +2 -2
  403. package/dist/{embedded-new-voice-LFHWWYD2.js → embedded-new-voice-RZZEJT6M.js} +7 -7
  404. package/dist/{embedded-voice-6QS4ANNX.js → embedded-voice-6OKSSPLW.js} +7 -7
  405. package/dist/{fleet-decision-row-QNSTP3VX.js → fleet-decision-row-NN2HXDX3.js} +2 -2
  406. package/dist/hooks/internal.d.ts +38 -0
  407. package/dist/hooks/use-client-config-flags.d.ts +12 -0
  408. package/dist/hooks/use-workspace-sessions.d.ts +10 -1
  409. package/dist/index.js +233 -227
  410. package/dist/interaction.js +11 -9
  411. package/dist/interaction.js.map +1 -1
  412. package/dist/{latest-question-AW3PPDUM.js → latest-question-2PFWQSSG.js} +4 -3
  413. package/dist/{latest-question-AW3PPDUM.js.map → latest-question-2PFWQSSG.js.map} +1 -1
  414. package/dist/machines.js +5 -5
  415. package/dist/messages/en.d.ts +3 -3
  416. package/dist/messages.js +1 -1
  417. package/dist/{model-policy-picker-menu-CURJ247L.js → model-policy-picker-menu-VVFGGAI6.js} +6 -6
  418. package/dist/native-previews.js +3 -3
  419. package/dist/{platform-activity-row-BMXXNZKX.js → platform-activity-row-ENQVIFTL.js} +2 -2
  420. package/dist/{queue-surface-implementation-2X5AXB6I.js → queue-surface-implementation-4SHOQPQQ.js} +10 -8
  421. package/dist/{queue-surface-implementation-2X5AXB6I.js.map → queue-surface-implementation-4SHOQPQQ.js.map} +1 -1
  422. package/dist/realtime.js +6 -6
  423. package/dist/{sandbox-files-4FBG3GS2.js → sandbox-files-CCOTGXXA.js} +11 -11
  424. package/dist/sandbox-files-CCOTGXXA.js.map +1 -0
  425. package/dist/session-app.js +258 -252
  426. package/dist/session-list-model.d.ts +1 -0
  427. package/dist/session-list-model.js +8 -2
  428. package/dist/{session-realtime-2XIB254N.js → session-realtime-JNKDSGH7.js} +3 -3
  429. package/dist/session-realtime-JNKDSGH7.js.map +1 -0
  430. package/dist/session-realtime.js +2 -2
  431. package/dist/session-ui.js +76 -71
  432. package/dist/session.js +24 -22
  433. package/dist/sites.js +2 -2
  434. package/dist/terminal.js +2 -2
  435. package/dist/this-computer.js +3 -3
  436. package/dist/timeline/invoked-tool.d.ts +5 -0
  437. package/dist/timeline/tool-display-name.d.ts +2 -2
  438. package/dist/timeline/tool-icon.d.ts +14 -0
  439. package/dist/timeline/tool-presentation.d.ts +8 -3
  440. package/dist/{timeline-annotation-markers-X4K2IEOO.js → timeline-annotation-markers-KHNYNY2J.js} +5 -5
  441. package/dist/{timeline-annotation-selection-MEHBW676.js → timeline-annotation-selection-AXEDJHBP.js} +7 -7
  442. package/dist/{timeline-annotations-dialog-U2FPQ3UY.js → timeline-annotations-dialog-AV4ZBXRC.js} +9 -9
  443. package/dist/timeline-model.js +25 -23
  444. package/dist/ui/access-list.js +18 -18
  445. package/dist/ui/cadence-picker.js +2 -2
  446. package/dist/ui/choice-cards.js +2 -2
  447. package/dist/ui/detail-page.js +2 -2
  448. package/dist/ui/detail-sheet.js +2 -2
  449. package/dist/ui/diff-view.js +2 -2
  450. package/dist/ui/disclosure.js +4 -4
  451. package/dist/ui/flush-form-page.js +3 -3
  452. package/dist/ui/form-dialog.js +2 -2
  453. package/dist/ui/list-row.js +4 -4
  454. package/dist/ui/revision-history.js +11 -11
  455. package/dist/ui/role-select.js +7 -7
  456. package/dist/ui/select-menu.js +2 -2
  457. package/dist/ui/settings-nav.js +3 -3
  458. package/dist/usage.js +3 -3
  459. package/dist/workbench.js +11 -11
  460. package/package.json +4 -4
  461. package/src/app/app-state.tsx +3 -1
  462. package/src/app/components/capabilities/session-machine-card.tsx +9 -2
  463. package/src/app/components/rail/session-list.tsx +254 -44
  464. package/src/app/components/rail/session-row-content.tsx +24 -2
  465. package/src/app/components/rail/session-shell.tsx +14 -9
  466. package/src/app/components/rail/site-session-group-heading.tsx +59 -20
  467. package/src/app/components/session/session-tenancy-control.tsx +18 -0
  468. package/src/app/components/session/site-origin-link.test.tsx +73 -0
  469. package/src/app/components/session/site-origin-link.tsx +4 -2
  470. package/src/app/embed/memory-navigation.tsx +1 -0
  471. package/src/app/lib/actions/held-modifier.test.ts +101 -0
  472. package/src/app/lib/actions/held-modifier.ts +108 -0
  473. package/src/app/lib/console-site.tsx +38 -0
  474. package/src/app/lib/navigation.tsx +4 -0
  475. package/src/app/lib/routes.tsx +42 -0
  476. package/src/app/lib/session-failure-toasts.ts +26 -0
  477. package/src/app/lib/session-ui-features.tsx +18 -4
  478. package/src/app/lib/sessions-group.tsx +219 -30
  479. package/src/app/lib/site-opened.tsx +48 -0
  480. package/src/app/lib/site-session-groups.test.ts +173 -6
  481. package/src/app/lib/site-view-routes.test.ts +55 -0
  482. package/src/app/lib/use-session-list-hint-refresh.tsx +44 -4
  483. package/src/app/routes/artifacts.tsx +2 -29
  484. package/src/app/routes/session-transient-failures.test.tsx +343 -0
  485. package/src/app/routes/session-unavailable.tsx +74 -3
  486. package/src/app/routes/session.tsx +4 -13
  487. package/src/app/routes/sessions-index.tsx +13 -9
  488. package/src/app/routes/site-view.test.tsx +476 -0
  489. package/src/app/routes/site-view.tsx +583 -0
  490. package/src/components/browser-viewer.tsx +16 -2
  491. package/src/hooks/internal.ts +129 -6
  492. package/src/hooks/use-client-config-flags.ts +8 -0
  493. package/src/hooks/use-session-events.ts +83 -9
  494. package/src/hooks/use-workspace-sessions.ts +21 -1
  495. package/src/messages/en.ts +3 -3
  496. package/src/session-list-model.ts +4 -0
  497. package/src/timeline/activity-rail.tsx +3 -2
  498. package/src/timeline/invoked-tool.ts +14 -4
  499. package/src/timeline/projection.ts +11 -6
  500. package/src/timeline/rolling-activity.tsx +6 -2
  501. package/src/timeline/tool-display-name.ts +2 -2
  502. package/src/timeline/tool-icon.tsx +165 -0
  503. package/src/timeline/tool-presentation.ts +207 -48
  504. package/src/timeline/tool-renderers.tsx +1 -70
  505. package/styles/compiled.css +38 -0
  506. package/dist/chunk-22ZBT6CN.js +0 -50
  507. package/dist/chunk-22ZBT6CN.js.map +0 -1
  508. package/dist/chunk-4R3JCVID.js.map +0 -1
  509. package/dist/chunk-4W7VISE7.js.map +0 -1
  510. package/dist/chunk-5JZYPZ72.js.map +0 -1
  511. package/dist/chunk-5MZTJMZ3.js.map +0 -1
  512. package/dist/chunk-6W3LF3DB.js.map +0 -1
  513. package/dist/chunk-ADJJQSYC.js.map +0 -1
  514. package/dist/chunk-APU42QDI.js.map +0 -1
  515. package/dist/chunk-BJIZ7PL7.js.map +0 -1
  516. package/dist/chunk-CVG4FILQ.js.map +0 -1
  517. package/dist/chunk-EF5SYXAY.js.map +0 -1
  518. package/dist/chunk-EHCUFCXM.js.map +0 -1
  519. package/dist/chunk-GZ64CASI.js.map +0 -1
  520. package/dist/chunk-I6VUUEXH.js.map +0 -1
  521. package/dist/chunk-JRXHSVD5.js.map +0 -1
  522. package/dist/chunk-KF3MF6FP.js.map +0 -1
  523. package/dist/chunk-MYNUBDU7.js.map +0 -1
  524. package/dist/chunk-NAWXARTY.js.map +0 -1
  525. package/dist/chunk-PM3OSANE.js.map +0 -1
  526. package/dist/chunk-Q35DT6I6.js.map +0 -1
  527. package/dist/chunk-R25ZKOZR.js +0 -24
  528. package/dist/chunk-R25ZKOZR.js.map +0 -1
  529. package/dist/chunk-RGPYMHKI.js.map +0 -1
  530. package/dist/chunk-RGW24ZZM.js.map +0 -1
  531. package/dist/chunk-ROQOVH4N.js.map +0 -1
  532. package/dist/chunk-TQGJN5UZ.js.map +0 -1
  533. package/dist/chunk-X7L4H4VG.js.map +0 -1
  534. package/dist/chunk-XFNLU7EW.js.map +0 -1
  535. package/dist/chunk-Z5WMLJKI.js.map +0 -1
  536. /package/dist/{browser-viewer-RYYQSRTC.js.map → app/lib/console-site.js.map} +0 -0
  537. /package/dist/{chat-interactive-block-ABCRKXJ4.js.map → app/lib/site-opened.js.map} +0 -0
  538. /package/dist/{computer-viewer-KEDVLD42.js.map → browser-viewer-QMCNV4RI.js.map} +0 -0
  539. /package/dist/{embedded-new-voice-LFHWWYD2.js.map → chat-interactive-block-PMIAUXSO.js.map} +0 -0
  540. /package/dist/{chunk-TGVVEGZG.js.map → chunk-22FFOHPT.js.map} +0 -0
  541. /package/dist/{chunk-UHFWF6ZU.js.map → chunk-2FPS5H2D.js.map} +0 -0
  542. /package/dist/{chunk-5POTDNQT.js.map → chunk-2NC7NZCE.js.map} +0 -0
  543. /package/dist/{chunk-ZKYYZH6L.js.map → chunk-2QBYDGWO.js.map} +0 -0
  544. /package/dist/{chunk-TWXIFWBD.js.map → chunk-34EU25RL.js.map} +0 -0
  545. /package/dist/{chunk-R63QEVPK.js.map → chunk-35BC2FU2.js.map} +0 -0
  546. /package/dist/{chunk-PTGRFAMH.js.map → chunk-3ABPIUCK.js.map} +0 -0
  547. /package/dist/{chunk-S4SC5SSV.js.map → chunk-3GU7AWG7.js.map} +0 -0
  548. /package/dist/{chunk-722UO6YQ.js.map → chunk-3PEXVG4D.js.map} +0 -0
  549. /package/dist/{chunk-63VGE4OH.js.map → chunk-3RMKPHBL.js.map} +0 -0
  550. /package/dist/{chunk-RQDFYQHA.js.map → chunk-3STBLX4O.js.map} +0 -0
  551. /package/dist/{chunk-S4EZ3JUB.js.map → chunk-3X5FKDYQ.js.map} +0 -0
  552. /package/dist/{chunk-KTRKZRID.js.map → chunk-4GLLWX33.js.map} +0 -0
  553. /package/dist/{chunk-SD2K5ZN5.js.map → chunk-4LPA25NQ.js.map} +0 -0
  554. /package/dist/{chunk-KWKGBGAF.js.map → chunk-4RMN4E2Y.js.map} +0 -0
  555. /package/dist/{chunk-X7ASQHR6.js.map → chunk-4SAGYEVB.js.map} +0 -0
  556. /package/dist/{chunk-HTT3FB7T.js.map → chunk-4VK2R5QC.js.map} +0 -0
  557. /package/dist/{chunk-DDK4WFJ3.js.map → chunk-4XQC7VLT.js.map} +0 -0
  558. /package/dist/{chunk-IVOA3DXA.js.map → chunk-4YXAQMTD.js.map} +0 -0
  559. /package/dist/{chunk-HOJGAJAB.js.map → chunk-52WK2GGK.js.map} +0 -0
  560. /package/dist/{chunk-NYZQ7LO7.js.map → chunk-552UYIQ7.js.map} +0 -0
  561. /package/dist/{chunk-LEXPBQ56.js.map → chunk-5DSKMG2I.js.map} +0 -0
  562. /package/dist/{chunk-WNG757ID.js.map → chunk-5FA455GR.js.map} +0 -0
  563. /package/dist/{chunk-HWDGJFM4.js.map → chunk-5FEN3KYH.js.map} +0 -0
  564. /package/dist/{chunk-OSVHU2WU.js.map → chunk-5JHRMUAZ.js.map} +0 -0
  565. /package/dist/{chunk-RKB2Z457.js.map → chunk-5VGJXWQ2.js.map} +0 -0
  566. /package/dist/{chunk-GFUUFM2O.js.map → chunk-5W6ZDKRR.js.map} +0 -0
  567. /package/dist/{chunk-6PQNLL4E.js.map → chunk-5W7KJ5NQ.js.map} +0 -0
  568. /package/dist/{chunk-Q35YZVDZ.js.map → chunk-5Y2FPLZE.js.map} +0 -0
  569. /package/dist/{chunk-F3NERYBQ.js.map → chunk-62VER7O4.js.map} +0 -0
  570. /package/dist/{chunk-FBMU3VK5.js.map → chunk-6DCEDIF6.js.map} +0 -0
  571. /package/dist/{chunk-LE2EDBXU.js.map → chunk-73WI7FL2.js.map} +0 -0
  572. /package/dist/{chunk-ZRJCGBVV.js.map → chunk-7FJMRJDG.js.map} +0 -0
  573. /package/dist/{chunk-7KGKDWWR.js.map → chunk-7HFLYNWN.js.map} +0 -0
  574. /package/dist/{chunk-72J6C2AJ.js.map → chunk-7KIENXRE.js.map} +0 -0
  575. /package/dist/{chunk-CBY5CXBD.js.map → chunk-7NPCEBZE.js.map} +0 -0
  576. /package/dist/{chunk-46VBQG2D.js.map → chunk-7P4AQMGA.js.map} +0 -0
  577. /package/dist/{chunk-S7PVL7XH.js.map → chunk-A4BD4ZVB.js.map} +0 -0
  578. /package/dist/{chunk-73SOCVLS.js.map → chunk-AIEXYO2X.js.map} +0 -0
  579. /package/dist/{chunk-U7TC2XJQ.js.map → chunk-AJPW3SV4.js.map} +0 -0
  580. /package/dist/{chunk-HRJQAFKR.js.map → chunk-AX6YJA5U.js.map} +0 -0
  581. /package/dist/{chunk-P5WABK2H.js.map → chunk-BCM7C3MJ.js.map} +0 -0
  582. /package/dist/{chunk-DT7BORXG.js.map → chunk-BMJTNPWK.js.map} +0 -0
  583. /package/dist/{chunk-HIHO2QE7.js.map → chunk-BT2MVGHT.js.map} +0 -0
  584. /package/dist/{chunk-3XOISKZC.js.map → chunk-BXQYAAVE.js.map} +0 -0
  585. /package/dist/{chunk-IBTXYLBW.js.map → chunk-CCFWY4GF.js.map} +0 -0
  586. /package/dist/{chunk-ZOC3OP6F.js.map → chunk-CCR33J7L.js.map} +0 -0
  587. /package/dist/{chunk-GTQ3SNEI.js.map → chunk-CD3MO3IC.js.map} +0 -0
  588. /package/dist/{chunk-WSMYOLHG.js.map → chunk-CDEXRJB6.js.map} +0 -0
  589. /package/dist/{chunk-3GLAPCVI.js.map → chunk-CFFNT2OY.js.map} +0 -0
  590. /package/dist/{chunk-HO5Y2OOX.js.map → chunk-CMLJSF2F.js.map} +0 -0
  591. /package/dist/{chunk-RA3FNMWF.js.map → chunk-CP7ZQHBW.js.map} +0 -0
  592. /package/dist/{chunk-IOKSNX74.js.map → chunk-D5OWJZQR.js.map} +0 -0
  593. /package/dist/{chunk-SQGXMHJO.js.map → chunk-DGLRZMXL.js.map} +0 -0
  594. /package/dist/{chunk-GNEHAPKV.js.map → chunk-DJFTH2DI.js.map} +0 -0
  595. /package/dist/{chunk-HQG4SLTE.js.map → chunk-DYJGYGPB.js.map} +0 -0
  596. /package/dist/{chunk-4EAF3HSD.js.map → chunk-EJ7WARW7.js.map} +0 -0
  597. /package/dist/{chunk-3AA6RNGE.js.map → chunk-ENS6E4RZ.js.map} +0 -0
  598. /package/dist/{chunk-OOEO4MKY.js.map → chunk-EPWD4KRA.js.map} +0 -0
  599. /package/dist/{chunk-PN66T6JA.js.map → chunk-EQE3MNQN.js.map} +0 -0
  600. /package/dist/{chunk-TSBE4KOQ.js.map → chunk-EWL6NDOO.js.map} +0 -0
  601. /package/dist/{chunk-OO2T63BY.js.map → chunk-EYS4ZOF5.js.map} +0 -0
  602. /package/dist/{chunk-7CZTKBTI.js.map → chunk-FDAV72IX.js.map} +0 -0
  603. /package/dist/{chunk-AG7VGUIW.js.map → chunk-FFNPUSVO.js.map} +0 -0
  604. /package/dist/{chunk-P5T36BA3.js.map → chunk-FRP64DEK.js.map} +0 -0
  605. /package/dist/{chunk-KBF3SE7G.js.map → chunk-FSP334UU.js.map} +0 -0
  606. /package/dist/{chunk-BSX2R4CW.js.map → chunk-FTX5CNHA.js.map} +0 -0
  607. /package/dist/{chunk-O756O2I7.js.map → chunk-FWOBNL2A.js.map} +0 -0
  608. /package/dist/{chunk-6NIB2KGJ.js.map → chunk-FWYEZ3LE.js.map} +0 -0
  609. /package/dist/{chunk-DLOYMWUQ.js.map → chunk-G4HQUBO4.js.map} +0 -0
  610. /package/dist/{chunk-CSHBR2IZ.js.map → chunk-GDLDBR6B.js.map} +0 -0
  611. /package/dist/{chunk-U36PO27Q.js.map → chunk-GHHM6WN4.js.map} +0 -0
  612. /package/dist/{chunk-OANSIX34.js.map → chunk-GRSODLVO.js.map} +0 -0
  613. /package/dist/{chunk-EU6XSQFM.js.map → chunk-GXW2I2M2.js.map} +0 -0
  614. /package/dist/{chunk-5JEIDFPD.js.map → chunk-GZS37O3G.js.map} +0 -0
  615. /package/dist/{chunk-HNYJEAES.js.map → chunk-HQWVDQXW.js.map} +0 -0
  616. /package/dist/{chunk-YXOKAG66.js.map → chunk-HU6JTNWF.js.map} +0 -0
  617. /package/dist/{chunk-QRVNI5V6.js.map → chunk-I6KIQKU6.js.map} +0 -0
  618. /package/dist/{chunk-BNUPYHHZ.js.map → chunk-IDXTASGN.js.map} +0 -0
  619. /package/dist/{chunk-L6RXRRN3.js.map → chunk-ILDOW2IQ.js.map} +0 -0
  620. /package/dist/{chunk-VUHPA3XQ.js.map → chunk-ITX2TB4K.js.map} +0 -0
  621. /package/dist/{chunk-BXRIQZAH.js.map → chunk-J22HD2PB.js.map} +0 -0
  622. /package/dist/{chunk-U47YDYLQ.js.map → chunk-J5MEDX7C.js.map} +0 -0
  623. /package/dist/{chunk-F6LBGYS6.js.map → chunk-J7FBBLHF.js.map} +0 -0
  624. /package/dist/{chunk-QZRDCFHI.js.map → chunk-JM4HQPAI.js.map} +0 -0
  625. /package/dist/{chunk-PIVGX42P.js.map → chunk-JNY5MT3I.js.map} +0 -0
  626. /package/dist/{chunk-XWWXIZFP.js.map → chunk-JO6R5EXF.js.map} +0 -0
  627. /package/dist/{chunk-NWZW2WHN.js.map → chunk-JQCGPTZ6.js.map} +0 -0
  628. /package/dist/{chunk-OR37STQZ.js.map → chunk-KEXYBG7Q.js.map} +0 -0
  629. /package/dist/{chunk-AZVANYMB.js.map → chunk-KUNFUSZ7.js.map} +0 -0
  630. /package/dist/{chunk-DXZNDKQD.js.map → chunk-LEEJBZ5B.js.map} +0 -0
  631. /package/dist/{chunk-AOLE4IRZ.js.map → chunk-LF5CBAOS.js.map} +0 -0
  632. /package/dist/{chunk-RIMKJBCD.js.map → chunk-LMPTC4CX.js.map} +0 -0
  633. /package/dist/{chunk-3KVWXKD6.js.map → chunk-LQ47YL6E.js.map} +0 -0
  634. /package/dist/{chunk-RSNYGEVZ.js.map → chunk-LT4J7RHI.js.map} +0 -0
  635. /package/dist/{chunk-U3HSFCON.js.map → chunk-MCTTONOW.js.map} +0 -0
  636. /package/dist/{chunk-7DU35P5J.js.map → chunk-MIECLOQC.js.map} +0 -0
  637. /package/dist/{chunk-FM4OUCC2.js.map → chunk-MOKYT3X3.js.map} +0 -0
  638. /package/dist/{chunk-L7YURQI2.js.map → chunk-MXLKI7BI.js.map} +0 -0
  639. /package/dist/{chunk-XRRSFQEV.js.map → chunk-NAZZLAWX.js.map} +0 -0
  640. /package/dist/{chunk-UWJ5P5CU.js.map → chunk-NEK4WB5P.js.map} +0 -0
  641. /package/dist/{chunk-6L7U46Y2.js.map → chunk-NKNVIO66.js.map} +0 -0
  642. /package/dist/{chunk-JKUICTLM.js.map → chunk-NLAFNMPK.js.map} +0 -0
  643. /package/dist/{chunk-4LKNIGHB.js.map → chunk-O2SBHS2N.js.map} +0 -0
  644. /package/dist/{chunk-DWPOQ3S5.js.map → chunk-OTMWHZBY.js.map} +0 -0
  645. /package/dist/{chunk-JTN3T4QN.js.map → chunk-PCFK7HKD.js.map} +0 -0
  646. /package/dist/{chunk-VVCDB2T7.js.map → chunk-PCJLH45G.js.map} +0 -0
  647. /package/dist/{chunk-PZ24CYDO.js.map → chunk-PFAUGEV5.js.map} +0 -0
  648. /package/dist/{chunk-HGMWMK5K.js.map → chunk-PO3BH3KQ.js.map} +0 -0
  649. /package/dist/{chunk-B74GSYR6.js.map → chunk-PUTS4DYW.js.map} +0 -0
  650. /package/dist/{chunk-JSIDLTTG.js.map → chunk-PZ2V2XIK.js.map} +0 -0
  651. /package/dist/{chunk-TMEQPODK.js.map → chunk-PZ37VDB5.js.map} +0 -0
  652. /package/dist/{chunk-LVONK3YQ.js.map → chunk-QRKTESVE.js.map} +0 -0
  653. /package/dist/{chunk-HT5WSUC7.js.map → chunk-QXEDIDBZ.js.map} +0 -0
  654. /package/dist/{chunk-WURSS6MP.js.map → chunk-R66YMYJU.js.map} +0 -0
  655. /package/dist/{chunk-HDHK3SXK.js.map → chunk-RFLYID6H.js.map} +0 -0
  656. /package/dist/{chunk-JK7C5A4I.js.map → chunk-RQNZDTKT.js.map} +0 -0
  657. /package/dist/{chunk-ST22GONV.js.map → chunk-S37GP7LX.js.map} +0 -0
  658. /package/dist/{chunk-A2EWJQXX.js.map → chunk-SM5QX6UK.js.map} +0 -0
  659. /package/dist/{chunk-FBE6AIIW.js.map → chunk-SOKNCW5U.js.map} +0 -0
  660. /package/dist/{chunk-UP4BE32Y.js.map → chunk-SY2AAZNB.js.map} +0 -0
  661. /package/dist/{chunk-33TPANCR.js.map → chunk-TFK4KFKA.js.map} +0 -0
  662. /package/dist/{chunk-4432A3HQ.js.map → chunk-TIQPKOFW.js.map} +0 -0
  663. /package/dist/{chunk-HPPKLBTJ.js.map → chunk-TJQDL3JH.js.map} +0 -0
  664. /package/dist/{chunk-FD4Q5KFL.js.map → chunk-TLL22FFO.js.map} +0 -0
  665. /package/dist/{chunk-QM5H4FPT.js.map → chunk-TV6BWONY.js.map} +0 -0
  666. /package/dist/{chunk-4VKA5O7T.js.map → chunk-U6MPB3K6.js.map} +0 -0
  667. /package/dist/{chunk-XOFUXMPP.js.map → chunk-ULJAOMJA.js.map} +0 -0
  668. /package/dist/{chunk-H5EVWF6L.js.map → chunk-UNNJUJVD.js.map} +0 -0
  669. /package/dist/{chunk-Z6DKXQG7.js.map → chunk-UXXFMF4X.js.map} +0 -0
  670. /package/dist/{chunk-OBQVTCTW.js.map → chunk-UYNCMZX5.js.map} +0 -0
  671. /package/dist/{chunk-KZHW27BV.js.map → chunk-V4QZ7UBK.js.map} +0 -0
  672. /package/dist/{chunk-SUVEDKE2.js.map → chunk-VH5EGTH2.js.map} +0 -0
  673. /package/dist/{chunk-QEJTQTF5.js.map → chunk-W6T5HR3Z.js.map} +0 -0
  674. /package/dist/{chunk-VP62LPLW.js.map → chunk-WCMG4HYI.js.map} +0 -0
  675. /package/dist/{chunk-GZLLDA6P.js.map → chunk-WEFN327U.js.map} +0 -0
  676. /package/dist/{chunk-7BST7BA6.js.map → chunk-WKHUZIOW.js.map} +0 -0
  677. /package/dist/{chunk-ANHUMDJX.js.map → chunk-WNDTLK44.js.map} +0 -0
  678. /package/dist/{chunk-2DS4UOYQ.js.map → chunk-WSZQNTVN.js.map} +0 -0
  679. /package/dist/{chunk-GALB2G3W.js.map → chunk-X2AH4DRF.js.map} +0 -0
  680. /package/dist/{chunk-Z2DAWUO3.js.map → chunk-XMNUZUUA.js.map} +0 -0
  681. /package/dist/{chunk-GAIM5RNE.js.map → chunk-XN7NSPE6.js.map} +0 -0
  682. /package/dist/{chunk-FLGUVRR7.js.map → chunk-Y5BSA3I7.js.map} +0 -0
  683. /package/dist/{chunk-QCD5Y7K5.js.map → chunk-YEROLKOA.js.map} +0 -0
  684. /package/dist/{chunk-NDF3SH3X.js.map → chunk-YJPKDRI2.js.map} +0 -0
  685. /package/dist/{chunk-VAIESMPY.js.map → chunk-YVBHGMKC.js.map} +0 -0
  686. /package/dist/{chunk-AD22P5X3.js.map → chunk-YXA2EKV3.js.map} +0 -0
  687. /package/dist/{chunk-FDNJVZRE.js.map → chunk-YYCOSTUU.js.map} +0 -0
  688. /package/dist/{chunk-NLMTNEWW.js.map → chunk-Z6E6TUAE.js.map} +0 -0
  689. /package/dist/{chunk-BJW7G6EF.js.map → chunk-Z7IGO5EA.js.map} +0 -0
  690. /package/dist/{chunk-NCX5SAQY.js.map → chunk-ZEIFJ6PX.js.map} +0 -0
  691. /package/dist/{chunk-4EONHNJU.js.map → chunk-ZVVT72MT.js.map} +0 -0
  692. /package/dist/{embedded-voice-6QS4ANNX.js.map → computer-viewer-25AJIDYA.js.map} +0 -0
  693. /package/dist/{model-policy-picker-menu-CURJ247L.js.map → embedded-new-voice-RZZEJT6M.js.map} +0 -0
  694. /package/dist/{sandbox-files-4FBG3GS2.js.map → embedded-voice-6OKSSPLW.js.map} +0 -0
  695. /package/dist/{fleet-decision-row-QNSTP3VX.js.map → fleet-decision-row-NN2HXDX3.js.map} +0 -0
  696. /package/dist/{session-realtime-2XIB254N.js.map → model-policy-picker-menu-VVFGGAI6.js.map} +0 -0
  697. /package/dist/{platform-activity-row-BMXXNZKX.js.map → platform-activity-row-ENQVIFTL.js.map} +0 -0
  698. /package/dist/{timeline-annotation-markers-X4K2IEOO.js.map → timeline-annotation-markers-KHNYNY2J.js.map} +0 -0
  699. /package/dist/{timeline-annotation-selection-MEHBW676.js.map → timeline-annotation-selection-AXEDJHBP.js.map} +0 -0
  700. /package/dist/{timeline-annotations-dialog-U2FPQ3UY.js.map → timeline-annotations-dialog-AV4ZBXRC.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/older-history.ts","../src/conversation-timeline.ts","../src/lib/session-startup-timeline.tsx","../src/hooks/use-available-models.ts","../src/hooks/use-human-input.ts","../src/hooks/use-session.ts","../src/lib/session-detail-read.ts","../src/hooks/use-session-control.ts","../src/hooks/use-session-events.ts","../src/hooks/page-wake.ts","../src/hooks/turnless-output-gaps.ts","../src/hooks/use-turn-queue.ts","../src/hooks/use-session-conversation.ts","../src/hooks/use-goal.ts","../src/hooks/use-session-read-acknowledgement.ts","../src/hooks/use-new-conversation.ts"],"sourcesContent":["/**\n * Await-compatible older-history result with a causal commit receipt.\n *\n * `committed` flips synchronously before the accepted older window is exposed\n * to React. Returning this exact object preserves the receipt directly;\n * synchronous wrappers that discard it remain supported through receipt\n * capture, while replacing it asynchronously with a plain promise does not.\n */\nexport type OlderHistoryLoadReceipt = Promise<boolean> & {\n readonly committed: boolean;\n readonly tailPreserved?: boolean;\n};\n\n/**\n * Source-compatible public callback accepted by MessageTimeline.\n *\n * The callback historically returned `void`, which permits consumers to\n * return any synchronous value or promise. Receipt-aware loaders opt into the\n * stronger runtime contract by returning (or synchronously creating through a\n * wrapper) an {@link OlderHistoryLoadReceipt}.\n */\nexport type OlderHistoryLoader = () => unknown;\n\ntype MutableOlderHistoryLoadReceipt = Promise<boolean> & {\n committed: boolean;\n tailPreserved: boolean;\n};\n\ntype OlderHistoryReceiptCapture = (receipt: OlderHistoryLoadReceipt) => void;\n\nlet activeReceiptCapture: OlderHistoryReceiptCapture | undefined;\nlet preserveTailForAutomaticLoad = false;\n\n/** Bind a receipt before a synchronous forwarding stack can publish state. */\nexport function invokeOlderHistoryLoaderWithReceiptCapture(\n load: OlderHistoryLoader,\n capture: OlderHistoryReceiptCapture,\n preserveTail = false,\n): unknown {\n const previousCapture = activeReceiptCapture;\n const previousPreserveTail = preserveTailForAutomaticLoad;\n activeReceiptCapture = capture;\n preserveTailForAutomaticLoad = preserveTail;\n try {\n return load();\n } finally {\n activeReceiptCapture = previousCapture;\n preserveTailForAutomaticLoad = previousPreserveTail;\n }\n}\n\n/**\n * Build an await-compatible older-history receipt for custom timeline hosts.\n * Call `markCommitted` immediately before publishing an accepted older window.\n */\nexport function createOlderHistoryLoadReceipt(\n load: (\n markCommitted: () => void,\n preserveTail: boolean,\n markTailPreserved: () => void,\n ) => boolean | Promise<boolean>,\n): OlderHistoryLoadReceipt {\n let resolveResult!: (value: boolean | PromiseLike<boolean>) => void;\n let rejectResult!: (reason?: unknown) => void;\n const result = new Promise<boolean>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n }) as MutableOlderHistoryLoadReceipt;\n result.committed = false;\n result.tailPreserved = false;\n activeReceiptCapture?.(result);\n try {\n const loaded = load(\n () => {\n result.committed = true;\n },\n preserveTailForAutomaticLoad,\n () => {\n result.tailPreserved = true;\n },\n );\n Promise.resolve(loaded).then(resolveResult, rejectResult);\n } catch (error) {\n rejectResult(error);\n }\n return result;\n}\n","import type { ComposerState } from \"./hooks/use-composer\";\nimport type { UseTurnQueueResult } from \"./hooks/use-turn-queue\";\nimport type { TimelineItem, UserMessageItem } from \"./timeline/types\";\n\n/** Keep pending prompts in the queue, not duplicated in the conversation. */\nexport function conversationTimeline(\n items: TimelineItem[],\n queue: Pick<UseTurnQueueResult, \"queue\" | \"snapshot\" | \"acceptedSteers\">,\n composer: Pick<\n ComposerState,\n | \"optimisticMessages\"\n | \"retryOptimisticMessage\"\n | \"restoreOptimisticMessage\"\n | \"removeOptimisticMessage\"\n >,\n): TimelineItem[] {\n const queued = new Set(\n queue.queue\n .filter((turn) => turn.metadata.delivery !== \"steer\")\n .map((turn) => turn.triggerEventId),\n );\n const pending = composer.optimisticMessages ?? [];\n const pendingQueue = new Set(\n pending\n .filter(\n (message) =>\n message.destination === \"queue\" &&\n !(\n message.turnId &&\n message.appliedQueueVersion != null &&\n queue.snapshot &&\n queue.snapshot.version >= message.appliedQueueVersion &&\n !queue.queue.some((turn) => turn.id === message.turnId)\n ),\n )\n .map((message) => `user-message:${message.clientEventId}`),\n );\n const visible = items.filter(\n (item) =>\n item.kind !== \"user-message\" ||\n (!queued.has(item.id) && !pendingQueue.has(item.reconciliationKey ?? \"\")),\n );\n const keys = new Set(\n visible.flatMap((item) => (item.kind === \"user-message\" ? [item.reconciliationKey] : [])),\n );\n const optimistic: UserMessageItem[] = pending\n .filter(\n (message) =>\n (message.destination === \"chat\" || message.state === \"failed\") &&\n !keys.has(`user-message:${message.clientEventId}`) &&\n !queue.queue.some((turn) => turn.id === message.turnId),\n )\n .map((message) => ({\n kind: \"user-message\",\n id: `optimistic:${message.clientEventId}`,\n reconciliationKey: `user-message:${message.clientEventId}`,\n text: message.text,\n annotations: message.annotations.map((annotation, ordinal) => ({ ...annotation, ordinal })),\n resources: message.resources,\n tools: [],\n occurredAt: message.occurredAt,\n delivery: {\n state: message.state,\n ...(message.error ? { error: message.error } : {}),\n ...(message.state === \"failed\"\n ? {\n ...(message.retryable !== false && composer.retryOptimisticMessage\n ? { onRetry: () => composer.retryOptimisticMessage?.(message.clientEventId) }\n : {}),\n ...(message.retryable === false && composer.restoreOptimisticMessage\n ? { onEdit: () => composer.restoreOptimisticMessage?.(message.clientEventId) }\n : {}),\n onRemove: () => composer.removeOptimisticMessage?.(message.clientEventId),\n }\n : {}),\n },\n }));\n const ids = new Set(visible.map((item) => item.id));\n const steers: UserMessageItem[] = (queue.acceptedSteers ?? [])\n .filter((steer) => !ids.has(steer.triggerEventId))\n .map((steer) => ({\n kind: \"user-message\",\n id: steer.triggerEventId,\n text: steer.text,\n annotations: steer.annotations,\n resources: steer.resources,\n tools: steer.tools,\n occurredAt: steer.occurredAt,\n delivery: { state: steer.state },\n }));\n return [...visible, ...optimistic, ...steers];\n}\n","import { useRef } from \"react\";\nimport type { Session, SessionEvent, SessionQueueSnapshot } from \"@opengeni/sdk\";\nimport type { ComposerState, TimelineItem } from \"../session\";\nimport { useSessionStartupState, type SessionStartupSource } from \"./session-startup\";\n\ntype StartupInput = {\n session: Pick<\n Session,\n | \"id\"\n | \"status\"\n | \"activeTurnId\"\n | \"effectiveControl\"\n | \"dispatchWait\"\n | \"inputWait\"\n | \"lastSequence\"\n | \"queueVersion\"\n >;\n events: SessionEvent[];\n optimisticMessages: ComposerState[\"optimisticMessages\"];\n hasNewer: boolean;\n queue?: SessionQueueSnapshot | null | undefined;\n fallbackStartedAt?: string | undefined;\n};\nfunction currentEvents(events: SessionEvent[]) {\n return events\n .filter(\n (event) =>\n !event.duplicateOfEventId &&\n (!event.turnAssociation || event.turnAssociation === \"current\"),\n )\n .sort((a, b) => a.sequence - b.sequence);\n}\nfunction payloadOf(event: SessionEvent): Record<string, unknown> {\n return event.payload && typeof event.payload === \"object\"\n ? (event.payload as Record<string, unknown>)\n : {};\n}\n\n/** Presentation only. Accepted work is not proof that a worker is executing. */\nexport function sessionStartupTimeline(items: TimelineItem[], input: StartupInput): TimelineItem[] {\n const { session, optimisticMessages, hasNewer } = input;\n if (\n hasNewer ||\n session.effectiveControl.state !== \"active\" ||\n ![\"idle\", \"queued\", \"running\"].includes(session.status) ||\n (session.status === \"idle\" && session.inputWait)\n )\n return items;\n const claimed = new Set<string>();\n const pending = new Map<string, string>();\n let queueVersion = session.queueVersion;\n let newerProgress = false;\n let observedActiveTurn: string | null = null;\n // A prompt that waited behind earlier work starts its queue span when that\n // work ended, not when the person queued it.\n let previousTurnEndedAt: string | null = null;\n for (const event of currentEvents(input.events)) {\n const payload = payloadOf(event);\n if (\n event.turnId &&\n [\"turn.completed\", \"turn.failed\", \"turn.cancelled\", \"turn.superseded\"].includes(event.type)\n )\n previousTurnEndedAt = event.occurredAt;\n if (\n event.sequence > session.lastSequence &&\n ([\n \"turn.started\",\n \"turn.completed\",\n \"turn.failed\",\n \"turn.cancelled\",\n \"turn.superseded\",\n ].includes(event.type) ||\n (event.type === \"session.status.changed\" && payload.status !== \"queued\") ||\n (event.type === \"session.queue.changed\" &&\n [\"edit\", \"delete\"].includes(String(payload.operation))))\n )\n newerProgress = true;\n if (event.type === \"session.queue.changed\" && typeof payload.queueVersion === \"number\")\n queueVersion = Math.max(queueVersion, payload.queueVersion);\n const turnId = event.turnId ?? (typeof payload.turnId === \"string\" ? payload.turnId : null);\n if (!turnId) continue;\n if (event.sequence > session.lastSequence) {\n if (event.type === \"turn.started\") observedActiveTurn = turnId;\n else if (\n observedActiveTurn === turnId &&\n [\"turn.completed\", \"turn.failed\", \"turn.cancelled\", \"turn.superseded\"].includes(event.type)\n )\n observedActiveTurn = null;\n }\n if (\n [\n \"turn.started\",\n \"turn.completed\",\n \"turn.failed\",\n \"turn.cancelled\",\n \"turn.superseded\",\n ].includes(event.type) ||\n (event.type === \"session.queue.changed\" &&\n [\"edit\", \"delete\"].includes(String(payload.operation)))\n )\n claimed.add(turnId);\n if (\n (event.type === \"turn.queued\" || event.type === \"user.message\") &&\n payload.routing === \"accepted_for_execution\" &&\n (session.status !== \"idle\" || event.sequence > session.lastSequence)\n )\n pending.set(turnId, event.occurredAt);\n }\n for (const message of optimisticMessages ?? []) {\n if (\n message.state === \"queued\" &&\n message.destination === \"chat\" &&\n message.delivery === \"send\" &&\n message.turnId &&\n !pending.has(message.turnId) &&\n (session.status !== \"idle\" ||\n (message.appliedQueueVersion != null && message.appliedQueueVersion > session.queueVersion))\n )\n pending.set(message.turnId, message.occurredAt);\n }\n // The visible queue excludes the already accepted current message. Only its\n // authoritative first item may become the next startup; replay order is not priority.\n const head = input.queue && input.queue.version >= queueVersion ? input.queue.items[0] : null;\n if (session.status === \"queued\" && !session.activeTurnId && head && !pending.has(head.id))\n pending.set(\n head.id,\n previousTurnEndedAt && previousTurnEndedAt > head.createdAt\n ? previousTurnEndedAt\n : head.createdAt,\n );\n const candidate = [...pending].find(\n ([turnId]) =>\n !claimed.has(turnId) &&\n (!session.activeTurnId || session.activeTurnId === turnId) &&\n (!observedActiveTurn || observedActiveTurn === turnId) &&\n !items.some((item) => \"turnId\" in item && item.turnId === turnId),\n );\n const fallback =\n !candidate &&\n !newerProgress &&\n session.status === \"queued\" &&\n !session.activeTurnId &&\n input.fallbackStartedAt;\n if (!candidate && !fallback) return items;\n const [turnId, startedAt] = candidate ?? [\n `pending-startup:${session.id}`,\n input.fallbackStartedAt!,\n ];\n return [\n ...items,\n {\n kind: \"startup-phase\",\n id: `${turnId}-queue`,\n turnId,\n phase: \"queue\",\n status: \"running\",\n startedAt,\n occurredAt: startedAt,\n completedAt: null,\n durationMs: null,\n outcome: null,\n ...(session.activeTurnId\n ? {}\n : { dispatchWait: session.status === \"queued\" ? (session.dispatchWait ?? null) : null }),\n },\n ];\n}\n\ntype Bridge = { scope: string; id: string; turnId: string | null; since: string; sequence: number };\n\n/** A prompt the host already sent while its session is still being created or loaded. */\nexport type PendingPrompt = {\n /** The prompt exactly as the person sent it. */\n text: string;\n /** When the person sent it (ISO 8601). Anchors the startup row's clock. */\n sentAt: string;\n};\n\nconst PENDING_SCOPE = \"pending-prompt\";\n/** The startup row keeps this id from the pending prompt through the live projection. */\nexport const PENDING_PROMPT_STARTUP_ID = \"pending-prompt-startup\";\n\nfunction pendingPromptItems(prompt: PendingPrompt): TimelineItem[] {\n return [\n {\n kind: \"user-message\",\n id: \"pending-prompt-message\",\n text: prompt.text,\n resources: [],\n tools: [],\n occurredAt: prompt.sentAt,\n },\n {\n kind: \"startup-phase\",\n id: PENDING_PROMPT_STARTUP_ID,\n turnId: PENDING_SCOPE,\n phase: \"queue\",\n status: \"running\",\n startedAt: prompt.sentAt,\n occurredAt: prompt.sentAt,\n completedAt: null,\n durationMs: null,\n outcome: null,\n },\n ];\n}\n/**\n * Keep the current loading visual while a session-only wake acquires a turn ID.\n * The web app's session page and the embeddable conversation both project\n * through this, so a sent prompt shows the same startup row in either. A\n * session that has not loaded yet leaves the timeline unchanged.\n */\nexport function useSessionStartupTimeline(\n items: TimelineItem[],\n input: Omit<StartupInput, \"fallbackStartedAt\" | \"session\"> & {\n session: (StartupInput[\"session\"] & SessionStartupSource) | null;\n /**\n * A prompt sent before the session or its history is readable. Until\n * `historyReady`, the timeline is that prompt and a running startup row;\n * the live row then keeps the same id and clock, so nothing remounts.\n */\n pendingPrompt?: PendingPrompt | null | undefined;\n historyReady?: boolean | undefined;\n },\n): TimelineItem[] {\n const startup = useSessionStartupState(input.session);\n const bridgeRef = useRef<Bridge | null>(null);\n const { pendingPrompt } = input;\n if (pendingPrompt && (!input.session || input.historyReady === false)) {\n bridgeRef.current = {\n scope: PENDING_SCOPE,\n id: PENDING_PROMPT_STARTUP_ID,\n turnId: null,\n since: pendingPrompt.sentAt,\n sequence: 0,\n };\n return [...items, ...pendingPromptItems(pendingPrompt)];\n }\n if (!input.session) {\n bridgeRef.current = null;\n return items;\n }\n const scope = `${input.session.workspaceId}:${input.session.id}`;\n // The pending prompt's row becomes this session's row.\n if (bridgeRef.current?.scope === PENDING_SCOPE)\n bridgeRef.current = { ...bridgeRef.current, scope };\n if (\n bridgeRef.current?.scope !== scope ||\n input.hasNewer ||\n input.session.effectiveControl.state !== \"active\" ||\n ![\"queued\", \"running\", \"idle\"].includes(input.session.status)\n )\n bridgeRef.current = null;\n // A new wake may arrive in the same render as settlement, without an idle\n // frame. Retire the old episode before choosing the next fallback clock.\n const boundTurn = bridgeRef.current?.turnId;\n const settled =\n boundTurn &&\n currentEvents(input.events).find(\n (event) =>\n event.turnId === boundTurn &&\n [\"turn.completed\", \"turn.failed\", \"turn.cancelled\", \"turn.superseded\"].includes(event.type),\n );\n let fallbackStartedAt =\n bridgeRef.current?.turnId === null ? bridgeRef.current.since : startup?.startedAt;\n if (settled) {\n bridgeRef.current = null;\n fallbackStartedAt =\n input.session.status === \"queued\" && input.session.lastSequence >= settled.sequence\n ? input.session.updatedAt\n : undefined;\n }\n const projected = sessionStartupTimeline(items, {\n ...input,\n session: input.session,\n fallbackStartedAt,\n });\n if (projected !== items) {\n const phase = projected.at(-1)!;\n if (phase.kind !== \"startup-phase\") return projected;\n const turnId = phase.turnId === `pending-startup:${input.session.id}` ? null : phase.turnId;\n let bridge = bridgeRef.current;\n if (!bridge || (bridge.turnId && turnId && bridge.turnId !== turnId)) {\n bridge = {\n scope,\n id: phase.id,\n turnId,\n since: phase.startedAt,\n sequence: input.session.lastSequence,\n };\n } else\n bridge = {\n ...bridge,\n turnId: turnId ?? bridge.turnId,\n since: bridge.since < phase.startedAt ? bridge.since : phase.startedAt,\n };\n bridgeRef.current = bridge;\n return [\n ...projected.slice(0, -1),\n { ...phase, id: bridge.id, startedAt: bridge.since, occurredAt: bridge.since },\n ];\n }\n const bridge = bridgeRef.current;\n if (!bridge) return items;\n if (input.session.status === \"idle\") {\n bridgeRef.current = null;\n return items;\n }\n const started = currentEvents(input.events).find(\n (event) =>\n event.type === \"turn.started\" &&\n (bridge.turnId ? event.turnId === bridge.turnId : event.sequence > bridge.sequence),\n );\n const turnId = bridge.turnId ?? started?.turnId ?? input.session.activeTurnId;\n const phase = items.find((item) => item.kind === \"startup-phase\" && item.turnId === turnId);\n if (phase?.kind === \"startup-phase\") {\n bridgeRef.current = { ...bridge, turnId };\n return items.map((item) =>\n item === phase\n ? {\n ...phase,\n id: bridge.id,\n loadingStartedAt: bridge.since < phase.startedAt ? bridge.since : phase.startedAt,\n }\n : item,\n );\n }\n if (turnId && (started || input.session.activeTurnId === turnId)) {\n bridgeRef.current = { ...bridge, turnId };\n // The claim can arrive before the first preparation receipt. This is a\n // display span for the observed wait, not an event or execution authority.\n return [\n ...items,\n {\n kind: \"startup-phase\",\n id: bridge.id,\n turnId,\n phase: \"queue\",\n status: \"complete\",\n startedAt: bridge.since,\n occurredAt: bridge.since,\n completedAt: started?.occurredAt ?? input.session.updatedAt,\n durationMs: null,\n outcome: null,\n },\n ];\n }\n // An authoritative idle snapshot supersedes acceptance even before SSE catches up.\n if (turnId) bridgeRef.current = null;\n return items;\n}\n","import type { WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\nimport { useCallback } from \"react\";\nimport { projectPickerRows, sortPickerRows, type PickerModelRow } from \"../model-policy\";\nimport { useOpenGeniClient, type ClientOverride } from \"../session-context\";\nimport { joinClientConfigRead } from \"../lib/client-config-read\";\nimport { useSharedQuery } from \"./shared-query\";\nimport { useOpenGeniText } from \"../messages/runtime\";\n\nexport type UseAvailableModelsOptions = Pick<ClientOverride, \"client\"> & {\n /** Refresh interval (ms). Off by default — the host model list rarely moves. */\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n};\n\nexport type UseAvailableModelsResult = {\n models: import(\"@opengeni/sdk\").ClientModel[];\n defaultModel: string | null;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n};\n\nexport type UseWorkspaceModelCatalogOptions = Pick<ClientOverride, \"client\"> & {\n workspaceId: string | null;\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n};\n\nexport type UseWorkspaceModelCatalogResult = {\n models: WorkspaceModelCatalogModel[];\n rows: PickerModelRow[];\n defaultModel: string | null;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n};\n\n/**\n * The host-exposed model list for a <ModelPicker>: fetches the deployment's\n * public client config (`GET /v1/config/client`) and surfaces the richer\n * provider-grouped `models` plus the `defaultModel` the picker should preselect.\n * Deployment-scoped, so it only needs the client (no workspace). Mounted readers\n * of one client share one request.\n */\nexport function useAvailableModels(\n options: UseAvailableModelsOptions = {},\n): UseAvailableModelsResult {\n const client = useOpenGeniClient(options);\n const load = useCallback(\n async (signal: AbortSignal) => await client.getClientConfig({ signal }),\n [client],\n );\n const state = useSharedQuery(client, [\"available-models\"], load, {\n pollIntervalMs: options.pollIntervalMs,\n enabled: options.enabled,\n });\n return {\n models: state.data?.models ?? [],\n defaultModel: state.data?.defaultModel ?? null,\n loading: state.loading,\n error: state.error,\n refresh: state.refresh,\n };\n}\n\n/**\n * Workspace-scoped catalog with selectability and billing-class picker rows.\n * Mounted readers of one workspace (the conversation and the new-chat composer)\n * share one catalog and config request.\n */\nexport function useWorkspaceModelCatalog(\n options: UseWorkspaceModelCatalogOptions,\n): UseWorkspaceModelCatalogResult {\n const t = useOpenGeniText();\n const client = useOpenGeniClient(options);\n const load = useCallback(\n async (signal: AbortSignal) => {\n if (!options.workspaceId) {\n return { models: [], defaultModel: null };\n }\n const [catalog, config] = await Promise.all([\n client.getWorkspaceModelCatalog(options.workspaceId, { signal }),\n // Joins the same workspace's config read already in flight (for\n // example the composer's voice availability).\n joinClientConfigRead(client, options.workspaceId),\n ]);\n return {\n models: catalog.models,\n defaultModel: config.defaultModel,\n };\n },\n [client, options.workspaceId],\n );\n const state = useSharedQuery(client, [\"workspace-model-catalog\", options.workspaceId], load, {\n pollIntervalMs: options.pollIntervalMs,\n enabled: options.enabled !== false && Boolean(options.workspaceId),\n });\n const rows = sortPickerRows(projectPickerRows(t, state.data?.models ?? []));\n return {\n models: state.data?.models ?? [],\n rows,\n defaultModel: state.data?.defaultModel ?? null,\n loading: state.loading,\n error: state.error,\n refresh: state.refresh,\n };\n}\n","import type {\n SessionEvent,\n SessionHumanInputRequest,\n SubmitHumanInputResponseRequest,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n useEmbeddedHumanInputSession,\n type EmbeddedHumanInputClientOverride,\n} from \"../session-context\";\nimport { isActionableHumanInputRequest } from \"../human-input\";\nimport { forgetSessionHumanInputDrafts, pruneHumanInputDrafts } from \"../human-input-draft-store\";\nimport { deniesRetainedView, useRetainedSessionView } from \"./session-view-cache\";\nimport {\n projectionReadThrough,\n useDebouncedCallback,\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\n/** Events that can create, settle, or invalidate an actionable request. */\nexport function isHumanInputEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return (\n event.type === \"session.humanInput.requested\" ||\n event.type === \"user.humanInputResponse\" ||\n event.type === \"turn.completed\" ||\n event.type === \"turn.failed\" ||\n event.type === \"turn.cancelled\"\n );\n}\n\nexport type UseHumanInputRequestsOptions = EmbeddedHumanInputClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling. Durable events drive refresh by default. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseHumanInputRequestsResult = {\n requests: SessionHumanInputRequest[];\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n respond: (\n requestId: string,\n response: SubmitHumanInputResponseRequest,\n ) => Promise<SessionEvent | null>;\n respondingRequestId: string | null;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/**\n * Authoritative structured-human-input hook. The server's pending-request\n * table is the read model; events only trigger reconciliation. This lets an\n * embedded host use the same primitive with a shared event feed or its own SDK\n * proxy without rebuilding request lifecycle logic.\n */\nexport function useHumanInputRequests(\n sessionId: string | null | undefined,\n options: UseHumanInputRequestsOptions = {},\n): UseHumanInputRequestsResult {\n const { client, workspaceId, registerSessionReconciler } = useEmbeddedHumanInputSession(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const load = useCallback(async (): Promise<SessionHumanInputRequest[]> => {\n if (!sessionId) return [];\n const readStartedAt = Date.now();\n const requests = await client.listHumanInputRequests(workspaceId, sessionId, {\n status: \"pending\",\n });\n // Unsent answers belong only to requests that are still answerable here:\n // forget drafts for requests answered elsewhere, skipped, or expired.\n const now = Date.now();\n pruneHumanInputDrafts(\n workspaceId,\n sessionId,\n requests\n .filter((request) => isActionableHumanInputRequest(request, now))\n .map((request) => request.id),\n readStartedAt,\n );\n return requests;\n }, [client, sessionId, workspaceId]);\n const state = usePolledValue(load, {\n enabled,\n pollIntervalMs: options.pollIntervalMs,\n });\n const loadedRequests = state.data;\n const refreshRequests = state.refresh;\n // A person who may no longer see this session keeps none of its unsent answers.\n const readDenied = enabled && Boolean(sessionId) && deniesRetainedView(state.error);\n useEffect(() => {\n if (readDenied && sessionId) forgetSessionHumanInputDrafts(workspaceId, sessionId);\n }, [readDenied, sessionId, workspaceId]);\n const mutation = useMutationRunner(`${workspaceId}\\u0000${sessionId ?? \"\"}`);\n const [respondingRequestId, setRespondingRequestId] = useState<string | null>(null);\n const [deadlineVersion, setDeadlineVersion] = useState(0);\n const respondingRequestRef = useRef<string | null>(null);\n\n useEffect(() => {\n respondingRequestRef.current = null;\n setRespondingRequestId(null);\n }, [sessionId, workspaceId]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"human-input\", state.refresh);\n }, [enabled, registerSessionReconciler, sessionId, state.refresh]);\n\n const scheduleRefresh = useDebouncedCallback(() => void state.refresh());\n useSessionEventTrigger(client, workspaceId, sessionId, isHumanInputEvent, scheduleRefresh, {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n readThrough: projectionReadThrough(state.data, state.loading),\n refresh: scheduleRefresh,\n });\n // Until the first read lands, show the questions pending when this\n // conversation was last left (only when the host retains reads).\n const retainedRequests = useRetainedSessionView(\n client,\n workspaceId,\n sessionId,\n \"human-input\",\n state.data,\n { enabled, discard: deniesRetainedView(state.error) },\n );\n\n useEffect(() => {\n const now = Date.now();\n const nextDeadline = (loadedRequests ?? []).reduce<number | null>((next, request) => {\n if (request.status !== \"pending\" || !request.expiresAt) return next;\n const deadline = Date.parse(request.expiresAt);\n if (!Number.isFinite(deadline) || deadline <= now) return next;\n return next === null ? deadline : Math.min(next, deadline);\n }, null);\n if (nextDeadline === null) return;\n const timer = globalThis.setTimeout(\n () => {\n setDeadlineVersion((current) => current + 1);\n void refreshRequests();\n },\n Math.min(2_147_483_647, Math.max(0, nextDeadline - now + 1)),\n );\n return () => globalThis.clearTimeout(timer);\n }, [loadedRequests, refreshRequests]);\n\n const respond = useCallback(\n async (\n requestId: string,\n response: SubmitHumanInputResponseRequest,\n ): Promise<SessionEvent | null> => {\n if (!sessionId || respondingRequestRef.current !== null) return null;\n respondingRequestRef.current = requestId;\n setRespondingRequestId(requestId);\n try {\n const event = await mutation.run(() =>\n client.submitHumanInputResponse(workspaceId, sessionId, requestId, response, {\n clientEventId: globalThis.crypto.randomUUID(),\n }),\n );\n if (event) await state.refresh();\n return event;\n } finally {\n if (respondingRequestRef.current === requestId) {\n respondingRequestRef.current = null;\n setRespondingRequestId(null);\n }\n }\n },\n [client, mutation, sessionId, state, workspaceId],\n );\n\n const now = Date.now();\n void deadlineVersion;\n return {\n requests: [...(state.data ?? retainedRequests ?? [])]\n .filter((request) => isActionableHumanInputRequest(request, now))\n .sort(\n (left, right) =>\n left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id),\n ),\n loading: state.loading && retainedRequests === null,\n error: state.error,\n refresh: state.refresh,\n respond,\n respondingRequestId,\n mutationError: mutation.mutationError,\n clearMutationError: mutation.clearMutationError,\n };\n}\n","import type { Session, SessionEvent } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { readFreshSessionDetail } from \"../lib/session-detail-read\";\nimport { useEmbeddedSessionRead, type EmbeddedSessionReadClientOverride } from \"../session-context\";\nimport { deniesRetainedView, useRetainedSessionView } from \"./session-view-cache\";\nimport {\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\nexport type UseSessionOptions = EmbeddedSessionReadClientOverride &\n SessionEventFeedOptions & {\n /** Re-fetch on an interval (ms). Off by default — pair with `useSessionEvents` for live status. */\n pollIntervalMs?: number | undefined;\n /** Optional shared causal clock invoked when each network read starts. */\n beginRead?: (() => number) | undefined;\n };\n\nexport type UseSessionResult = {\n session: Session | null;\n loading: boolean;\n error: Error | null;\n /** Monotonic revision of accepted authoritative detail reads. */\n readRevision: number;\n /** Causal generation captured when the accepted network read started. */\n readGeneration: number;\n refresh: () => Promise<void>;\n /** Manually rename the session (PATCH, source='user'). Returns the updated session, or null on failure. */\n updateTitle: (title: string) => Promise<Session | null>;\n /** True while a rename is in flight. */\n updating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/** Event types that change the session title (auto + cross-client renames). */\nexport function isTitleEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return event.type === \"session.title_set\";\n}\n\nfunction isSessionDetailEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return (\n isTitleEvent(event) ||\n event.type.startsWith(\"session.command.\") ||\n event.type.startsWith(\"session.wait.\") ||\n event.type === \"session.status.changed\" ||\n event.type === \"system.update.pending\"\n );\n}\n\n/** Fetch one session (with optional polling), live-patching its title on `session.title_set`. */\nexport function useSession(\n sessionId: string | null | undefined,\n options: UseSessionOptions = {},\n): UseSessionResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSessionRead(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const [override, setOverride] = useState<Session | null>(null);\n const nextReadRevision = useRef(0);\n const nextReadGeneration = useRef(0);\n const beginRead = options.beginRead;\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner();\n const load = useCallback(\n async (signal?: AbortSignal) => {\n if (!sessionId) {\n return null;\n }\n let readGeneration = 0;\n // The live stream's head read joins this read (see session-detail-read).\n const fetched = await readFreshSessionDetail(client, workspaceId, sessionId, {\n signal,\n onRequestStart: () => {\n readGeneration = beginRead?.() ?? ++nextReadGeneration.current;\n },\n });\n // A fresh server read supersedes any optimistic/event-driven override.\n setOverride(null);\n return {\n session: fetched,\n revision: ++nextReadRevision.current,\n readGeneration,\n };\n },\n [beginRead, client, workspaceId, sessionId],\n );\n const { data, loading, error, refresh } = usePolledValue(load, {\n pollIntervalMs: options.pollIntervalMs,\n enabled,\n });\n useEffect(() => {\n if (enabled && workspaceControlEvent) void refresh();\n }, [enabled, refresh, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"session\", refresh);\n }, [enabled, refresh, registerSessionReconciler, sessionId]);\n\n // Until this conversation's first read lands, show what was left when the\n // person last had it open (only when the host retains reads for `client`).\n const retained = useRetainedSessionView(\n client,\n workspaceId,\n sessionId,\n \"detail\",\n data?.session ?? null,\n { enabled, discard: deniesRetainedView(error) },\n );\n const base = data?.session ?? null;\n const readRevision = data?.revision ?? 0;\n const readGeneration = data?.readGeneration ?? 0;\n // The override only ever carries title/titleSource patches; it is reset on\n // every fresh load so it can never go stale against the server snapshot.\n const session = useMemo(\n () =>\n base && override && override.id === base.id\n ? { ...base, title: override.title, titleSource: override.titleSource }\n : (base ?? retained),\n [base, override, retained],\n );\n\n const sharedEvents = options.events;\n const refreshDetail = useCallback(() => void refresh(), [refresh]);\n\n // Live-patch the title on auto (agent) + cross-client (user/agent) renames so\n // the UI reflects the new title without polling or a full re-fetch.\n const onTitleEvent = useCallback(\n (event: SessionEvent) => {\n // Reconciliation emits only the last matching member of a shared batch.\n // A later title must not hide an earlier command activity change.\n if (\n sharedEvents?.some(\n (item) =>\n item.sessionId === sessionId &&\n !isTitleEvent(item) &&\n isSessionDetailEvent(item) &&\n item.sequence > (base?.lastSequence ?? -1),\n )\n ) {\n void refresh();\n } else if (!isTitleEvent(event)) {\n if (!base || event.sequence > base.lastSequence) void refresh();\n return;\n }\n // The fetched session row is the authoritative title projection through\n // lastSequence. Shared feeds may replay that historical tail after the\n // fetch; applying it would undo a row-only migration quarantine. Only an\n // event committed after this snapshot may live-patch the title.\n if (!base || event.sequence <= base.lastSequence) {\n return;\n }\n const payload = (event.payload ?? {}) as { title?: unknown; source?: unknown };\n const title = payload.title;\n if (typeof title !== \"string\") {\n return;\n }\n const source: \"user\" | \"agent\" | null =\n payload.source === \"user\" || payload.source === \"agent\" ? payload.source : null;\n setOverride((current): Session | null => {\n const next = current ?? base;\n return { ...next, title, titleSource: source };\n });\n },\n [base, refresh, sharedEvents, sessionId],\n );\n useSessionEventTrigger(client, workspaceId, sessionId, isSessionDetailEvent, onTitleEvent, {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n // The detail row is authoritative through its lastSequence: only a later\n // event can make it stale, and one that arrives first waits for the read.\n readThrough: base ? base.lastSequence : loading ? \"reading\" : null,\n refresh: refreshDetail,\n });\n\n const updateTitle = useCallback(\n async (title: string): Promise<Session | null> => {\n if (!sessionId) {\n return null;\n }\n const result = await run(() => client.updateSession(workspaceId, sessionId, { title }));\n if (result) {\n setOverride(result);\n }\n return result;\n },\n [client, workspaceId, sessionId, run],\n );\n\n return {\n session,\n loading: loading && retained === null,\n error,\n readRevision,\n readGeneration,\n refresh,\n updateTitle,\n updating: mutating,\n mutationError,\n clearMutationError,\n };\n}\n","import type { GetSessionOptions, Session } from \"@opengeni/sdk\";\n\n/**\n * `useSession` reads a conversation's detail fresh (`getSession` with\n * `fresh: true`), and `useSessionEvents` reads the same detail for the durable\n * head once its first window lands, to join the live stream there. When both\n * open one conversation through one client object, the head read joins the\n * detail read started since the stream began loading (in flight or settled)\n * instead of reading the session a second time.\n *\n * A joined head can only be older than a new read would be; the stream then\n * replays the difference from its cursor, which is always correct. A failed\n * read is never kept.\n */\ntype SessionDetailSource = {\n getSession: (\n workspaceId: string,\n sessionId: string,\n options?: GetSessionOptions,\n ) => Promise<Session>;\n};\ntype DetailRead = { promise: Promise<Session>; ordinal: number };\n\n// Orders reads across clients: a read is joinable when it started after a mark.\nlet lastOrdinal = 0;\n// Per client object, the newest fresh detail read of each conversation.\nconst reads = new WeakMap<object, Map<string, DetailRead>>();\n\nfunction readKey(workspaceId: string, sessionId: string): string {\n return `${workspaceId}\\u0000${sessionId}`;\n}\n\n/** A mark: `joinSessionDetailRead` accepts only reads started after it. */\nexport function sessionDetailReadMark(): number {\n return lastOrdinal;\n}\n\n/** Read the detail fresh, so a head read started later can join it. */\nexport function readFreshSessionDetail(\n client: SessionDetailSource,\n workspaceId: string,\n sessionId: string,\n options: Omit<GetSessionOptions, \"fresh\"> = {},\n): Promise<Session> {\n const promise = client.getSession(workspaceId, sessionId, { ...options, fresh: true });\n const read: DetailRead = { promise, ordinal: ++lastOrdinal };\n let scoped = reads.get(client);\n if (!scoped) {\n scoped = new Map();\n reads.set(client, scoped);\n }\n const key = readKey(workspaceId, sessionId);\n scoped.set(key, read);\n promise.catch(() => {\n if (scoped.get(key) === read) scoped.delete(key);\n });\n return promise;\n}\n\n/** The newest fresh detail read started after `mark`, or null. */\nexport function joinSessionDetailRead(\n client: object,\n workspaceId: string,\n sessionId: string,\n mark: number,\n): Promise<Session> | null {\n const read = reads.get(client)?.get(readKey(workspaceId, sessionId));\n return read && read.ordinal > mark ? read.promise : null;\n}\n","import type { SessionControlResponse, SessionEvent } from \"@opengeni/sdk\";\nimport { useCallback, useLayoutEffect, useRef } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport { useMutationRunner } from \"./internal\";\n\nexport type UseSessionControlOptions = EmbeddedSessionClientOverride;\n\nexport type UseSessionControlResult = {\n pause: (reason?: string) => Promise<SessionControlResponse | null>;\n resume: (reason?: string) => Promise<SessionControlResponse | null>;\n controlling: boolean;\n /** Approve a pending `requires_action` approval. */\n approve: (approvalId: string, message?: string) => Promise<SessionEvent | null>;\n /** Reject a pending `requires_action` approval. */\n reject: (approvalId: string, message?: string) => Promise<SessionEvent | null>;\n /** True while an approval decision is in flight. */\n responding: boolean;\n error: Error | null;\n clearError: () => void;\n};\n\n/**\n * Session pause/resume and approval decisions. Pair with\n * `useSessionEvents` (for `session.requiresAction` payloads carrying the\n * `approvalId`) to render an approval bar.\n */\nexport function useSessionControl(\n sessionId: string | null | undefined,\n options: UseSessionControlOptions = {},\n): UseSessionControlResult {\n const { client, workspaceId } = useEmbeddedSession(options);\n const approvalTargetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}`;\n const pendingApproval = useRef<{\n targetKey: string;\n decisionKey: string;\n clientEventId: string;\n } | null>(null);\n useLayoutEffect(() => {\n if (pendingApproval.current?.targetKey !== approvalTargetKey) {\n pendingApproval.current = null;\n }\n }, [approvalTargetKey]);\n const {\n run: runControl,\n mutating: controlling,\n mutationError: controlError,\n clearMutationError: clearControlError,\n } = useMutationRunner(approvalTargetKey);\n const {\n run: runApproval,\n mutating: responding,\n mutationError: approvalError,\n clearMutationError: clearApprovalError,\n } = useMutationRunner(approvalTargetKey);\n\n const pause = useCallback(\n async (reason?: string): Promise<SessionControlResponse | null> => {\n if (!sessionId) {\n return null;\n }\n return await runControl(() =>\n client.pauseSession(workspaceId, sessionId, reason !== undefined ? { reason } : {}),\n );\n },\n [client, workspaceId, sessionId, runControl],\n );\n\n const resume = useCallback(\n async (reason?: string): Promise<SessionControlResponse | null> => {\n if (!sessionId) return null;\n return await runControl(() =>\n client.resumeSession(workspaceId, sessionId, reason !== undefined ? { reason } : {}),\n );\n },\n [client, workspaceId, sessionId, runControl],\n );\n\n const decide = useCallback(\n async (\n approvalId: string,\n decision: \"approve\" | \"reject\",\n message?: string,\n ): Promise<SessionEvent | null> => {\n if (!sessionId) {\n return null;\n }\n const decisionKey = JSON.stringify([approvalId, decision, message ?? null]);\n if (pendingApproval.current?.decisionKey !== decisionKey) {\n pendingApproval.current = {\n targetKey: approvalTargetKey,\n decisionKey,\n clientEventId: crypto.randomUUID(),\n };\n }\n const clientEventId = pendingApproval.current.clientEventId;\n const accepted = await runApproval(() =>\n client.sendApprovalDecision(workspaceId, sessionId, {\n approvalId,\n decision,\n ...(message !== undefined ? { message } : {}),\n clientEventId,\n }),\n );\n if (\n accepted !== null &&\n pendingApproval.current?.targetKey === approvalTargetKey &&\n pendingApproval.current.clientEventId === clientEventId\n ) {\n pendingApproval.current = null;\n }\n return accepted;\n },\n [approvalTargetKey, client, workspaceId, sessionId, runApproval],\n );\n\n const approve = useCallback(\n async (approvalId: string, message?: string) => await decide(approvalId, \"approve\", message),\n [decide],\n );\n const reject = useCallback(\n async (approvalId: string, message?: string) => await decide(approvalId, \"reject\", message),\n [decide],\n );\n\n const error = approvalError ?? controlError;\n const clearError = useCallback(() => {\n clearControlError();\n clearApprovalError();\n }, [clearControlError, clearApprovalError]);\n\n return {\n pause,\n resume,\n controlling,\n approve,\n reject,\n responding,\n error,\n clearError,\n };\n}\n","import {\n isPresentedSessionToolName,\n isRetryableStreamError,\n isSessionModelResponsePhase,\n isTransientRequestError,\n SESSION_EVENT_COMPAT_EXCLUDED_STEP_TYPES,\n SESSION_EVENT_CONTENT_STEP_TYPES,\n SESSION_EVENT_CONVERSATION_FILTER_VERSION,\n SESSION_EVENT_STEP_TYPES,\n sessionEventStreamCoveredThrough,\n type SessionEvent,\n type SessionEventListOptions,\n type SessionEventPage,\n type SessionEventType,\n type SessionStatus,\n type StreamConnectionState,\n} from \"@opengeni/sdk\";\nimport { startTransition, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport { createOlderHistoryLoadReceipt, type OlderHistoryLoadReceipt } from \"../older-history\";\nimport { buildTimeline, groupTimeline, sessionStatusFromEvents } from \"../timeline/projection\";\nimport type { TimelineItem, TurnStepsItem } from \"../timeline/types\";\nimport type { EmbeddedSessionClientLike } from \"../client\";\nimport { normalizeError } from \"../lib/error-message\";\nimport { joinSessionDetailRead, sessionDetailReadMark } from \"../lib/session-detail-read\";\nimport {\n DEFAULT_TRANSIENT_READ_RETRY,\n transientReadRetryStep,\n usePageLiveActivity,\n} from \"./internal\";\nimport { subscribePageWake } from \"./page-wake\";\nimport { deniesRetainedView, useRetainedSessionView } from \"./session-view-cache\";\nimport { markTurnlessOutputGap } from \"./turnless-output-gaps\";\nimport type { LatestQuestionOptions } from \"./latest-question\";\nimport { useOpenGeniText, type OpenGeniText } from \"../messages/runtime\";\nimport { isToolOutputPreviewEvent, useToolOutputReads } from \"./tool-output-reads\";\n\nexport type SessionEventsConnectionState = StreamConnectionState | \"idle\" | \"ended\" | \"error\";\n\nexport type UseSessionEventsOptions = EmbeddedSessionClientOverride & {\n /** Resume after this sequence (exclusive). Nonzero keeps full replay/resume semantics. */\n after?: number | undefined;\n /** Load a bounded tail by default, or opt back into full replay from `after`. */\n replay?: \"windowed\" | \"full\" | undefined;\n /** Pause the stream without unmounting (e.g. hidden tab). Defaults to true. */\n enabled?: boolean | undefined;\n};\n\nexport type UseSessionEventsResult = {\n /**\n * Loaded events, ordered by sequence, no duplicates. Windowed history holds a\n * session's conversation; a turn's steps (tool calls and outputs, streamed\n * reasoning and command output) are included while live and once a reader\n * opens that turn. Full replay holds every event.\n */\n events: SessionEvent[];\n /** Renderable timeline, including the bounded navigation witness for a distant queued prompt. */\n timeline: TimelineItem[];\n /** Latest session status observed in the event log, if any. */\n sessionStatus: SessionStatus | null;\n /** Sequence of the retained status projection, including events evicted from the window. */\n sessionStatusSequence?: number;\n connectionState: SessionEventsConnectionState;\n /** Highest sequence seen so far (0 before the first event). */\n lastSequence: number;\n /** Exact serialized bytes retained in the current browser event window. */\n windowBytes: number;\n /** Whether older delivered events were evicted from the browser window. */\n windowTruncated: boolean;\n /** True until the initial tail window has been applied (windowed mode). */\n initialLoading: boolean;\n /** A history window (including an empty tail) succeeded for this session/replay\n * identity. Stays true through later stream errors and navigation/reloads.\n * Full replay has no snapshot-completion watermark and does not set this by itself. */\n initialHistoryReady: boolean;\n /** Whether older durable events are available before the current window. */\n hasOlder: boolean;\n /** True while an older window is being fetched. */\n loadingOlder: boolean;\n /** Prepend an older density-bounded window; resolves true when more remain. */\n loadOlder: () => OlderHistoryLoadReceipt;\n /**\n * Durable events exist after the current window (history view jumped away\n * from the live tip, or a forward page is incomplete).\n */\n hasNewer: boolean;\n /** True while a newer history page is being fetched. */\n loadingNewer: boolean;\n /**\n * Append one density-bounded newer page without pulling the whole gap.\n * Resolves true when more newer history remains.\n */\n loadNewer: () => Promise<boolean>;\n /** True while replacing the window with the session start. */\n loadingOldest: boolean;\n /**\n * Jump to the durable session start: one bounded oldest window, no middle.\n * Leaves live streaming until {@link jumpToLatest} (or loadNewer catches up).\n */\n loadOldest: () => Promise<boolean>;\n /** True while reloading the live tip window. */\n loadingLatest: boolean;\n /**\n * Reload the newest bounded tip and resume live streaming. Use for\n * \"Jump to latest\" when the tip is not in memory (history view).\n */\n jumpToLatest: () => Promise<void>;\n /** Resolve the newest eligible durable human question. Pending prompts use the\n * optional queue destination and return null; started prompts load their actual\n * turn context (pass `timeline` to MessageTimeline as `items`). */\n jumpToLatestQuestion: (options?: LatestQuestionOptions) => Promise<number | null>;\n /** Replace history with a bounded window containing this exact durable event. */\n jumpToSequence: (sequence: number, options?: { signal?: AbortSignal }) => Promise<boolean>;\n loadingTarget: boolean;\n error: Error | null;\n};\n\n// Keep every browser history read inside one database batch, including the\n// server's one-row continuation lookahead. A large total session must never\n// turn one lazy page into dozens of sequential database round trips.\nconst SESSION_HISTORY_PAGE_SIZE = 1000;\nconst INITIAL_FETCH_CAP = 1;\nconst OLDER_GROUP_TARGET = 32;\nconst OLDER_FETCH_CAP = 2;\nconst NEWER_GROUP_TARGET = 32;\nconst NEWER_FETCH_CAP = 2;\nconst OLDEST_GROUP_TARGET = 32;\nconst OLDEST_FETCH_CAP = 2;\n// A tail page may land inside one unusually dense turn. Permit exactly one\n// additional bounded page to find its user/session boundary without turning a\n// fresh open into an unbounded history walk.\nconst BOUNDARY_PAGE_CAP = 1;\n// When the reader asks for older or newer history, pages a fallback\n// conversation read keeps nothing of (an older server's tool calls only) do\n// not use up the caps above; at most this many more are read per load. Any\n// load that stops on an empty window stays pageable from where it stopped.\n// The first window keeps the plain caps, so opening a chat stays one read.\nconst FILTERED_PAGE_CAP = 32;\n// Rejoining the live tip (first open of a working turn, a return to a hidden\n// tab or from a sleep, any stream reconnect, catching up from history)\n// replays a tiny raw gap over SSE. A larger gap catches up the conversation\n// only and reads the working turn's latest steps, instead of replaying every\n// step since the last conversation event. Only a gap of more than this many\n// pages of conversation reloads the latest window.\nconst DIRECT_REPLAY_MAX_SEQUENCES = 16;\nconst CATCHUP_MAX_PAGES = 2;\n// Rejoining the tip after a reconnect or a wake is bounded: an attempt that\n// completes no read for REJOIN_STALL_TIMEOUT_MS is abandoned (a slow but\n// progressing catch-up is never cut short), a transient failure retries (with\n// backoff) only this many times in a row, and after that the stream replays\n// exactly from where the view stands rather than staying stuck \"reconnecting\".\nconst STRICT_REJOIN_ATTEMPTS = 5;\nexport const REJOIN_STALL_TIMEOUT_MS = 30_000;\nconst FOREGROUND_REJOIN_RETRY_MS = 500;\nconst FOREGROUND_REJOIN_RETRY_MAX_MS = 8_000;\nconst EMPTY_EVENTS: SessionEvent[] = [];\nconst encoder = new TextEncoder();\n// Durable history remains on the server and is available through bounded\n// navigation. Keep the live browser working set small across multiple tabs;\n// serialized payloads also expand into objects and timeline projections.\nexport const SESSION_EVENT_BROWSER_MAX_BYTES = 16 * 1024 * 1024;\nexport const SESSION_EVENT_BROWSER_MAX_COUNT = 20_000;\nexport const SESSION_EVENT_BROWSER_PENDING_MAX_BYTES = 1024 * 1024;\nexport const SESSION_EVENT_BROWSER_PENDING_MAX_COUNT = 256;\n\nexport type BrowserSessionEventWindow = {\n events: SessionEvent[];\n bytes: number;\n truncated: boolean;\n};\n\nconst EMPTY_EVENT_WINDOW: BrowserSessionEventWindow = {\n events: EMPTY_EVENTS,\n bytes: 2,\n truncated: false,\n};\n\n/**\n * Live-stream a session's event log with replay-by-sequence, reconnect, and\n * batched React updates. Fresh loads default to a bounded tail window; pass\n * `replay: \"full\"` or a nonzero `after` for the previous full replay path.\n */\nexport function useSessionEvents(\n sessionId: string | null | undefined,\n options: UseSessionEventsOptions = {},\n): UseSessionEventsResult {\n const t = useOpenGeniText();\n const { client, workspaceId, reconcileSession } = useEmbeddedSession(options);\n const enabled = options.enabled ?? true;\n const pageLive = usePageLiveActivity();\n const streamEnabled = enabled && pageLive;\n const after = options.after ?? 0;\n const replay = options.replay ?? \"windowed\";\n const fullReplay = replay === \"full\" || after !== 0;\n const streamKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${after}\\u0000${fullReplay ? \"full\" : \"windowed\"}`;\n // Bind callbacks to this read lifetime, including a return to a previous\n // identity. Publish during render so old callbacks are fenced before passive\n // cleanup can advance the navigation generation.\n const navigationIdentityRef = useRef({ client, streamKey, enabled });\n if (\n navigationIdentityRef.current.client !== client ||\n navigationIdentityRef.current.streamKey !== streamKey ||\n navigationIdentityRef.current.enabled !== enabled\n ) {\n navigationIdentityRef.current = { client, streamKey, enabled };\n }\n const navigationIdentity = navigationIdentityRef.current;\n const ownsNavigation = useCallback(\n () => navigationIdentityRef.current === navigationIdentity,\n [navigationIdentity],\n );\n\n const [eventWindow, setEventWindow] = useState<BrowserSessionEventWindow>(EMPTY_EVENT_WINDOW);\n // One navigation witness, not a second history cache. Raw events stay contiguous.\n const [questionEvidence, setQuestionEvidence] = useState<{\n client: EmbeddedSessionClientLike;\n streamKey: string;\n anchor: number;\n events: SessionEvent[];\n } | null>(null);\n const [connectionState, setConnectionState] = useState<SessionEventsConnectionState>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [newerError, setNewerError] = useState<Error | null>(null);\n const [hasOlder, setHasOlder] = useState(false);\n const [hasNewer, setHasNewer] = useState(false);\n const [sessionStatusProjection, setSessionStatusProjection] = useState<SessionStatus | null>(\n null,\n );\n const [initialLoading, setInitialLoading] = useState(true);\n const [initialHistoryReady, setInitialHistoryReady] = useState(false);\n const [loadingOlder, setLoadingOlder] = useState(false);\n const [loadingNewer, setLoadingNewer] = useState(false);\n const [loadingOldest, setLoadingOldest] = useState(false);\n const [loadingLatest, setLoadingLatest] = useState(false);\n const [loadingTarget, setLoadingTarget] = useState(false);\n const loadingTargetRef = useRef(false);\n const [streamEpoch, setStreamEpoch] = useState(0);\n // \"history\" = reading a non-tip window; live SSE must not fill the gap.\n const [viewMode, setViewMode] = useState<\"live\" | \"history\">(\"live\");\n const lastSequenceRef = useRef(after);\n const streamResumeSequenceRef = useRef(after);\n /**\n * The newest row a first window read but kept none of: the live stream\n * resumed above it, so a working turn older history reveals below it has\n * steps up to there that neither the window nor the stream holds.\n */\n const skippedStepsThroughRef = useRef<number | null>(null);\n const oldestSequenceRef = useRef<number | null>(null);\n const newestSequenceRef = useRef<number | null>(null);\n const hasOlderRef = useRef(false);\n const hasNewerRef = useRef(false);\n const loadingOlderRef = useRef(false);\n const loadingNewerRef = useRef(false);\n const loadingOldestRef = useRef(false);\n const loadingLatestRef = useRef(false);\n const viewModeRef = useRef<\"live\" | \"history\">(\"live\");\n const initialWindowLoadedRef = useRef(false);\n // The stream key whose live stream has opened at least once in this mount.\n const openedStreamKeyRef = useRef<string | null>(null);\n const reconcileAfterPageResumeRef = useRef(false);\n const streamAbortRef = useRef<AbortController | null>(null);\n const streamKeyRef = useRef<string | null>(null);\n const generationRef = useRef(0);\n const navigationGenerationRef = useRef(0);\n const eventWindowRef = useRef<BrowserSessionEventWindow>(EMPTY_EVENT_WINDOW);\n const sessionStatusRef = useRef<{\n sequence: number;\n status: SessionStatus | null;\n }>({\n sequence: after,\n status: null,\n });\n // Effects reset state after commit. Tag the state so the first render for a\n // new stream identity cannot expose the previous session's event log.\n const [stateStreamKey, setStateStreamKey] = useState(streamKey);\n\n const historyFilter = fullReplay ? undefined : CONVERSATION_FILTER;\n // Conversation-first history: a turn's steps live here, per turn, apart\n // from the contiguous conversation window (see `isConversationHistoryEvent`).\n const [stepStores, setStepStores] = useState<TurnStepStores>(EMPTY_STEP_STORES);\n const stepStoresRef = useRef<TurnStepStores>(EMPTY_STEP_STORES);\n // Live step rows without a turn (PTY and background command output): a\n // short tail outside the window. The sandbox dock reads their history itself.\n const [turnlessSteps, setTurnlessSteps] = useState<TurnlessSteps>(EMPTY_TURNLESS_STEPS);\n const turnlessStepsRef = useRef<TurnlessSteps>(EMPTY_TURNLESS_STEPS);\n // How many live turnless rows the last committed render had seen, and\n // whether a gap was already marked for rows appended since.\n const renderedTurnlessRef = useRef({ appended: 0, marked: false });\n useEffect(() => {\n renderedTurnlessRef.current = { appended: turnlessSteps.appended, marked: false };\n }, [turnlessSteps]);\n // Through which sequence the live stream delivered every row. A stream that\n // starts past it (the conversation side moved the cursor) skipped terminal\n // output nobody read.\n const liveThroughRef = useRef(0);\n // Retires step reads issued for a previous stream identity.\n const stepGenerationRef = useRef(0);\n // Each step read's id; a store answers only its newest read.\n const stepRequestRef = useRef(0);\n // Turns a reader has open: their steps are never trimmed or evicted.\n const retainedTurnsRef = useRef(new Map<string, number>());\n const turnStepHandlesRef = useRef(new Map<string, Pick<TurnStepsItem, \"load\" | \"retain\">>());\n // Presented tools (images, published files, Skill and learning writes) stay\n // in the conversation window with their results.\n const presentedCallIdsRef = useRef(new Set<string>());\n const presentedScanRef = useRef<readonly SessionEvent[] | null>(null);\n // Turns whose model has not responded yet: their model request rows still\n // draw the startup rail, so live ones stay in the conversation window.\n const startupRef = useRef<StartupTurns>(emptyStartupTurns());\n const [presentedOutputs, setPresentedOutputs] =\n useState<ReadonlyMap<string, SessionEvent>>(EMPTY_PRESENTED_OUTPUTS);\n const presentedRequestedRef = useRef(new Map<string, PresentedRequest>());\n // Failed reads per call: each retries after a growing pause, a few times.\n const presentedFailuresRef = useRef(new Map<string, number>());\n // Bumped when a presented-result read settles, so the next pass runs.\n const [presentedPass, setPresentedPass] = useState(0);\n // A return to the live tip from history: catch up without replaying steps.\n const rejoinPendingRef = useRef(false);\n // Consecutive transient failures to open this stream (a deploy or network\n // blip): they restart it quietly before an error is shown.\n const streamTransientStreakRef = useRef<{\n since: number;\n attempts: number;\n surfaced: boolean;\n } | null>(null);\n\n const commitStepStores = useCallback((next: TurnStepStores) => {\n stepStoresRef.current = next;\n setStepStores(next);\n }, []);\n\n /**\n * Keep the steps that are still whole for a new `window`: only turns in it,\n * and, when live continuity broke, only turns already settled in the window\n * before the break (`sealedBy`). A turn still working then may have written\n * steps this browser never saw; it reloads them when opened. `rereading` is\n * a working turn whose tail is read again right after: its steps stay on\n * screen until that read replaces them. Presented results of turns that\n * left the window go too.\n */\n const pruneStepStores = useCallback(\n (\n window: readonly SessionEvent[],\n sealedBy: readonly SessionEvent[] | null,\n rereading: string | null = null,\n ) => {\n const present = windowTurns(window);\n const settled = sealedBy ? settledTurns(sealedBy) : null;\n const next = new Map<string, TurnStepStore>();\n for (const [turnId, store] of stepStoresRef.current) {\n // A dropped store also retires its read in flight (see requestId).\n if (present.has(turnId) && (!settled || settled.has(turnId) || turnId === rereading)) {\n next.set(turnId, store);\n }\n }\n if (next.size !== stepStoresRef.current.size) commitStepStores(next);\n // After a break, results still missing are read again; otherwise only\n // reads for turns that left the window are forgotten (reads in flight\n // for the rest carry on).\n if (sealedBy) {\n presentedRequestedRef.current = new Map();\n } else {\n for (const [callId, request] of presentedRequestedRef.current) {\n if (request.turnId && !present.has(request.turnId)) {\n presentedRequestedRef.current.delete(callId);\n }\n }\n }\n setPresentedOutputs((current) => {\n let kept: Map<string, SessionEvent> | null = null;\n for (const [callId, output] of current) {\n if (output.turnId && present.has(output.turnId)) continue;\n kept ??= new Map(current);\n kept.delete(callId);\n }\n return kept ?? current;\n });\n },\n [commitStepStores],\n );\n\n const presentedCallIds = useCallback((event: SessionEvent): ReadonlySet<string> => {\n const ids = presentedCallIdsRef.current;\n if (event.type === \"agent.toolCall.created\") {\n notePresentedCalls([event], ids);\n } else if (event.type === \"agent.toolCall.output\") {\n const payload = event.payload as Record<string, unknown> | null;\n const windowEvents = eventWindowRef.current.events;\n if (\n typeof payload?.id === \"string\" &&\n !ids.has(payload.id) &&\n presentedScanRef.current !== windowEvents\n ) {\n // Presented calls loaded with history: scan once per window.\n presentedScanRef.current = windowEvents;\n notePresentedCalls(windowEvents, ids);\n }\n }\n return ids;\n }, []);\n\n /** The turns whose live model request rows are still conversation. */\n const startupTurns = useCallback((): StartupTurns => {\n const windowEvents = eventWindowRef.current.events;\n if (startupRef.current.window !== windowEvents) {\n // History replaced or trimmed the window: read it again once.\n const state = emptyStartupTurns();\n noteStartupTurns(windowEvents, state);\n state.window = windowEvents;\n startupRef.current = state;\n }\n return startupRef.current;\n }, []);\n\n const appendLiveSteps = useCallback(\n (steps: readonly SessionEvent[]) => {\n if (steps.some((event) => !event.turnId)) {\n const incoming = steps.filter((event) => !event.turnId);\n const turnless = appendTurnlessSteps(turnlessStepsRef.current, incoming);\n // A burst larger than the tail dropped rows no render showed: the\n // terminal re-reads them.\n const rendered = renderedTurnlessRef.current;\n if (!rendered.marked && turnless.appended - rendered.appended > turnless.events.length) {\n rendered.marked = true;\n if (sessionId) markTurnlessOutputGap(workspaceId, sessionId);\n }\n turnlessStepsRef.current = turnless;\n setTurnlessSteps(turnless);\n }\n const windowEvents = withTurnlessSteps(\n eventWindowRef.current.events,\n turnlessStepsRef.current,\n );\n const next = new Map(stepStoresRef.current);\n const now = Date.now();\n for (const [turnId, events] of groupByTurn(steps)) {\n const existing = next.get(turnId);\n const store: TurnStepStore = existing ?? {\n events: [],\n bytes: 2,\n // Earlier steps exist when the window skips sequences between the\n // turn's start and this first live step.\n hasOlder: turnHasHiddenSequences(windowEvents, turnId, events[0]!.sequence),\n cursor: null,\n floor: null,\n pinned: null,\n loading: false,\n error: false,\n touched: now,\n requestId: 0,\n };\n let updated: TurnStepStore = { ...store, ...appendStepEvents(store, events), touched: now };\n if (!retainedTurnsRef.current.get(turnId)) updated = trimLiveStepTail(updated);\n next.set(turnId, updated);\n }\n commitStepStores(boundStepStores(next, retainedTurnsRef.current));\n },\n [commitStepStores, workspaceId, sessionId],\n );\n\n /**\n * Read a turn's newest unloaded steps: the latest page when none are\n * loaded, else the page before the oldest loaded step. `before` pins the\n * read's upper bound (the durable head when rejoining a working turn) and\n * replaces whatever was loaded or loading.\n */\n const loadTurnSteps = useCallback(\n (turnId: string, before?: number) => {\n if (!ownsNavigation() || !sessionId || fullReplay) return;\n const current = stepStoresRef.current.get(turnId);\n // Retrying a failed pinned read reads the same tail again: continuing\n // below the loaded steps would leave the gap above them unread.\n const pinnedUpper =\n before ?? (current?.error && current.pinned !== null ? current.pinned : undefined);\n const pinned = pinnedUpper !== undefined;\n if (!pinned && current?.loading) return;\n const bounds = conversationTurnBounds(eventWindowRef.current.events).get(turnId);\n if (!bounds) return;\n if (!pinned && current && !stepStoreHasOlder(current, bounds) && !current.error) return;\n const upper =\n pinnedUpper ??\n current?.cursor ??\n current?.events[0]?.sequence ??\n (bounds.terminal !== null ? bounds.terminal + 1 : Number.MAX_SAFE_INTEGER);\n // Without the turn's start in the window (it begins mid-turn), the read\n // reaches back to the previous turn and stops at another turn's steps.\n const exactStart = bounds.started !== null;\n const lower = turnStepLowerBound(bounds);\n const generation = stepGenerationRef.current;\n const requestId = ++stepRequestRef.current;\n const isCurrent = () =>\n ownsNavigation() &&\n generation === stepGenerationRef.current &&\n stepStoresRef.current.get(turnId)?.requestId === requestId;\n // A pinned read (rejoining the tip) keeps the loaded steps on screen\n // while it runs, then replaces them (see below).\n const base: TurnStepStore = current ?? {\n events: [],\n bytes: 2,\n hasOlder: true,\n cursor: null,\n floor: null,\n pinned: null,\n loading: false,\n error: false,\n touched: 0,\n requestId,\n };\n commitStepStores(\n new Map(stepStoresRef.current).set(turnId, {\n ...base,\n pinned: pinned ? upper : null,\n loading: true,\n error: false,\n touched: Date.now(),\n requestId,\n }),\n );\n void readEventPage(client, workspaceId, sessionId, {\n // Bookkeeping too, whichever read built this window: rows it already\n // holds (a fallback read keeps them) merge once by id.\n includeTypes: [...TURN_STEP_READ_TYPES],\n after: Math.max(0, lower),\n before: upper,\n direction: \"before\",\n limit: SESSION_TURN_STEP_PAGE_SIZE,\n compact: true,\n payloadMode: \"full\",\n // Large tool outputs arrive as bounded previews; a row reads its\n // exact output when the reader needs it (see useToolOutputReads).\n toolOutputs: \"preview\",\n }).then(\n (page) => {\n if (!isCurrent()) return;\n const own = page.events.filter((event) => event.turnId === turnId);\n const latest = stepStoresRef.current.get(turnId)!;\n // A pinned page replaces what was loaded (merging a newest page into\n // older loaded steps could hide the steps between them); live steps\n // that arrived during the read stay.\n const merged = pinned\n ? appendStepEvents(\n { events: [], bytes: 2 },\n [...own, ...latest.events.filter((event) => event.sequence >= upper)].sort(\n (left, right) => left.sequence - right.sequence,\n ),\n )\n : appendStepEvents(latest, own);\n const oldestOwn = merged.events[0]?.sequence ?? upper;\n // Turnless rows (queue changes, PTY output) say nothing about where\n // this turn starts.\n const passedStart =\n !exactStart &&\n page.events.some(\n (event) => !!event.turnId && event.turnId !== turnId && event.sequence < oldestOwn,\n );\n const moreBelow = !passedStart && (page.hasMore ?? page.events.length > 0);\n // Reaching the bottom of a guessed range (no start in the window) is\n // not final: remember where the read stopped.\n const reachedFloor = !moreBelow && !passedStart && !exactStart;\n const next = new Map(stepStoresRef.current).set(turnId, {\n ...merged,\n // A page read without a continuation fact (a client without\n // listEventPage) offers one more page until a read comes back empty.\n hasOlder: moreBelow,\n // The next page continues below this page's oldest row, even when\n // the page held only other turns' rows, or below the floor.\n cursor: reachedFloor\n ? lower + 1\n : page.events.reduce((oldest, event) => Math.min(oldest, event.sequence), upper),\n floor: reachedFloor ? lower : null,\n pinned: null,\n loading: false,\n error: false,\n touched: Date.now(),\n requestId,\n });\n commitStepStores(boundStepStores(next, retainedTurnsRef.current));\n },\n () => {\n if (!isCurrent()) return;\n const latest = stepStoresRef.current.get(turnId)!;\n commitStepStores(\n new Map(stepStoresRef.current).set(turnId, { ...latest, loading: false, error: true }),\n );\n },\n );\n },\n [client, workspaceId, sessionId, fullReplay, ownsNavigation, commitStepStores],\n );\n const loadTurnStepsRef = useRef(loadTurnSteps);\n useEffect(() => {\n loadTurnStepsRef.current = loadTurnSteps;\n }, [loadTurnSteps]);\n\n /** Stable per-turn handles, so an open turn's loader effects run once. */\n const turnStepHandle = useCallback((turnId: string) => {\n let handle = turnStepHandlesRef.current.get(turnId);\n if (!handle) {\n const retained = retainedTurnsRef.current;\n handle = {\n load: () => loadTurnStepsRef.current(turnId),\n retain: () => {\n retained.set(turnId, (retained.get(turnId) ?? 0) + 1);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const count = (retained.get(turnId) ?? 1) - 1;\n if (count > 0) retained.set(turnId, count);\n else retained.delete(turnId);\n };\n },\n };\n turnStepHandlesRef.current.set(turnId, handle);\n }\n return handle;\n }, []);\n\n // Navigation belongs to the session/client lifetime, not the transport: an\n // SSE reconnect must never cancel an in-flight history page.\n useEffect(() => {\n navigationGenerationRef.current += 1;\n setNewerError(null);\n loadingOlderRef.current = false;\n loadingNewerRef.current = false;\n loadingOldestRef.current = false;\n loadingTargetRef.current = false;\n setQuestionEvidence(null);\n setLoadingTarget(false);\n setLoadingOlder(false);\n setLoadingNewer(false);\n setLoadingOldest(false);\n return () => {\n navigationGenerationRef.current += 1;\n };\n }, [client, workspaceId, sessionId, after, enabled, fullReplay]);\n\n useEffect(() => {\n // Reset the accumulated log only when the stream identity changes —\n // pausing via `enabled: false` keeps the timeline visible.\n if (streamKeyRef.current !== streamKey) {\n streamKeyRef.current = streamKey;\n setStateStreamKey(streamKey);\n eventWindowRef.current = EMPTY_EVENT_WINDOW;\n setEventWindow(EMPTY_EVENT_WINDOW);\n setError(null);\n setHasOlder(false);\n setHasNewer(false);\n sessionStatusRef.current = { sequence: after, status: null };\n setSessionStatusProjection(null);\n setLoadingOlder(false);\n setLoadingNewer(false);\n setLoadingOldest(false);\n setLoadingLatest(false);\n setInitialLoading(true);\n setInitialHistoryReady(false);\n lastSequenceRef.current = after;\n streamResumeSequenceRef.current = after;\n liveThroughRef.current = after;\n skippedStepsThroughRef.current = null;\n oldestSequenceRef.current = null;\n newestSequenceRef.current = null;\n hasOlderRef.current = false;\n hasNewerRef.current = false;\n loadingOlderRef.current = false;\n loadingNewerRef.current = false;\n loadingOldestRef.current = false;\n loadingLatestRef.current = false;\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n initialWindowLoadedRef.current = false;\n reconcileAfterPageResumeRef.current = false;\n rejoinPendingRef.current = false;\n streamTransientStreakRef.current = null;\n stepGenerationRef.current += 1;\n stepStoresRef.current = EMPTY_STEP_STORES;\n setStepStores(EMPTY_STEP_STORES);\n turnlessStepsRef.current = EMPTY_TURNLESS_STEPS;\n setTurnlessSteps(EMPTY_TURNLESS_STEPS);\n turnStepHandlesRef.current = new Map();\n presentedCallIdsRef.current = new Set();\n presentedScanRef.current = null;\n startupRef.current = emptyStartupTurns();\n presentedRequestedRef.current = new Map();\n presentedFailuresRef.current = new Map();\n setPresentedOutputs(EMPTY_PRESENTED_OUTPUTS);\n }\n // AbortController is advisory: custom SDK clients and async iterators may\n // ignore it and resolve/yield after cleanup. Fence every effect instance so\n // only the newest dependency generation can mutate refs or React state.\n const generation = generationRef.current + 1;\n generationRef.current = generation;\n if (!sessionId || !streamEnabled) {\n // A suspended stream starts a fresh transient streak when it resumes: a\n // failure right after a wake must not count the hidden time.\n streamTransientStreakRef.current = null;\n // A page that stayed hidden beyond the live-activity grace deliberately\n // closed its SSE connection. Replaying from the old cursor on return can\n // drip a large background backlog through React in many fast batches and\n // leave the pinned camera catching up long after the user is foregrounded.\n // Remember that suspension so the next live effect replaces the browser\n // window with one compact durable tail instead.\n if (\n sessionId &&\n enabled &&\n !pageLive &&\n !fullReplay &&\n viewModeRef.current === \"live\" &&\n initialWindowLoadedRef.current\n ) {\n reconcileAfterPageResumeRef.current = true;\n }\n setConnectionState(\"idle\");\n return;\n }\n // History view owns a non-tip window; do not open SSE (it would replay the\n // entire gap into the browser). jumpToLatest / catching loadNewer resume live.\n if (viewMode === \"history\") {\n reconcileAfterPageResumeRef.current = false;\n setConnectionState(\"idle\");\n setInitialLoading(false);\n return;\n }\n const reconcileForegroundResume = reconcileAfterPageResumeRef.current && !fullReplay;\n reconcileAfterPageResumeRef.current = false;\n const controller = new AbortController();\n // A head read joins a fresh detail read (useSession's) started from here on.\n const detailReadMark = sessionDetailReadMark();\n const isCurrent = () =>\n generationRef.current === generation &&\n !controller.signal.aborted &&\n navigationIdentityRef.current.client === client &&\n navigationIdentityRef.current.streamKey === streamKey &&\n navigationIdentityRef.current.enabled === enabled;\n streamAbortRef.current = controller;\n // A quiet restart or reconciliation retry scheduled by this effect instance.\n let transientRetryTimer: ReturnType<typeof setTimeout> | null = null;\n const scheduleTransientRetry = (delayMs: number, retry: () => void) => {\n if (transientRetryTimer !== null) clearTimeout(transientRetryTimer);\n transientRetryTimer = setTimeout(() => {\n transientRetryTimer = null;\n if (isCurrent()) retry();\n }, delayMs);\n };\n // Batch yielded events into one React update per flush window so a long\n // replay (thousands of events) does not render per event. Project every\n // event before retaining it here and synchronously flush at independent\n // count+byte high-water marks: a synchronously yielding async iterator can\n // otherwise starve the 16 ms timer and grow this pre-React buffer without\n // bound even though the final browser window is bounded.\n let pending: SessionEvent[] = [];\n let pendingBytes = 2; // []\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n const flush = () => {\n // A synchronous count/byte high-water flush can run before the scheduled\n // callback gets a macrotask. Cancel that callback before clearing its\n // handle so a long synchronously yielding replay retains at most one\n // timer rather than one stale callback per flushed batch.\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n if (!isCurrent()) {\n pending = [];\n pendingBytes = 2;\n return;\n }\n if (pending.length === 0) {\n return;\n }\n const batch = pending;\n pending = [];\n pendingBytes = 2;\n // The resume cursor only advances with delivered batches: events still\n // sitting in `pending` when the stream is torn down are re-fetched on\n // the next connect instead of being skipped.\n const lastInBatch = batch[batch.length - 1];\n if (lastInBatch) {\n const batchResumeSequence = Math.max(...batch.map(eventResumeSequence));\n lastSequenceRef.current = Math.max(lastSequenceRef.current, batchResumeSequence);\n streamResumeSequenceRef.current = Math.max(\n streamResumeSequenceRef.current,\n batchResumeSequence,\n );\n liveThroughRef.current = Math.max(liveThroughRef.current, batchResumeSequence);\n }\n const status = observeSessionStatus(batch, sessionStatusRef);\n if (status !== undefined) {\n setSessionStatusProjection(status);\n }\n // Live steps go to their turn's step store; the window stays the\n // conversation so it is never crowded out by one long turn's steps.\n let conversation: SessionEvent[] = batch;\n const steps: SessionEvent[] = [];\n if (!fullReplay) {\n const windowNewest = newestSequenceRef.current ?? 0;\n const startup = startupTurns();\n conversation = [];\n for (const event of batch) {\n if (!isConversationHistoryEvent(event, presentedCallIds(event), startup.open)) {\n steps.push(event);\n }\n // Rejoining at a durable head never re-applies a windowed event.\n else if (event.sequence > windowNewest) conversation.push(event);\n noteStartupTurns([event], startup);\n }\n }\n if (conversation.length > 0) {\n const current = eventWindowRef.current;\n const next = appendBrowserSessionEventWindow(current, conversation);\n const retained = {\n ...next,\n truncated: current.truncated || next.truncated,\n };\n eventWindowRef.current = retained;\n setEventWindow(retained);\n // This batch is already noted: no rescan for its own append.\n if (!fullReplay) startupRef.current.window = retained.events;\n oldestSequenceRef.current = retained.events[0]?.sequence ?? null;\n newestSequenceRef.current = maxResumeSequenceOrNull(retained.events);\n if (retained.truncated) {\n hasOlderRef.current = true;\n setHasOlder(true);\n }\n }\n // After the batch's conversation, so a turn started in this batch is\n // known to the window when its first steps arrive.\n if (steps.length > 0) appendLiveSteps(steps);\n };\n const scheduleFlush = () => {\n if (!isCurrent()) return;\n flushTimer ??= setTimeout(flush, 16);\n };\n const installCatchup = (events: SessionEvent[], head: number) => {\n const current = eventWindowRef.current;\n const windowNewest = newestSequenceRef.current ?? 0;\n const fresh = events.filter((event) => event.sequence > windowNewest);\n const status = observeSessionStatus(fresh, sessionStatusRef);\n const next = appendBrowserSessionEventWindow(current, fresh);\n const retained = { ...next, truncated: current.truncated || next.truncated };\n eventWindowRef.current = retained;\n // A window that still kept nothing keeps its raw cursors.\n oldestSequenceRef.current = retained.events[0]?.sequence ?? oldestSequenceRef.current;\n newestSequenceRef.current =\n maxResumeSequenceOrNull(retained.events) ?? newestSequenceRef.current;\n lastSequenceRef.current = Math.max(lastSequenceRef.current, head);\n streamResumeSequenceRef.current = Math.max(streamResumeSequenceRef.current, head);\n // Steps skipped below an empty first window now reach the catch-up head.\n if (skippedStepsThroughRef.current !== null) {\n skippedStepsThroughRef.current = Math.max(skippedStepsThroughRef.current, head);\n }\n if (status !== undefined) setSessionStatusProjection(status);\n if (fresh.length > 0) setEventWindow(retained);\n if (retained.truncated) {\n hasOlderRef.current = true;\n setHasOlder(true);\n }\n };\n /**\n * Join the live tip without replaying the steps written since the\n * window's newest conversation event. Small gaps replay over SSE; larger\n * ones catch up the conversation and read the working turn's latest\n * steps. Resolves \"reload\" when the missed conversation is too long to\n * append (the caller then loads the latest window).\n */\n // The durable head: the conversation's fresh detail read when one started\n // since `mark` (the session view's own), else a new one.\n const effectScope: RejoinScope = { signal: controller.signal, isCurrent };\n const readSessionHead = async (mark: number, scope: RejoinScope) => {\n const joined = joinSessionDetailRead(client, workspaceId, sessionId, mark);\n if (joined) {\n try {\n return await joined;\n } catch (cause) {\n if (scope.signal.aborted) throw cause;\n }\n }\n return await client.getSession(workspaceId, sessionId, {\n fresh: true,\n signal: scope.signal,\n });\n };\n // `strict` (a stream reconnect) fails on a transient read failure, so the\n // stream backs off and retries the whole check instead of replaying a\n // backlog it could not size; any other failed read replays the gap.\n const rejoinLive = async (\n force: boolean,\n {\n strict = false,\n mark = detailReadMark,\n scope = effectScope,\n }: { strict?: boolean; mark?: number; scope?: RejoinScope } = {},\n ): Promise<RejoinOutcome> => {\n const activeTurn = activeConversationTurn(eventWindowRef.current.events);\n if (!force && !activeTurn) return \"joined\";\n const cursor = streamResumeSequenceRef.current;\n let head: number;\n let sessionActiveTurn: string | null = null;\n try {\n const session = await readSessionHead(mark, scope);\n scope.progress?.();\n head = session.lastSequence;\n sessionActiveTurn = session.activeTurnId;\n } catch (cause) {\n if (!scope.isCurrent() || (strict && isRetryableStreamError(cause))) throw cause;\n // An optimization read: replay from the exact cursor instead.\n return \"joined\";\n }\n if (!scope.isCurrent()) throw abortError();\n // A head the client does not report is unknown: replay from the cursor.\n if (!Number.isSafeInteger(head) || head - cursor <= DIRECT_REPLAY_MAX_SEQUENCES) {\n return \"joined\";\n }\n let catchup: SessionEvent[] | null;\n try {\n catchup = await loadConversationCatchup(\n client,\n workspaceId,\n sessionId,\n cursor,\n head,\n scope,\n );\n } catch (cause) {\n if (!scope.isCurrent() || (strict && isRetryableStreamError(cause))) throw cause;\n return \"joined\";\n }\n if (!scope.isCurrent()) throw abortError();\n if (catchup === null) return \"reload\";\n // Continuity broke: steps of turns still working before the catch-up\n // may be missing, so those stores go (the working one is re-read).\n const previous = eventWindowRef.current.events;\n installCatchup(catchup, head);\n const working = sessionActiveTurn ?? activeConversationTurn(eventWindowRef.current.events);\n pruneStepStores(eventWindowRef.current.events, previous, working);\n if (working) loadTurnStepsRef.current(working, head + 1);\n // A working turn the window now shows had its steps read just now; one\n // still below the window is read once older history reveals it.\n if (working && conversationTurnBounds(eventWindowRef.current.events).has(working)) {\n skippedStepsThroughRef.current = null;\n }\n return \"joined\";\n };\n\n // Replace the browser window with the newest conversation window. The\n // previous window stays on screen until the replacement is installed.\n const loadLatestWindow = async (scope: RejoinScope = effectScope): Promise<boolean> => {\n // First paint is ONE compact fetch of the conversation — the newest\n // window, revealed at the bottom in a few hundred ms. Deeper history\n // loads only when the reader scrolls up (the sentinel drives\n // loadOlder); a turn's steps load when the reader opens it.\n const window = await loadEventWindow(t, client, workspaceId, sessionId, {\n before: Number.MAX_SAFE_INTEGER,\n pageSize: SESSION_HISTORY_PAGE_SIZE,\n targetGroups: Number.POSITIVE_INFINITY,\n maxFetches: INITIAL_FETCH_CAP,\n boundaryPageCap: BOUNDARY_PAGE_CAP,\n signal: scope.signal,\n ...(scope.progress ? { progress: scope.progress } : {}),\n filter: CONVERSATION_FILTER,\n });\n if (!scope.isCurrent()) {\n return false;\n }\n const status = observeSessionStatus(window.events, sessionStatusRef);\n const retained = boundBrowserSessionEventWindow(window.events);\n // A replacement tail retires requests against the discarded window.\n // Ordinary SSE reconnects preserve navigation, but splicing an old\n // page into this new tail could leave an inaccessible history gap.\n navigationGenerationRef.current += 1;\n loadingOlderRef.current = false;\n loadingNewerRef.current = false;\n loadingOldestRef.current = false;\n setLoadingOlder(false);\n setLoadingNewer(false);\n setLoadingOldest(false);\n const previous = eventWindowRef.current.events;\n eventWindowRef.current = retained;\n pruneStepStores(retained.events, previous);\n oldestSequenceRef.current =\n retained.events[0]?.sequence ?? window.oldestSequence ?? window.scanCursor;\n newestSequenceRef.current = maxResumeSequenceOrNull(retained.events) ?? window.newestSequence;\n hasOlderRef.current = window.hasOlder || retained.truncated;\n hasNewerRef.current = false;\n lastSequenceRef.current = Math.max(lastSequenceRef.current, window.newestSequence);\n streamResumeSequenceRef.current = window.newestSequence;\n skippedStepsThroughRef.current =\n retained.events.length === 0 && window.newestSequence > 0 ? window.newestSequence : null;\n initialWindowLoadedRef.current = true;\n streamTransientStreakRef.current = null;\n setInitialHistoryReady(true);\n setError(null);\n if (status !== undefined) {\n setSessionStatusProjection(status);\n }\n setEventWindow(retained);\n setHasOlder(window.hasOlder || retained.truncated);\n setHasNewer(false);\n setInitialLoading(false);\n return true;\n };\n\n // The stream starts past what it last delivered: a window load,\n // catch-up, page or jump moved the cursor with conversation reads, which\n // carry no terminal output, so the sandbox terminal reads it again.\n const noteStreamResume = () => {\n if (!fullReplay && streamResumeSequenceRef.current > liveThroughRef.current) {\n markTurnlessOutputGap(workspaceId, sessionId);\n }\n liveThroughRef.current = Math.max(liveThroughRef.current, streamResumeSequenceRef.current);\n };\n\n // Reconciliation after an open re-reads the API contract and projections.\n // A transient failure (a reconnect during an API rollout often lands on a\n // pod that is still starting) retries quietly; the error is shown only\n // when it is definitive or outlasts the quiet window.\n const reconcileAfterOpen = (\n initialOpen: boolean,\n streak: { since: number; attempts: number; surfaced: boolean } | null = null,\n ) => {\n void Promise.resolve()\n .then(() => reconcileSession(sessionId, { initialOpen }))\n .catch((cause) => {\n if (!isCurrent()) return;\n if (isTransientRequestError(cause)) {\n const now = Date.now();\n const current = streak ?? { since: now, attempts: 0, surfaced: false };\n const step = transientReadRetryStep(current, now, DEFAULT_TRANSIENT_READ_RETRY);\n if (step.quiet) {\n scheduleTransientRetry(step.delayMs, () => reconcileAfterOpen(initialOpen, current));\n return;\n }\n }\n setError(normalizeError(cause));\n });\n };\n\n // One bounded rejoin attempt: it is abandoned once no read completes for\n // REJOIN_STALL_TIMEOUT_MS, and a late result is fenced out of the view\n // (reads without a signal can only be outwaited). A `strict` attempt\n // that failed transiently or stalled resolves the cause so the caller\n // retries; a lenient one that stalled resolves \"joined\", which replays\n // exactly from where the view stands. Read failures are translated where\n // they happen, so anything else is a bug applying the result: it throws\n // rather than passing for a rejoin.\n const boundedRejoin = async (\n strict: boolean,\n join: (scope: RejoinScope) => Promise<RejoinOutcome>,\n ): Promise<RejoinOutcome | { retry: unknown }> => {\n if (!isCurrent()) throw abortError();\n const attempt = new AbortController();\n let timedOut = false;\n const abortAttempt = () => attempt.abort();\n controller.signal.addEventListener(\"abort\", abortAttempt, { once: true });\n const stalled = () => {\n timedOut = true;\n attempt.abort();\n };\n let timer = setTimeout(stalled, REJOIN_STALL_TIMEOUT_MS);\n let stopWaiting: (() => void) | undefined;\n const stopped = new Promise<never>((_resolve, reject) => {\n stopWaiting = () => reject(abortError());\n attempt.signal.addEventListener(\"abort\", stopWaiting, { once: true });\n });\n const scope: RejoinScope = {\n signal: attempt.signal,\n isCurrent: () => isCurrent() && !attempt.signal.aborted,\n progress: () => {\n if (attempt.signal.aborted) return;\n clearTimeout(timer);\n timer = setTimeout(stalled, REJOIN_STALL_TIMEOUT_MS);\n },\n };\n try {\n return await Promise.race([join(scope), stopped]);\n } catch (cause) {\n if (!isCurrent()) throw cause;\n if (timedOut) {\n return strict\n ? {\n retry: new TypeError(\n `rejoining the live session stalled for ${REJOIN_STALL_TIMEOUT_MS}ms`,\n ),\n }\n : \"joined\";\n }\n if (strict && isRetryableStreamError(cause)) return { retry: cause };\n throw cause;\n } finally {\n clearTimeout(timer);\n controller.signal.removeEventListener(\"abort\", abortAttempt);\n if (stopWaiting) attempt.signal.removeEventListener(\"abort\", stopWaiting);\n }\n };\n // A bounded rejoin whose failure replays exactly (the first open after\n // a window load, or a return from history: their gaps are short).\n const leniently = async (\n join: (scope: RejoinScope) => Promise<RejoinOutcome>,\n ): Promise<RejoinOutcome> => {\n const result = await boundedRejoin(false, join);\n return typeof result === \"string\" ? result : \"joined\";\n };\n\n // Every reconnect after the stream first opened (a dropped connection, a\n // heartbeat timeout, a sleep) joins the tip like a hidden-tab return: a\n // short gap replays over SSE, a long one is caught up or reloaded instead\n // of being poured through the live stream. A transient failure makes the\n // SDK back off and call this again, at most STRICT_REJOIN_ATTEMPTS times\n // in a row (until a connection opens); after that the reconnect replays\n // exactly rather than staying stuck.\n let strictFailures = 0;\n const beforeReconnect = async (cursor: number): Promise<number> => {\n // Deliver what the broken connection already yielded first.\n flush();\n if (!isCurrent()) throw abortError();\n const strict = strictFailures < STRICT_REJOIN_ATTEMPTS;\n const mark = sessionDetailReadMark();\n let result: RejoinOutcome | { retry: unknown };\n try {\n result = await boundedRejoin(strict, async (scope) => {\n if ((await rejoinLive(true, { strict, mark, scope })) === \"joined\") return \"joined\";\n let loaded: boolean;\n try {\n loaded = await loadLatestWindow(scope);\n } catch (cause) {\n if (!scope.isCurrent() || (strict && isRetryableStreamError(cause))) throw cause;\n // A window that cannot be read: replay exactly instead.\n return \"joined\";\n }\n if (!loaded) throw abortError();\n // The fresh window's own gap is short: join its head the same way.\n if ((await rejoinLive(true, { strict, mark, scope })) === \"reload\" && strict) {\n throw new TypeError(\"the session outran a fresh window while rejoining it\");\n }\n return \"joined\";\n });\n } catch (cause) {\n if (!isCurrent()) throw abortError();\n // Not a read failure: end the stream visibly instead of letting the\n // SDK retry it forever.\n if (!isRetryableStreamError(cause)) throw cause;\n throw new Error(\n `rejoining the live session failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n );\n }\n if (!isCurrent()) throw abortError();\n if (typeof result === \"object\") {\n strictFailures += 1;\n throw result.retry;\n }\n noteStreamResume();\n return Math.max(cursor, streamResumeSequenceRef.current);\n };\n\n void (async () => {\n try {\n if (reconcileForegroundResume) {\n setConnectionState(\"connecting\");\n // A short gap replays over SSE into the loaded steps; a longer one\n // drops the steps of turns that were working and re-reads the tail.\n // A transient failure (the network often returns just after a wake)\n // retries with backoff instead of replaying the backlog it could\n // not size; only after that does the stream replay exactly.\n let outcome: RejoinOutcome;\n for (let attempt = 0; ; attempt += 1) {\n const strict = attempt < STRICT_REJOIN_ATTEMPTS;\n const result = await boundedRejoin(strict, (scope) =>\n rejoinLive(true, { strict, scope }),\n );\n if (typeof result === \"string\") {\n outcome = result;\n break;\n }\n await abortableDelay(\n Math.min(FOREGROUND_REJOIN_RETRY_MS * 2 ** attempt, FOREGROUND_REJOIN_RETRY_MAX_MS),\n controller.signal,\n );\n }\n if (outcome === \"reload\") {\n // Keep the last known window visible until the bounded latest\n // replacement is ready, then install that replacement below.\n initialWindowLoadedRef.current = false;\n setError(null);\n }\n } else if (!fullReplay && initialWindowLoadedRef.current && rejoinPendingRef.current) {\n rejoinPendingRef.current = false;\n if ((await leniently((scope) => rejoinLive(false, { scope }))) === \"reload\") {\n initialWindowLoadedRef.current = false;\n }\n }\n rejoinPendingRef.current = false;\n // A second pass only when the catch-up after the first window was too\n // long to append; the second window is fresh, so its gap is short.\n const windowPasses = fullReplay ? 0 : 2;\n for (\n let attempt = 0;\n attempt < windowPasses && !initialWindowLoadedRef.current;\n attempt += 1\n ) {\n setConnectionState(\"connecting\");\n if (!(await loadLatestWindow())) {\n return;\n }\n // Join at the durable head rather than replaying every row since the\n // window's last conversation event: a working turn's steps (its\n // latest are read), or terminal output written after the last turn,\n // which only the sandbox dock reads.\n if (\n (await leniently((scope) => rejoinLive(true, { scope }))) === \"reload\" &&\n attempt === 0\n ) {\n initialWindowLoadedRef.current = false;\n }\n }\n if (fullReplay) {\n setInitialLoading(false);\n }\n noteStreamResume();\n const stream = client.streamEvents(workspaceId, sessionId, {\n after: streamResumeSequenceRef.current,\n signal: controller.signal,\n // Full replay keeps the SDK's exactly-once reconnects.\n ...(fullReplay ? {} : { beforeReconnect }),\n onOpen: () => {\n // The first open after this mount's initial tail: every read hook\n // read its projection alongside that tail, and the shared feed\n // re-reads one only for a later event. Later opens (reconnects,\n // foreground resumes) repair every projection.\n const initialOpen = openedStreamKeyRef.current !== streamKey;\n openedStreamKeyRef.current = streamKey;\n strictFailures = 0;\n // The outage is over: drop an error a long transient streak surfaced.\n if (streamTransientStreakRef.current?.surfaced) setError(null);\n streamTransientStreakRef.current = null;\n // Reconciliation repairs projections, but it must not block reading\n // the already-open SSE body. Otherwise live events accumulate in the\n // browser and appear as one delayed burst after every reconciler ends.\n reconcileAfterOpen(initialOpen);\n },\n onStateChange: (state) => {\n if (isCurrent()) {\n setConnectionState(state);\n }\n },\n });\n for await (const event of stream) {\n if (!isCurrent()) break;\n const boundedEvent = event;\n const boundedEventBytes = browserJsonBytes(boundedEvent);\n const separatorBytes = pending.length === 0 ? 0 : 1;\n if (\n pending.length > 0 &&\n (pending.length >= SESSION_EVENT_BROWSER_PENDING_MAX_COUNT ||\n pendingBytes + separatorBytes + boundedEventBytes >\n SESSION_EVENT_BROWSER_PENDING_MAX_BYTES)\n ) {\n flush();\n }\n pending.push(boundedEvent);\n pendingBytes += (pending.length === 1 ? 0 : 1) + boundedEventBytes;\n if (\n pending.length >= SESSION_EVENT_BROWSER_PENDING_MAX_COUNT ||\n pendingBytes >= SESSION_EVENT_BROWSER_PENDING_MAX_BYTES\n ) {\n flush();\n } else {\n scheduleFlush();\n }\n }\n if (isCurrent()) {\n flush();\n setConnectionState(\"ended\");\n }\n } catch (cause) {\n if (isCurrent()) {\n flush();\n let announce = true;\n if (isTransientRequestError(cause)) {\n // The tail read or the stream failed transiently (an API rollout\n // or a network blip). Restart quietly, keeping the loading state\n // or the current view, and show the error only if it outlasts the\n // quiet window. Afterwards keep retrying in the background.\n const now = Date.now();\n const streak = (streamTransientStreakRef.current ??= {\n since: now,\n attempts: 0,\n surfaced: false,\n });\n const step = transientReadRetryStep(streak, now, DEFAULT_TRANSIENT_READ_RETRY);\n scheduleTransientRetry(step.delayMs, () => setStreamEpoch((epoch) => epoch + 1));\n if (step.quiet) {\n setConnectionState(\"connecting\");\n return;\n }\n // One stable error per streak: background retries that fail the\n // same way must not re-announce it.\n announce = !streak.surfaced;\n streak.surfaced = true;\n } else {\n streamTransientStreakRef.current = null;\n }\n if (announce) setError(normalizeError(cause));\n setConnectionState(\"error\");\n // A failed first compact-tail request has no later success path in\n // this effect instance. End the loading gate so hosts can render the\n // retryable error instead of an infinite initial spinner.\n setInitialLoading(false);\n }\n }\n })();\n\n return () => {\n controller.abort();\n if (transientRetryTimer !== null) clearTimeout(transientRetryTimer);\n if (generationRef.current === generation) {\n generationRef.current = generation + 1;\n }\n if (streamAbortRef.current === controller) {\n streamAbortRef.current = null;\n }\n if (flushTimer !== null) {\n clearTimeout(flushTimer);\n }\n };\n }, [\n client,\n workspaceId,\n sessionId,\n after,\n enabled,\n pageLive,\n streamEnabled,\n fullReplay,\n streamKey,\n streamEpoch,\n viewMode,\n reconcileSession,\n t,\n pruneStepStores,\n appendLiveSteps,\n presentedCallIds,\n startupTurns,\n ]);\n\n // A sleep, frozen tab or lost network usually killed the stream without the\n // page ever going hidden. Rejoin at once, like a hidden-tab return, instead\n // of waiting for the heartbeat timeout and then replaying the backlog.\n useEffect(() => {\n if (!sessionId || !streamEnabled) return;\n return subscribePageWake(() => {\n const stream = streamAbortRef.current;\n // History views and paused streams have no live connection to restore.\n if (!stream || stream.signal.aborted || viewModeRef.current !== \"live\") return;\n if (!fullReplay && initialWindowLoadedRef.current) {\n reconcileAfterPageResumeRef.current = true;\n }\n setStreamEpoch((epoch) => epoch + 1);\n });\n }, [sessionId, streamEnabled, fullReplay]);\n\n const navigationBusy = (): boolean =>\n loadingTargetRef.current ||\n loadingOlderRef.current ||\n loadingNewerRef.current ||\n loadingOldestRef.current ||\n loadingLatestRef.current;\n\n const loadOlder = useCallback(\n (): OlderHistoryLoadReceipt =>\n createOlderHistoryLoadReceipt(async (markCommitted, preserveTail, markTailPreserved) => {\n if (!ownsNavigation() || !sessionId || navigationBusy() || !hasOlderRef.current) {\n return false;\n }\n const before = oldestSequenceRef.current;\n if (before === null) {\n oldestSequenceRef.current = null;\n hasOlderRef.current = false;\n setHasOlder(false);\n return false;\n }\n const generation = navigationGenerationRef.current;\n const isCurrent = () => ownsNavigation() && navigationGenerationRef.current === generation;\n loadingOlderRef.current = true;\n setLoadingOlder(true);\n let published = false;\n try {\n const window = await loadEventWindow(t, client, workspaceId, sessionId, {\n before,\n pageSize: SESSION_HISTORY_PAGE_SIZE,\n targetGroups: OLDER_GROUP_TARGET,\n maxFetches: OLDER_FETCH_CAP,\n filteredPageCap: FILTERED_PAGE_CAP,\n isCurrent,\n filter: historyFilter,\n });\n if (!isCurrent()) {\n return false;\n }\n if (window.events.length === 0) {\n if (window.hasOlder && window.scanCursor < before) {\n // Every row read was dropped (a fallback read): continue below them.\n oldestSequenceRef.current = window.scanCursor;\n return true;\n }\n oldestSequenceRef.current = null;\n hasOlderRef.current = false;\n setHasOlder(false);\n return false;\n }\n const current = eventWindowRef.current;\n assertPrependOrder(current.events, window.events);\n const next = boundBrowserSessionEventWindow([...window.events, ...current.events], {\n direction: \"oldest\",\n });\n if (preserveTail && maxResumeSequence(next.events) < maxResumeSequence(current.events)) {\n // Automatic viewport filling must not navigate away from the\n // reader's retained tail. Explicit history navigation may do so.\n markTailPreserved();\n return false;\n }\n const status = observeSessionStatus(window.events, sessionStatusRef);\n const retained = {\n ...next,\n truncated: current.truncated || next.truncated,\n };\n const retainedOldest = retained.events[0]?.sequence ?? null;\n if (retainedOldest === null || retainedOldest >= before) {\n throw new Error(\"@opengeni/react: loadOlder made no durable sequence progress\");\n }\n const retainedNewest = maxResumeSequenceOrNull(retained.events);\n const previousNewest = maxResumeSequenceOrNull(current.events);\n const evictedLiveTail =\n previousNewest !== null && retainedNewest !== null && retainedNewest < previousNewest;\n if (evictedLiveTail && viewModeRef.current === \"live\") {\n // The prepend leaves the live tip. Freeze the iterator before the\n // window is replaced so a late flush cannot append live rows onto\n // (and newest-bound away) the history the reader just requested.\n streamAbortRef.current?.abort();\n }\n eventWindowRef.current = retained;\n // Leaving the live tip ends live steps: working turns' steps go.\n if (evictedLiveTail) {\n skippedStepsThroughRef.current = null;\n pruneStepStores(retained.events, current.events);\n } else {\n const skippedThrough = skippedStepsThroughRef.current;\n if (skippedThrough !== null && windowTurns(window.events).size > 0) {\n // The first turn rows below the skipped range: when they reveal a\n // working turn that began below it, read that turn's newest steps\n // up to there, as rejoining a working turn does. Rows that arrived\n // live since (of any turn or none) do not change that.\n skippedStepsThroughRef.current = null;\n const working = activeConversationTurn(retained.events);\n const bounds = working\n ? conversationTurnBounds(retained.events).get(working)\n : undefined;\n if (working && bounds && bounds.first <= skippedThrough) {\n loadTurnStepsRef.current(working, skippedThrough + 1);\n }\n }\n }\n markCommitted();\n oldestSequenceRef.current = retainedOldest;\n newestSequenceRef.current = retainedNewest;\n if (evictedLiveTail) {\n streamResumeSequenceRef.current = maxResumeSequence(retained.events);\n }\n // Oldest-directed eviction can discard newer in-memory rows. That fact\n // keeps windowTruncated true, but it does not imply older durable rows\n // exist; only the backward DB page can answer hasOlder truthfully.\n const olderStillAvailable = window.hasOlder;\n hasOlderRef.current = olderStillAvailable;\n let newer: boolean | null = null;\n let enterHistory = false;\n if (viewModeRef.current === \"history\" || evictedLiveTail) {\n const highWater = lastSequenceRef.current;\n newer = retainedNewest !== null && (retainedNewest < highWater || retained.truncated);\n hasNewerRef.current = newer;\n if (evictedLiveTail) {\n // A full oldest-directed browser window cannot also retain the\n // live suffix. Keep the newly loaded history and page forward;\n // reconnecting SSE here immediately newest-bounds the window and\n // evicts every row the reader just requested.\n viewModeRef.current = \"history\";\n enterHistory = true;\n }\n }\n // Otherwise the merge is still one contiguous live suffix and the open\n // SSE iterator keeps appending to it: every flush reads\n // eventWindowRef, so rows delivered during or after this fetch land\n // once, in order, on the prepended window. Reopening the stream here\n // would flash a connecting state and re-run session reconciliation on\n // every scroll-up for no data benefit.\n loadingOlderRef.current = false;\n startTransition(() => {\n if (status !== undefined) {\n setSessionStatusProjection(status);\n }\n setEventWindow(retained);\n setHasOlder(olderStillAvailable);\n if (newer !== null) {\n setHasNewer(newer);\n }\n if (enterHistory) {\n setViewMode(\"history\");\n }\n setLoadingOlder(false);\n });\n published = true;\n return olderStillAvailable;\n } catch (reason) {\n if (!isCurrent()) return false;\n throw reason;\n } finally {\n if (!published && isCurrent()) {\n loadingOlderRef.current = false;\n setLoadingOlder(false);\n }\n }\n }),\n [client, workspaceId, sessionId, ownsNavigation, t, historyFilter, pruneStepStores],\n );\n\n const loadOldest = useCallback(async (): Promise<boolean> => {\n if (!ownsNavigation() || !sessionId || navigationBusy() || !hasOlderRef.current) {\n return false;\n }\n // Explicit window replacement supersedes unresolved question destinations.\n const generation = ++navigationGenerationRef.current;\n const isCurrent = () => ownsNavigation() && navigationGenerationRef.current === generation;\n setQuestionEvidence(null);\n loadingOldestRef.current = true;\n setLoadingOldest(true);\n let published = false;\n try {\n const window = await loadForwardEventWindow(t, client, workspaceId, sessionId, {\n after: 0,\n pageSize: SESSION_HISTORY_PAGE_SIZE,\n targetGroups: OLDEST_GROUP_TARGET,\n maxFetches: OLDEST_FETCH_CAP,\n isCurrent,\n filter: historyFilter,\n });\n if (!isCurrent()) {\n return false;\n }\n if (window.events.length === 0) {\n hasOlderRef.current = false;\n setHasOlder(false);\n return false;\n }\n streamAbortRef.current?.abort();\n const status = observeSessionStatus(window.events, sessionStatusRef);\n // Keep the oldest prefix — never the middle or tip.\n const retained = boundBrowserSessionEventWindow(window.events, { direction: \"oldest\" });\n const retainedOldest = retained.events[0]?.sequence ?? null;\n const retainedNewest = maxResumeSequenceOrNull(retained.events);\n const previous = eventWindowRef.current.events;\n eventWindowRef.current = retained;\n // The start of history replaces the window; paging forward reads the rest.\n skippedStepsThroughRef.current = null;\n pruneStepStores(retained.events, previous);\n oldestSequenceRef.current = retainedOldest;\n newestSequenceRef.current = retainedNewest;\n hasOlderRef.current = false;\n const highWater = Math.max(lastSequenceRef.current, retainedNewest ?? 0);\n lastSequenceRef.current = highWater;\n const newer =\n window.hasNewer ||\n retained.truncated ||\n (retainedNewest !== null && retainedNewest < highWater);\n hasNewerRef.current = newer;\n initialWindowLoadedRef.current = true;\n setInitialHistoryReady(true);\n setError(null);\n viewModeRef.current = \"history\";\n loadingOldestRef.current = false;\n setNewerError(null);\n startTransition(() => {\n if (status !== undefined) {\n setSessionStatusProjection(status);\n }\n setEventWindow(retained);\n setHasOlder(false);\n setHasNewer(newer);\n setViewMode(\"history\");\n setLoadingOldest(false);\n });\n published = true;\n return newer;\n } catch (reason) {\n if (!isCurrent()) return false;\n throw reason;\n } finally {\n if (!published && isCurrent()) {\n loadingOldestRef.current = false;\n setLoadingOldest(false);\n }\n }\n }, [client, workspaceId, sessionId, ownsNavigation, t, historyFilter, pruneStepStores]);\n\n const loadNewer = useCallback(async (): Promise<boolean> => {\n if (!ownsNavigation() || !sessionId || navigationBusy() || !hasNewerRef.current) {\n return false;\n }\n const afterSequence = newestSequenceRef.current;\n if (afterSequence === null) {\n hasNewerRef.current = false;\n setHasNewer(false);\n return false;\n }\n const generation = navigationGenerationRef.current;\n const isCurrent = () => ownsNavigation() && navigationGenerationRef.current === generation;\n loadingNewerRef.current = true;\n setLoadingNewer(true);\n let published = false;\n try {\n const window = await loadForwardEventWindow(t, client, workspaceId, sessionId, {\n after: afterSequence,\n pageSize: SESSION_HISTORY_PAGE_SIZE,\n targetGroups: NEWER_GROUP_TARGET,\n maxFetches: NEWER_FETCH_CAP,\n filteredPageCap: FILTERED_PAGE_CAP,\n isCurrent,\n filter: historyFilter,\n });\n if (!isCurrent()) {\n return false;\n }\n if (window.events.length === 0) {\n if (window.hasNewer && window.scanCursor > afterSequence) {\n // Every row read was dropped (a fallback read): continue above them.\n newestSequenceRef.current = window.scanCursor;\n return true;\n }\n setNewerError(null);\n hasNewerRef.current = false;\n setHasNewer(false);\n // Caught up with durable history — resume the live tip stream.\n streamResumeSequenceRef.current = afterSequence;\n rejoinPendingRef.current = true;\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n return false;\n }\n const current = eventWindowRef.current;\n assertAppendOrder(current.events, window.events);\n const status = observeSessionStatus(window.events, sessionStatusRef);\n const previousOldest = current.events[0]?.sequence ?? null;\n // Moving forward through history: keep the newest suffix of the merge.\n const next = appendBrowserSessionEventWindow(current, window.events);\n const retained = {\n ...next,\n truncated: current.truncated || next.truncated || window.hasNewer,\n };\n const retainedOldest = retained.events[0]?.sequence ?? null;\n const retainedNewest = maxResumeSequenceOrNull(retained.events);\n if (retainedNewest === null || retainedNewest <= afterSequence) {\n throw new Error(\"@opengeni/react: loadNewer made no durable sequence progress\");\n }\n eventWindowRef.current = retained;\n pruneStepStores(retained.events, null);\n oldestSequenceRef.current = retainedOldest;\n newestSequenceRef.current = retainedNewest;\n // Evicting the start while paging forward re-arms hasOlder.\n if (\n retainedOldest !== null &&\n (previousOldest === null ||\n retainedOldest > previousOldest ||\n (retained.truncated &&\n retained.events[0]?.type !== \"session.created\" &&\n retainedOldest > 1))\n ) {\n hasOlderRef.current = true;\n }\n const rearmedOlder = hasOlderRef.current;\n const highWater = Math.max(lastSequenceRef.current, retainedNewest);\n lastSequenceRef.current = highWater;\n const newer = window.hasNewer || retainedNewest < highWater;\n hasNewerRef.current = newer;\n let resumeLive = false;\n if (!newer) {\n streamResumeSequenceRef.current = retainedNewest;\n rejoinPendingRef.current = true;\n viewModeRef.current = \"live\";\n resumeLive = true;\n }\n loadingNewerRef.current = false;\n setNewerError(null);\n startTransition(() => {\n if (status !== undefined) {\n setSessionStatusProjection(status);\n }\n setEventWindow(retained);\n setHasOlder(rearmedOlder);\n setHasNewer(newer);\n if (resumeLive) {\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n }\n setLoadingNewer(false);\n });\n published = true;\n return newer;\n } catch (reason) {\n // A settled request from an old navigation lifetime is not a failure of\n // the current session. Preserve current loading/error state as well.\n if (!isCurrent()) {\n return false;\n }\n setNewerError(normalizeError(reason));\n // Keep authorization and integrity failures actionable for callers;\n // timeline-owned invocations attach their own explicit recovery UI.\n throw reason;\n } finally {\n if (!published && isCurrent()) {\n loadingNewerRef.current = false;\n setLoadingNewer(false);\n }\n }\n }, [client, workspaceId, sessionId, ownsNavigation, t, historyFilter, pruneStepStores]);\n\n const jumpToSequence = useCallback(\n async (sequence: number, navigationOptions?: { signal?: AbortSignal }): Promise<boolean> => {\n const signal = navigationOptions?.signal;\n if (!ownsNavigation() || !sessionId || !Number.isSafeInteger(sequence) || sequence < 1)\n return false;\n // A navigation that was already cancelled (for example Find closed before\n // the caller could react) must not disturb any current view state.\n if (signal?.aborted) return false;\n // Explicit targets supersede both other targets and adjacent-page requests.\n const generation = ++navigationGenerationRef.current;\n setQuestionEvidence(null);\n const current = () => generation === navigationGenerationRef.current && ownsNavigation();\n const previousMode = viewModeRef.current;\n streamAbortRef.current?.abort();\n generationRef.current += 1;\n viewModeRef.current = \"history\";\n setViewMode(\"history\");\n loadingOlderRef.current = loadingNewerRef.current = loadingOldestRef.current = false;\n setLoadingOlder(false);\n setLoadingNewer(false);\n setLoadingOldest(false);\n loadingTargetRef.current = true;\n setLoadingTarget(true);\n let published = false;\n try {\n const around = (filter: HistoryFilter | undefined) =>\n Promise.all([\n loadPreviousPage(client, workspaceId, sessionId, sequence + 1, {\n pageSize: 128,\n filter,\n }),\n loadNextPage(client, workspaceId, sessionId, sequence, { pageSize: 128, filter }),\n ]);\n let [before, following] = await around(historyFilter);\n // A step target (for example a Find match in a tool output) is read\n // with its neighbouring steps, as before conversation-first history.\n if (historyFilter && current() && !before.some((event) => event.sequence === sequence)) {\n [before, following] = await around(undefined);\n }\n // Close-during-fetch fence: a pending jump must not replace the window\n // after its owner (for example ConversationFind) has gone away. The\n // finally block still settles loadingTarget for this generation.\n if (signal?.aborted) return false;\n if (!current()) return false;\n if (!before.some((event) => event.sequence === sequence)) return false;\n // Bound each side, keeping the target even if its message alone exceeds\n // the ordinary byte budget. Never evict the very event being navigated to.\n const prefix = boundBrowserSessionEventWindow(before, {\n direction: \"newest\",\n maxBytes: SESSION_EVENT_BROWSER_MAX_BYTES / 2,\n });\n const retained = boundBrowserSessionEventWindow([...prefix.events, ...following], {\n direction: \"oldest\",\n });\n if (!retained.events.some((event) => event.sequence === sequence)) return false;\n streamAbortRef.current?.abort();\n generationRef.current += 1;\n const status = observeSessionStatus(retained.events, sessionStatusRef);\n const previous = eventWindowRef.current.events;\n eventWindowRef.current = retained;\n pruneStepStores(retained.events, previous);\n oldestSequenceRef.current = retained.events[0]!.sequence;\n newestSequenceRef.current = maxResumeSequenceOrNull(retained.events);\n lastSequenceRef.current = Math.max(lastSequenceRef.current, newestSequenceRef.current ?? 0);\n hasOlderRef.current = !isLogStart(retained.events[0]!);\n // Compact/byte-bounded pages may be short despite more durable history.\n // Only an empty forward page proves the end (same rule as loadNewer).\n hasNewerRef.current =\n following.length > 0 ||\n retained.truncated ||\n (newestSequenceRef.current ?? 0) < lastSequenceRef.current;\n initialWindowLoadedRef.current = true;\n setInitialHistoryReady(true);\n setError(null);\n viewModeRef.current = \"history\";\n setEventWindow(retained);\n setHasOlder(hasOlderRef.current);\n setHasNewer(hasNewerRef.current);\n setInitialLoading(false);\n setViewMode(\"history\");\n setNewerError(null);\n if (status !== undefined) setSessionStatusProjection(status);\n published = true;\n return true;\n } catch (reason) {\n if (!current() || signal?.aborted) return false;\n throw reason;\n } finally {\n if (current()) {\n loadingTargetRef.current = false;\n setLoadingTarget(false);\n if (!published && previousMode === \"live\") {\n viewModeRef.current = \"live\";\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n }\n }\n }\n },\n [client, workspaceId, sessionId, ownsNavigation, historyFilter, pruneStepStores],\n );\n\n const jumpToLatestQuestion = useCallback(\n async (questionOptions?: LatestQuestionOptions): Promise<number | null> => {\n if (!sessionId || !ownsNavigation()) return null;\n let generation = navigationGenerationRef.current;\n const current = () => ownsNavigation() && generation === navigationGenerationRef.current;\n try {\n // Optional action code stays off the session-open path. Capture identity\n // before the import and fence its completion just like network reads.\n const { resolveLatestQuestion } = await import(\"./latest-question\");\n if (!current()) return null;\n const destination = await resolveLatestQuestion(t, {\n client,\n workspaceId,\n sessionId,\n isCurrent: current,\n resumeSequence: maxResumeSequence,\n options: questionOptions,\n });\n if (!destination || !current()) return null;\n if (!eventWindowRef.current.events.some((event) => event.sequence === destination.anchor)) {\n const navigation = jumpToSequence(destination.anchor);\n generation = navigationGenerationRef.current;\n if (!(await navigation) || !current()) return null;\n }\n setQuestionEvidence({\n client,\n streamKey,\n anchor: destination.anchor,\n events: destination.events,\n });\n return destination.questionSequence;\n } catch (reason) {\n if (!current()) return null;\n throw reason;\n }\n },\n [client, workspaceId, sessionId, streamKey, ownsNavigation, jumpToSequence, t],\n );\n\n const jumpToLatest = useCallback(async (): Promise<void> => {\n // An old host retry closure must not clear a replacement session's error\n // or abort its live feed before the passive effect cleanup has run.\n if (!ownsNavigation()) return;\n if (loadingTargetRef.current) {\n navigationGenerationRef.current += 1;\n loadingTargetRef.current = false;\n setLoadingTarget(false);\n }\n if (!sessionId || navigationBusy()) {\n return;\n }\n navigationGenerationRef.current += 1;\n setQuestionEvidence(null);\n loadingLatestRef.current = true;\n setLoadingLatest(true);\n setNewerError(null);\n setError(null);\n let published = false;\n try {\n streamAbortRef.current?.abort();\n hasNewerRef.current = false;\n hasOlderRef.current = false;\n newestSequenceRef.current = null;\n oldestSequenceRef.current = null;\n eventWindowRef.current = EMPTY_EVENT_WINDOW;\n initialWindowLoadedRef.current = false;\n streamResumeSequenceRef.current = after;\n viewModeRef.current = \"live\";\n loadingLatestRef.current = false;\n startTransition(() => {\n setHasNewer(false);\n setHasOlder(false);\n setEventWindow(EMPTY_EVENT_WINDOW);\n setInitialLoading(true);\n setViewMode(\"live\");\n setStreamEpoch((epoch) => epoch + 1);\n setLoadingLatest(false);\n });\n published = true;\n // Effect reloads the tip. The tip fetch itself is owned by the effect.\n await Promise.resolve();\n } finally {\n if (!published) {\n loadingLatestRef.current = false;\n setLoadingLatest(false);\n }\n }\n }, [after, sessionId, ownsNavigation]);\n\n const identityMatches = stateStreamKey === streamKey;\n const freshTail =\n identityMatches && initialHistoryReady && viewMode === \"live\" && !fullReplay\n ? {\n events: eventWindow.events,\n hasOlder,\n truncated: eventWindow.truncated,\n bytes: eventWindow.bytes,\n sessionStatus: sessionStatusProjection,\n }\n : null;\n // Reopening a conversation draws the tail it showed when it was left (only\n // when the host retains reads for `client`) until its own fresh tail lands.\n const retainedTail = useRetainedSessionView(client, workspaceId, sessionId, \"events\", freshTail, {\n enabled: !fullReplay,\n bytes: (tail) => tail.bytes,\n budgetBytes: SESSION_EVENT_BROWSER_MAX_BYTES,\n discard: identityMatches && deniesRetainedView(error),\n });\n const showRetained = retainedTail !== null && !(identityMatches && initialHistoryReady);\n const visibleEvents = showRetained\n ? retainedTail.events\n : identityMatches\n ? eventWindow.events\n : EMPTY_EVENTS;\n const visibleHasOlder = showRetained ? retainedTail.hasOlder : identityMatches && hasOlder;\n const visibleTruncated = showRetained ? retainedTail.truncated : eventWindow.truncated;\n const liveSteps = identityMatches && !showRetained;\n const visibleStepStores = liveSteps ? stepStores : EMPTY_STEP_STORES;\n const visiblePresentedOutputs = liveSteps ? presentedOutputs : EMPTY_PRESENTED_OUTPUTS;\n const visibleTurnless = liveSteps ? turnlessSteps : EMPTY_TURNLESS_STEPS;\n const readToolOutput = useCallback(\n async (sequence: number) =>\n sessionId\n ? (\n await readEventPage(client, workspaceId, sessionId, {\n includeTypes: [\"agent.toolCall.output\"],\n after: Math.max(0, sequence - 1),\n before: sequence + 1,\n direction: \"after\",\n limit: 1,\n payloadMode: \"full\",\n })\n ).events\n : [],\n [client, workspaceId, sessionId],\n );\n const toolOutputs = useToolOutputReads(readToolOutput, stepStores);\n const visibleToolOutputs = liveSteps ? toolOutputs.exact : EMPTY_PRESENTED_OUTPUTS;\n // The conversation plus loaded steps, presented results, exact tool outputs\n // and the live turnless tail, by sequence.\n const loadedEvents = useMemo(\n () =>\n mergeLoadedEvents(\n visibleEvents,\n visibleStepStores,\n visiblePresentedOutputs,\n visibleTurnless.events,\n visibleToolOutputs,\n ),\n [\n visibleEvents,\n visibleStepStores,\n visiblePresentedOutputs,\n visibleTurnless,\n visibleToolOutputs,\n ],\n );\n // Turns whose steps are not all loaded get an expandable, loadable marker.\n const turnSteps = useMemo(() => {\n if (fullReplay) return undefined;\n const markers = new Map<string, Pick<TurnStepsItem, \"state\" | \"load\" | \"retain\">>();\n // Live turnless rows inside a turn are not its hidden steps.\n const bounded = withTurnlessSteps(visibleEvents, visibleTurnless);\n for (const [turnId, bounds] of conversationTurnBounds(bounded)) {\n const store = visibleStepStores.get(turnId);\n // A turn whose only steps are its bookkeeping (a plain answer's model\n // usage) has nothing to open.\n if (store && !store.loading && !store.error && !stepStoreHasOlder(store, bounds)) {\n if (!store.events.some((event) => CONTENT_STEP_TYPES.has(event.type))) continue;\n }\n const state: TurnStepsItem[\"state\"] | null = store\n ? store.loading\n ? \"loading\"\n : store.error\n ? \"error\"\n : stepStoreHasOlder(store, bounds)\n ? \"partial\"\n : \"complete\"\n : bounds.hidden\n ? \"idle\"\n : null;\n if (state === null) continue;\n // A retained view is drawn before its session's own window: its\n // markers wait, and load once that window replaces them.\n markers.set(turnId, { state, ...(liveSteps ? turnStepHandle(turnId) : RETAINED_VIEW_STEPS) });\n }\n return markers;\n }, [fullReplay, visibleEvents, visibleTurnless, visibleStepStores, liveSteps, turnStepHandle]);\n const timeline = useMemo(() => {\n const witness =\n questionEvidence?.client === client &&\n questionEvidence.streamKey === streamKey &&\n visibleEvents.some((event) => event.sequence === questionEvidence.anchor)\n ? questionEvidence.events\n : EMPTY_EVENTS;\n const timelineOptions = {\n partialStart: visibleHasOlder || visibleTruncated || after > 0,\n ...(turnSteps ? { turnSteps } : {}),\n ...(liveSteps ? { toolOutputs: toolOutputs.reader } : {}),\n };\n if (witness.length === 0) return buildTimeline(t, loadedEvents, timelineOptions);\n const ids = new Set(loadedEvents.map((event) => event.id));\n return buildTimeline(\n t,\n [...loadedEvents, ...witness.filter((event) => !ids.has(event.id))],\n timelineOptions,\n );\n }, [\n loadedEvents,\n visibleEvents,\n visibleHasOlder,\n visibleTruncated,\n after,\n questionEvidence,\n client,\n streamKey,\n turnSteps,\n liveSteps,\n toolOutputs.reader,\n t,\n ]);\n\n // Presented results (an image, a published file, a Skill change) are primary\n // output, but their output rows are steps: read each one directly.\n useEffect(() => {\n if (fullReplay || !sessionId || !identityMatches || !initialHistoryReady) return;\n const resolved = new Set<string>(presentedOutputs.keys());\n const collect = (events: readonly SessionEvent[]) => {\n for (const event of events) {\n // A previewed result is not presented: its exact read still runs.\n if (event.type !== \"agent.toolCall.output\" || isToolOutputPreviewEvent(event)) continue;\n const id = (event.payload as Record<string, unknown> | null)?.id;\n if (typeof id === \"string\") resolved.add(id);\n }\n };\n collect(eventWindow.events);\n for (const store of stepStores.values()) collect(store.events);\n const requested = presentedRequestedRef.current;\n // At most PRESENTED_OUTPUT_READS_PER_PASS reads run at once.\n let inFlight = 0;\n for (const request of requested.values()) if (request.pending) inFlight += 1;\n const room = PRESENTED_OUTPUT_READS_PER_PASS - inFlight;\n if (room <= 0) return;\n const missing: Array<{ callId: string; sequence: number; turnId: string | null }> = [];\n for (const event of eventWindow.events) {\n if (event.type !== \"agent.toolCall.created\") continue;\n const payload = event.payload as Record<string, unknown> | null;\n const callId = payload?.id;\n if (\n typeof callId !== \"string\" ||\n resolved.has(callId) ||\n requested.has(callId) ||\n !isPresentedSessionToolName(payload?.name)\n ) {\n continue;\n }\n missing.push({ callId, sequence: event.sequence, turnId: event.turnId ?? null });\n }\n if (missing.length === 0) return;\n const bounds = conversationTurnBounds(eventWindow.events);\n for (const { callId, sequence, turnId } of missing.slice(-room)) {\n const request: PresentedRequest = { turnId, pending: true };\n requested.set(callId, request);\n const isCurrent = () =>\n presentedRequestedRef.current === requested && requested.get(callId) === request;\n const terminal = turnId ? (bounds.get(turnId)?.terminal ?? null) : null;\n void findPresentedOutput(client, workspaceId, sessionId, callId, sequence, terminal).then(\n (output) => {\n if (!ownsNavigation() || !isCurrent()) return;\n request.pending = false;\n // Not found: a working tool's result arrives live, and a settled\n // turn's result does not exist. Either way, read the next ones.\n if (output) setPresentedOutputs((current) => new Map(current).set(callId, output));\n setPresentedPass((pass) => pass + 1);\n },\n () => {\n // Retried after a pause; meanwhile the tool row still shows its call.\n if (!isCurrent()) return;\n requested.delete(callId);\n const failures = (presentedFailuresRef.current.get(callId) ?? 0) + 1;\n presentedFailuresRef.current.set(callId, failures);\n if (failures > PRESENTED_OUTPUT_RETRIES) return;\n setTimeout(() => {\n if (ownsNavigation()) setPresentedPass((pass) => pass + 1);\n }, PRESENTED_OUTPUT_RETRY_MS * failures);\n },\n );\n }\n }, [\n fullReplay,\n sessionId,\n identityMatches,\n initialHistoryReady,\n eventWindow,\n stepStores,\n presentedOutputs,\n presentedPass,\n client,\n workspaceId,\n ownsNavigation,\n ]);\n\n return {\n events: loadedEvents,\n timeline,\n sessionStatus: showRetained\n ? retainedTail.sessionStatus\n : identityMatches\n ? sessionStatusProjection\n : null,\n sessionStatusSequence: identityMatches ? sessionStatusRef.current.sequence : 0,\n connectionState: identityMatches ? connectionState : \"idle\",\n lastSequence: identityMatches ? lastSequenceRef.current : after,\n windowBytes: identityMatches ? eventWindow.bytes : 2,\n windowTruncated: identityMatches ? eventWindow.truncated : false,\n initialLoading: fullReplay || showRetained ? false : identityMatches ? initialLoading : true,\n initialHistoryReady: identityMatches && initialHistoryReady,\n hasOlder: visibleHasOlder,\n loadingOlder: !identityMatches ? false : loadingOlder,\n loadOlder,\n hasNewer: !identityMatches ? false : hasNewer,\n loadingNewer: !identityMatches ? false : loadingNewer,\n loadNewer,\n loadingOldest: !identityMatches ? false : loadingOldest,\n loadOldest,\n loadingLatest: !identityMatches ? false : loadingLatest,\n jumpToLatest,\n jumpToLatestQuestion,\n jumpToSequence,\n loadingTarget: identityMatches && loadingTarget,\n error: identityMatches ? (newerError ?? error) : null,\n };\n}\n\n/**\n * Keep one direction-aware count+byte-bounded browser window. Live/default\n * accumulation retains the newest suffix; backward paging retains the oldest\n * prefix so newly fetched history cannot be immediately evicted. This is\n * deliberately separate from durable history and transport paging: when a\n * backward page evicts the live tail, the hook enters bounded history mode and\n * preserves the highest-ever-observed sequence separately for forward paging.\n * The source event remains durable in PostgreSQL throughout. An event larger\n * than the byte target is retained alone, never replaced by a lossy preview.\n */\nexport function boundBrowserSessionEventWindow(\n events: readonly SessionEvent[],\n options: {\n maxBytes?: number;\n maxCount?: number;\n direction?: \"newest\" | \"oldest\";\n } = {},\n): BrowserSessionEventWindow {\n const maxBytes = Math.max(1024, options.maxBytes ?? SESSION_EVENT_BROWSER_MAX_BYTES);\n const maxCount = Math.max(1, Math.floor(options.maxCount ?? SESSION_EVENT_BROWSER_MAX_COUNT));\n const safe = events;\n const selected: SessionEvent[] = [];\n let bytes = 2; // []\n const direction = options.direction ?? \"newest\";\n const start = direction === \"newest\" ? safe.length - 1 : 0;\n const end = direction === \"newest\" ? Math.max(-1, safe.length - maxCount - 1) : safe.length;\n const step = direction === \"newest\" ? -1 : 1;\n for (let index = start; index !== end && selected.length < maxCount; index += step) {\n const event = safe[index]!;\n const eventBytes = browserJsonBytes(event);\n const separator = selected.length === 0 ? 0 : 1;\n if (selected.length > 0 && bytes + separator + eventBytes > maxBytes) break;\n selected.push(event);\n bytes += separator + eventBytes;\n }\n if (direction === \"newest\") selected.reverse();\n return {\n events: selected,\n bytes,\n truncated: selected.length < safe.length,\n };\n}\n\n/** @internal Append immutable events without serializing the retained history again. */\nexport function appendBrowserSessionEventWindow(\n current: BrowserSessionEventWindow,\n batch: readonly SessionEvent[],\n options: { maxBytes?: number; maxCount?: number } = {},\n): BrowserSessionEventWindow {\n const maxBytes = Math.max(1024, options.maxBytes ?? SESSION_EVENT_BROWSER_MAX_BYTES);\n const maxCount = Math.max(1, Math.floor(options.maxCount ?? SESSION_EVENT_BROWSER_MAX_COUNT));\n const events = [...current.events, ...batch];\n let bytes = current.bytes;\n for (let index = 0; index < batch.length; index += 1) {\n bytes += browserJsonBytes(batch[index]) + (current.events.length + index > 0 ? 1 : 0);\n }\n let start = 0;\n // Preserve the newest event even when it alone exceeds the byte target,\n // matching the full-window reducer and retaining exact cursor progress.\n while (events.length - start > 1 && (bytes > maxBytes || events.length - start > maxCount)) {\n bytes -= browserJsonBytes(events[start]) + 1;\n start += 1;\n }\n return {\n events: start === 0 ? events : events.slice(start),\n bytes,\n truncated: current.truncated || start > 0,\n };\n}\n\nfunction browserJsonBytes(value: unknown): number {\n return encoder.encode(JSON.stringify(value)).byteLength;\n}\n\nfunction observeSessionStatus(\n events: readonly SessionEvent[],\n ref: { current: { sequence: number; status: SessionStatus | null } },\n): SessionStatus | undefined {\n let latest: { sequence: number; status: SessionStatus } | null = null;\n for (const event of events) {\n const status = sessionStatusFromEvents([event]);\n if (status && (!latest || event.sequence >= latest.sequence)) {\n latest = { sequence: event.sequence, status };\n }\n }\n if (!latest || latest.sequence < ref.current.sequence) return undefined;\n ref.current = latest;\n return latest.status;\n}\n\n/**\n * The conversation events after `cursor` through `head`, or null when they\n * span more than the catch-up cap (the caller then reloads the latest window).\n * Steps are not replayed: a turn's steps load when a reader opens it.\n */\nasync function loadConversationCatchup(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n cursor: number,\n head: number,\n options: { signal?: AbortSignal; isCurrent: () => boolean; progress?: () => void },\n): Promise<SessionEvent[] | null> {\n const events: SessionEvent[] = [];\n let after = cursor;\n for (let fetch = 0; fetch < CATCHUP_MAX_PAGES; fetch += 1) {\n if (options.signal?.aborted) throw abortError();\n const page = await readConversationPage(client, workspaceId, sessionId, {\n after,\n before: head + 1,\n direction: \"after\",\n limit: SESSION_HISTORY_PAGE_SIZE,\n compact: true,\n payloadMode: \"full\",\n });\n if (!options.isCurrent()) throw abortError();\n options.progress?.();\n const fresh = page.filter((event) => eventResumeSequence(event) > after);\n assertAscending(fresh);\n events.push(...fresh);\n // Rows the reader dropped (an older server's tool calls) still advance.\n if (page.raw.newest === null || page.raw.newest <= after) return events;\n after = page.raw.newest;\n if (after >= head || page.hasMore === false) return events;\n }\n return null;\n}\n\ntype LoadedEventWindow = {\n events: SessionEvent[];\n oldestSequence: number | null;\n newestSequence: number;\n hasOlder: boolean;\n /** The next older read starts below this (the oldest row read, kept or not). */\n scanCursor: number;\n};\n\ntype LoadedForwardEventWindow = {\n events: SessionEvent[];\n oldestSequence: number | null;\n newestSequence: number;\n hasNewer: boolean;\n /** The next newer read starts above this (the newest row read, kept or not). */\n scanCursor: number;\n};\n\nasync function loadEventWindow(\n t: OpenGeniText,\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n options: {\n before: number;\n pageSize: number;\n targetGroups: number;\n maxFetches: number;\n boundaryPageCap?: number;\n /** Pages kept nothing of that do not count against the caps. */\n filteredPageCap?: number;\n signal?: AbortSignal;\n isCurrent?: () => boolean;\n /** Called after each completed page read. */\n progress?: () => void;\n filter?: HistoryFilter | undefined;\n },\n): Promise<LoadedEventWindow> {\n let cursor = options.before;\n let buffer: SessionEvent[] = [];\n let reachedStart = false;\n let fetches = 0;\n let filteredPages = 0;\n // The newest sequence read, kept or not: what the window has covered.\n let rawNewest = 0;\n // A page the reader kept nothing of does not count, up to filteredPageCap.\n const counts = (page: PreviousPage): boolean => {\n rawNewest = Math.max(rawNewest, page.raw.newest ?? 0);\n return page.length > 0 || (filteredPages += 1) > (options.filteredPageCap ?? 0);\n };\n\n while (fetches < options.maxFetches) {\n if (buffer.length > 0 && groupCount(t, buffer) >= options.targetGroups) {\n break;\n }\n const page = await loadPreviousPage(client, workspaceId, sessionId, cursor, {\n pageSize: options.pageSize,\n filter: options.filter,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (options.isCurrent?.() === false) throw abortError();\n options.progress?.();\n if (page.raw.oldest === null) {\n reachedStart = true;\n break;\n }\n if (counts(page)) fetches += 1;\n assertAscending(page);\n buffer = [...page, ...buffer];\n // Below the oldest row read, even one the reader dropped.\n cursor = page.raw.oldest;\n if (page.raw.oldest <= 1 || (page[0] !== undefined && isLogStart(page[0]))) {\n reachedStart = true;\n break;\n }\n }\n\n // Boundary snap: a window that starts mid-turn TRIMS its head to the oldest\n // turn boundary already in the buffer — the dropped fragment is refetched by\n // the next loadOlder (everything below the new oldest sequence), whose own\n // window snaps the same way, so every seam lands on a turn start. Extra\n // page is fetched only when the buffer holds no boundary at all (one dense\n // turn); past the cap the existing truncation/hasOlder signal remains true.\n let snapPages = 0;\n while (\n !reachedStart &&\n findBoundaryIndex(buffer) === -1 &&\n snapPages < (options.boundaryPageCap ?? 0)\n ) {\n const page = await loadPreviousPage(client, workspaceId, sessionId, cursor, {\n pageSize: options.pageSize,\n filter: options.filter,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (options.isCurrent?.() === false) throw abortError();\n options.progress?.();\n if (page.raw.oldest === null) {\n reachedStart = true;\n break;\n }\n if (counts(page)) {\n fetches += 1;\n snapPages += 1;\n }\n assertAscending(page);\n buffer = [...page, ...buffer];\n cursor = page.raw.oldest;\n if (page.raw.oldest <= 1 || (page[0] !== undefined && isLogStart(page[0]))) {\n reachedStart = true;\n break;\n }\n }\n if (!reachedStart) {\n const boundary = findBoundaryIndex(buffer);\n if (boundary > 0) {\n buffer = buffer.slice(boundary);\n }\n }\n const densityWindow = trimBackwardToGroupTarget(t, buffer, options.targetGroups);\n buffer = densityWindow.events;\n\n const oldest = buffer[0] ?? null;\n const newest = buffer[buffer.length - 1] ?? null;\n return {\n events: buffer,\n oldestSequence: oldest?.sequence ?? null,\n // A window that kept nothing resumes a live stream above the rows it read,\n // not at the start of history. Otherwise rows dropped above its newest\n // kept row are replayed (or caught up) into their turn's steps, so a\n // working turn's latest tool calls still show.\n newestSequence: newest ? maxResumeSequence(buffer) : rawNewest,\n // An empty window that stopped before the start is still pageable.\n hasOlder:\n buffer.length > 0\n ? densityWindow.trimmed || (!reachedStart && oldest?.type !== \"session.created\")\n : !reachedStart,\n scanCursor: cursor,\n };\n}\n\n/** Index of the oldest clean turn start in the buffer, or -1. */\nfunction findBoundaryIndex(events: SessionEvent[]): number {\n for (let index = 0; index < events.length; index += 1) {\n if (isTurnBoundary(events[index]!)) {\n return index;\n }\n }\n return -1;\n}\n\nfunction isTurnBoundary(event: SessionEvent): boolean {\n return event.type === \"session.created\" || event.type === \"user.message\";\n}\n\n/**\n * Forward (oldest→newer) density-bounded window. Used for jump-to-start and\n * loadNewer so the browser never walks the whole middle gap.\n */\nasync function loadForwardEventWindow(\n t: OpenGeniText,\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n options: {\n after: number;\n pageSize: number;\n targetGroups: number;\n maxFetches: number;\n /** Pages kept nothing of that do not count against the caps. */\n filteredPageCap?: number;\n signal?: AbortSignal;\n isCurrent?: () => boolean;\n filter?: HistoryFilter | undefined;\n },\n): Promise<LoadedForwardEventWindow> {\n let cursor = options.after;\n let buffer: SessionEvent[] = [];\n let fetches = 0;\n let reachedEnd = false;\n let filteredPages = 0;\n\n while (fetches < options.maxFetches) {\n if (buffer.length > 0 && groupCount(t, buffer) >= options.targetGroups) {\n break;\n }\n const page = await loadNextPage(client, workspaceId, sessionId, cursor, {\n pageSize: options.pageSize,\n filter: options.filter,\n ...(options.signal ? { signal: options.signal } : {}),\n });\n if (options.isCurrent?.() === false) throw abortError();\n if (page.raw.newest === null) {\n reachedEnd = true;\n break;\n }\n // A page the reader kept nothing of does not count, up to filteredPageCap.\n if (page.length > 0 || (filteredPages += 1) > (options.filteredPageCap ?? 0)) fetches += 1;\n assertAscending(page);\n buffer = [...buffer, ...page];\n // Compact events retain their first raw sequence in `sequence` and expose\n // the covered high-water mark through `coalescedUntil`. Advancing by the\n // first sequence duplicates compacted text on the next page. A compact\n // response length is not an end-of-history signal either: thousands of raw\n // events may legitimately collapse into one returned event.\n cursor = page.raw.newest;\n }\n const densityWindow = trimForwardToGroupTarget(t, buffer, options.targetGroups);\n buffer = densityWindow.events;\n\n const oldest = buffer[0] ?? null;\n const newest = buffer[buffer.length - 1] ?? null;\n return {\n events: buffer,\n oldestSequence: oldest?.sequence ?? null,\n newestSequence: newest ? maxResumeSequence(buffer) : 0,\n // An empty window that stopped before the end is still pageable.\n hasNewer: buffer.length > 0 ? densityWindow.trimmed || !reachedEnd : !reachedEnd,\n scanCursor: cursor,\n };\n}\n\ntype DensityWindow = {\n events: SessionEvent[];\n trimmed: boolean;\n};\n\n/** Keep the newest complete turn groups near an older-history seam. */\nfunction trimBackwardToGroupTarget(\n t: OpenGeniText,\n events: SessionEvent[],\n targetGroups: number,\n): DensityWindow {\n if (!Number.isFinite(targetGroups) || targetGroups <= 0 || events.length === 0) {\n return { events, trimmed: false };\n }\n for (let index = events.length - 1; index > 0; index -= 1) {\n if (!isTurnBoundary(events[index]!)) continue;\n const candidate = events.slice(index);\n if (groupCount(t, candidate) >= targetGroups) {\n return { events: candidate, trimmed: true };\n }\n }\n return { events, trimmed: false };\n}\n\n/** Keep the oldest complete turn groups near a forward-history seam. */\nfunction trimForwardToGroupTarget(\n t: OpenGeniText,\n events: SessionEvent[],\n targetGroups: number,\n): DensityWindow {\n if (!Number.isFinite(targetGroups) || targetGroups <= 0 || events.length === 0) {\n return { events, trimmed: false };\n }\n for (let index = 1; index < events.length; index += 1) {\n if (!isTurnBoundary(events[index]!)) continue;\n const candidate = events.slice(0, index);\n if (groupCount(t, candidate) >= targetGroups) {\n return { events: candidate, trimmed: true };\n }\n }\n return { events, trimmed: false };\n}\n\n/** A history page, plus the rows read before the reader dropped any. */\ntype PreviousPage = SessionEvent[] & {\n requested: number;\n raw: RawPageExtent;\n hasMore?: boolean | null;\n};\n\ntype RawPageExtent = {\n /** The oldest row read (null when the read was empty). */\n oldest: number | null;\n /** The newest sequence the read covered (null when it was empty). */\n newest: number | null;\n};\n\nfunction rawPageExtent(events: readonly SessionEvent[]): RawPageExtent {\n return events.length === 0\n ? { oldest: null, newest: null }\n : { oldest: events[0]!.sequence, newest: maxResumeSequence(events) };\n}\n\nfunction historyPage(\n events: SessionEvent[],\n requested: number,\n raw: RawPageExtent = rawPageExtent(events),\n): PreviousPage {\n return Object.assign(events, { requested, raw });\n}\n\nasync function loadPreviousPage(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n before: number,\n options: {\n pageSize: number;\n signal?: AbortSignal;\n filter?: HistoryFilter | undefined;\n },\n): Promise<PreviousPage> {\n if (options.signal?.aborted) {\n throw abortError();\n }\n const requested = options.pageSize;\n if (requested === 0) {\n return historyPage([], requested);\n }\n const read: ConversationReadOptions = {\n before,\n limit: requested,\n compact: true,\n // Monitoring summaries omit correlation fields once a bounded durable\n // payload exceeds their preview threshold. The browser timeline needs the\n // exact stored payload so persisted tool outputs still match their\n // calls and expose truthful truncation telemetry after a reload.\n payloadMode: \"full\",\n };\n const page = options.filter\n ? await readConversationPage(client, workspaceId, sessionId, read)\n : historyPage(await client.listEvents(workspaceId, sessionId, read), requested);\n if (options.signal?.aborted) {\n throw abortError();\n }\n return Object.assign(page, { requested });\n}\n\nasync function loadNextPage(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n after: number,\n options: {\n pageSize: number;\n signal?: AbortSignal;\n filter?: HistoryFilter | undefined;\n before?: number | undefined;\n },\n): Promise<PreviousPage> {\n if (options.signal?.aborted) {\n throw abortError();\n }\n const requested = options.pageSize;\n if (requested === 0) {\n return historyPage([], requested);\n }\n const read: ConversationReadOptions = {\n ...(options.before !== undefined ? { before: options.before } : {}),\n after,\n limit: requested,\n compact: true,\n direction: \"after\",\n payloadMode: \"full\",\n };\n const page = options.filter\n ? await readConversationPage(client, workspaceId, sessionId, read)\n : historyPage(await client.listEvents(workspaceId, sessionId, read), requested);\n if (options.signal?.aborted) {\n throw abortError();\n }\n return Object.assign(page, { requested });\n}\n\nfunction groupCount(t: OpenGeniText, events: SessionEvent[]): number {\n if (events.length === 0) {\n return 0;\n }\n return groupTimeline(t, buildTimeline(t, events)).length;\n}\n\nfunction isLogStart(event: SessionEvent): boolean {\n return event.type === \"session.created\" || event.sequence <= 1;\n}\n\nfunction maxResumeSequence(events: readonly SessionEvent[]): number {\n return events.reduce((max, event) => Math.max(max, eventResumeSequence(event)), 0);\n}\n\nfunction maxResumeSequenceOrNull(events: readonly SessionEvent[]): number | null {\n return events.length > 0 ? maxResumeSequence(events) : null;\n}\n\nfunction eventResumeSequence(event: SessionEvent): number {\n const streamedCoverage = sessionEventStreamCoveredThrough(event);\n if (streamedCoverage !== null) return streamedCoverage;\n return typeof event.coveredThrough === \"number\" &&\n Number.isSafeInteger(event.coveredThrough) &&\n event.coveredThrough >= event.sequence\n ? event.coveredThrough\n : event.sequence;\n}\n\nfunction assertAscending(events: SessionEvent[]): void {\n for (let index = 1; index < events.length; index += 1) {\n if (events[index - 1]!.sequence >= events[index]!.sequence) {\n throw new Error(\"@opengeni/react: session events must be ordered by ascending sequence\");\n }\n }\n}\n\nfunction assertPrependOrder(existing: SessionEvent[], older: SessionEvent[]): void {\n if (!shouldAssertDevelopment() || existing.length === 0 || older.length === 0) {\n return;\n }\n if (older[older.length - 1]!.sequence >= existing[0]!.sequence) {\n throw new Error(\"@opengeni/react: loadOlder returned overlapping session events\");\n }\n}\n\nfunction assertAppendOrder(existing: SessionEvent[], newer: SessionEvent[]): void {\n if (!shouldAssertDevelopment() || existing.length === 0 || newer.length === 0) {\n return;\n }\n if (newer[0]!.sequence <= existing[existing.length - 1]!.sequence) {\n throw new Error(\"@opengeni/react: loadNewer returned overlapping session events\");\n }\n}\n\nfunction shouldAssertDevelopment(): boolean {\n const processEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env;\n return processEnv !== undefined && processEnv.NODE_ENV !== \"production\";\n}\n\nfunction abortError(): Error {\n const error = new Error(\"The operation was aborted.\");\n error.name = \"AbortError\";\n return error;\n}\n\nfunction abortableDelay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) {\n reject(abortError());\n return;\n }\n const onAbort = () => {\n clearTimeout(timer);\n reject(abortError());\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/**\n * One rejoin attempt's cancellation: its signal, whether it still owns state,\n * and `progress`, reported after each completed read (it keeps a slow but\n * progressing attempt from being abandoned as stalled).\n */\ntype RejoinScope = { signal: AbortSignal; isCurrent: () => boolean; progress?: () => void };\ntype RejoinOutcome = \"joined\" | \"reload\";\n\n/* ----------------------------------------------------------------------------\n Conversation-first history\n\n History reads exclude a turn's steps (tool calls and outputs, streamed\n reasoning and command output), which are most of a long session's rows and\n bytes. Live steps and steps a reader opens are kept per turn, apart from the\n contiguous conversation window, and merged only for projection.\n -------------------------------------------------------------------------- */\n\nconst CONTENT_STEP_TYPES: ReadonlySet<string> = new Set(SESSION_EVENT_CONTENT_STEP_TYPES);\nconst COMPAT_EXCLUDED_TYPES: ReadonlySet<string> = new Set(\n SESSION_EVENT_COMPAT_EXCLUDED_STEP_TYPES,\n);\n/** History reads of the conversation (see {@link readConversationPage}). */\nconst CONVERSATION_FILTER: HistoryFilter = \"conversation\";\n// One opened page of a turn's steps, newest first. Inside the server's\n// single-query interactive page so opening a turn is one indexed read.\nexport const SESSION_TURN_STEP_PAGE_SIZE = 200;\n// A collapsed live turn only shows its latest step; keep a short tail.\nexport const SESSION_TURN_LIVE_STEP_TAIL = 200;\nconst SESSION_TURN_LIVE_STEP_TAIL_BYTES = 2 * 1024 * 1024;\n// Live turnless output kept for the sandbox terminal between its renders.\n// It reads its own history; a burst past this tail makes it re-read.\nconst TURNLESS_STEP_TAIL = 1000;\nconst TURNLESS_STEP_TAIL_BYTES = 4 * 1024 * 1024;\n// A turn's step reads skip PTY output: it never belongs to a turn's work rows,\n// and a turn with only terminal output in its span finds nothing in one read.\nconst TURN_STEP_READ_TYPES: readonly SessionEventType[] = SESSION_EVENT_STEP_TYPES.filter(\n (type) => type !== \"terminal.pty.output.delta\",\n);\n// Steps of turns nobody is viewing; least recently used turns are dropped\n// first and reload when reopened. Opened turns are never evicted.\nexport const SESSION_STEP_BROWSER_MAX_BYTES = 16 * 1024 * 1024;\nconst TERMINAL_TURN_TYPES: ReadonlySet<string> = new Set([\n \"turn.completed\",\n \"turn.failed\",\n \"turn.cancelled\",\n \"turn.superseded\",\n]);\n\ntype HistoryFilter = \"conversation\";\n\ntype TurnStepStore = {\n /** This turn's loaded steps, ascending, one per event id. */\n events: SessionEvent[];\n bytes: number;\n /** Earlier steps of this turn exist before `events[0]`. */\n hasOlder: boolean;\n /** Exclusive upper bound of the next earlier page (else `events[0]`). */\n cursor: number | null;\n /**\n * The lower bound a read reached without the turn's start in the window.\n * Steps below it were not read: when a later window gives the turn a lower\n * bound (its start, or an earlier other turn), the store has older steps.\n */\n floor: number | null;\n /** The upper bound of a pinned read not yet answered; a retry stays pinned. */\n pinned: number | null;\n loading: boolean;\n error: boolean;\n /** Recency for eviction of turns nobody is viewing. */\n touched: number;\n /** The read this store answers; a newer read or a dropped store retires it. */\n requestId: number;\n};\n\ntype TurnStepStores = ReadonlyMap<string, TurnStepStore>;\n\nconst EMPTY_STEP_STORES: TurnStepStores = new Map();\n\ntype TurnlessSteps = {\n /** The newest live turnless steps, ascending. */\n events: SessionEvent[];\n bytes: number;\n /** Inclusive sequence runs of every live turnless step seen, ascending. */\n ranges: ReadonlyArray<readonly [number, number]>;\n /** How many live turnless rows were ever appended. */\n appended: number;\n};\n\nconst EMPTY_TURNLESS_STEPS: TurnlessSteps = { events: [], bytes: 2, ranges: [], appended: 0 };\n// Runs of turnless sequences kept for turn extents; terminal output comes in\n// bursts, so a run usually spans many rows.\nconst TURNLESS_STEP_MAX_RANGES = 4096;\n\n/** Add live turnless steps, keeping a bounded tail for the sandbox terminal. */\nfunction appendTurnlessSteps(\n current: TurnlessSteps,\n incoming: readonly SessionEvent[],\n): TurnlessSteps {\n const ranges = current.ranges.map((range): [number, number] => [range[0], range[1]]);\n for (const event of incoming) {\n const sequence = event.sequence;\n const last = ranges.at(-1);\n if (last && sequence >= last[0] && sequence <= last[1]) continue;\n if (last && sequence === last[1] + 1) last[1] = sequence;\n else if (!last || sequence > last[1]) ranges.push([sequence, sequence]);\n else if (!ranges.some(([first, end]) => sequence >= first && sequence <= end)) {\n ranges.push([sequence, sequence]);\n ranges.sort((left, right) => left[0] - right[0]);\n }\n }\n if (ranges.length > TURNLESS_STEP_MAX_RANGES) {\n ranges.splice(0, ranges.length - TURNLESS_STEP_MAX_RANGES);\n }\n const next = appendStepEvents(current, incoming);\n const appended = current.appended + incoming.length;\n if (next.events.length <= TURNLESS_STEP_TAIL && next.bytes <= TURNLESS_STEP_TAIL_BYTES) {\n return { ...next, ranges, appended };\n }\n const kept = boundBrowserSessionEventWindow(next.events, {\n maxCount: TURNLESS_STEP_TAIL,\n maxBytes: TURNLESS_STEP_TAIL_BYTES,\n });\n return { events: kept.events, bytes: kept.bytes, ranges, appended };\n}\n\n/**\n * The window with a placeholder over each run of live turnless steps inside\n * its range, so the sequences they fill do not read as a turn's hidden steps.\n * Only for turn extents: placeholders are never shown.\n */\nfunction withTurnlessSteps(\n window: readonly SessionEvent[],\n turnless: TurnlessSteps,\n): readonly SessionEvent[] {\n const first = window[0]?.sequence;\n if (first === undefined || turnless.ranges.length === 0) return window;\n const placeholders: SessionEvent[] = [];\n for (const [start, end] of turnless.ranges) {\n // Runs past the window's newest event still fill a live turn's span.\n if (end < first) continue;\n placeholders.push({\n id: `turnless-steps-${start}`,\n workspaceId: window[0]!.workspaceId,\n sessionId: window[0]!.sessionId,\n sequence: start,\n coveredThrough: end,\n type: \"terminal.pty.output.delta\",\n payload: null,\n occurredAt: window[0]!.occurredAt,\n turnId: null,\n });\n }\n if (placeholders.length === 0) return window;\n return [...window, ...placeholders].sort((left, right) => left.sequence - right.sequence);\n}\n\n/** The exclusive lower bound of a turn's step reads in the current window. */\nfunction turnStepLowerBound(bounds: TurnBounds): number {\n return bounds.started !== null ? bounds.started - 1 : bounds.previous;\n}\n\n/** Whether earlier steps of a turn remain to read, for the current window. */\nfunction stepStoreHasOlder(store: TurnStepStore, bounds: TurnBounds): boolean {\n return store.hasOlder || (store.floor !== null && turnStepLowerBound(bounds) < store.floor);\n}\n\n/**\n * @internal Whether an event belongs in the conversation window. With\n * `startupTurns` (the turns whose model has not responded yet), a turn's\n * bookkeeping is a step except its model request rows up to that response.\n */\nexport function isConversationHistoryEvent(\n event: SessionEvent,\n presentedCallIds: ReadonlySet<string>,\n startupTurns?: ReadonlySet<string>,\n): boolean {\n if (event.turnId) {\n if (event.type === \"agent.model.usage\") return startupTurns === undefined;\n if (event.type === \"agent.model.request\") {\n return startupTurns === undefined || startupTurns.has(event.turnId);\n }\n }\n if (!CONTENT_STEP_TYPES.has(event.type)) return true;\n const payload = event.payload as Record<string, unknown> | null;\n // Presented results stay, with or without a turn (the server keeps them too).\n if (event.type === \"agent.toolCall.created\") return isPresentedSessionToolName(payload?.name);\n if (event.type === \"agent.toolCall.output\") {\n return typeof payload?.id === \"string\" && presentedCallIds.has(payload.id);\n }\n // Other steps, including turnless PTY and background command output, which\n // the sandbox terminal reads itself so they never crowd the conversation.\n return false;\n}\n\ntype StartupTurns = {\n /** The window last read into this state. */\n window: readonly SessionEvent[] | null;\n /** Turns started and still waiting for their model's first response. */\n open: Set<string>;\n responded: Set<string>;\n};\n\nfunction emptyStartupTurns(): StartupTurns {\n return { window: null, open: new Set(), responded: new Set() };\n}\n\nfunction noteStartupTurns(events: readonly SessionEvent[], state: StartupTurns): void {\n for (const event of events) {\n const turnId = event.turnId;\n if (!turnId) continue;\n if (event.type === \"turn.started\") {\n if (!state.responded.has(turnId)) state.open.add(turnId);\n } else if (\n event.type === \"agent.model.request\" &&\n isSessionModelResponsePhase((event.payload as Record<string, unknown> | null)?.phase)\n ) {\n state.open.delete(turnId);\n state.responded.add(turnId);\n }\n }\n}\n\n/*\n * Conversation reads and server versions. A server announcing\n * SESSION_EVENT_CONVERSATION_FILTER_VERSION applies `presentedToolCalls` and\n * keeps the bookkeeping rows the conversation draws; it is read with every\n * step type excluded. A server that announces nothing may ignore\n * `presentedToolCalls` (and drop presented tool calls with the other steps),\n * so it is read with tool calls included and bookkeeping kept, and the reader\n * drops the calls that are not presented. Each read learns the mode for the\n * next one, so neither the server nor the package has to be released first.\n */\ntype ConversationFilterMode = \"v2\" | \"compat\";\nconst conversationFilterModes = new WeakMap<object, ConversationFilterMode>();\ntype ConversationRead = { excludeTypes: SessionEventType[]; presentedToolCalls: \"include\" };\ntype ConversationReadOptions = {\n after?: number;\n before?: number;\n limit: number;\n compact: true;\n direction?: \"before\" | \"after\";\n payloadMode: \"full\";\n};\nconst CONVERSATION_READS: Record<ConversationFilterMode, ConversationRead> = {\n v2: { excludeTypes: [...SESSION_EVENT_STEP_TYPES], presentedToolCalls: \"include\" },\n compat: {\n excludeTypes: [...SESSION_EVENT_COMPAT_EXCLUDED_STEP_TYPES],\n presentedToolCalls: \"include\",\n },\n};\n\n/**\n * @internal How the next conversation read of `client` filters. A client\n * without `listEventPage` cannot see the server's announcement.\n */\nexport function conversationFilterMode(client: EmbeddedSessionClientLike): ConversationFilterMode {\n if (typeof (client as EmbeddedSessionClientLike & EventPageClient).listEventPage !== \"function\") {\n return \"compat\";\n }\n return conversationFilterModes.get(client) ?? \"v2\";\n}\n\n/** One conversation page, read the way the server supports. */\nasync function readConversationPage(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n options: ConversationReadOptions,\n): Promise<PreviousPage> {\n let mode = conversationFilterMode(client);\n for (;;) {\n const read = await readEventPage(client, workspaceId, sessionId, {\n ...CONVERSATION_READS[mode],\n ...options,\n });\n const announced = (read.conversationFilter ?? 0) >= SESSION_EVENT_CONVERSATION_FILTER_VERSION;\n if (read.conversationFilter !== undefined) {\n conversationFilterModes.set(client, announced ? \"v2\" : \"compat\");\n }\n // The server may have dropped presented tool calls: read the page again.\n if (mode === \"v2\" && !announced) {\n mode = \"compat\";\n continue;\n }\n const events = mode === \"compat\" ? read.events.filter(isCompatConversationEvent) : read.events;\n return Object.assign(events === read.events ? [...events] : events, {\n requested: options.limit,\n raw: rawPageExtent(read.events),\n hasMore: read.hasMore,\n });\n }\n}\n\n/**\n * A compat read's rows minus a turn's steps: tool calls that are not\n * presented, and any excluded step row a server returned anyway.\n */\nfunction isCompatConversationEvent(event: SessionEvent): boolean {\n // Turnless output too: the sandbox terminal reads it itself.\n if (COMPAT_EXCLUDED_TYPES.has(event.type)) return false;\n if (event.type !== \"agent.toolCall.created\") return true;\n return isPresentedSessionToolName((event.payload as Record<string, unknown> | null)?.name);\n}\n\nfunction notePresentedCalls(events: readonly SessionEvent[], ids: Set<string>): void {\n for (const event of events) {\n if (event.type !== \"agent.toolCall.created\") continue;\n const payload = event.payload as Record<string, unknown> | null;\n if (typeof payload?.id === \"string\" && isPresentedSessionToolName(payload.name)) {\n ids.add(payload.id);\n }\n }\n}\n\ntype TurnBounds = {\n /** The turn's first window event (normally `turn.started`). */\n first: number;\n /** The turn's `turn.started`, when the window holds it. */\n started: number | null;\n /**\n * The last sequence of another turn before this turn's first window event\n * (0 when none). Turnless rows (queue changes, PTY output) do not count:\n * the turn's steps can sit below them.\n */\n previous: number;\n /** The turn's settlement, when the window holds it. */\n terminal: number | null;\n /** Steps hidden between the turn's window events. */\n hidden: boolean;\n};\n\n/**\n * Each turn's extent in the conversation window and whether sequences inside\n * it are absent: those are steps (or other unread rows) a reader can load.\n * Compacted events cover `[sequence, coveredThrough]`.\n */\nexport function conversationTurnBounds(events: readonly SessionEvent[]): Map<string, TurnBounds> {\n const bounds = new Map<string, TurnBounds & { last: number }>();\n const gaps: number[] = []; // first missing sequence of each gap\n let expected: number | null = null;\n let previous = 0;\n for (const event of events) {\n if (expected !== null && event.sequence > expected) gaps.push(expected);\n const resume = eventResumeSequence(event);\n expected = Math.max(expected ?? 0, resume + 1);\n const turnId = event.turnId;\n if (!turnId) continue;\n const current = bounds.get(turnId);\n if (!current) {\n bounds.set(turnId, {\n first: event.sequence,\n started: event.type === \"turn.started\" ? event.sequence : null,\n previous,\n last: resume,\n terminal: TERMINAL_TURN_TYPES.has(event.type) ? event.sequence : null,\n hidden: false,\n });\n } else {\n current.last = Math.max(current.last, resume);\n if (event.type === \"turn.started\" && current.started === null) {\n current.started = event.sequence;\n }\n if (TERMINAL_TURN_TYPES.has(event.type)) current.terminal = event.sequence;\n }\n // A queued turn's rows can precede the working turn's later steps.\n if (!PRE_START_TURN_TYPES.has(event.type)) previous = resume;\n }\n for (const turn of bounds.values()) {\n // Any gap that starts after the turn's first event and before its last.\n let low = 0;\n let high = gaps.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if (gaps[middle]! <= turn.first) low = middle + 1;\n else high = middle;\n }\n turn.hidden = low < gaps.length && gaps[low]! < turn.last;\n }\n return bounds;\n}\n\n/** The newest turn in the window that has started but not settled. */\nexport function activeConversationTurn(events: readonly SessionEvent[]): string | null {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index]!;\n if (!event.turnId) continue;\n if (TERMINAL_TURN_TYPES.has(event.type)) return null;\n if (event.type === \"turn.started\") return event.turnId;\n }\n return null;\n}\n\nfunction settledTurns(events: readonly SessionEvent[]): Set<string> {\n const settled = new Set<string>();\n for (const event of events) {\n if (event.turnId && TERMINAL_TURN_TYPES.has(event.type)) settled.add(event.turnId);\n }\n return settled;\n}\n\nfunction windowTurns(events: readonly SessionEvent[]): Set<string> {\n const turns = new Set<string>();\n for (const event of events) if (event.turnId) turns.add(event.turnId);\n return turns;\n}\n\nconst EMPTY_PRESENTED_OUTPUTS: ReadonlyMap<string, SessionEvent> = new Map();\n/** Rows a turn writes before it starts, while an earlier turn may still run. */\nconst PRE_START_TURN_TYPES: ReadonlySet<string> = new Set([\"turn.queued\", \"turn.capacity_waiting\"]);\n/** A presented result read: its turn, and whether it is still in flight. */\ntype PresentedRequest = { turnId: string | null; pending: boolean };\n// Presented results read per pass; each scans later outputs a page at a time,\n// bounded by its turn's settlement, up to a page cap.\nconst PRESENTED_OUTPUT_READS_PER_PASS = 8;\nconst PRESENTED_OUTPUT_PAGE_SIZE = 16;\nconst PRESENTED_OUTPUT_MAX_PAGES = 16;\nconst PRESENTED_OUTPUT_RETRIES = 3;\nconst PRESENTED_OUTPUT_RETRY_MS = 2_000;\nconst RETAINED_VIEW_STEPS: Pick<TurnStepsItem, \"load\" | \"retain\"> = {\n load: () => {},\n retain: () => () => {},\n};\n\n/**\n * The conversation window with loaded steps and presented results of its\n * turns merged in.\n */\nfunction mergeLoadedEvents(\n conversation: SessionEvent[],\n stores: TurnStepStores,\n presented: ReadonlyMap<string, SessionEvent>,\n turnless: readonly SessionEvent[],\n exactOutputs: ReadonlyMap<string, SessionEvent> = EMPTY_PRESENTED_OUTPUTS,\n): SessionEvent[] {\n if (\n stores.size === 0 &&\n presented.size === 0 &&\n turnless.length === 0 &&\n exactOutputs.size === 0\n ) {\n return conversation;\n }\n const turns = windowTurns(conversation);\n const ids = new Set(conversation.map((event) => event.id));\n const extra: SessionEvent[] = [];\n const add = (event: SessionEvent) => {\n if (ids.has(event.id) || !event.turnId || !turns.has(event.turnId)) return;\n ids.add(event.id);\n extra.push(event);\n };\n // Exact outputs first: they replace the previews a step page delivered.\n presented.forEach(add);\n // `add` keeps only events of the window's turns.\n exactOutputs.forEach(add);\n for (const [turnId, store] of stores) if (turns.has(turnId)) store.events.forEach(add);\n for (const event of turnless) {\n if (ids.has(event.id)) continue;\n ids.add(event.id);\n extra.push(event);\n }\n if (extra.length === 0) return conversation;\n return [...conversation, ...extra].sort((left, right) => left.sequence - right.sequence);\n}\n\nfunction groupByTurn(events: readonly SessionEvent[]): Map<string, SessionEvent[]> {\n const turns = new Map<string, SessionEvent[]>();\n for (const event of events) {\n if (!event.turnId) continue;\n const list = turns.get(event.turnId);\n if (list) list.push(event);\n else turns.set(event.turnId, [event]);\n }\n return turns;\n}\n\n/** Add steps once each, ascending, counting only the added bytes. */\nfunction appendStepEvents(\n store: Pick<TurnStepStore, \"events\" | \"bytes\">,\n incoming: readonly SessionEvent[],\n): Pick<TurnStepStore, \"events\" | \"bytes\"> {\n if (incoming.length === 0) return { events: store.events, bytes: store.bytes };\n const ids = new Set(store.events.map((event) => event.id));\n let bytes = store.bytes;\n const fresh: SessionEvent[] = [];\n for (const event of incoming) {\n if (ids.has(event.id)) continue;\n ids.add(event.id);\n fresh.push(event);\n bytes += browserJsonBytes(event) + (store.events.length + fresh.length > 1 ? 1 : 0);\n }\n if (fresh.length === 0) return { events: store.events, bytes: store.bytes };\n const last = store.events[store.events.length - 1];\n const events = [...store.events, ...fresh];\n if (last && fresh.some((event) => event.sequence < last.sequence)) {\n events.sort((left, right) => left.sequence - right.sequence);\n } else if (!last) {\n events.sort((left, right) => left.sequence - right.sequence);\n }\n return { events, bytes };\n}\n\n/**\n * Whether the window skips a sequence between a turn's first window event and\n * `before`: steps of that turn the browser has not read. A turn the window\n * does not know is assumed to have some.\n */\nfunction turnHasHiddenSequences(\n events: readonly SessionEvent[],\n turnId: string,\n before: number,\n): boolean {\n const start = events.findIndex((event) => event.turnId === turnId);\n if (start < 0) return true;\n let expected = eventResumeSequence(events[start]!) + 1;\n for (let index = start + 1; index < events.length; index += 1) {\n const event = events[index]!;\n if (event.sequence >= before) break;\n if (event.sequence > expected) return true;\n expected = Math.max(expected, eventResumeSequence(event) + 1);\n }\n return expected < before;\n}\n\n/** Keep the newest steps of a collapsed live turn. */\nfunction trimLiveStepTail(store: TurnStepStore): TurnStepStore {\n if (\n store.events.length <= SESSION_TURN_LIVE_STEP_TAIL &&\n store.bytes <= SESSION_TURN_LIVE_STEP_TAIL_BYTES\n ) {\n return store;\n }\n const kept = boundBrowserSessionEventWindow(store.events, {\n maxCount: SESSION_TURN_LIVE_STEP_TAIL,\n maxBytes: SESSION_TURN_LIVE_STEP_TAIL_BYTES,\n });\n return { ...store, events: kept.events, bytes: kept.bytes, hasOlder: true, cursor: null };\n}\n\n/** Drop the least recently used steps of turns nobody is viewing. */\nfunction boundStepStores(\n stores: Map<string, TurnStepStore>,\n retained: ReadonlyMap<string, number>,\n): Map<string, TurnStepStore> {\n let total = 0;\n for (const [turnId, store] of stores) {\n if (!retained.get(turnId)) total += store.bytes;\n }\n if (total <= SESSION_STEP_BROWSER_MAX_BYTES) return stores;\n const candidates = [...stores]\n .filter(([turnId, store]) => !retained.get(turnId) && !store.loading)\n .sort((left, right) => left[1].touched - right[1].touched);\n for (const [turnId, store] of candidates) {\n if (total <= SESSION_STEP_BROWSER_MAX_BYTES) break;\n stores.delete(turnId);\n total -= store.bytes;\n }\n return stores;\n}\n\n/**\n * A presented call's result: later outputs, a page at a time, up to the\n * call's turn settlement (parallel calls can put many outputs before it).\n */\nasync function findPresentedOutput(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n callId: string,\n after: number,\n terminal: number | null,\n): Promise<SessionEvent | null> {\n let cursor = after;\n for (let page = 0; page < PRESENTED_OUTPUT_MAX_PAGES; page += 1) {\n const read = await readEventPage(client, workspaceId, sessionId, {\n includeTypes: [\"agent.toolCall.output\"],\n after: cursor,\n ...(terminal !== null ? { before: terminal + 1 } : {}),\n direction: \"after\",\n limit: PRESENTED_OUTPUT_PAGE_SIZE,\n payloadMode: \"full\",\n });\n const output = read.events.find(\n (event) => (event.payload as Record<string, unknown> | null)?.id === callId,\n );\n if (output) return output;\n const last = read.events.at(-1);\n if (!last || !(read.hasMore ?? read.events.length >= PRESENTED_OUTPUT_PAGE_SIZE)) return null;\n cursor = last.sequence;\n }\n return null;\n}\n\ntype StepPage = {\n events: SessionEvent[];\n hasMore: boolean | null;\n /** The server's conversation-filter announcement; undefined when unseen. */\n conversationFilter?: number | null;\n};\n\ntype EventPageClient = {\n listEventPage?: (\n workspaceId: string,\n sessionId: string,\n options: SessionEventListOptions,\n ) => Promise<SessionEventPage>;\n};\n\n/**\n * One bounded page. Uses the SDK's page read when the client has it, which\n * reports whether more rows remain; a compact page's length cannot.\n */\nasync function readEventPage(\n client: EmbeddedSessionClientLike,\n workspaceId: string,\n sessionId: string,\n options: SessionEventListOptions,\n): Promise<StepPage> {\n const pageClient = client as EmbeddedSessionClientLike & EventPageClient;\n if (typeof pageClient.listEventPage === \"function\") {\n const page = await pageClient.listEventPage(workspaceId, sessionId, options);\n return {\n events: page.events,\n hasMore: page.hasMore,\n // An SDK that predates the announcement reports nothing: treat it as none.\n conversationFilter: page.conversationFilter ?? null,\n };\n }\n return { events: await client.listEvents(workspaceId, sessionId, options), hasMore: null };\n}\n","/**\n * Notices when the page wakes from a suspension it could not observe: a\n * laptop sleep, a frozen tab, or a network that came back. Live streams on a\n * page that slept usually died with it, while the hidden-tab signal never\n * fired (or its grace timer could not run), so they would otherwise wait for\n * a heartbeat timeout before reconnecting.\n *\n * Detection: a light timer compares wall-clock time between ticks (timers do\n * not run while the machine sleeps, but the wall clock moves on), checked\n * again when the page becomes visible, plus the `online`, `resume` (Page\n * Lifecycle) and bfcache `pageshow` events. One shared detector serves every\n * subscriber and stops with the last one.\n */\n\n/** How often the wall clock is sampled while anyone listens. */\nexport const PAGE_WAKE_CHECK_INTERVAL_MS = 2_000;\n/** A tick this long after the previous one means the page was suspended. */\nexport const PAGE_WAKE_GAP_MS = 15_000;\n\ntype PageWakeListener = () => void;\n\nconst listeners = new Set<PageWakeListener>();\nlet stopDetector: (() => void) | null = null;\n\n/** Call `listener` on every detected wake; returns the unsubscribe. */\nexport function subscribePageWake(listener: PageWakeListener): () => void {\n listeners.add(listener);\n stopDetector ??= startDetector();\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0 && stopDetector) {\n stopDetector();\n stopDetector = null;\n }\n };\n}\n\nfunction emitPageWake(): void {\n for (const listener of [...listeners]) {\n try {\n listener();\n } catch {\n // One subscriber cannot keep the others asleep.\n }\n }\n}\n\nfunction startDetector(): () => void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return () => {};\n let lastTick = Date.now();\n const check = () => {\n const now = Date.now();\n const elapsed = now - lastTick;\n lastTick = now;\n if (elapsed > PAGE_WAKE_GAP_MS) emitPageWake();\n };\n const onVisibility = () => {\n if (document.visibilityState !== \"hidden\") check();\n };\n const onPageShow = (event: Event) => {\n lastTick = Date.now();\n if ((event as PageTransitionEvent).persisted) emitPageWake();\n };\n const onResume = () => {\n lastTick = Date.now();\n emitPageWake();\n };\n const timer = setInterval(check, PAGE_WAKE_CHECK_INTERVAL_MS);\n document.addEventListener(\"visibilitychange\", onVisibility);\n document.addEventListener(\"resume\", onResume);\n window.addEventListener(\"pageshow\", onPageShow);\n window.addEventListener(\"online\", onResume);\n return () => {\n clearInterval(timer);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n document.removeEventListener(\"resume\", onResume);\n window.removeEventListener(\"pageshow\", onPageShow);\n window.removeEventListener(\"online\", onResume);\n };\n}\n","import { useCallback, useSyncExternalStore } from \"react\";\n\n/**\n * Live turnless output (PTY and background command output) reaches the\n * sandbox terminal through the session's live stream, but conversation reads\n * never carry it. When the stream rejoins at the durable head past unread\n * rows, or a burst overflows the live tail before anyone rendered it,\n * `useSessionEvents` bumps this session's generation and the terminal re-reads\n * its newest output by type.\n *\n * Keyed by workspace and session rather than client object: the session\n * history and the terminal can hold different client wrappers, and a spurious\n * re-read is only one bounded read.\n */\ntype GapEntry = { generation: number; listeners: Set<() => void> };\n\nconst MAX_IDLE_ENTRIES = 256;\nconst entries = new Map<string, GapEntry>();\n\nfunction gapKey(workspaceId: string, sessionId: string): string {\n return `${workspaceId}\\u0000${sessionId}`;\n}\n\nfunction gapEntry(key: string): GapEntry {\n let entry = entries.get(key);\n if (!entry) {\n entry = { generation: 0, listeners: new Set() };\n entries.set(key, entry);\n if (entries.size > MAX_IDLE_ENTRIES) {\n for (const [candidate, held] of entries) {\n if (entries.size <= MAX_IDLE_ENTRIES) break;\n if (candidate !== key && held.listeners.size === 0) entries.delete(candidate);\n }\n }\n }\n return entry;\n}\n\n/** @internal Live turnless output of this session may have been missed. */\nexport function markTurnlessOutputGap(workspaceId: string, sessionId: string): void {\n const entry = gapEntry(gapKey(workspaceId, sessionId));\n entry.generation += 1;\n for (const listener of [...entry.listeners]) listener();\n}\n\n/** @internal This session's gap generation; it changes after each possible gap. */\nexport function useTurnlessOutputGap(\n workspaceId: string,\n sessionId: string | null | undefined,\n): number {\n const key = sessionId ? gapKey(workspaceId, sessionId) : null;\n const subscribe = useCallback(\n (listener: () => void) => {\n if (!key) return () => {};\n const entry = gapEntry(key);\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n },\n [key],\n );\n const read = useCallback(() => (key ? (entries.get(key)?.generation ?? 0) : 0), [key]);\n return useSyncExternalStore(subscribe, read, read);\n}\n","import type {\n ComposerDraft,\n EffectiveSessionControl,\n McpPersonalConnectionSummary,\n SessionEvent,\n SessionQueueMutationResponse,\n SessionQueueSnapshot,\n SessionPendingInputPreview,\n SessionTurn,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useEmbeddedSession, type EmbeddedSessionClientOverride } from \"../session-context\";\nimport { normalizeError } from \"../lib/error-message\";\nimport { deniesRetainedView, useRetainedSessionView } from \"./session-view-cache\";\nimport {\n projectionReadThrough,\n useDebouncedCallback,\n usePageLiveActivity,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\nimport { useOpenGeniText } from \"../messages/runtime\";\n\n/** Events that can change the authoritative prompt queue or effective control. */\nexport function isTurnQueueEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return (\n event.type.startsWith(\"turn.\") ||\n event.type.startsWith(\"session.queue.\") ||\n event.type.startsWith(\"session.control.\") ||\n event.type.startsWith(\"system.update.\") ||\n event.type.startsWith(\"workspace.inference.\")\n );\n}\n\nfunction queueSnapshotCovers(\n candidate: SessionQueueSnapshot | null,\n observed: SessionQueueSnapshot,\n): boolean {\n return Boolean(\n candidate &&\n candidate.version >= observed.version &&\n candidate.effectiveControl.controlVersion >= observed.effectiveControl.controlVersion,\n );\n}\n\nexport type QueueMutationKind = \"move\" | \"edit\" | \"steer\" | \"delete\";\nconst EMPTY_PENDING_BY_TURN: Readonly<Record<string, QueueMutationKind>> = {};\n\nexport type AcceptedQueueSteer = {\n turnId: string;\n triggerEventId: string;\n text: string;\n annotations: SessionTurn[\"annotations\"];\n resources: SessionTurn[\"resources\"];\n tools: SessionTurn[\"tools\"];\n occurredAt: string;\n state: \"sending\" | \"queued\";\n};\n\nexport type UseTurnQueueOptions = EmbeddedSessionClientOverride &\n SessionEventFeedOptions & {\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseTurnQueueResult = {\n snapshot: SessionQueueSnapshot | null;\n /** Human/API prompts exactly in server execution order. Never client-sorted. */\n queue: SessionTurn[];\n /** Canonical pending machine inputs. Events only trigger an authoritative refresh. */\n pendingInputs: SessionPendingInputPreview[];\n /** Exact pending members projected to join an already-waiting prompt. */\n pendingInputAttachment: SessionQueueSnapshot[\"pendingInputAttachment\"];\n /** Secret-safe personal MCP summaries frozen on the exact active turn. */\n activePersonalConnections: McpPersonalConnectionSummary[];\n effectiveControl: EffectiveSessionControl | null;\n /** The latest interrupted attempt has not yet durably proved physical quiescence. */\n stoppingPreviousAttempt: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n moveTurn: (turnId: string, beforeTurnId: string | null) => Promise<boolean>;\n /** Atomically withdraw a waiting prompt into the private durable composer draft. */\n editTurn: (\n turnId: string,\n options: { expectedDraftRevision: number; replaceDraft: boolean },\n ) => Promise<ComposerDraft | null>;\n /** Advance the same durable waiting prompt; no duplicate prompt is created. */\n steerTurn: (turnId: string) => Promise<boolean>;\n removeTurn: (turnId: string) => Promise<boolean>;\n pendingByTurn: Readonly<Record<string, QueueMutationKind>>;\n mutationFor: (turnId: string) => QueueMutationKind | null;\n mutating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n /** Immediate chat bridge while the durable Steer event catches up over SSE. */\n acceptedSteers?: AcceptedQueueSteer[] | undefined;\n};\n\n/**\n * The one authoritative human prompt queue. Every mutation carries the exact\n * server versions the operator saw and accepts only monotonic snapshots. A\n * conflict immediately reloads server truth; the client never invents order.\n */\nexport function useTurnQueue(\n sessionId: string | null | undefined,\n options: UseTurnQueueOptions = {},\n): UseTurnQueueResult {\n const t = useOpenGeniText();\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSession(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}`;\n const pageLive = usePageLiveActivity();\n const [snapshot, setSnapshot] = useState<SessionQueueSnapshot | null>(null);\n const [stateTargetKey, setStateTargetKey] = useState(targetKey);\n const [loading, setLoading] = useState(enabled);\n const [error, setError] = useState<Error | null>(null);\n const [mutationError, setMutationError] = useState<Error | null>(null);\n const [pendingByTurn, setPendingByTurn] = useState<Record<string, QueueMutationKind>>({});\n const [acceptedSteers, setAcceptedSteers] = useState<AcceptedQueueSteer[]>([]);\n const pendingRef = useRef<Record<string, QueueMutationKind>>({});\n const readGeneration = useRef(0);\n const targetKeyRef = useRef(targetKey);\n const snapshotRef = useRef<SessionQueueSnapshot | null>(null);\n\n // Revoke the old target only when the new one commits. A concurrent render\n // may suspend while the previous target remains visible and interactive.\n useLayoutEffect(() => {\n if (targetKeyRef.current === targetKey) return;\n targetKeyRef.current = targetKey;\n readGeneration.current += 1;\n snapshotRef.current = null;\n pendingRef.current = {};\n setStateTargetKey(targetKey);\n setSnapshot(null);\n setLoading(enabled);\n setError(null);\n setMutationError(null);\n setPendingByTurn({});\n setAcceptedSteers([]);\n }, [enabled, targetKey]);\n\n useEffect(() => {\n if (acceptedSteers.length === 0 || options.events === undefined) return;\n const durablyConsumedTurnIds = new Set(\n options.events.flatMap((event) =>\n [\n \"turn.started\",\n \"turn.superseded\",\n \"turn.cancelled\",\n \"turn.failed\",\n \"turn.completed\",\n ].includes(event.type) && event.turnId\n ? [event.turnId]\n : [],\n ),\n );\n if (durablyConsumedTurnIds.size === 0) return;\n // steer_requested can reach the browser before the timeline projection\n // that moves the queued user.message into chat. Keep this bridge through\n // physical cancellation. Starting or settling that exact queued turn\n // proves the durable timeline has taken ownership (including batched Steers).\n setAcceptedSteers((current) =>\n current.filter((steer) => !durablyConsumedTurnIds.has(steer.turnId)),\n );\n }, [acceptedSteers.length, options.events]);\n\n const acceptSnapshot = useCallback(\n (ownedTargetKey: string, next: SessionQueueSnapshot | null): boolean => {\n if (targetKeyRef.current !== ownedTargetKey) return false;\n const current = snapshotRef.current;\n if (\n next &&\n current &&\n (next.version < current.version ||\n next.effectiveControl.controlVersion < current.effectiveControl.controlVersion)\n ) {\n return false;\n }\n snapshotRef.current = next;\n setStateTargetKey(ownedTargetKey);\n setSnapshot(next);\n return true;\n },\n [],\n );\n\n const load = useCallback(\n async (rejectOnFailure = false): Promise<void> => {\n if (!sessionId) return;\n const ownedTargetKey = `${workspaceId}\\u0000${sessionId}`;\n const ticket = ++readGeneration.current;\n try {\n const fetched = await client.getQueue(workspaceId, sessionId);\n if (targetKeyRef.current !== ownedTargetKey) return;\n const ownsLatestRead = ticket === readGeneration.current;\n if (rejectOnFailure) {\n const committed = acceptSnapshot(ownedTargetKey, fetched);\n if (!committed && !queueSnapshotCovers(snapshotRef.current, fetched)) {\n throw new TypeError(\"Queue reconciliation did not commit authoritative state\");\n }\n setError(null);\n if (ownsLatestRead) setLoading(false);\n } else if (ownsLatestRead) {\n acceptSnapshot(ownedTargetKey, fetched);\n setError(null);\n setLoading(false);\n }\n } catch (cause) {\n if (\n targetKeyRef.current === ownedTargetKey &&\n (ticket === readGeneration.current || rejectOnFailure)\n ) {\n setError(asError(cause));\n if (ticket === readGeneration.current) setLoading(false);\n }\n if (rejectOnFailure) throw cause;\n }\n },\n [client, workspaceId, sessionId, acceptSnapshot],\n );\n\n useEffect(() => {\n if (!enabled || !pageLive) {\n setLoading(false);\n return;\n }\n setLoading(true);\n const pollIntervalMs = options.pollIntervalMs;\n if (pollIntervalMs === undefined || pollIntervalMs <= 0) {\n void load();\n return () => {\n readGeneration.current += 1;\n };\n }\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const schedule = () => {\n if (cancelled) return;\n timer = setTimeout(() => {\n timer = null;\n void load().finally(schedule);\n }, pollIntervalMs);\n };\n void load().finally(schedule);\n return () => {\n cancelled = true;\n if (timer !== null) clearTimeout(timer);\n readGeneration.current += 1;\n };\n }, [load, enabled, pageLive, options.pollIntervalMs]);\n\n useEffect(() => {\n if (enabled && workspaceControlEvent) void load();\n }, [enabled, load, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"queue\", load);\n }, [enabled, load, registerSessionReconciler, sessionId]);\n\n const scheduleRefresh = useDebouncedCallback(() => void load());\n const freshSnapshot = stateTargetKey === targetKey ? snapshot : null;\n const freshLoading = stateTargetKey === targetKey ? loading : enabled;\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isTurnQueueEvent,\n scheduleRefresh,\n {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n readThrough: projectionReadThrough(freshSnapshot, freshLoading),\n refresh: scheduleRefresh,\n },\n async () => await load(true),\n );\n // Until the first read lands, show the queue as it was when this\n // conversation was last left (only when the host retains reads). Commands\n // still act only on a fresh snapshot.\n const retainedSnapshot = useRetainedSessionView(\n client,\n workspaceId,\n sessionId,\n \"queue\",\n freshSnapshot,\n { enabled, discard: stateTargetKey === targetKey && deniesRetainedView(error) },\n );\n\n const mutate = useCallback(\n async (\n turnId: string,\n kind: QueueMutationKind,\n command: (\n current: SessionQueueSnapshot,\n turn: SessionTurn,\n clientEventId: string,\n ) => Promise<SessionQueueMutationResponse>,\n ): Promise<SessionQueueMutationResponse | null> => {\n const ownedTargetKey = targetKey;\n if (!sessionId || targetKeyRef.current !== ownedTargetKey || pendingRef.current[turnId]) {\n return null;\n }\n const current = snapshotRef.current;\n const turn = current?.items.find((candidate) => candidate.id === turnId);\n if (!current || !turn) return null;\n pendingRef.current = { ...pendingRef.current, [turnId]: kind };\n setStateTargetKey(ownedTargetKey);\n setPendingByTurn(pendingRef.current);\n setMutationError(null);\n const clientEventId = operationKey();\n try {\n let result: SessionQueueMutationResponse;\n try {\n result = await command(current, turn, clientEventId);\n } catch (cause) {\n if (!isOutcomeUnknownError(cause)) throw cause;\n // Same-key replay is a fact check against the durable receipt. It\n // cannot duplicate the command even if the first response was lost.\n result = await command(current, turn, clientEventId);\n }\n if (targetKeyRef.current !== ownedTargetKey) return null;\n acceptSnapshot(ownedTargetKey, result.snapshot);\n return result;\n } catch (cause) {\n if (targetKeyRef.current === ownedTargetKey) {\n setMutationError(asError(cause));\n await load();\n }\n return null;\n } finally {\n if (targetKeyRef.current === ownedTargetKey && turnId in pendingRef.current) {\n const next = { ...pendingRef.current };\n delete next[turnId];\n pendingRef.current = next;\n setPendingByTurn(next);\n }\n }\n },\n [acceptSnapshot, load, sessionId, targetKey],\n );\n\n const moveTurn = useCallback(\n async (turnId: string, beforeTurnId: string | null): Promise<boolean> => {\n const result = await mutate(turnId, \"move\", (current, _turn, clientEventId) =>\n client.moveQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedQueueVersion: current.version,\n beforeTurnId,\n }),\n );\n return result !== null;\n },\n [client, mutate, sessionId, workspaceId],\n );\n\n const editTurn = useCallback(\n async (\n turnId: string,\n edit: { expectedDraftRevision: number; replaceDraft: boolean },\n ): Promise<ComposerDraft | null> => {\n const result = await mutate(turnId, \"edit\", (_current, turn, clientEventId) =>\n client.editQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedTurnVersion: turn.version,\n expectedDraftRevision: edit.expectedDraftRevision,\n replaceDraft: edit.replaceDraft,\n }),\n );\n return result?.draft ?? null;\n },\n [client, mutate, sessionId, workspaceId],\n );\n\n const steerTurn = useCallback(\n async (turnId: string): Promise<boolean> => {\n const ownedTargetKey = targetKey;\n const turn = snapshotRef.current?.items.find((candidate) => candidate.id === turnId);\n if (targetKeyRef.current !== ownedTargetKey) return false;\n if (!turn) {\n setMutationError(new Error(t(\"hooks.useTurnQueue.thatQueuedPromptChangedBefore\")));\n await load();\n return false;\n }\n const optimistic: AcceptedQueueSteer = {\n turnId: turn.id,\n triggerEventId: turn.triggerEventId,\n text: turn.prompt,\n annotations: turn.annotations ?? [],\n resources: turn.resources,\n tools: turn.tools,\n occurredAt: new Date().toISOString(),\n state: \"sending\",\n };\n setAcceptedSteers((current) => [\n ...current.filter((steer) => steer.turnId !== turnId),\n optimistic,\n ]);\n const result = await mutate(turnId, \"steer\", (current, queuedTurn, clientEventId) =>\n client.steerQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedTurnVersion: queuedTurn.version,\n controlEtag: current.effectiveControl.controlEtag,\n }),\n );\n if (targetKeyRef.current !== ownedTargetKey) return false;\n // The active turn can finish while the operator clicks Steer. In that\n // race the queued prompt is atomically claimed before the steer command,\n // so the command conflicts but the user's prompt already advanced into\n // chat. Reconciled absence is success, not a scary unknown-outcome lie.\n const advancedWithoutSteer =\n result === null &&\n snapshotRef.current !== null &&\n !snapshotRef.current.items.some((candidate) => candidate.id === turnId);\n if (advancedWithoutSteer) {\n setMutationError(null);\n setAcceptedSteers((current) => current.filter((steer) => steer.turnId !== turnId));\n return true;\n }\n const accepted =\n result !== null ||\n snapshotRef.current?.items.some(\n (candidate) => candidate.id === turnId && candidate.metadata.delivery === \"steer\",\n ) === true;\n setAcceptedSteers((current) =>\n accepted\n ? current.map((steer) =>\n steer.turnId === turnId ? { ...steer, state: \"queued\" as const } : steer,\n )\n : current.filter((steer) => steer.turnId !== turnId),\n );\n return accepted;\n },\n [client, load, mutate, sessionId, targetKey, workspaceId, t],\n );\n\n const removeTurn = useCallback(\n async (turnId: string): Promise<boolean> => {\n const result = await mutate(turnId, \"delete\", (_current, turn, clientEventId) =>\n client.deleteQueueItem(workspaceId, sessionId!, turnId, {\n clientEventId,\n expectedTurnVersion: turn.version,\n reason: \"Deleted from the prompt queue\",\n }),\n );\n return result !== null;\n },\n [client, mutate, sessionId, workspaceId],\n );\n\n const identityMatches = stateTargetKey === targetKey;\n const visibleSnapshot = freshSnapshot ?? retainedSnapshot;\n const visiblePendingByTurn = identityMatches ? pendingByTurn : EMPTY_PENDING_BY_TURN;\n const mutating = useMemo(\n () => Object.keys(visiblePendingByTurn).length > 0,\n [visiblePendingByTurn],\n );\n const mutationFor = useCallback(\n (turnId: string): QueueMutationKind | null => visiblePendingByTurn[turnId] ?? null,\n [visiblePendingByTurn],\n );\n\n return {\n snapshot: visibleSnapshot,\n queue: visibleSnapshot?.items ?? [],\n pendingInputs: visibleSnapshot?.pendingInputs ?? [],\n pendingInputAttachment: visibleSnapshot?.pendingInputAttachment ?? null,\n activePersonalConnections: visibleSnapshot?.activePersonalConnections ?? [],\n effectiveControl: visibleSnapshot?.effectiveControl ?? null,\n stoppingPreviousAttempt: visibleSnapshot?.stoppingPreviousAttempt ?? false,\n loading: freshLoading && retainedSnapshot === null,\n error: identityMatches ? error : null,\n refresh: load,\n moveTurn,\n editTurn,\n steerTurn,\n removeTurn,\n pendingByTurn: visiblePendingByTurn,\n mutationFor,\n mutating,\n mutationError: identityMatches ? mutationError : null,\n clearMutationError: useCallback(() => {\n if (targetKeyRef.current === targetKey) setMutationError(null);\n }, [targetKey]),\n acceptedSteers: identityMatches ? acceptedSteers : [],\n };\n}\n\nfunction operationKey(): string {\n return globalThis.crypto.randomUUID();\n}\n\nfunction asError(cause: unknown): Error {\n return normalizeError(cause);\n}\n\nfunction isOutcomeUnknownError(cause: unknown): boolean {\n return (\n typeof cause === \"object\" &&\n cause !== null &&\n (cause as { outcomeUnknown?: unknown }).outcomeUnknown === true\n );\n}\n","import type { SendMessageInput } from \"@opengeni/sdk\";\nimport { useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { projectPendingApprovals } from \"../approvals\";\nimport { conversationTimeline } from \"../conversation-timeline\";\nimport { useSessionStartupTimeline, type PendingPrompt } from \"../lib/session-startup-timeline\";\nimport { admissionRecheckControl } from \"../session-admission-model\";\nimport { useOpenGeni, type ClientOverride } from \"../session-context\";\nimport { useWorkspaceModelCatalog } from \"./use-available-models\";\nimport { useClientConfigFlags } from \"./use-client-config-flags\";\nimport { useComposer, type UseComposerOptions } from \"./use-composer\";\nimport { useFileAttachments } from \"./use-file-attachments\";\nimport { useHumanInputRequests } from \"./use-human-input\";\nimport { useSession } from \"./use-session\";\nimport { useSessionControl } from \"./use-session-control\";\nimport { useSessionEvents } from \"./use-session-events\";\nimport { useTurnQueue } from \"./use-turn-queue\";\n\nexport type UseSessionConversationOptions = ClientOverride & {\n /** Uploads remain subject to the client's capabilities. Defaults to true. */\n attachments?: boolean | undefined;\n /** Defaults to the client's model-selection offer. */\n modelPicker?: boolean | undefined;\n /**\n * Optional host context and notifications. The stock composer still owns\n * draft validation, annotations, retry identity, queueing and delivery.\n * File cleanup and upload blocking are composed with, not replaced by, these hooks.\n *\n * `busySend: \"steer\"` gives people one Send and nothing to learn: a message\n * sent while the agent works is read as soon as it can, with no Queue\n * choice beside Send and no Queue or Steer words (`offerQueue` brings the\n * Queue choice back).\n */\n composerOptions?:\n | Pick<\n UseComposerOptions,\n | \"sendExtras\"\n | \"sendBlocked\"\n | \"onSubmitted\"\n | \"onSent\"\n | \"onDeliveryError\"\n | \"initialDraft\"\n | \"busySend\"\n | \"offerQueue\"\n >\n | undefined;\n /**\n * The first prompt, when the host sent it before this conversation could\n * read it back (for example while the host's server creates the session).\n * The conversation shows it with the startup row from the first frame,\n * keeps them while the session id is still `null` and history loads, and\n * then hands over to the live timeline without a blank frame or a second\n * loading style. Read once per conversation; later changes are ignored.\n * While the id is `null` nothing can be sent, and the stock view disables\n * its composer; a custom layout should disable its composer too, since a\n * draft written then is not carried into the created session.\n */\n pendingPrompt?: PendingPrompt | null | undefined;\n};\n\nexport type { PendingPrompt };\n\nexport type SessionConversationController = ReturnType<typeof useSessionConversation>;\n\n/**\n * The complete conversation's state, independent of its layout. Mount once in\n * a stable host and pass the result to SessionConversationView, or compose the\n * stock timeline/chrome/composer around the same controller. Unmounting a view\n * does not dispose the stream, draft or uploads while this hook stays mounted.\n * The ordinary SessionConversation component uses this exact implementation.\n */\nexport function useSessionConversation(\n /** `null` while the host is still creating the session; pass `pendingPrompt` with it. */\n sessionId: string | null,\n options: UseSessionConversationOptions = {},\n) {\n // Captured once: hosts often drop the prompt after the first render. It\n // belongs to the first conversation only (see `usePendingPrompt`).\n const [initialPrompt] = useState(() => options.pendingPrompt ?? null);\n const context = useOpenGeni(options);\n const scope = { client: context.client, workspaceId: context.workspaceId };\n const config = useClientConfigFlags(context.client);\n const showModelPicker = options.modelPicker ?? config.modelSelection;\n const catalog = useWorkspaceModelCatalog({ ...scope, enabled: showModelPicker });\n const feed = useSessionEvents(sessionId, scope);\n const pendingPrompt = usePendingPrompt(initialPrompt, sessionId, feed.initialHistoryReady);\n const eventOptions = { ...scope, events: feed.events };\n const detail = useSession(sessionId, eventOptions);\n const queue = useTurnQueue(sessionId, eventOptions);\n const human = useHumanInputRequests(sessionId, eventOptions);\n const control = useSessionControl(sessionId, scope);\n const approvals = useMemo(() => projectPendingApprovals(feed.events), [feed.events]);\n const files = useFileAttachments(scope);\n const clearFiles = files.clear;\n const attachmentSession = useRef(sessionId);\n useLayoutEffect(() => {\n if (attachmentSession.current === sessionId) return;\n const created = attachmentSession.current === null;\n attachmentSession.current = sessionId;\n // A session the host just created keeps what the person attached meanwhile.\n if (created) return;\n // Upload transport is workspace-scoped; these unsent cards belong to one\n // conversation. Retiring them also makes late settlements no-ops because\n // their local attachment identities no longer exist in the queue.\n clearFiles();\n }, [clearFiles, sessionId]);\n const uploadsEnabled = (options.attachments ?? true) && config.uploads;\n const status = feed.sessionStatus ?? detail.session?.status;\n const terminal = status === \"cancelled\";\n const importedArchive = detail.session?.importedArchive?.readOnly === true;\n const host = options.composerOptions;\n const resolveExtras = () =>\n typeof host?.sendExtras === \"function\" ? host.sendExtras() : host?.sendExtras;\n const releaseSentFiles = (input: SendMessageInput) =>\n files.removeReadyFiles(\n (input.resources ?? []).flatMap((resource) =>\n resource.kind === \"file\" ? [resource.fileId] : [],\n ),\n );\n const composer = useComposer(sessionId, {\n ...eventOptions,\n initialDraft: host?.initialDraft,\n busySend: host?.busySend,\n offerQueue: host?.offerQueue,\n effectiveControl: queue.effectiveControl ?? detail.session?.effectiveControl,\n // As in the console and the native screen: a turn that is still current\n // (running, recovering or waiting for capacity) means a Send waits.\n sendDestination: () =>\n queue.queue.length > 0 ||\n status === \"running\" ||\n (detail.session?.activeTurnId ?? null) !== null\n ? \"queue\"\n : \"chat\",\n sendExtras: () => {\n const extras = resolveExtras();\n return {\n ...extras,\n resources: [...(extras?.resources ?? []), ...(uploadsEnabled ? files.readyResources : [])],\n };\n },\n sendBlocked: () =>\n sessionId === null ||\n terminal ||\n importedArchive ||\n (uploadsEnabled && files.hasUnresolved) ||\n host?.sendBlocked?.() === true,\n onSubmitted: (text, input) => {\n releaseSentFiles(input);\n return host?.onSubmitted?.(text, input);\n },\n onSent: (text, input) => {\n releaseSentFiles(input);\n return host?.onSent?.(text, input);\n },\n onDeliveryError: host?.onDeliveryError,\n });\n const conversation = useMemo(\n () => conversationTimeline(feed.timeline, queue, composer),\n [feed.timeline, queue, composer],\n );\n // The same startup row as the web app's session page: from the accepted\n // prompt until the turn's own work row, one loading state, never a gap.\n // A session without control state yet shows no startup row rather than\n // guessing whether it is active.\n const session = detail.session;\n const sessionControl = session?.effectiveControl;\n const timeline = useSessionStartupTimeline(conversation, {\n session:\n session && sessionControl\n ? {\n ...session,\n effectiveControl: admissionRecheckControl(\n sessionControl,\n queue.effectiveControl,\n composer.effectiveControl,\n ),\n }\n : null,\n events: feed.events,\n optimisticMessages: composer.optimisticMessages,\n hasNewer: feed.hasNewer,\n queue: queue.snapshot,\n pendingPrompt,\n historyReady: sessionId !== null && feed.initialHistoryReady,\n });\n const error = detail.error ?? feed.error ?? human.error;\n const loadFailed = Boolean(feed.error) && !feed.initialHistoryReady;\n const retry = async () => {\n await Promise.all([\n ...(detail.error ? [detail.refresh()] : []),\n ...(human.error ? [human.refresh()] : []),\n ...(feed.error ? [feed.jumpToLatest()] : []),\n ]);\n };\n\n return {\n ...scope,\n sessionId,\n config,\n catalog,\n showModelPicker,\n feed,\n detail,\n queue,\n human,\n control,\n approvals,\n files,\n uploadsEnabled,\n composer,\n /** The same live application context for text and durable voice messages. */\n getModelContext: () => resolveExtras()?.modelContext,\n timeline,\n status,\n terminal,\n importedArchive,\n running: status === \"running\" || status === \"recovering\" || status === \"waiting_capacity\",\n error,\n loadFailed,\n retry,\n };\n}\n\n/**\n * The first prompt belongs to the conversation it was sent in: the session\n * that is still being created (`null`) and the id it then gets. It retires\n * once that session's history is readable, or when the conversation moves to\n * any other session, so no later session can show it.\n */\nfunction usePendingPrompt(\n prompt: PendingPrompt | null,\n sessionId: string | null,\n historyReady: boolean,\n): PendingPrompt | null {\n const owner = useRef<{ sessionId: string | null; retired: boolean }>({\n sessionId,\n retired: prompt === null,\n });\n const current = owner.current;\n if (!current.retired && current.sessionId !== sessionId) {\n if (current.sessionId === null) current.sessionId = sessionId;\n else current.retired = true;\n }\n if (!current.retired && sessionId !== null && historyReady) current.retired = true;\n return current.retired ? null : prompt;\n}\n","import {\n OpenGeniApiError,\n observedSessionSequence,\n type SessionEvent,\n type SessionGoal,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { useEmbeddedGoal, type EmbeddedGoalClientOverride } from \"../session-context\";\nimport { normalizeError } from \"../lib/error-message\";\nimport { deniesRetainedView, useRetainedSessionView } from \"./session-view-cache\";\nimport {\n projectionReadThrough,\n useDebouncedCallback,\n useMutationRunner,\n usePageLiveActivity,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\n/** Event types that change the session goal (set/updated/completed/paused/...). */\nexport function isGoalEvent(event: Pick<SessionEvent, \"type\">): boolean {\n return event.type.startsWith(\"goal.\");\n}\n\n/**\n * Events that can change the server-authoritative continuation projection.\n * The projection is derived from durable turn, session, control, and system\n * update state, so those events refresh the goal without model polling.\n */\nexport function isGoalRefreshEvent(event: Pick<SessionEvent, \"type\">): boolean {\n const type = event.type;\n return (\n isGoalEvent(event) ||\n type.startsWith(\"turn.\") ||\n type.startsWith(\"session.\") ||\n type.startsWith(\"system.update.\") ||\n type.startsWith(\"workspace.inference.\") ||\n type.startsWith(\"user.\")\n );\n}\n\nexport type UseGoalOptions = EmbeddedGoalClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default — event refreshes drive updates. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseGoalResult = {\n /** The session goal, or null when the session has none. */\n goal: SessionGoal | null;\n /** Convenience flags over `goal.status`. */\n isActive: boolean;\n isPaused: boolean;\n isCompleted: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n /** Pause the goal loop (PATCH status=paused). */\n pause: (rationale?: string) => Promise<SessionGoal | null>;\n /** Resume a paused goal: resets counters and re-arms continuations. */\n resume: () => Promise<SessionGoal | null>;\n /** Clear the session goal; goal-less sessions remain a successful no-op. */\n clearGoal: () => Promise<void>;\n /** Alias for `clearGoal`. */\n deleteGoal: () => Promise<void>;\n /** True while a pause/resume/clear is in flight. */\n updating: boolean;\n mutationError: Error | null;\n clearMutationError: () => void;\n};\n\n/**\n * The session's goal: state, the autonomy counters (`autoContinuations`,\n * `noProgressStreak`), and pause/resume control. A goal-less session yields\n * `goal: null`: read through `findGoal` as a successful null when the client\n * has it, otherwise from an absorbed 404. Live-updates on goal, turn, session,\n * control, and system-update events — pass `options.events` from\n * `useSessionEvents` to reuse its stream.\n */\nexport function useGoal(\n sessionId: string | null | undefined,\n options: UseGoalOptions = {},\n): UseGoalResult {\n const { client, workspaceId } = useEmbeddedGoal(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const sharedEvents = options.events;\n const sharedFeed = sharedEvents !== undefined;\n const pageLive = usePageLiveActivity();\n const [goal, setGoal] = useState<SessionGoal | null>(null);\n const [loading, setLoading] = useState(enabled);\n const [error, setError] = useState<Error | null>(null);\n // The latest read (or a delete) established that this conversation has no goal.\n const [readAbsent, setReadAbsent] = useState(false);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner();\n const generation = useRef(0);\n const targetKeyRef = useRef<string | null>(null);\n // True after the server answered that no goal exists. Only a goal event can\n // create a goal, so turn/session traffic must not refetch while none exists.\n const goalAbsentRef = useRef(false);\n // Refresh events not yet covered by a read: \"goal\" when any was a goal.*\n // event. Events that arrive while a read is in flight are decided when it\n // settles, so the stream's opening burst never re-reads a goal-less session.\n const pendingRefreshRef = useRef<\"none\" | \"refresh\" | \"goal\">(\"none\");\n const sharedEventsRef = useRef(sharedEvents);\n useLayoutEffect(() => {\n sharedEventsRef.current = sharedEvents;\n }, [sharedEvents]);\n const loadAbort = useRef<AbortController | null>(null);\n const scheduleRefreshRef = useRef<() => void>(() => undefined);\n\n const retireLoads = useCallback(() => {\n generation.current += 1;\n loadAbort.current?.abort();\n loadAbort.current = null;\n }, []);\n\n const load = useCallback(async (): Promise<void> => {\n if (!sessionId) {\n return;\n }\n const ticket = ++generation.current;\n pendingRefreshRef.current = \"none\";\n loadAbort.current?.abort();\n const controller = new AbortController();\n loadAbort.current = controller;\n let fetchedGoal: SessionGoal | null = null;\n try {\n // findGoal reads a goal-less session as a successful null, so no failed\n // request reaches the browser console. Custom clients without it keep\n // getGoal, whose 404 is absorbed below (as it is from older servers).\n const fetched =\n typeof client.findGoal === \"function\"\n ? await client.findGoal(workspaceId, sessionId, { signal: controller.signal })\n : await client.getGoal(workspaceId, sessionId, { signal: controller.signal });\n fetchedGoal = fetched;\n if (ticket === generation.current) {\n goalAbsentRef.current = fetched === null;\n setReadAbsent(fetched === null);\n setGoal(fetched);\n setError(null);\n setLoading(false);\n }\n } catch (cause) {\n if (ticket !== generation.current) {\n return;\n }\n if (cause instanceof OpenGeniApiError && cause.status === 404) {\n // No goal is a normal state, not an error.\n goalAbsentRef.current = true;\n setReadAbsent(true);\n setGoal(null);\n setError(null);\n } else {\n setError(normalizeError(cause));\n }\n setLoading(false);\n } finally {\n if (loadAbort.current === controller) loadAbort.current = null;\n }\n if (ticket !== generation.current || pendingRefreshRef.current === \"none\") {\n return;\n }\n // Events arrived during this read, but a goal read that reports the session\n // sequence it reflects already includes every one at or below it. Only a\n // shared feed shows which events those were; a self-stream re-reads.\n const readThrough = fetchedGoal ? observedSessionSequence(fetchedGoal) : undefined;\n if (readThrough !== undefined && sharedEventsRef.current !== undefined) {\n const events = sharedEventsRef.current;\n const newest = events[events.length - 1];\n if (!newest || newest.sequence <= readThrough) {\n pendingRefreshRef.current = \"none\";\n return;\n }\n }\n // Events arrived during this read. A shared feed's first batch reports only\n // its latest match, so a goal.* event behind newer turn traffic is visible\n // only in the log: re-read when its latest goal event is not a clear.\n if (goalAbsentRef.current && pendingRefreshRef.current === \"refresh\") {\n const events = sharedEventsRef.current ?? [];\n let latestGoalEvent: SessionEvent | undefined;\n for (let index = events.length - 1; index >= 0 && !latestGoalEvent; index -= 1) {\n const event = events[index];\n if (event && isGoalEvent(event)) latestGoalEvent = event;\n }\n if (!latestGoalEvent || latestGoalEvent.type === \"goal.cleared\") {\n pendingRefreshRef.current = \"none\";\n return;\n }\n pendingRefreshRef.current = \"goal\";\n }\n scheduleRefreshRef.current();\n }, [client, workspaceId, sessionId]);\n\n useEffect(() => {\n const targetKey = `${workspaceId} ${sessionId ?? \"\"}`;\n if (targetKeyRef.current !== targetKey) {\n targetKeyRef.current = targetKey;\n goalAbsentRef.current = false;\n pendingRefreshRef.current = \"none\";\n setReadAbsent(false);\n setGoal(null);\n setError(null);\n }\n if (!enabled || !pageLive) {\n retireLoads();\n setLoading(false);\n return;\n }\n if (sharedFeed) {\n // A shared log supplies invalidations, not the authoritative goal snapshot.\n setLoading(true);\n void load();\n return () => {\n retireLoads();\n };\n }\n setLoading(true);\n const pollIntervalMs = options.pollIntervalMs;\n if (pollIntervalMs === undefined || pollIntervalMs <= 0) {\n void load();\n return () => {\n retireLoads();\n };\n }\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const schedule = () => {\n if (cancelled) return;\n timer = setTimeout(() => {\n timer = null;\n void load().finally(schedule);\n }, pollIntervalMs);\n };\n void load().finally(schedule);\n return () => {\n cancelled = true;\n if (timer !== null) clearTimeout(timer);\n retireLoads();\n };\n }, [\n load,\n enabled,\n pageLive,\n workspaceId,\n sessionId,\n options.pollIntervalMs,\n retireLoads,\n sharedFeed,\n ]);\n\n const scheduleRefresh = useDebouncedCallback(() => {\n const pending = pendingRefreshRef.current;\n // An in-flight read settles pending events itself.\n if (pending === \"none\" || loadAbort.current !== null) return;\n if (pending === \"refresh\" && goalAbsentRef.current) {\n pendingRefreshRef.current = \"none\";\n return;\n }\n void load();\n });\n useLayoutEffect(() => {\n scheduleRefreshRef.current = scheduleRefresh;\n }, [scheduleRefresh]);\n const isRefreshEvent = useCallback(\n (event: SessionEvent) =>\n goalAbsentRef.current ? isGoalEvent(event) : isGoalRefreshEvent(event),\n [],\n );\n const refreshGoal = useCallback(() => {\n pendingRefreshRef.current = \"goal\";\n scheduleRefresh();\n }, [scheduleRefresh]);\n const onRefreshEvent = useCallback(\n (event: SessionEvent) => {\n if (isGoalEvent(event)) pendingRefreshRef.current = \"goal\";\n else if (pendingRefreshRef.current === \"none\") pendingRefreshRef.current = \"refresh\";\n scheduleRefresh();\n },\n [scheduleRefresh],\n );\n useSessionEventTrigger(client, workspaceId, sessionId, isRefreshEvent, onRefreshEvent, {\n enabled,\n ...(sharedEvents !== undefined ? { events: sharedEvents } : {}),\n // The load settles events that arrive during its read itself (above).\n readThrough: projectionReadThrough(goal, false),\n refresh: refreshGoal,\n });\n // Until the first read lands, show the goal as it was when this conversation\n // was last left (only when the host retains reads).\n const retainedGoal = useRetainedSessionView(\n client,\n workspaceId,\n sessionId,\n \"goal\",\n loading ? null : goal,\n { enabled, discard: readAbsent || deniesRetainedView(error) },\n );\n const visibleGoal = loading ? (goal ?? retainedGoal) : goal;\n\n // A retained goal is shown before this open's read lands. A command issued\n // then waits for that read and runs only if the goal it was aimed at is\n // still the current objective; another actor may have replaced it meanwhile.\n const goalRef = useRef(goal);\n const shownRetainedRef = useRef<SessionGoal | null>(null);\n const readWaitersRef = useRef<Array<() => void>>([]);\n useLayoutEffect(() => {\n goalRef.current = goal;\n shownRetainedRef.current = loading && goal === null ? retainedGoal : null;\n });\n useEffect(() => {\n if (loading) return;\n const waiters = readWaitersRef.current;\n readWaitersRef.current = [];\n for (const resolve of waiters) resolve();\n }, [loading]);\n useEffect(\n () => () => {\n // Leaving the conversation settles waiting commands as not applicable.\n goalRef.current = null;\n const waiters = readWaitersRef.current;\n readWaitersRef.current = [];\n for (const resolve of waiters) resolve();\n },\n [workspaceId, sessionId],\n );\n const aimedAtCurrentGoal = useCallback(async (): Promise<boolean> => {\n const shown = shownRetainedRef.current;\n if (!shown) return true;\n await new Promise<void>((resolve) => readWaitersRef.current.push(resolve));\n const fresh = goalRef.current;\n return (\n fresh !== null && fresh.id === shown.id && fresh.objectiveRevision === shown.objectiveRevision\n );\n }, []);\n\n const pause = useCallback(\n async (rationale?: string): Promise<SessionGoal | null> => {\n if (!sessionId || !(await aimedAtCurrentGoal())) {\n return null;\n }\n const result = await run(() =>\n client.updateGoal(workspaceId, sessionId, {\n status: \"paused\",\n ...(rationale !== undefined ? { rationale } : {}),\n }),\n );\n if (result) {\n setGoal(result);\n }\n return result;\n },\n [client, workspaceId, sessionId, run, aimedAtCurrentGoal],\n );\n\n const resume = useCallback(async (): Promise<SessionGoal | null> => {\n if (!sessionId || !(await aimedAtCurrentGoal())) {\n return null;\n }\n const result = await run(() => client.updateGoal(workspaceId, sessionId, { status: \"active\" }));\n if (result) {\n setGoal(result);\n }\n return result;\n }, [client, workspaceId, sessionId, run, aimedAtCurrentGoal]);\n\n const clearGoal = useCallback(async (): Promise<void> => {\n if (!sessionId || !(await aimedAtCurrentGoal())) {\n return;\n }\n // deleteGoal resolves void, so distinguish success (a truthy sentinel) from\n // mutation.run's null-on-failure. Only a SUCCESSFUL delete hides the goal:\n // a failed one leaves the pill up so its mutationError renders. And invalidate\n // any in-flight load first so a slower getGoal started before the delete can't\n // commit and repopulate the just-cleared goal.\n const ok = await run(async () => {\n await client.deleteGoal(workspaceId, sessionId);\n return true as const;\n });\n if (ok) {\n retireLoads();\n setReadAbsent(true);\n setGoal(null);\n setError(null);\n }\n }, [client, workspaceId, sessionId, run, retireLoads, aimedAtCurrentGoal]);\n\n return {\n goal: visibleGoal,\n isActive: visibleGoal?.status === \"active\",\n isPaused: visibleGoal?.status === \"paused\",\n isCompleted: visibleGoal?.status === \"completed\",\n loading: loading && retainedGoal === null,\n error,\n refresh: load,\n pause,\n resume,\n clearGoal,\n deleteGoal: clearGoal,\n updating: mutating,\n mutationError,\n clearMutationError,\n };\n}\n","import type { SessionEvent } from \"@opengeni/sdk\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport {\n readAcknowledgementFrontier,\n sessionAttentionReadThroughSequence,\n} from \"../session-attention-model\";\n\n/** The optional attention mutation a host client may expose (the SDK client does). */\nexport type SessionAttentionClientLike = {\n updateSessionAttention?(\n workspaceId: string,\n sessionId: string,\n request: { unread?: boolean; acknowledgedThroughSequence?: number },\n ): Promise<unknown>;\n};\n\nexport type UseSessionReadAcknowledgementInput = {\n client: SessionAttentionClientLike;\n workspaceId: string;\n /** `null` while the host is still creating the session: nothing to acknowledge. */\n sessionId: string | null;\n /** The session row as last read. A row for another session is ignored. */\n session:\n | {\n id?: string | undefined;\n unread?: boolean | undefined;\n lastSequence?: number | undefined;\n }\n | null\n | undefined;\n /** The conversation's delivered events (the shared feed). */\n events: readonly SessionEvent[];\n /**\n * True only while the person can actually see the conversation: on the web\n * its timeline is on screen, the page is visible and the window focused; on\n * a phone the screen is focused and the app in the foreground.\n */\n active: boolean;\n};\n\n/** Delay before the single retry of a transient failure. */\nexport const SESSION_READ_ACKNOWLEDGEMENT_RETRY_MS = 1_000;\n\n/** A rejection that will not change on retry (no permission, route not offered). */\nfunction isPermanentRejection(error: unknown): boolean {\n const status =\n error && typeof error === \"object\" ? (error as { status?: unknown }).status : undefined;\n return (\n typeof status === \"number\" && status >= 400 && status < 500 && status !== 408 && status !== 429\n );\n}\n\n/**\n * Mark an open conversation read while the person is looking at it. Reading a\n * session never acknowledges it on the server; without this every reply stays\n * unread, and attention signals built on it (unread dots, pushes, webhooks a\n * host turns into notifications) fire even while the person watches the reply.\n *\n * It acknowledges through the latest delivered attention boundary (a completed\n * reply, question, approval or failure), never per streaming flush, and sends\n * `acknowledgedThroughSequence`, so a request that arrives late can never\n * consume a newer reply. One transient failure is retried once; after that the\n * frontier is released and the next foreground change retries it, so a failing\n * server never becomes a request loop. A permanent rejection (4xx) stops\n * acknowledgement for that session until the component remounts.\n */\nexport function useSessionReadAcknowledgement(input: UseSessionReadAcknowledgementInput): void {\n const { client, workspaceId, sessionId, events, active } = input;\n const session =\n input.session && (input.session.id ?? sessionId) === sessionId ? input.session : null;\n const attentionThrough = useMemo(() => sessionAttentionReadThroughSequence(events), [events]);\n const { readThrough, unread } = readAcknowledgementFrontier(session, attentionThrough);\n const hasSession = session !== null;\n /** The frontier currently being acknowledged or already acknowledged. */\n const receipt = useRef<string | null>(null);\n /** Sessions whose acknowledgement the server refused for good. */\n const refused = useRef(new Set<string>());\n const retryTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (retryTimer.current !== null) clearTimeout(retryTimer.current);\n retryTimer.current = null;\n receipt.current = null;\n },\n [],\n );\n\n useEffect(() => {\n if (!active || !hasSession || !unread || readThrough <= 0) return;\n if (!workspaceId || !sessionId || typeof client.updateSessionAttention !== \"function\") return;\n const scope = `${workspaceId}:${sessionId}`;\n if (refused.current.has(scope)) return;\n const key = `${scope}:${readThrough}`;\n if (receipt.current === key) return;\n receipt.current = key;\n if (retryTimer.current !== null) clearTimeout(retryTimer.current);\n retryTimer.current = null;\n\n const attempt = (retried: boolean) => {\n void Promise.resolve()\n .then(() =>\n client.updateSessionAttention!(workspaceId, sessionId, {\n unread: false,\n acknowledgedThroughSequence: readThrough,\n }),\n )\n .catch((error: unknown) => {\n // A newer frontier (or another session) owns acknowledgement now.\n if (receipt.current !== key) return;\n if (isPermanentRejection(error)) {\n refused.current.add(scope);\n return;\n }\n if (!retried) {\n retryTimer.current = setTimeout(() => {\n retryTimer.current = null;\n if (receipt.current === key) attempt(true);\n }, SESSION_READ_ACKNOWLEDGEMENT_RETRY_MS);\n return;\n }\n // Release this frontier so the next focus or visibility change can\n // try again, without retrying on our own.\n receipt.current = null;\n });\n };\n attempt(false);\n }, [active, client, hasSession, readThrough, sessionId, unread, workspaceId]);\n}\n","import {\n OpenGeniApiError,\n type FileResourceRef,\n type LatencyMode,\n type OpenGeniClient,\n type ReasoningEffort,\n} from \"@opengeni/sdk\";\nimport type { SessionRealtimeModel } from \"@opengeni/sdk/realtime\";\nimport { useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useOpenGeni, type ClientOverride } from \"../session-context\";\nimport { notifyObserver } from \"../lib/notify-observer\";\nimport {\n coerceReasoningEffortForModel,\n defaultEffortForModel,\n runnableLatencyModesForModel,\n} from \"../model-policy\";\nimport { useWorkspaceModelCatalog } from \"./use-available-models\";\nimport { useClientConfigFlags } from \"./use-client-config-flags\";\nimport {\n FILE_ONLY_MESSAGE_TEXT,\n type ComposerState,\n type InitialComposerDraft,\n} from \"./use-composer\";\nimport { useFileAttachments } from \"./use-file-attachments\";\nimport { useOpenGeniText } from \"../messages/runtime\";\n\n/** Browser choices, not server-owned agent configuration or authority. */\nexport type NewConversationCreateOptions = {\n resources?: FileResourceRef[] | undefined;\n model?: string | undefined;\n reasoningEffort?: ReasoningEffort | undefined;\n latencyMode?: LatencyMode | undefined;\n /** Creates an empty session; no synthetic first user message. */\n startMode?: \"realtime\" | undefined;\n};\n\nexport type CreatedConversation = {\n sessionId: string;\n /** The accepted first message; empty for voice-first creation. */\n initialMessage: string;\n /** When the person sent it (ISO 8601); pass both as the conversation's `pendingPrompt`. */\n sentAt: string;\n /** Newer unsent content, or the whole untouched draft for voice-first creation. */\n draft: InitialComposerDraft;\n realtimeModel?: SessionRealtimeModel | undefined;\n};\n\nexport type UseNewConversationOptions = ClientOverride & {\n createSession?:\n | ((\n initialMessage: string,\n idempotencyKey: string,\n options: NewConversationCreateOptions,\n ) => Promise<string>)\n | undefined;\n onCreated?: ((created: CreatedConversation) => void) | undefined;\n /** A host may disable creation while its own required state is loading. */\n enabled?: boolean | undefined;\n attachments?: boolean | undefined;\n modelPicker?: boolean | undefined;\n realtimeVoice?: boolean | undefined;\n /** Changes reset this new-chat draft; use for host record/project scope. */\n scopeKey?: string | undefined;\n};\n\ntype Choice = Pick<NewConversationCreateOptions, \"model\" | \"reasoningEffort\" | \"latencyMode\">;\ntype Attempt = {\n key: string;\n initialMessage: string;\n sentAt: string;\n options: NewConversationCreateOptions;\n textRevision: number;\n clearDraft: boolean;\n realtimeModel?: SessionRealtimeModel | undefined;\n /** Freeze the host adapter too: its captured context belongs to this attempt. */\n create: NonNullable<UseNewConversationOptions[\"createSession\"]>;\n};\ntype Completion = { sessionId: string; attempt: Attempt; generation: number };\nconst NOOP_ASYNC = async () => {};\n\nexport type NewConversationController = ReturnType<typeof useNewConversation>;\n\n/** Stock new-chat state shared by OpenGeniChat and custom host layouts. */\nexport function useNewConversation(options: UseNewConversationOptions = {}) {\n const t = useOpenGeniText();\n const context = useOpenGeni(options);\n const scope = { client: context.client, workspaceId: context.workspaceId };\n const config = useClientConfigFlags(context.client);\n const showModelPicker = options.modelPicker ?? config.modelSelection;\n const catalog = useWorkspaceModelCatalog({ ...scope, enabled: showModelPicker });\n const files = useFileAttachments(scope);\n const uploadsEnabled = (options.attachments ?? true) && config.uploads;\n const available =\n options.enabled !== false && (options.createSession !== undefined || config.sessionCreation);\n const [text, setText] = useState(\"\");\n const [choice, setChoice] = useState<Choice>({});\n const [sending, setSending] = useState(false);\n const [error, setError] = useState<{ cause: unknown } | null>(null);\n const [pending, setPending] = useState<Attempt | null>(null);\n const [completion, setCompletion] = useState<Completion | null>(null);\n const textRef = useRef(text);\n const textRevision = useRef(0);\n const choiceRef = useRef(choice);\n const filesRef = useRef(files);\n filesRef.current = files;\n const pendingRef = useRef<Attempt | null>(null);\n const completionRef = useRef<Completion | null>(null);\n const inFlight = useRef(false);\n const lifetime = useRef({ mounted: true, generation: 0 }).current;\n // An identity value may recur (A → B → A); callbacks from the first A\n // must not become live again. Commit a distinct token for each scope epoch.\n const identity = useMemo(\n () => ({\n client: context.client,\n workspaceId: context.workspaceId,\n scopeKey: options.scopeKey,\n }),\n [context.client, context.workspaceId, options.scopeKey],\n );\n const committedIdentity = useRef(identity);\n useLayoutEffect(() => {\n lifetime.mounted = true;\n return () => {\n lifetime.mounted = false;\n lifetime.generation++;\n };\n }, [lifetime]);\n useLayoutEffect(() => {\n if (committedIdentity.current === identity) return;\n committedIdentity.current = identity;\n lifetime.generation++;\n inFlight.current = false;\n pendingRef.current = null;\n completionRef.current = null;\n textRef.current = \"\";\n textRevision.current = 0;\n choiceRef.current = {};\n setText(\"\");\n setChoice({});\n setSending(false);\n setError(null);\n setPending(null);\n setCompletion(null);\n filesRef.current.clear();\n }, [identity, lifetime]);\n\n const ownsScope = () => lifetime.mounted && committedIdentity.current === identity;\n const updateText = (value: string) => {\n if (!ownsScope()) return;\n if (value !== textRef.current) textRevision.current++;\n textRef.current = value;\n setText(value);\n };\n const updateChoice = (patch: Choice) => {\n if (!ownsScope()) return;\n const next = { ...choiceRef.current, ...patch };\n const model = catalog.models.find((row) => row.id === (next.model ?? catalog.defaultModel));\n if (model) {\n if (next.reasoningEffort)\n next.reasoningEffort = coerceReasoningEffortForModel(model, next.reasoningEffort);\n if (next.latencyMode && !runnableLatencyModesForModel(model).includes(next.latencyMode))\n next.latencyMode = \"standard\";\n }\n choiceRef.current = next;\n setChoice(choiceRef.current);\n };\n const effectivePolicy = () => {\n const model = choiceRef.current.model ?? catalog.defaultModel;\n const definition = catalog.models.find((row) => row.id === model);\n const effort =\n choiceRef.current.reasoningEffort ??\n (definition\n ? defaultEffortForModel(definition)\n : (config.defaultReasoningEffort ?? \"medium\"));\n return showModelPicker && model\n ? {\n model,\n reasoningEffort: definition ? coerceReasoningEffortForModel(definition, effort) : effort,\n latencyMode: choiceRef.current.latencyMode ?? (\"standard\" as const),\n }\n : undefined;\n };\n const create: Attempt[\"create\"] =\n options.createSession ??\n (async (initialMessage, idempotencyKey, input) => {\n const creator = (context.client as unknown as Partial<Pick<OpenGeniClient, \"createSession\">>)\n .createSession;\n if (typeof creator !== \"function\")\n throw new Error(t(\"hooks.useNewConversation.newChatsAreNotEnabled\"));\n const created = await creator.call(context.client, context.workspaceId, {\n ...(input.startMode === \"realtime\" ? {} : { initialMessage }),\n idempotencyKey,\n ...input,\n } as Parameters<OpenGeniClient[\"createSession\"]>[1]);\n return created.id;\n });\n\n const finishCreation = (accepted: Completion) => {\n if (!lifetime.mounted || lifetime.generation !== accepted.generation) return;\n const { attempt, sessionId } = accepted;\n const sentFiles = new Set(attempt.options.resources?.map((resource) => resource.fileId) ?? []);\n const policyChanged = ([\"model\", \"reasoningEffort\", \"latencyMode\"] as const).some(\n (field) => choiceRef.current[field] !== attempt.options[field],\n );\n const draft: InitialComposerDraft = {\n text:\n attempt.clearDraft && textRevision.current === attempt.textRevision ? \"\" : textRef.current,\n resources: filesRef.current.readyResources.filter(\n (resource) => !sentFiles.has(resource.fileId),\n ),\n // Unchanged choices are already part of the created session. Do not\n // replace server-owned defaults with a browser's catalog estimate.\n ...(policyChanged ? { policy: effectivePolicy() } : {}),\n };\n pendingRef.current = null;\n completionRef.current = null;\n setPending(null);\n setCompletion(null);\n updateText(draft.text);\n filesRef.current.removeReadyFiles(sentFiles);\n notifyObserver(options.onCreated, {\n sessionId,\n initialMessage: attempt.initialMessage,\n sentAt: attempt.sentAt,\n draft,\n ...(attempt.realtimeModel ? { realtimeModel: attempt.realtimeModel } : {}),\n });\n };\n const finishRef = useRef(finishCreation);\n finishRef.current = finishCreation;\n useLayoutEffect(() => {\n if (completion && !files.hasUnresolved) finishRef.current(completion);\n }, [completion, files.hasUnresolved]);\n\n const deliver = async (attempt: Attempt): Promise<boolean> => {\n if (!ownsScope() || inFlight.current || completionRef.current || !available) return false;\n const ownedGeneration = lifetime.generation;\n inFlight.current = true;\n pendingRef.current = attempt;\n setSending(true);\n setError(null);\n setPending(null);\n try {\n const sessionId = await attempt.create(\n attempt.initialMessage,\n attempt.key,\n structuredClone(attempt.options),\n );\n // Creation still succeeded, but navigation must not seize a different\n // scope's composer or selection when the original host is gone.\n if (!lifetime.mounted || lifetime.generation !== ownedGeneration) return true;\n const accepted = { sessionId, attempt, generation: ownedGeneration };\n completionRef.current = accepted;\n // The user may attach more files while creation is in flight. Keep this\n // composer until those cards resolve or are removed, then hand off their\n // durable references. Never lose browser-local upload bytes on navigation.\n if (filesRef.current.hasUnresolved) setCompletion(accepted);\n else finishCreation(accepted);\n return true;\n } catch (cause) {\n if (!lifetime.mounted || lifetime.generation !== ownedGeneration) return false;\n setError({ cause });\n if (cause instanceof OpenGeniApiError && cause.outcomeUnknown === false) {\n pendingRef.current = null;\n } else {\n // Unknown transport outcomes retain the exact key, payload and host\n // adapter. Editing the next draft must never mint a second session.\n setPending(attempt);\n }\n return false;\n } finally {\n if (lifetime.mounted && lifetime.generation === ownedGeneration) {\n inFlight.current = false;\n setSending(false);\n }\n }\n };\n const submit = async (explicit?: string): Promise<boolean> => {\n if (\n !ownsScope() ||\n !available ||\n inFlight.current ||\n pendingRef.current ||\n (uploadsEnabled && filesRef.current.hasUnresolved)\n )\n return false;\n const resources = uploadsEnabled ? filesRef.current.readyResources : [];\n const draftText = explicit ?? textRef.current;\n const initialMessage =\n draftText.trim() || (resources.length > 0 ? FILE_ONLY_MESSAGE_TEXT(t) : \"\");\n if (!initialMessage) return false;\n return deliver({\n key: crypto.randomUUID(),\n initialMessage,\n sentAt: new Date().toISOString(),\n textRevision: textRevision.current,\n clearDraft: explicit === undefined,\n create,\n options: {\n ...(resources.length ? { resources: structuredClone(resources) } : {}),\n ...(showModelPicker ? { ...choiceRef.current } : {}),\n },\n });\n };\n const startRealtime = async (model: SessionRealtimeModel): Promise<boolean> => {\n if (\n !ownsScope() ||\n !available ||\n inFlight.current ||\n pendingRef.current ||\n !config.realtimeVoice ||\n !(options.realtimeVoice ?? config.realtimeVoiceOffered)\n )\n return false;\n if (filesRef.current.hasUnresolved) return false;\n return deliver({\n key: crypto.randomUUID(),\n initialMessage: \"\",\n sentAt: new Date().toISOString(),\n textRevision: textRevision.current,\n clearDraft: false,\n create,\n options: { ...(showModelPicker ? { ...choiceRef.current } : {}), startMode: \"realtime\" },\n realtimeModel: model,\n });\n };\n const composer: ComposerState = {\n value: text,\n setValue: updateText,\n hasDraftContent: () => textRef.current.length > 0 || filesRef.current.attachments.length > 0,\n send: submit,\n steer: submit,\n sending,\n canSend:\n available &&\n !sending &&\n !pending &&\n !completion &&\n (text.trim().length > 0 || (uploadsEnabled && files.readyResources.length > 0)) &&\n !(uploadsEnabled && files.hasUnresolved),\n pause: NOOP_ASYNC,\n pausing: false,\n resume: NOOP_ASYNC,\n resumeScope: NOOP_ASYNC,\n resuming: false,\n draft: null,\n draftRevision: 0,\n draftLoading: false,\n draftSaving: false,\n draftConflict: null,\n policy: effectivePolicy() ?? null,\n setModel: (model) => updateChoice({ model }),\n setReasoningEffort: (reasoningEffort) => updateChoice({ reasoningEffort }),\n setLatencyMode: (latencyMode) => updateChoice({ latencyMode }),\n draftPersistence: \"disabled\",\n applyDraft: () => {},\n reloadDraft: NOOP_ASYNC,\n resolveDraftConflict: NOOP_ASYNC,\n restoredResources: [],\n removeRestoredResource: () => {},\n error: null,\n clearError: () => {\n if (ownsScope()) setError(null);\n },\n };\n return {\n ...scope,\n config,\n files,\n uploadsEnabled,\n available,\n showModelPicker,\n catalog,\n composer,\n realtimeVoiceEnabled:\n config.realtimeVoice && (options.realtimeVoice ?? config.realtimeVoiceOffered),\n error,\n finishingUploads: completion !== null,\n pending: pending ? { idempotencyKey: pending.key, realtimeModel: pending.realtimeModel } : null,\n retry: () => (pendingRef.current ? deliver(pendingRef.current) : Promise.resolve(false)),\n startRealtime,\n };\n}\n"],"mappings":"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","names":["turnId","phase","bridge","useCallback","useRef","useCallback","now","useRef","useCallback","useEffect","useRef","useState","useState","useRef","useCallback","readGeneration","useEffect","useCallback","useRef","useRef","useCallback","useCallback","useEffect","useMemo","useRef","useState","useCallback","useRef","useCallback","useState","useEffect","window","useMemo","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","useState","useRef","useLayoutEffect","useEffect","useCallback","useMemo","useLayoutEffect","useMemo","useRef","useState","useState","useMemo","useRef","useLayoutEffect","useCallback","useEffect","useLayoutEffect","useRef","useState","useState","useRef","useLayoutEffect","useCallback","useEffect","useEffect","useMemo","useRef","useMemo","useRef","useEffect","OpenGeniApiError","useLayoutEffect","useMemo","useRef","useState","useState","useRef","useMemo","useLayoutEffect","OpenGeniApiError"]}