@opengeni/react 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/README.md +8 -0
  2. package/dist/accounts.js +2 -0
  3. package/dist/accounts.js.map +1 -1
  4. package/dist/artifacts-document.js +5 -4
  5. package/dist/artifacts-presentation.js +5 -4
  6. package/dist/artifacts-spreadsheet.js +4 -3
  7. package/dist/artifacts.js +14 -13
  8. package/dist/artifacts.js.map +1 -1
  9. package/dist/browser-viewer-WGJ43YGI.js +17 -0
  10. package/dist/chat-interactive-block-ZFHOKTMS.js +12 -0
  11. package/dist/{chunk-WEHMPOXK.js → chunk-2DDJ6YH6.js} +3 -1
  12. package/dist/{chunk-WEHMPOXK.js.map → chunk-2DDJ6YH6.js.map} +1 -1
  13. package/dist/{chunk-C5X5AJXK.js → chunk-2HVLQ26H.js} +5 -4
  14. package/dist/{chunk-C5X5AJXK.js.map → chunk-2HVLQ26H.js.map} +1 -1
  15. package/dist/{chunk-A4UJB2MM.js → chunk-32CGLXW2.js} +4 -3
  16. package/dist/{chunk-A4UJB2MM.js.map → chunk-32CGLXW2.js.map} +1 -1
  17. package/dist/{chunk-5CVXZA3Y.js → chunk-45NUOSXQ.js} +3 -2
  18. package/dist/{chunk-5CVXZA3Y.js.map → chunk-45NUOSXQ.js.map} +1 -1
  19. package/dist/{chunk-WUISZ3WU.js → chunk-53KJBGPZ.js} +5 -4
  20. package/dist/{chunk-WUISZ3WU.js.map → chunk-53KJBGPZ.js.map} +1 -1
  21. package/dist/{chunk-MBMPHOMA.js → chunk-55DXD22O.js} +3 -2
  22. package/dist/{chunk-MBMPHOMA.js.map → chunk-55DXD22O.js.map} +1 -1
  23. package/dist/{chunk-JT4JW7BC.js → chunk-5I4VRWBB.js} +3 -1
  24. package/dist/{chunk-JT4JW7BC.js.map → chunk-5I4VRWBB.js.map} +1 -1
  25. package/dist/{chunk-UK4TINKT.js → chunk-B27E3V37.js} +3 -1
  26. package/dist/{chunk-UK4TINKT.js.map → chunk-B27E3V37.js.map} +1 -1
  27. package/dist/{chunk-J6DBS4T3.js → chunk-BNKV5ZLF.js} +5 -4
  28. package/dist/{chunk-J6DBS4T3.js.map → chunk-BNKV5ZLF.js.map} +1 -1
  29. package/dist/{chunk-YM2DE7BQ.js → chunk-C5BF4L26.js} +13 -12
  30. package/dist/{chunk-YM2DE7BQ.js.map → chunk-C5BF4L26.js.map} +1 -1
  31. package/dist/{chunk-YBXQDQFX.js → chunk-C7CMD56T.js} +6 -5
  32. package/dist/{chunk-YBXQDQFX.js.map → chunk-C7CMD56T.js.map} +1 -1
  33. package/dist/{chunk-UGLEYEMP.js → chunk-CM7LVUKC.js} +3 -1
  34. package/dist/{chunk-UGLEYEMP.js.map → chunk-CM7LVUKC.js.map} +1 -1
  35. package/dist/{chunk-LJ2UTJJE.js → chunk-CREMJMVN.js} +181 -96
  36. package/dist/chunk-CREMJMVN.js.map +1 -0
  37. package/dist/{chunk-JVYQRRC4.js → chunk-CVYCLFMH.js} +3 -1
  38. package/dist/{chunk-JVYQRRC4.js.map → chunk-CVYCLFMH.js.map} +1 -1
  39. package/dist/{chunk-Y2PRMYLC.js → chunk-G3U2A6GS.js} +3 -2
  40. package/dist/{chunk-Y2PRMYLC.js.map → chunk-G3U2A6GS.js.map} +1 -1
  41. package/dist/{chunk-WZMYFJD3.js → chunk-G6YRCIYJ.js} +16 -7
  42. package/dist/{chunk-WZMYFJD3.js.map → chunk-G6YRCIYJ.js.map} +1 -1
  43. package/dist/{chunk-B3V6TG77.js → chunk-GC3PH6N7.js} +3 -1
  44. package/dist/{chunk-B3V6TG77.js.map → chunk-GC3PH6N7.js.map} +1 -1
  45. package/dist/{chunk-CJUO7J5Z.js → chunk-HXYOSSQO.js} +3 -2
  46. package/dist/{chunk-CJUO7J5Z.js.map → chunk-HXYOSSQO.js.map} +1 -1
  47. package/dist/{chunk-BRM6FVZA.js → chunk-IEE7WCLN.js} +4 -3
  48. package/dist/{chunk-BRM6FVZA.js.map → chunk-IEE7WCLN.js.map} +1 -1
  49. package/dist/{chunk-DYWBUX5Q.js → chunk-IMSUVYQB.js} +6 -5
  50. package/dist/{chunk-DYWBUX5Q.js.map → chunk-IMSUVYQB.js.map} +1 -1
  51. package/dist/{chunk-LN6TCXD3.js → chunk-IUHHPMAX.js} +184 -48
  52. package/dist/chunk-IUHHPMAX.js.map +1 -0
  53. package/dist/{chunk-SGKD2OCN.js → chunk-IYQCWGU5.js} +6 -5
  54. package/dist/{chunk-SGKD2OCN.js.map → chunk-IYQCWGU5.js.map} +1 -1
  55. package/dist/{chunk-J2QWVSQY.js → chunk-JH7V627O.js} +8 -7
  56. package/dist/{chunk-J2QWVSQY.js.map → chunk-JH7V627O.js.map} +1 -1
  57. package/dist/{chunk-EESD3PY3.js → chunk-JHTIMBOL.js} +6 -5
  58. package/dist/{chunk-EESD3PY3.js.map → chunk-JHTIMBOL.js.map} +1 -1
  59. package/dist/{chunk-LNIRAOA3.js → chunk-L2J3PU7A.js} +7 -6
  60. package/dist/{chunk-LNIRAOA3.js.map → chunk-L2J3PU7A.js.map} +1 -1
  61. package/dist/{chunk-ZYRGEKWS.js → chunk-LJUMYUBO.js} +3 -1
  62. package/dist/{chunk-ZYRGEKWS.js.map → chunk-LJUMYUBO.js.map} +1 -1
  63. package/dist/{chunk-4RVYOY4O.js → chunk-LSW2OJVV.js} +4 -3
  64. package/dist/{chunk-4RVYOY4O.js.map → chunk-LSW2OJVV.js.map} +1 -1
  65. package/dist/{chunk-UTRTG6LH.js → chunk-LVS3MH5T.js} +3 -1
  66. package/dist/{chunk-UTRTG6LH.js.map → chunk-LVS3MH5T.js.map} +1 -1
  67. package/dist/chunk-M357MHH3.js +2 -0
  68. package/dist/{chunk-GYVRFZDY.js → chunk-MDIXFKA3.js} +9 -8
  69. package/dist/{chunk-GYVRFZDY.js.map → chunk-MDIXFKA3.js.map} +1 -1
  70. package/dist/{chunk-WRHIZYZF.js → chunk-MEQM4LI3.js} +6 -5
  71. package/dist/{chunk-WRHIZYZF.js.map → chunk-MEQM4LI3.js.map} +1 -1
  72. package/dist/chunk-NX4ADH73.js +14 -0
  73. package/dist/chunk-NX4ADH73.js.map +1 -0
  74. package/dist/{chunk-XCHWDJ22.js → chunk-OGTTUYNT.js} +3 -1
  75. package/dist/{chunk-XCHWDJ22.js.map → chunk-OGTTUYNT.js.map} +1 -1
  76. package/dist/{chunk-GIMRELBW.js → chunk-OYQQJL3J.js} +3 -1
  77. package/dist/{chunk-GIMRELBW.js.map → chunk-OYQQJL3J.js.map} +1 -1
  78. package/dist/{chunk-RSI7XYXL.js → chunk-PBCZL4JP.js} +6 -5
  79. package/dist/{chunk-RSI7XYXL.js.map → chunk-PBCZL4JP.js.map} +1 -1
  80. package/dist/{chunk-I7IWRQLN.js → chunk-PHBFJCEU.js} +17 -11
  81. package/dist/chunk-PHBFJCEU.js.map +1 -0
  82. package/dist/{chunk-3CTRFMAK.js → chunk-PKCAYHDC.js} +5 -4
  83. package/dist/{chunk-3CTRFMAK.js.map → chunk-PKCAYHDC.js.map} +1 -1
  84. package/dist/{chunk-K3HQAKQX.js → chunk-PMV53IMM.js} +3 -1
  85. package/dist/{chunk-K3HQAKQX.js.map → chunk-PMV53IMM.js.map} +1 -1
  86. package/dist/{chunk-YQEAA6LT.js → chunk-QHUE7E4N.js} +3 -2
  87. package/dist/{chunk-YQEAA6LT.js.map → chunk-QHUE7E4N.js.map} +1 -1
  88. package/dist/{chunk-OA6HFRQP.js → chunk-QMMCJGFI.js} +4 -3
  89. package/dist/{chunk-OA6HFRQP.js.map → chunk-QMMCJGFI.js.map} +1 -1
  90. package/dist/{chunk-YV4L3ILF.js → chunk-QV3DJVRZ.js} +3 -1
  91. package/dist/{chunk-YV4L3ILF.js.map → chunk-QV3DJVRZ.js.map} +1 -1
  92. package/dist/{chunk-447JLCBU.js → chunk-S2QH6EZ5.js} +3 -1
  93. package/dist/{chunk-447JLCBU.js.map → chunk-S2QH6EZ5.js.map} +1 -1
  94. package/dist/{chunk-PNY3JKBJ.js → chunk-SFH43JT2.js} +5 -4
  95. package/dist/{chunk-PNY3JKBJ.js.map → chunk-SFH43JT2.js.map} +1 -1
  96. package/dist/{chunk-AWZLIMKX.js → chunk-T46QZH3E.js} +3 -1
  97. package/dist/{chunk-AWZLIMKX.js.map → chunk-T46QZH3E.js.map} +1 -1
  98. package/dist/{chunk-5J4FOW6Q.js → chunk-TNEZNMSN.js} +3 -1
  99. package/dist/{chunk-5J4FOW6Q.js.map → chunk-TNEZNMSN.js.map} +1 -1
  100. package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
  101. package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
  102. package/dist/{chunk-H5X55XH7.js → chunk-UDPH5SLV.js} +4 -3
  103. package/dist/{chunk-H5X55XH7.js.map → chunk-UDPH5SLV.js.map} +1 -1
  104. package/dist/{chunk-HDJWDK7W.js → chunk-VCSERYXH.js} +10 -9
  105. package/dist/{chunk-HDJWDK7W.js.map → chunk-VCSERYXH.js.map} +1 -1
  106. package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
  107. package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
  108. package/dist/{chunk-5F4WR7X7.js → chunk-XS67YG5R.js} +3 -1
  109. package/dist/{chunk-5F4WR7X7.js.map → chunk-XS67YG5R.js.map} +1 -1
  110. package/dist/{chunk-TKOTKRWY.js → chunk-XTD7TZHW.js} +3 -1
  111. package/dist/{chunk-TKOTKRWY.js.map → chunk-XTD7TZHW.js.map} +1 -1
  112. package/dist/{chunk-A2PI6UMY.js → chunk-YSRBFJMQ.js} +3 -1
  113. package/dist/{chunk-A2PI6UMY.js.map → chunk-YSRBFJMQ.js.map} +1 -1
  114. package/dist/chunk-YVFRBXST.js +1420 -0
  115. package/dist/chunk-YVFRBXST.js.map +1 -0
  116. package/dist/{chunk-SCOTPE2I.js → chunk-YYLBXXTE.js} +3 -1
  117. package/dist/{chunk-SCOTPE2I.js.map → chunk-YYLBXXTE.js.map} +1 -1
  118. package/dist/{chunk-RHREZ7BO.js → chunk-ZUWF4NF7.js} +3 -1
  119. package/dist/{chunk-RHREZ7BO.js.map → chunk-ZUWF4NF7.js.map} +1 -1
  120. package/dist/clipboard.js +3 -2
  121. package/dist/components/composer-transcription-control.d.ts +4 -0
  122. package/dist/components/session-conversation.d.ts +6 -0
  123. package/dist/composer-voice-events.d.ts +8 -0
  124. package/dist/composer.js +15 -13
  125. package/dist/computer-viewer-46UIN7F3.js +20 -0
  126. package/dist/connect.js +15 -12
  127. package/dist/connect.js.map +1 -1
  128. package/dist/desktop.js +6 -5
  129. package/dist/desktop.js.map +1 -1
  130. package/dist/diffs.js +2 -1
  131. package/dist/diffs.js.map +1 -1
  132. package/dist/editor.js +4 -3
  133. package/dist/editor.js.map +1 -1
  134. package/dist/embedded-voice-NIL4RDX3.js +69 -0
  135. package/dist/embedded-voice-NIL4RDX3.js.map +1 -0
  136. package/dist/{fleet-decision-row-YZ3ZKWMM.js → fleet-decision-row-SI63O5V4.js} +3 -1
  137. package/dist/{fleet-decision-row-YZ3ZKWMM.js.map → fleet-decision-row-SI63O5V4.js.map} +1 -1
  138. package/dist/hooks/use-client-config-flags.d.ts +6 -0
  139. package/dist/hooks/use-realtime-voice-models.d.ts +9 -0
  140. package/dist/hooks/use-voice-input.d.ts +8 -1
  141. package/dist/index.js +47 -45
  142. package/dist/index.js.map +1 -1
  143. package/dist/interaction.js +14 -13
  144. package/dist/interaction.js.map +1 -1
  145. package/dist/{latest-question-GPYM2JNU.js → latest-question-2POFPYNB.js} +5 -4
  146. package/dist/{latest-question-GPYM2JNU.js.map → latest-question-2POFPYNB.js.map} +1 -1
  147. package/dist/machines.js +8 -7
  148. package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-DQ4DRNVT.js} +3 -1
  149. package/dist/{markdown-table-layout-QXSLK4BY.js.map → markdown-table-layout-DQ4DRNVT.js.map} +1 -1
  150. package/dist/model-policy-picker-menu-WRNSRFQC.js +15 -0
  151. package/dist/model-policy.js +2 -1
  152. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
  153. package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
  154. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
  155. package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
  156. package/dist/{platform-activity-row-627BFZ46.js → platform-activity-row-PJJVATTZ.js} +3 -1
  157. package/dist/{platform-activity-row-627BFZ46.js.map → platform-activity-row-PJJVATTZ.js.map} +1 -1
  158. package/dist/{queue-surface-implementation-ZHFI5JBP.js → queue-surface-implementation-67FS7FUI.js} +10 -9
  159. package/dist/{queue-surface-implementation-ZHFI5JBP.js.map → queue-surface-implementation-67FS7FUI.js.map} +1 -1
  160. package/dist/realtime/embedded-voice.d.ts +20 -0
  161. package/dist/realtime.js +22 -1353
  162. package/dist/realtime.js.map +1 -1
  163. package/dist/sandbox-files-34CJJNOY.js +21 -0
  164. package/dist/session-ui.js +32 -30
  165. package/dist/session-ui.js.map +1 -1
  166. package/dist/session.js +10 -9
  167. package/dist/sites.js +2 -1
  168. package/dist/terminal.js +6 -5
  169. package/dist/terminal.js.map +1 -1
  170. package/dist/{timeline-annotation-markers-GNDHTGBD.js → timeline-annotation-markers-U3G66KUD.js} +5 -4
  171. package/dist/{timeline-annotation-markers-GNDHTGBD.js.map → timeline-annotation-markers-U3G66KUD.js.map} +1 -1
  172. package/dist/{timeline-annotation-selection-DMLMM2TX.js → timeline-annotation-selection-BI7QTPTZ.js} +4 -3
  173. package/dist/{timeline-annotation-selection-DMLMM2TX.js.map → timeline-annotation-selection-BI7QTPTZ.js.map} +1 -1
  174. package/dist/{timeline-annotations-dialog-ELRDBHTS.js → timeline-annotations-dialog-FOMHSDTE.js} +7 -6
  175. package/dist/{timeline-annotations-dialog-ELRDBHTS.js.map → timeline-annotations-dialog-FOMHSDTE.js.map} +1 -1
  176. package/dist/usage.js +6 -5
  177. package/dist/usage.js.map +1 -1
  178. package/dist/voice-recording-owner.d.ts +7 -0
  179. package/package.json +3 -3
  180. package/src/components/composer-transcription-control.tsx +109 -27
  181. package/src/components/markdown.tsx +7 -2
  182. package/src/components/message-timeline.tsx +10 -1
  183. package/src/components/session-conversation.tsx +44 -0
  184. package/src/components/session-proxy-scope.tsx +26 -5
  185. package/src/composer-voice-events.ts +12 -0
  186. package/src/connection-discovery.tsx +4 -1
  187. package/src/hooks/use-client-config-flags.ts +8 -0
  188. package/src/hooks/use-goal.ts +12 -1
  189. package/src/hooks/use-realtime-voice-models.ts +67 -0
  190. package/src/hooks/use-voice-input.ts +109 -18
  191. package/src/realtime/embedded-voice.tsx +81 -0
  192. package/src/realtime/realtime-control.tsx +82 -17
  193. package/src/voice-recording-owner.ts +22 -0
  194. package/styles/compiled.css +72 -18
  195. package/styles/index.css +49 -0
  196. package/styles/responsive.css +61 -4
  197. package/styles/session-capability.css +1 -1
  198. package/dist/browser-viewer-SHYKQRNX.js +0 -16
  199. package/dist/chat-interactive-block-UGBTNB3L.js +0 -11
  200. package/dist/chunk-I7IWRQLN.js.map +0 -1
  201. package/dist/chunk-IWIDV7SB.js +0 -1
  202. package/dist/chunk-LJ2UTJJE.js.map +0 -1
  203. package/dist/chunk-LN6TCXD3.js.map +0 -1
  204. package/dist/computer-viewer-6SRGWRUX.js +0 -19
  205. package/dist/model-policy-picker-menu-DXHUL73H.js +0 -14
  206. package/dist/sandbox-files-GORZOUUJ.js +0 -20
  207. /package/dist/{browser-viewer-SHYKQRNX.js.map → browser-viewer-WGJ43YGI.js.map} +0 -0
  208. /package/dist/{chat-interactive-block-UGBTNB3L.js.map → chat-interactive-block-ZFHOKTMS.js.map} +0 -0
  209. /package/dist/{chunk-IWIDV7SB.js.map → chunk-M357MHH3.js.map} +0 -0
  210. /package/dist/{computer-viewer-6SRGWRUX.js.map → computer-viewer-46UIN7F3.js.map} +0 -0
  211. /package/dist/{model-policy-picker-menu-DXHUL73H.js.map → model-policy-picker-menu-WRNSRFQC.js.map} +0 -0
  212. /package/dist/{sandbox-files-GORZOUUJ.js.map → sandbox-files-34CJJNOY.js.map} +0 -0
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/timeline/tool-display-name.ts
2
4
  function mcpToolLeaf(name) {
3
5
  const boundary = name.indexOf("__");
@@ -18,4 +20,4 @@ export {
18
20
  toolMatchesLeaf,
19
21
  toolDisplayName
20
22
  };
21
- //# sourceMappingURL=chunk-AWZLIMKX.js.map
23
+ //# sourceMappingURL=chunk-T46QZH3E.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/timeline/tool-display-name.ts"],"sourcesContent":["/**\n * MCP / first-party tool naming helpers.\n *\n * Wire names are often `<serverId>__<toolName>` (see prefixedMcpToolName).\n * Matching and titles must use the leaf tool name so `opengeni__session_create`\n * and bare `session_create` resolve the same UI — without inventing previews\n * from argument JSON.\n */\n\nimport type { ToolDisplayMetadata } from \"@opengeni/sdk\";\n\n/** Leaf tool name after the first `__` server boundary (or the whole name). */\nexport function mcpToolLeaf(name: string): string {\n const boundary = name.indexOf(\"__\");\n return boundary >= 0 ? name.slice(boundary + 2) : name;\n}\n\n/**\n * True when `wireName` is exactly `leaf` or ends with `__${leaf}` (MCP prefix).\n * Does not treat arbitrary suffixes as matches — the leaf must be the full\n * right-hand side after `__`.\n */\nexport function toolMatchesLeaf(wireName: string, leaf: string): boolean {\n return wireName === leaf || wireName.endsWith(`__${leaf}`);\n}\n\n/**\n * Readable label for a tool call (\"session_create\" / \"opengeni__session_create\"\n * → \"Session create\"). Title-cases the first character of the leaf phrase.\n */\nexport function toolDisplayName(name: string, display?: ToolDisplayMetadata): string {\n if (!display && /^[a-f0-9]{64}$/.test(name)) return \"Tool call\";\n // \"batch modify messages\" → \"Modify messages\": batching is transport, not the action.\n const phrase = (display?.toolName ?? mcpToolLeaf(name))\n .replace(/[_-]+/g, \" \")\n .trim()\n .replace(/^batch\\s+(?=\\S)/i, \"\");\n const title =\n display?.title ?? (phrase ? phrase.charAt(0).toUpperCase() + phrase.slice(1) : name);\n return display?.accountLabel ? `${title} — ${display.accountLabel}` : title;\n}\n"],"mappings":";AAYO,SAAS,YAAY,MAAsB;AAChD,QAAM,WAAW,KAAK,QAAQ,IAAI;AAClC,SAAO,YAAY,IAAI,KAAK,MAAM,WAAW,CAAC,IAAI;AACpD;AAOO,SAAS,gBAAgB,UAAkB,MAAuB;AACvE,SAAO,aAAa,QAAQ,SAAS,SAAS,KAAK,IAAI,EAAE;AAC3D;AAMO,SAAS,gBAAgB,MAAc,SAAuC;AACnF,MAAI,CAAC,WAAW,iBAAiB,KAAK,IAAI,EAAG,QAAO;AAEpD,QAAM,UAAU,SAAS,YAAY,YAAY,IAAI,GAClD,QAAQ,UAAU,GAAG,EACrB,KAAK,EACL,QAAQ,oBAAoB,EAAE;AACjC,QAAM,QACJ,SAAS,UAAU,SAAS,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC,IAAI;AACjF,SAAO,SAAS,eAAe,GAAG,KAAK,WAAM,QAAQ,YAAY,KAAK;AACxE;","names":[]}
1
+ {"version":3,"sources":["../src/timeline/tool-display-name.ts"],"sourcesContent":["/**\n * MCP / first-party tool naming helpers.\n *\n * Wire names are often `<serverId>__<toolName>` (see prefixedMcpToolName).\n * Matching and titles must use the leaf tool name so `opengeni__session_create`\n * and bare `session_create` resolve the same UI — without inventing previews\n * from argument JSON.\n */\n\nimport type { ToolDisplayMetadata } from \"@opengeni/sdk\";\n\n/** Leaf tool name after the first `__` server boundary (or the whole name). */\nexport function mcpToolLeaf(name: string): string {\n const boundary = name.indexOf(\"__\");\n return boundary >= 0 ? name.slice(boundary + 2) : name;\n}\n\n/**\n * True when `wireName` is exactly `leaf` or ends with `__${leaf}` (MCP prefix).\n * Does not treat arbitrary suffixes as matches — the leaf must be the full\n * right-hand side after `__`.\n */\nexport function toolMatchesLeaf(wireName: string, leaf: string): boolean {\n return wireName === leaf || wireName.endsWith(`__${leaf}`);\n}\n\n/**\n * Readable label for a tool call (\"session_create\" / \"opengeni__session_create\"\n * → \"Session create\"). Title-cases the first character of the leaf phrase.\n */\nexport function toolDisplayName(name: string, display?: ToolDisplayMetadata): string {\n if (!display && /^[a-f0-9]{64}$/.test(name)) return \"Tool call\";\n // \"batch modify messages\" → \"Modify messages\": batching is transport, not the action.\n const phrase = (display?.toolName ?? mcpToolLeaf(name))\n .replace(/[_-]+/g, \" \")\n .trim()\n .replace(/^batch\\s+(?=\\S)/i, \"\");\n const title =\n display?.title ?? (phrase ? phrase.charAt(0).toUpperCase() + phrase.slice(1) : name);\n return display?.accountLabel ? `${title} — ${display.accountLabel}` : title;\n}\n"],"mappings":";;;AAYO,SAAS,YAAY,MAAsB;AAChD,QAAM,WAAW,KAAK,QAAQ,IAAI;AAClC,SAAO,YAAY,IAAI,KAAK,MAAM,WAAW,CAAC,IAAI;AACpD;AAOO,SAAS,gBAAgB,UAAkB,MAAuB;AACvE,SAAO,aAAa,QAAQ,SAAS,SAAS,KAAK,IAAI,EAAE;AAC3D;AAMO,SAAS,gBAAgB,MAAc,SAAuC;AACnF,MAAI,CAAC,WAAW,iBAAiB,KAAK,IAAI,EAAG,QAAO;AAEpD,QAAM,UAAU,SAAS,YAAY,YAAY,IAAI,GAClD,QAAQ,UAAU,GAAG,EACrB,KAAK,EACL,QAAQ,oBAAoB,EAAE;AACjC,QAAM,QACJ,SAAS,UAAU,SAAS,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC,IAAI;AACjF,SAAO,SAAS,eAAe,GAAG,KAAK,WAAM,QAAQ,YAAY,KAAK;AACxE;","names":[]}
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/lib/relay-wire.ts
2
4
  import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
3
5
  var STREAM_KIND_DESKTOP = 2;
@@ -105,4 +107,4 @@ export {
105
107
  decodeStreamOpenAck,
106
108
  decodeStreamFrame
107
109
  };
108
- //# sourceMappingURL=chunk-5J4FOW6Q.js.map
110
+ //# sourceMappingURL=chunk-TNEZNMSN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/relay-wire.ts"],"sourcesContent":["// Minimal HAND-MIRROR of the relay stream wire messages the desktop frame client\n// needs (`StreamOpen`/`StreamClose` encode; `StreamOpenAck` + `StreamFrame` decode). It exists\n// because the publish-closure guard (scripts/publish-closure-guard.ts) forbids\n// `@opengeni/react` from depending on `@opengeni/agent-proto` — the published SDK\n// closure may only reach `@opengeni/sdk` among `@opengeni/*` packages. So, exactly\n// as the guard prescribes (\"hand-mirror it\"), we re-encode just these three\n// messages against the third-party `@bufbuild/protobuf/wire` runtime (the same\n// runtime `@opengeni/agent-proto` generates against), byte-compatible with the\n// generated code. Field numbers copied verbatim from\n// `packages/agent-proto/src/gen/opengeni_agent.ts`:\n// StreamChannel: channelId=1, workspaceId=2, agentId=3, kind=4(int32), port=5(uint32)\n// StreamOpen: channel=1(msg), token=2, role=3(int32), resumeFromSeq=4(uint64, omitted when \"0\")\n// StreamOpenAck: accepted=1(bool), error=2(AgentError msg), resumeFromSeq=3\n// AgentError: code=1, message=2, retryable=3, detail=4 (we read only message)\n// StreamFrame: channelId=1, seq=2, data=3(bytes), producedAtMs=4 (we read only data)\n// StreamClose: channelId=1, reason=2(int32), message=3\nimport { BinaryReader, BinaryWriter } from \"@bufbuild/protobuf/wire\";\n\n/** `StreamKind.STREAM_KIND_DESKTOP` (agent-proto enum value). */\nexport const STREAM_KIND_DESKTOP = 2;\n/** `StreamKind.STREAM_KIND_PTY` (agent-proto enum value). */\nexport const STREAM_KIND_PTY = 1;\n/** `StreamKind.STREAM_KIND_BROWSER` (agent-proto enum value). */\nexport const STREAM_KIND_BROWSER = 3;\n/** `StreamKind.STREAM_KIND_COMPUTER` (agent-proto enum value). */\nexport const STREAM_KIND_COMPUTER = 4;\n/** `StreamRole.STREAM_ROLE_CLIENT` (agent-proto enum value). */\nexport const STREAM_ROLE_CLIENT = 2;\n/** `StreamCloseReason.STREAM_CLOSE_REASON_NORMAL`. */\nexport const STREAM_CLOSE_REASON_NORMAL = 1;\n\nexport interface RelayChannel {\n channelId: string;\n workspaceId: string;\n agentId: string;\n kind: number;\n port: number;\n}\n\nexport interface RelayStreamOpen {\n channel: RelayChannel;\n token: string;\n role: number;\n resumeFromSeq: string;\n}\n\nfunction encodeChannel(message: RelayChannel, writer: BinaryWriter): BinaryWriter {\n if (message.channelId !== \"\") writer.uint32(10).string(message.channelId);\n if (message.workspaceId !== \"\") writer.uint32(18).string(message.workspaceId);\n if (message.agentId !== \"\") writer.uint32(26).string(message.agentId);\n if (message.kind !== 0) writer.uint32(32).int32(message.kind);\n if (message.port !== 0) writer.uint32(40).uint32(message.port);\n return writer;\n}\n\n/** Encode a `StreamOpen`, byte-compatible with `StreamOpen.encode(...).finish()`. */\nexport function encodeStreamOpen(message: RelayStreamOpen): Uint8Array {\n const writer = new BinaryWriter();\n encodeChannel(message.channel, writer.uint32(10).fork()).join();\n if (message.token !== \"\") writer.uint32(18).string(message.token);\n if (message.role !== 0) writer.uint32(24).int32(message.role);\n if (message.resumeFromSeq !== \"0\") writer.uint32(32).uint64(message.resumeFromSeq);\n return writer.finish();\n}\n\n/** Encode an intentional viewer detach. Transport loss omits this message so\n * reconnect/resume remains available. */\nexport function encodeStreamClose(message: {\n channelId: string;\n reason: number;\n message: string;\n}): Uint8Array {\n const writer = new BinaryWriter();\n if (message.channelId !== \"\") writer.uint32(10).string(message.channelId);\n if (message.reason !== 0) writer.uint32(16).int32(message.reason);\n if (message.message !== \"\") writer.uint32(26).string(message.message);\n return writer.finish();\n}\n\n/** Encode a viewer→agent PTY input `StreamFrame`. */\nexport function encodeStreamFrame(message: {\n channelId: string;\n seq: string;\n data: Uint8Array;\n producedAtMs: string;\n}): Uint8Array {\n const writer = new BinaryWriter();\n if (message.channelId !== \"\") writer.uint32(10).string(message.channelId);\n if (message.seq !== \"0\") writer.uint32(16).uint64(message.seq);\n if (message.data.length > 0) writer.uint32(26).bytes(message.data);\n if (message.producedAtMs !== \"0\") writer.uint32(32).uint64(message.producedAtMs);\n return writer.finish();\n}\n\n/** The only `AgentError` field we surface from a rejected ack. */\nfunction decodeAgentErrorMessage(reader: BinaryReader, length: number): { message?: string } {\n const end = reader.pos + length;\n let message: string | undefined;\n while (reader.pos < end) {\n const tag = reader.uint32();\n if (tag >>> 3 === 2 && tag === 18) {\n message = reader.string();\n continue;\n }\n if ((tag & 7) === 4 || tag === 0) break;\n reader.skip(tag & 7);\n }\n return message !== undefined ? { message } : {};\n}\n\n/** Decode a `StreamOpenAck` (we need `accepted` + the error message). */\nexport function decodeStreamOpenAck(bytes: Uint8Array): {\n accepted: boolean;\n error?: { message?: string };\n} {\n const reader = new BinaryReader(bytes);\n const end = reader.len;\n let accepted = false;\n let error: { message?: string } | undefined;\n while (reader.pos < end) {\n const tag = reader.uint32();\n if (tag >>> 3 === 1 && tag === 8) {\n accepted = reader.bool();\n continue;\n }\n if (tag >>> 3 === 2 && tag === 18) {\n error = decodeAgentErrorMessage(reader, reader.uint32());\n continue;\n }\n if ((tag & 7) === 4 || tag === 0) break;\n reader.skip(tag & 7);\n }\n return error !== undefined ? { accepted, error } : { accepted };\n}\n\n/** Decode the sequence plus `data` from a `StreamFrame`. */\nexport function decodeStreamFrame(bytes: Uint8Array): { seq: string; data: Uint8Array } {\n const reader = new BinaryReader(bytes);\n const end = reader.len;\n let seq = \"0\";\n let data = new Uint8Array(0);\n while (reader.pos < end) {\n const tag = reader.uint32();\n if (tag >>> 3 === 2 && tag === 16) {\n seq = reader.uint64().toString();\n continue;\n }\n if (tag >>> 3 === 3 && tag === 26) {\n // Copy into a fresh ArrayBuffer-backed view: BinaryReader.bytes() returns\n // `Uint8Array<ArrayBufferLike>` (a view into the message buffer), which both\n // narrows the type to `Uint8Array<ArrayBuffer>` and isolates just this frame.\n data = new Uint8Array(reader.bytes());\n continue;\n }\n if ((tag & 7) === 4 || tag === 0) break;\n reader.skip(tag & 7);\n }\n return { seq, data };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/relay-wire.ts"],"sourcesContent":["// Minimal HAND-MIRROR of the relay stream wire messages the desktop frame client\n// needs (`StreamOpen`/`StreamClose` encode; `StreamOpenAck` + `StreamFrame` decode). It exists\n// because the publish-closure guard (scripts/publish-closure-guard.ts) forbids\n// `@opengeni/react` from depending on `@opengeni/agent-proto` — the published SDK\n// closure may only reach `@opengeni/sdk` among `@opengeni/*` packages. So, exactly\n// as the guard prescribes (\"hand-mirror it\"), we re-encode just these three\n// messages against the third-party `@bufbuild/protobuf/wire` runtime (the same\n// runtime `@opengeni/agent-proto` generates against), byte-compatible with the\n// generated code. Field numbers copied verbatim from\n// `packages/agent-proto/src/gen/opengeni_agent.ts`:\n// StreamChannel: channelId=1, workspaceId=2, agentId=3, kind=4(int32), port=5(uint32)\n// StreamOpen: channel=1(msg), token=2, role=3(int32), resumeFromSeq=4(uint64, omitted when \"0\")\n// StreamOpenAck: accepted=1(bool), error=2(AgentError msg), resumeFromSeq=3\n// AgentError: code=1, message=2, retryable=3, detail=4 (we read only message)\n// StreamFrame: channelId=1, seq=2, data=3(bytes), producedAtMs=4 (we read only data)\n// StreamClose: channelId=1, reason=2(int32), message=3\nimport { BinaryReader, BinaryWriter } from \"@bufbuild/protobuf/wire\";\n\n/** `StreamKind.STREAM_KIND_DESKTOP` (agent-proto enum value). */\nexport const STREAM_KIND_DESKTOP = 2;\n/** `StreamKind.STREAM_KIND_PTY` (agent-proto enum value). */\nexport const STREAM_KIND_PTY = 1;\n/** `StreamKind.STREAM_KIND_BROWSER` (agent-proto enum value). */\nexport const STREAM_KIND_BROWSER = 3;\n/** `StreamKind.STREAM_KIND_COMPUTER` (agent-proto enum value). */\nexport const STREAM_KIND_COMPUTER = 4;\n/** `StreamRole.STREAM_ROLE_CLIENT` (agent-proto enum value). */\nexport const STREAM_ROLE_CLIENT = 2;\n/** `StreamCloseReason.STREAM_CLOSE_REASON_NORMAL`. */\nexport const STREAM_CLOSE_REASON_NORMAL = 1;\n\nexport interface RelayChannel {\n channelId: string;\n workspaceId: string;\n agentId: string;\n kind: number;\n port: number;\n}\n\nexport interface RelayStreamOpen {\n channel: RelayChannel;\n token: string;\n role: number;\n resumeFromSeq: string;\n}\n\nfunction encodeChannel(message: RelayChannel, writer: BinaryWriter): BinaryWriter {\n if (message.channelId !== \"\") writer.uint32(10).string(message.channelId);\n if (message.workspaceId !== \"\") writer.uint32(18).string(message.workspaceId);\n if (message.agentId !== \"\") writer.uint32(26).string(message.agentId);\n if (message.kind !== 0) writer.uint32(32).int32(message.kind);\n if (message.port !== 0) writer.uint32(40).uint32(message.port);\n return writer;\n}\n\n/** Encode a `StreamOpen`, byte-compatible with `StreamOpen.encode(...).finish()`. */\nexport function encodeStreamOpen(message: RelayStreamOpen): Uint8Array {\n const writer = new BinaryWriter();\n encodeChannel(message.channel, writer.uint32(10).fork()).join();\n if (message.token !== \"\") writer.uint32(18).string(message.token);\n if (message.role !== 0) writer.uint32(24).int32(message.role);\n if (message.resumeFromSeq !== \"0\") writer.uint32(32).uint64(message.resumeFromSeq);\n return writer.finish();\n}\n\n/** Encode an intentional viewer detach. Transport loss omits this message so\n * reconnect/resume remains available. */\nexport function encodeStreamClose(message: {\n channelId: string;\n reason: number;\n message: string;\n}): Uint8Array {\n const writer = new BinaryWriter();\n if (message.channelId !== \"\") writer.uint32(10).string(message.channelId);\n if (message.reason !== 0) writer.uint32(16).int32(message.reason);\n if (message.message !== \"\") writer.uint32(26).string(message.message);\n return writer.finish();\n}\n\n/** Encode a viewer→agent PTY input `StreamFrame`. */\nexport function encodeStreamFrame(message: {\n channelId: string;\n seq: string;\n data: Uint8Array;\n producedAtMs: string;\n}): Uint8Array {\n const writer = new BinaryWriter();\n if (message.channelId !== \"\") writer.uint32(10).string(message.channelId);\n if (message.seq !== \"0\") writer.uint32(16).uint64(message.seq);\n if (message.data.length > 0) writer.uint32(26).bytes(message.data);\n if (message.producedAtMs !== \"0\") writer.uint32(32).uint64(message.producedAtMs);\n return writer.finish();\n}\n\n/** The only `AgentError` field we surface from a rejected ack. */\nfunction decodeAgentErrorMessage(reader: BinaryReader, length: number): { message?: string } {\n const end = reader.pos + length;\n let message: string | undefined;\n while (reader.pos < end) {\n const tag = reader.uint32();\n if (tag >>> 3 === 2 && tag === 18) {\n message = reader.string();\n continue;\n }\n if ((tag & 7) === 4 || tag === 0) break;\n reader.skip(tag & 7);\n }\n return message !== undefined ? { message } : {};\n}\n\n/** Decode a `StreamOpenAck` (we need `accepted` + the error message). */\nexport function decodeStreamOpenAck(bytes: Uint8Array): {\n accepted: boolean;\n error?: { message?: string };\n} {\n const reader = new BinaryReader(bytes);\n const end = reader.len;\n let accepted = false;\n let error: { message?: string } | undefined;\n while (reader.pos < end) {\n const tag = reader.uint32();\n if (tag >>> 3 === 1 && tag === 8) {\n accepted = reader.bool();\n continue;\n }\n if (tag >>> 3 === 2 && tag === 18) {\n error = decodeAgentErrorMessage(reader, reader.uint32());\n continue;\n }\n if ((tag & 7) === 4 || tag === 0) break;\n reader.skip(tag & 7);\n }\n return error !== undefined ? { accepted, error } : { accepted };\n}\n\n/** Decode the sequence plus `data` from a `StreamFrame`. */\nexport function decodeStreamFrame(bytes: Uint8Array): { seq: string; data: Uint8Array } {\n const reader = new BinaryReader(bytes);\n const end = reader.len;\n let seq = \"0\";\n let data = new Uint8Array(0);\n while (reader.pos < end) {\n const tag = reader.uint32();\n if (tag >>> 3 === 2 && tag === 16) {\n seq = reader.uint64().toString();\n continue;\n }\n if (tag >>> 3 === 3 && tag === 26) {\n // Copy into a fresh ArrayBuffer-backed view: BinaryReader.bytes() returns\n // `Uint8Array<ArrayBufferLike>` (a view into the message buffer), which both\n // narrows the type to `Uint8Array<ArrayBuffer>` and isolates just this frame.\n data = new Uint8Array(reader.bytes());\n continue;\n }\n if ((tag & 7) === 4 || tag === 0) break;\n reader.skip(tag & 7);\n }\n return { seq, data };\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/lib/cn.ts
2
4
  import { clsx } from "clsx";
3
5
  import { extendTailwindMerge } from "tailwind-merge";
@@ -28,4 +30,4 @@ function cn(...inputs) {
28
30
  export {
29
31
  cn
30
32
  };
31
- //# sourceMappingURL=chunk-22KP6LR5.js.map
33
+ //# sourceMappingURL=chunk-TXS65BB2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/* ----------------------------------------------------------------------------\n tailwind-merge, taught our design tokens.\n\n Our type scale and color ramp share the `og-` prefix: `text-og-base` is a\n FONT SIZE, `text-og-fg-muted` is a COLOR. Stock tailwind-merge can't tell\n them apart — it lumps every `text-og-*` into one `font-size` group and, when\n two land in the same class list, drops the earlier one. That silently ate the\n size off rows like `text-og-base text-og-fg-muted`, leaving titles at the\n browser-default 16px. Register the custom font-size scale so the size and the\n color live in different conflict groups and both survive a merge.\n -------------------------------------------------------------------------- */\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n \"font-size\": [\n {\n text: [\n \"og-xs\",\n \"og-sm\",\n \"og-base\",\n \"og-md\",\n \"og-control\",\n \"og-menu\",\n \"og-composer\",\n \"og-composer-wide\",\n ],\n },\n ],\n },\n },\n});\n\n/** Merge class names with Tailwind-aware conflict resolution. */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,2BAA2B;AAapC,IAAM,UAAU,oBAAoB;AAAA,EAClC,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,aAAa;AAAA,QACX;AAAA,UACE,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAGM,SAAS,MAAM,QAA8B;AAClD,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
1
+ {"version":3,"sources":["../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/* ----------------------------------------------------------------------------\n tailwind-merge, taught our design tokens.\n\n Our type scale and color ramp share the `og-` prefix: `text-og-base` is a\n FONT SIZE, `text-og-fg-muted` is a COLOR. Stock tailwind-merge can't tell\n them apart — it lumps every `text-og-*` into one `font-size` group and, when\n two land in the same class list, drops the earlier one. That silently ate the\n size off rows like `text-og-base text-og-fg-muted`, leaving titles at the\n browser-default 16px. Register the custom font-size scale so the size and the\n color live in different conflict groups and both survive a merge.\n -------------------------------------------------------------------------- */\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n \"font-size\": [\n {\n text: [\n \"og-xs\",\n \"og-sm\",\n \"og-base\",\n \"og-md\",\n \"og-control\",\n \"og-menu\",\n \"og-composer\",\n \"og-composer-wide\",\n ],\n },\n ],\n },\n },\n});\n\n/** Merge class names with Tailwind-aware conflict resolution. */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAAA,SAAS,YAA6B;AACtC,SAAS,2BAA2B;AAapC,IAAM,UAAU,oBAAoB;AAAA,EAClC,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,aAAa;AAAA,QACX;AAAA,UACE,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAGM,SAAS,MAAM,QAA8B;AAClD,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
@@ -1,13 +1,14 @@
1
+ "use client";
1
2
  import {
2
3
  useDebouncedCallback,
3
4
  useMutationRunner,
4
5
  usePolledValue,
5
6
  useSessionEventTrigger
6
- } from "./chunk-YQEAA6LT.js";
7
+ } from "./chunk-QHUE7E4N.js";
7
8
  import {
8
9
  useEmbeddedSessionLineage,
9
10
  useEmbeddedSessionMcpApprovalPolicy
10
- } from "./chunk-TKOTKRWY.js";
11
+ } from "./chunk-XTD7TZHW.js";
11
12
 
12
13
  // src/embedded-session-client.ts
13
14
  var requiredMethods = [
@@ -294,4 +295,4 @@ export {
294
295
  isLineageRefreshEvent,
295
296
  useSessionLineage
296
297
  };
297
- //# sourceMappingURL=chunk-H5X55XH7.js.map
298
+ //# sourceMappingURL=chunk-UDPH5SLV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/embedded-session-client.ts","../src/hooks/use-session-mcp-approval-policy.ts","../src/hooks/use-session-lineage.ts"],"sourcesContent":["import type { ComposerDraft } from \"@opengeni/sdk\";\nimport type { EmbeddedSessionClientLike } from \"./client\";\n\nexport type ComposerDraftMapContext = {\n operation: \"read\" | \"save\" | \"submit\";\n workspaceId: string;\n sessionId: string;\n};\n\nexport type CreateEmbeddedSessionClientOptions = {\n /**\n * Explicit host-owned method replacements. Methods inherited from `base`\n * retain `base` as their receiver; overrides retain this object as theirs.\n */\n overrides?: Partial<EmbeddedSessionClientLike> | undefined;\n /** Presentation/policy projection for every draft entering the React layer. */\n mapComposerDraft?:\n | ((draft: ComposerDraft, context: ComposerDraftMapContext) => ComposerDraft)\n | undefined;\n};\n\nconst requiredMethods = [\n \"getSession\",\n \"listEvents\",\n \"streamEvents\",\n \"getComposerDraft\",\n \"saveComposerDraft\",\n \"submitComposerDraft\",\n \"sendMessage\",\n \"steerMessage\",\n \"getQueue\",\n \"moveQueueItem\",\n \"editQueueItem\",\n \"steerQueueItem\",\n \"deleteQueueItem\",\n \"pauseSession\",\n \"resumeSession\",\n \"sendApprovalDecision\",\n] as const satisfies readonly (keyof EmbeddedSessionClientLike)[];\n\n/**\n * Build the exact client required by `@opengeni/react/session` from a full SDK\n * client or host proxy. The constructor binds every delegated method once,\n * supports a host-owned atomic composer-submit override, and fails at creation\n * time instead of waiting for a missing method to be exercised by a hook.\n */\nexport function createEmbeddedSessionClient(\n base: EmbeddedSessionClientLike,\n options: CreateEmbeddedSessionClientOptions = {},\n): EmbeddedSessionClientLike {\n const overrides = options.overrides ?? {};\n const client = {} as EmbeddedSessionClientLike;\n for (const key of requiredMethods) {\n const override = overrides[key];\n const method = override ?? base[key];\n if (typeof method !== \"function\") {\n throw new TypeError(`Embedded session client method is required: ${key}`);\n }\n client[key] = method.bind(override === undefined ? base : overrides) as never;\n }\n\n const inferenceOverride = overrides.setWorkspaceInferenceState;\n const inferenceBase = base.setWorkspaceInferenceState;\n const inferenceMethod = inferenceOverride ?? inferenceBase;\n if (typeof inferenceMethod === \"function\") {\n client.setWorkspaceInferenceState = inferenceMethod.bind(\n inferenceOverride === undefined ? base : overrides,\n );\n }\n\n const mapDraft = options.mapComposerDraft;\n if (!mapDraft) return client;\n\n const getComposerDraft = client.getComposerDraft;\n client.getComposerDraft = async (workspaceId, sessionId) =>\n mapDraft(await getComposerDraft(workspaceId, sessionId), {\n operation: \"read\",\n workspaceId,\n sessionId,\n });\n\n const saveComposerDraft = client.saveComposerDraft;\n client.saveComposerDraft = async (workspaceId, sessionId, request) =>\n mapDraft(await saveComposerDraft(workspaceId, sessionId, request), {\n operation: \"save\",\n workspaceId,\n sessionId,\n });\n\n const submitComposerDraft = client.submitComposerDraft;\n client.submitComposerDraft = async (workspaceId, sessionId, request) => {\n const response = await submitComposerDraft(workspaceId, sessionId, request);\n return {\n ...response,\n draft: mapDraft(response.draft, {\n operation: \"submit\",\n workspaceId,\n sessionId,\n }),\n };\n };\n\n return client;\n}\n","import type {\n SessionEvent,\n SessionMcpApprovalPolicy,\n SessionMcpApprovalPolicyTarget,\n UpdateSessionMcpApprovalPolicyResponse,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useEmbeddedSessionMcpApprovalPolicy,\n type EmbeddedSessionMcpApprovalPolicyClientOverride,\n} from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\nexport function isSessionMcpApprovalPolicyEvent(\n event: Pick<SessionEvent, \"type\" | \"payload\">,\n serverId?: string,\n): boolean {\n if (event.type !== \"session.mcp.approval_policy.updated\") {\n return false;\n }\n if (serverId === undefined) {\n return true;\n }\n const payload = event.payload as { serverId?: unknown } | null;\n return payload?.serverId === serverId;\n}\n\nexport type UseSessionMcpApprovalPolicyOptions = EmbeddedSessionMcpApprovalPolicyClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default; policy events drive refreshes. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseSessionMcpApprovalPolicyResult = {\n server: SessionMcpApprovalPolicyTarget | null;\n policy: SessionMcpApprovalPolicy | null;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n update: (\n policy: SessionMcpApprovalPolicy,\n ) => Promise<UpdateSessionMcpApprovalPolicyResponse | null>;\n updating: boolean;\n clearError: () => void;\n};\n\n/**\n * Read and update one existing session MCP server's approval policy. Updates\n * become effective for the next claimed attempt; current work is unchanged.\n */\nexport function useSessionMcpApprovalPolicy(\n sessionId: string | null | undefined,\n serverId: string | null | undefined,\n options: UseSessionMcpApprovalPolicyOptions = {},\n): UseSessionMcpApprovalPolicyResult {\n const { client, workspaceId } = useEmbeddedSessionMcpApprovalPolicy(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId && serverId);\n const [override, setOverride] = useState<SessionMcpApprovalPolicyTarget | null>(null);\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${serverId ?? \"\"}`;\n const authoritativeGeneration = useRef(0);\n const mutationIdentity = useMemo(() => ({ client, targetKey }), [client, targetKey]);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner(mutationIdentity);\n\n useLayoutEffect(() => {\n authoritativeGeneration.current += 1;\n setOverride(null);\n }, [client, targetKey]);\n\n type PolicyRead = {\n targetKey: string;\n generation: number;\n server: SessionMcpApprovalPolicyTarget | null;\n };\n const load = useCallback(async (): Promise<PolicyRead> => {\n const generation = authoritativeGeneration.current;\n if (!sessionId || !serverId) {\n return { targetKey, generation, server: null };\n }\n const session = await client.getSession(workspaceId, sessionId);\n return {\n targetKey,\n generation,\n server:\n session.mcpServers.find((server) => server.id === serverId) ??\n (session.mcpApprovalPolicies && Object.hasOwn(session.mcpApprovalPolicies, serverId)\n ? {\n id: serverId,\n source: \"workspace\",\n requireApproval: session.mcpApprovalPolicies[serverId]!,\n }\n : null),\n };\n }, [client, serverId, sessionId, targetKey, workspaceId]);\n const {\n data,\n loading,\n error: loadError,\n refresh,\n } = usePolledValue(load, {\n enabled,\n pollIntervalMs: options.pollIntervalMs,\n });\n useEffect(() => {\n if (data?.targetKey === targetKey && data.generation === authoritativeGeneration.current) {\n setOverride(null);\n }\n }, [data, targetKey]);\n\n const scheduleRefresh = useDebouncedCallback(() => void refresh());\n const matchesPolicyEvent = useCallback(\n (event: Pick<SessionEvent, \"type\" | \"payload\">) =>\n isSessionMcpApprovalPolicyEvent(event, serverId ?? undefined),\n [serverId],\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n matchesPolicyEvent,\n scheduleRefresh,\n {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n },\n async () => await refresh(),\n );\n\n const update = useCallback(\n async (\n policy: SessionMcpApprovalPolicy,\n ): Promise<UpdateSessionMcpApprovalPolicyResponse | null> => {\n if (!sessionId || !serverId) {\n return null;\n }\n const response = await run(() =>\n client.updateSessionMcpApprovalPolicy(workspaceId, sessionId, serverId, {\n requireApproval: policy,\n }),\n );\n if (response) {\n authoritativeGeneration.current += 1;\n setOverride(response.server);\n void refresh();\n }\n return response;\n },\n [client, refresh, run, serverId, sessionId, workspaceId],\n );\n\n const server = override ?? data?.server ?? null;\n return {\n server,\n policy: server?.requireApproval ?? null,\n loading,\n error: mutationError ?? loadError,\n refresh: async () => {\n await refresh();\n },\n update,\n updating: mutating,\n clearError: clearMutationError,\n };\n}\n","import type { SessionEvent, SessionLineageResponse } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport {\n useEmbeddedSessionLineage,\n type EmbeddedSessionLineageClientOverride,\n} from \"../session-context\";\nimport { useDebouncedCallback, usePolledValue, useSessionEventTrigger } from \"./internal\";\n\nexport type UseSessionLineageOptions = EmbeddedSessionLineageClientOverride & {\n events?: SessionEvent[] | undefined;\n /** Refresh interval (ms). Off by default. */\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n /** Optional shared causal clock invoked when each network read starts. */\n beginRead?: (() => number) | undefined;\n};\n\nexport type UseSessionLineageResult = {\n lineage: SessionLineageResponse | null;\n loading: boolean;\n error: Error | null;\n /** Causal generation captured when the accepted lineage read started. */\n readGeneration: number;\n refresh: () => Promise<void>;\n};\n\nexport function isLineageRefreshEvent(event: SessionEvent): boolean {\n if (event.type === \"session.status.changed\" || event.type === \"session.created\") {\n return true;\n }\n // A child's creation never appears on the PARENT's stream as session.created —\n // the parent sees its own spawn as an agent.toolCall.* for session_create.\n // Created events are handled separately so they can refresh immediately and\n // once after the child row has had time to commit.\n if (event.type === \"agent.toolCall.output\") {\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n }\n return false;\n}\n\nfunction isSessionCreateToolCallCreated(event: SessionEvent): boolean {\n if (event.type !== \"agent.toolCall.created\") {\n return false;\n }\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n}\n\n/** Read the ancestors + descendant tree for one session. Data-only; no UI state. */\nexport function useSessionLineage(\n sessionId: string | null | undefined,\n options: UseSessionLineageOptions = {},\n): UseSessionLineageResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSessionLineage(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const nextReadGeneration = useRef(0);\n const beginRead = options.beginRead;\n const load = useCallback(\n async (signal?: AbortSignal) => {\n if (!sessionId) {\n return {\n lineage: { ancestors: [], children: [], truncated: false },\n readGeneration: 0,\n };\n }\n let readGeneration = 0;\n const lineage = await client.getSessionLineage(workspaceId, sessionId, {\n signal,\n onRequestStart: (sharedReadGeneration) => {\n readGeneration = sharedReadGeneration ?? beginRead?.() ?? ++nextReadGeneration.current;\n },\n });\n return {\n lineage,\n readGeneration,\n };\n },\n [beginRead, client, workspaceId, sessionId],\n );\n const state = usePolledValue(load, { pollIntervalMs: options.pollIntervalMs, enabled });\n const refresh = state.refresh;\n useEffect(() => {\n if (enabled && workspaceControlEvent) void refresh();\n }, [enabled, refresh, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"lineage\", refresh);\n }, [enabled, refresh, registerSessionReconciler, sessionId]);\n const refreshSoon = useDebouncedCallback(() => void refresh(), 150);\n const delayedChildRefreshRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Clear a pending delayed refresh on session/workspace SWITCH (not just\n // unmount): otherwise a timer scheduled for the previous session can fire\n // ~2.5s later and commit that session's lineage onto the new one.\n useEffect(() => {\n return () => {\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n delayedChildRefreshRef.current = null;\n }\n };\n }, [sessionId, workspaceId]);\n const refreshAfterChildCreate = useCallback(() => {\n void refresh();\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n }\n delayedChildRefreshRef.current = setTimeout(() => {\n delayedChildRefreshRef.current = null;\n void refresh();\n }, 2500);\n }, [refresh]);\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isLineageRefreshEvent,\n refreshSoon,\n // SHARED-FEED ONLY: without a caller-provided events log the trigger would\n // open its OWN streamEvents tail — a second live SSE connection next to the\n // session route's useSessionEvents. A caller with no feed opts into polling\n // (pollIntervalMs), never a duplicate stream.\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isSessionCreateToolCallCreated,\n refreshAfterChildCreate,\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n return {\n lineage: state.data?.lineage ?? null,\n loading: state.loading,\n error: state.error,\n readGeneration: state.data?.readGeneration ?? 0,\n refresh,\n };\n}\n"],"mappings":"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","names":["server","useCallback","useEffect","useRef","useRef","useCallback","useEffect"]}
1
+ {"version":3,"sources":["../src/embedded-session-client.ts","../src/hooks/use-session-mcp-approval-policy.ts","../src/hooks/use-session-lineage.ts"],"sourcesContent":["import type { ComposerDraft } from \"@opengeni/sdk\";\nimport type { EmbeddedSessionClientLike } from \"./client\";\n\nexport type ComposerDraftMapContext = {\n operation: \"read\" | \"save\" | \"submit\";\n workspaceId: string;\n sessionId: string;\n};\n\nexport type CreateEmbeddedSessionClientOptions = {\n /**\n * Explicit host-owned method replacements. Methods inherited from `base`\n * retain `base` as their receiver; overrides retain this object as theirs.\n */\n overrides?: Partial<EmbeddedSessionClientLike> | undefined;\n /** Presentation/policy projection for every draft entering the React layer. */\n mapComposerDraft?:\n | ((draft: ComposerDraft, context: ComposerDraftMapContext) => ComposerDraft)\n | undefined;\n};\n\nconst requiredMethods = [\n \"getSession\",\n \"listEvents\",\n \"streamEvents\",\n \"getComposerDraft\",\n \"saveComposerDraft\",\n \"submitComposerDraft\",\n \"sendMessage\",\n \"steerMessage\",\n \"getQueue\",\n \"moveQueueItem\",\n \"editQueueItem\",\n \"steerQueueItem\",\n \"deleteQueueItem\",\n \"pauseSession\",\n \"resumeSession\",\n \"sendApprovalDecision\",\n] as const satisfies readonly (keyof EmbeddedSessionClientLike)[];\n\n/**\n * Build the exact client required by `@opengeni/react/session` from a full SDK\n * client or host proxy. The constructor binds every delegated method once,\n * supports a host-owned atomic composer-submit override, and fails at creation\n * time instead of waiting for a missing method to be exercised by a hook.\n */\nexport function createEmbeddedSessionClient(\n base: EmbeddedSessionClientLike,\n options: CreateEmbeddedSessionClientOptions = {},\n): EmbeddedSessionClientLike {\n const overrides = options.overrides ?? {};\n const client = {} as EmbeddedSessionClientLike;\n for (const key of requiredMethods) {\n const override = overrides[key];\n const method = override ?? base[key];\n if (typeof method !== \"function\") {\n throw new TypeError(`Embedded session client method is required: ${key}`);\n }\n client[key] = method.bind(override === undefined ? base : overrides) as never;\n }\n\n const inferenceOverride = overrides.setWorkspaceInferenceState;\n const inferenceBase = base.setWorkspaceInferenceState;\n const inferenceMethod = inferenceOverride ?? inferenceBase;\n if (typeof inferenceMethod === \"function\") {\n client.setWorkspaceInferenceState = inferenceMethod.bind(\n inferenceOverride === undefined ? base : overrides,\n );\n }\n\n const mapDraft = options.mapComposerDraft;\n if (!mapDraft) return client;\n\n const getComposerDraft = client.getComposerDraft;\n client.getComposerDraft = async (workspaceId, sessionId) =>\n mapDraft(await getComposerDraft(workspaceId, sessionId), {\n operation: \"read\",\n workspaceId,\n sessionId,\n });\n\n const saveComposerDraft = client.saveComposerDraft;\n client.saveComposerDraft = async (workspaceId, sessionId, request) =>\n mapDraft(await saveComposerDraft(workspaceId, sessionId, request), {\n operation: \"save\",\n workspaceId,\n sessionId,\n });\n\n const submitComposerDraft = client.submitComposerDraft;\n client.submitComposerDraft = async (workspaceId, sessionId, request) => {\n const response = await submitComposerDraft(workspaceId, sessionId, request);\n return {\n ...response,\n draft: mapDraft(response.draft, {\n operation: \"submit\",\n workspaceId,\n sessionId,\n }),\n };\n };\n\n return client;\n}\n","import type {\n SessionEvent,\n SessionMcpApprovalPolicy,\n SessionMcpApprovalPolicyTarget,\n UpdateSessionMcpApprovalPolicyResponse,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useEmbeddedSessionMcpApprovalPolicy,\n type EmbeddedSessionMcpApprovalPolicyClientOverride,\n} from \"../session-context\";\nimport {\n useDebouncedCallback,\n useMutationRunner,\n usePolledValue,\n useSessionEventTrigger,\n type SessionEventFeedOptions,\n} from \"./internal\";\n\nexport function isSessionMcpApprovalPolicyEvent(\n event: Pick<SessionEvent, \"type\" | \"payload\">,\n serverId?: string,\n): boolean {\n if (event.type !== \"session.mcp.approval_policy.updated\") {\n return false;\n }\n if (serverId === undefined) {\n return true;\n }\n const payload = event.payload as { serverId?: unknown } | null;\n return payload?.serverId === serverId;\n}\n\nexport type UseSessionMcpApprovalPolicyOptions = EmbeddedSessionMcpApprovalPolicyClientOverride &\n SessionEventFeedOptions & {\n /** Optional safety-net polling (ms). Off by default; policy events drive refreshes. */\n pollIntervalMs?: number | undefined;\n };\n\nexport type UseSessionMcpApprovalPolicyResult = {\n server: SessionMcpApprovalPolicyTarget | null;\n policy: SessionMcpApprovalPolicy | null;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n update: (\n policy: SessionMcpApprovalPolicy,\n ) => Promise<UpdateSessionMcpApprovalPolicyResponse | null>;\n updating: boolean;\n clearError: () => void;\n};\n\n/**\n * Read and update one existing session MCP server's approval policy. Updates\n * become effective for the next claimed attempt; current work is unchanged.\n */\nexport function useSessionMcpApprovalPolicy(\n sessionId: string | null | undefined,\n serverId: string | null | undefined,\n options: UseSessionMcpApprovalPolicyOptions = {},\n): UseSessionMcpApprovalPolicyResult {\n const { client, workspaceId } = useEmbeddedSessionMcpApprovalPolicy(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId && serverId);\n const [override, setOverride] = useState<SessionMcpApprovalPolicyTarget | null>(null);\n const targetKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${serverId ?? \"\"}`;\n const authoritativeGeneration = useRef(0);\n const mutationIdentity = useMemo(() => ({ client, targetKey }), [client, targetKey]);\n const { run, mutating, mutationError, clearMutationError } = useMutationRunner(mutationIdentity);\n\n useLayoutEffect(() => {\n authoritativeGeneration.current += 1;\n setOverride(null);\n }, [client, targetKey]);\n\n type PolicyRead = {\n targetKey: string;\n generation: number;\n server: SessionMcpApprovalPolicyTarget | null;\n };\n const load = useCallback(async (): Promise<PolicyRead> => {\n const generation = authoritativeGeneration.current;\n if (!sessionId || !serverId) {\n return { targetKey, generation, server: null };\n }\n const session = await client.getSession(workspaceId, sessionId);\n return {\n targetKey,\n generation,\n server:\n session.mcpServers.find((server) => server.id === serverId) ??\n (session.mcpApprovalPolicies && Object.hasOwn(session.mcpApprovalPolicies, serverId)\n ? {\n id: serverId,\n source: \"workspace\",\n requireApproval: session.mcpApprovalPolicies[serverId]!,\n }\n : null),\n };\n }, [client, serverId, sessionId, targetKey, workspaceId]);\n const {\n data,\n loading,\n error: loadError,\n refresh,\n } = usePolledValue(load, {\n enabled,\n pollIntervalMs: options.pollIntervalMs,\n });\n useEffect(() => {\n if (data?.targetKey === targetKey && data.generation === authoritativeGeneration.current) {\n setOverride(null);\n }\n }, [data, targetKey]);\n\n const scheduleRefresh = useDebouncedCallback(() => void refresh());\n const matchesPolicyEvent = useCallback(\n (event: Pick<SessionEvent, \"type\" | \"payload\">) =>\n isSessionMcpApprovalPolicyEvent(event, serverId ?? undefined),\n [serverId],\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n matchesPolicyEvent,\n scheduleRefresh,\n {\n enabled,\n ...(options.events !== undefined ? { events: options.events } : {}),\n },\n async () => await refresh(),\n );\n\n const update = useCallback(\n async (\n policy: SessionMcpApprovalPolicy,\n ): Promise<UpdateSessionMcpApprovalPolicyResponse | null> => {\n if (!sessionId || !serverId) {\n return null;\n }\n const response = await run(() =>\n client.updateSessionMcpApprovalPolicy(workspaceId, sessionId, serverId, {\n requireApproval: policy,\n }),\n );\n if (response) {\n authoritativeGeneration.current += 1;\n setOverride(response.server);\n void refresh();\n }\n return response;\n },\n [client, refresh, run, serverId, sessionId, workspaceId],\n );\n\n const server = override ?? data?.server ?? null;\n return {\n server,\n policy: server?.requireApproval ?? null,\n loading,\n error: mutationError ?? loadError,\n refresh: async () => {\n await refresh();\n },\n update,\n updating: mutating,\n clearError: clearMutationError,\n };\n}\n","import type { SessionEvent, SessionLineageResponse } from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport {\n useEmbeddedSessionLineage,\n type EmbeddedSessionLineageClientOverride,\n} from \"../session-context\";\nimport { useDebouncedCallback, usePolledValue, useSessionEventTrigger } from \"./internal\";\n\nexport type UseSessionLineageOptions = EmbeddedSessionLineageClientOverride & {\n events?: SessionEvent[] | undefined;\n /** Refresh interval (ms). Off by default. */\n pollIntervalMs?: number | undefined;\n enabled?: boolean | undefined;\n /** Optional shared causal clock invoked when each network read starts. */\n beginRead?: (() => number) | undefined;\n};\n\nexport type UseSessionLineageResult = {\n lineage: SessionLineageResponse | null;\n loading: boolean;\n error: Error | null;\n /** Causal generation captured when the accepted lineage read started. */\n readGeneration: number;\n refresh: () => Promise<void>;\n};\n\nexport function isLineageRefreshEvent(event: SessionEvent): boolean {\n if (event.type === \"session.status.changed\" || event.type === \"session.created\") {\n return true;\n }\n // A child's creation never appears on the PARENT's stream as session.created —\n // the parent sees its own spawn as an agent.toolCall.* for session_create.\n // Created events are handled separately so they can refresh immediately and\n // once after the child row has had time to commit.\n if (event.type === \"agent.toolCall.output\") {\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n }\n return false;\n}\n\nfunction isSessionCreateToolCallCreated(event: SessionEvent): boolean {\n if (event.type !== \"agent.toolCall.created\") {\n return false;\n }\n const payload = event.payload as { name?: unknown; toolName?: unknown } | null | undefined;\n const name =\n typeof payload?.name === \"string\"\n ? payload.name\n : typeof payload?.toolName === \"string\"\n ? payload.toolName\n : \"\";\n return name === \"session_create\" || name.endsWith(\"__session_create\");\n}\n\n/** Read the ancestors + descendant tree for one session. Data-only; no UI state. */\nexport function useSessionLineage(\n sessionId: string | null | undefined,\n options: UseSessionLineageOptions = {},\n): UseSessionLineageResult {\n const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =\n useEmbeddedSessionLineage(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const nextReadGeneration = useRef(0);\n const beginRead = options.beginRead;\n const load = useCallback(\n async (signal?: AbortSignal) => {\n if (!sessionId) {\n return {\n lineage: { ancestors: [], children: [], truncated: false },\n readGeneration: 0,\n };\n }\n let readGeneration = 0;\n const lineage = await client.getSessionLineage(workspaceId, sessionId, {\n signal,\n onRequestStart: (sharedReadGeneration) => {\n readGeneration = sharedReadGeneration ?? beginRead?.() ?? ++nextReadGeneration.current;\n },\n });\n return {\n lineage,\n readGeneration,\n };\n },\n [beginRead, client, workspaceId, sessionId],\n );\n const state = usePolledValue(load, { pollIntervalMs: options.pollIntervalMs, enabled });\n const refresh = state.refresh;\n useEffect(() => {\n if (enabled && workspaceControlEvent) void refresh();\n }, [enabled, refresh, workspaceControlEvent]);\n useEffect(() => {\n if (!sessionId || !enabled) return;\n return registerSessionReconciler(sessionId, \"lineage\", refresh);\n }, [enabled, refresh, registerSessionReconciler, sessionId]);\n const refreshSoon = useDebouncedCallback(() => void refresh(), 150);\n const delayedChildRefreshRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Clear a pending delayed refresh on session/workspace SWITCH (not just\n // unmount): otherwise a timer scheduled for the previous session can fire\n // ~2.5s later and commit that session's lineage onto the new one.\n useEffect(() => {\n return () => {\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n delayedChildRefreshRef.current = null;\n }\n };\n }, [sessionId, workspaceId]);\n const refreshAfterChildCreate = useCallback(() => {\n void refresh();\n if (delayedChildRefreshRef.current !== null) {\n clearTimeout(delayedChildRefreshRef.current);\n }\n delayedChildRefreshRef.current = setTimeout(() => {\n delayedChildRefreshRef.current = null;\n void refresh();\n }, 2500);\n }, [refresh]);\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isLineageRefreshEvent,\n refreshSoon,\n // SHARED-FEED ONLY: without a caller-provided events log the trigger would\n // open its OWN streamEvents tail — a second live SSE connection next to the\n // session route's useSessionEvents. A caller with no feed opts into polling\n // (pollIntervalMs), never a duplicate stream.\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n useSessionEventTrigger(\n client,\n workspaceId,\n sessionId,\n isSessionCreateToolCallCreated,\n refreshAfterChildCreate,\n { events: options.events, enabled: enabled && options.events !== undefined },\n );\n return {\n lineage: state.data?.lineage ?? null,\n loading: state.loading,\n error: state.error,\n readGeneration: state.data?.readGeneration ?? 0,\n refresh,\n };\n}\n"],"mappings":"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","names":["server","useCallback","useEffect","useRef","useRef","useCallback","useEffect"]}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import {
2
3
  InteractionInterventionBanner,
3
4
  isInteractionControlUnavailable,
@@ -6,16 +7,16 @@ import {
6
7
  useInteractionInterventions,
7
8
  useInteractionInvalidation,
8
9
  useViewerMenuDismiss
9
- } from "./chunk-J6DBS4T3.js";
10
+ } from "./chunk-BNKV5ZLF.js";
10
11
  import {
11
12
  copyTextToClipboard
12
- } from "./chunk-JVYQRRC4.js";
13
+ } from "./chunk-CVYCLFMH.js";
13
14
  import {
14
15
  interactionHostPlatform
15
- } from "./chunk-RHREZ7BO.js";
16
+ } from "./chunk-ZUWF4NF7.js";
16
17
  import {
17
18
  formatBytes
18
- } from "./chunk-UTRTG6LH.js";
19
+ } from "./chunk-LVS3MH5T.js";
19
20
  import {
20
21
  STREAM_CLOSE_REASON_NORMAL,
21
22
  STREAM_KIND_BROWSER,
@@ -24,16 +25,16 @@ import {
24
25
  decodeStreamOpenAck,
25
26
  encodeStreamClose,
26
27
  encodeStreamOpen
27
- } from "./chunk-5J4FOW6Q.js";
28
+ } from "./chunk-TNEZNMSN.js";
28
29
  import {
29
30
  usePageLiveActivity
30
- } from "./chunk-YQEAA6LT.js";
31
+ } from "./chunk-QHUE7E4N.js";
31
32
  import {
32
33
  useEmbeddedBrowserInteraction
33
- } from "./chunk-TKOTKRWY.js";
34
+ } from "./chunk-XTD7TZHW.js";
34
35
  import {
35
36
  cn
36
- } from "./chunk-22KP6LR5.js";
37
+ } from "./chunk-TXS65BB2.js";
37
38
 
38
39
  // src/components/browser-viewer.tsx
39
40
  import { interactionControlFailureFromError } from "@opengeni/sdk/interaction";
@@ -4546,4 +4547,4 @@ export {
4546
4547
  useBrowserFrameStream,
4547
4548
  BrowserViewer
4548
4549
  };
4549
- //# sourceMappingURL=chunk-HDJWDK7W.js.map
4550
+ //# sourceMappingURL=chunk-VCSERYXH.js.map