@datalayer/agent-runtimes 1.5.65 → 1.5.70
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.
- package/dist-embed/chunks/{AgentDetails-RIFH8RAg.js → AgentDetails-BriiIXid.js} +1 -1
- package/dist-embed/chunks/{AgentDetailsDialog-CK7jVPSc.js → AgentDetailsDialog-Bh3yhb7O.js} +1 -1
- package/dist-embed/chunks/{AgentInspector-DwZk4yjT.js → AgentInspector-Dd-G3TvL.js} +1 -1
- package/dist-embed/chunks/{AgentInspectorDialog-Ct12Hqc-.js → AgentInspectorDialog-CQEiBqOl.js} +1 -1
- package/dist-embed/chunks/{CellSidebarExtension-CbVVhhaO.js → CellSidebarExtension-DbbW8AJP.js} +1 -1
- package/dist-embed/chunks/ChatView-LzqHHAEe.js +32 -0
- package/dist-embed/chunks/{ContextPie-DLR5REbp.js → ContextPie-I90j658q.js} +1 -1
- package/dist-embed/chunks/{DeckComponent-C_ZaO_iF.js → DeckComponent-DAnUabRV.js} +2 -2
- package/dist-embed/chunks/{DocumentView-DP-dxfpu.js → DocumentView-BKFitqiB.js} +1 -1
- package/dist-embed/chunks/{EphemeralDocument-D3rfKBME.js → EphemeralDocument-BRzYMd8Z.js} +1 -1
- package/dist-embed/chunks/{EphemeralNotebook-Dn3ku5jr.js → EphemeralNotebook-COnqhW7Q.js} +1 -1
- package/dist-embed/chunks/{ExcalidrawComponent-B7I0SoHM.js → ExcalidrawComponent-VnKcai35.js} +1 -1
- package/dist-embed/chunks/{ExcalidrawModal-B2VIt9DT.js → ExcalidrawModal-DrntFjbe.js} +1 -1
- package/dist-embed/chunks/{JupyterLexicalExtension-LpJ6Rj9h.js → JupyterLexicalExtension-BBivQZvX.js} +9 -9
- package/dist-embed/chunks/{KernelVariables-ZFnygJ4R.js → KernelVariables-CNEfUsyt.js} +1 -1
- package/dist-embed/chunks/{LexicalToolRegistry-BRMKFkxC.js → LexicalToolRegistry-B8ccPURu.js} +4 -4
- package/dist-embed/chunks/{NotebookToolSurfaces-Dz_cxy8L.js → NotebookToolSurfaces-B8Rmjy_m.js} +1 -1
- package/dist-embed/chunks/{NotebookView-DG-pAyOq.js → NotebookView-BDChKuA9.js} +1 -1
- package/dist-embed/chunks/{Output-Cnq5i-bK.js → Output-CEoYDjwn.js} +1 -1
- package/dist-embed/chunks/{SandboxDetailsDialog-BzGdQmTQ.js → SandboxDetailsDialog-DuavSJSL.js} +1 -1
- package/dist-embed/chunks/SchemaForm-C6wDxDrg.js +1 -0
- package/dist-embed/chunks/{WidgetVariableView-kRHeKnmD.js → WidgetVariableView-Tm5SSEKf.js} +1 -1
- package/dist-embed/chunks/{YouTubePlugin-ChwsOfjj.js → YouTubePlugin-C209681s.js} +1 -1
- package/dist-embed/chunks/{abnfDiagram-VCTEODGH-sr3TJAkV.js → abnfDiagram-VCTEODGH-CsKFU4Ej.js} +1 -1
- package/dist-embed/chunks/{abnfDiagram-VCTEODGH-Byz1QYm8.js → abnfDiagram-VCTEODGH-m7LJLYga.js} +1 -1
- package/dist-embed/chunks/{ar-SA-G6X2FPQ2-D1OmbW2u.js → ar-SA-G6X2FPQ2-Dypu3IcK.js} +1 -1
- package/dist-embed/chunks/{architectureDiagram-5GKGNRK7-B7rDWQh9.js → architectureDiagram-5GKGNRK7-C22xzf-o.js} +1 -1
- package/dist-embed/chunks/{architectureDiagram-5GKGNRK7-DOxpBf54.js → architectureDiagram-5GKGNRK7-iDgRBR0a.js} +1 -1
- package/dist-embed/chunks/{az-AZ-76LH7QW2-CmSoFd5x.js → az-AZ-76LH7QW2-D8CzfKb1.js} +1 -1
- package/dist-embed/chunks/{bg-BG-XCXSNQG7-D7b2U9I0.js → bg-BG-XCXSNQG7-_NVFEM1_.js} +1 -1
- package/dist-embed/chunks/{blockDiagram-868be97b-CKmWpImQ.js → blockDiagram-868be97b-D3BurtSN.js} +1 -1
- package/dist-embed/chunks/{blockDiagram-I7D4REHJ-_fDDlpCe.js → blockDiagram-I7D4REHJ-CHicgYkf.js} +1 -1
- package/dist-embed/chunks/{blockDiagram-I7D4REHJ-bzZkd0c3.js → blockDiagram-I7D4REHJ-oDRNhSU2.js} +1 -1
- package/dist-embed/chunks/{bn-BD-2XOGV67Q-CG3iRJ8B.js → bn-BD-2XOGV67Q-DMgdNi-k.js} +1 -1
- package/dist-embed/chunks/{c4Diagram-3f4bdde3-zvlk6Xm2.js → c4Diagram-3f4bdde3-Dmbl9p6m.js} +1 -1
- package/dist-embed/chunks/{c4Diagram-7LVT6UL2-NpmtOeoK.js → c4Diagram-7LVT6UL2-CR3iQQ6O.js} +1 -1
- package/dist-embed/chunks/{c4Diagram-7LVT6UL2-vHp7kFMG.js → c4Diagram-7LVT6UL2-auJZQjpw.js} +1 -1
- package/dist-embed/chunks/{ca-ES-6MX7JW3Y-BW4zf4cd.js → ca-ES-6MX7JW3Y-DpOQhzr4.js} +1 -1
- package/dist-embed/chunks/{celltoolbartracker-DDVXLR_l.js → celltoolbartracker-DCR86wxV.js} +1 -1
- package/dist-embed/chunks/{chunk-2Q5K7J3B-Blqxrfai.js → chunk-2Q5K7J3B-DpFWUcsT.js} +1 -1
- package/dist-embed/chunks/{chunk-2Q5K7J3B-D26LTlFj.js → chunk-2Q5K7J3B-H_DA_jTG.js} +1 -1
- package/dist-embed/chunks/{chunk-5VM5RSS4-CdbSD_M8.js → chunk-5VM5RSS4-BhWUyelG.js} +1 -1
- package/dist-embed/chunks/{chunk-5VM5RSS4-BcO1XpWr.js → chunk-5VM5RSS4-CaowF8Al.js} +1 -1
- package/dist-embed/chunks/{chunk-F27PBJKO-BQ-ZIw-1.js → chunk-F27PBJKO-B9wgW70d.js} +1 -1
- package/dist-embed/chunks/{chunk-F27PBJKO-BRe2RwsD.js → chunk-F27PBJKO-D7PuEggc.js} +1 -1
- package/dist-embed/chunks/{chunk-IMKFNOWR-D-RO-dCd.js → chunk-IMKFNOWR-DhXkXQPV.js} +1 -1
- package/dist-embed/chunks/{chunk-IMKFNOWR-CLFrksv5.js → chunk-IMKFNOWR-jZNuNkCa.js} +1 -1
- package/dist-embed/chunks/{chunk-JWPE2WC7-wyMu098x.js → chunk-JWPE2WC7-BIShIUcJ.js} +1 -1
- package/dist-embed/chunks/{chunk-JWPE2WC7-DbtWvNSt.js → chunk-JWPE2WC7-DaBG37yC.js} +1 -1
- package/dist-embed/chunks/{chunk-POPQ4Y6H-OgpU0qcq.js → chunk-POPQ4Y6H-DG5Q2OKT.js} +1 -1
- package/dist-embed/chunks/{chunk-POPQ4Y6H-lwXXWwpD.js → chunk-POPQ4Y6H-WjTzJISs.js} +1 -1
- package/dist-embed/chunks/{chunk-SVP7TREG-CtOO_gz8.js → chunk-SVP7TREG-ERRaAh-x.js} +1 -1
- package/dist-embed/chunks/{chunk-SVP7TREG-C1pZJEUL.js → chunk-SVP7TREG-bq0J6tH_.js} +1 -1
- package/dist-embed/chunks/{chunk-TICWLB2K-BUeW_P5i.js → chunk-TICWLB2K-B91fA6Jd.js} +1 -1
- package/dist-embed/chunks/{chunk-TICWLB2K-B2id4fS-.js → chunk-TICWLB2K-BV_9f6ak.js} +1 -1
- package/dist-embed/chunks/{chunk-XXDRQBXY-6emV99Se.js → chunk-XXDRQBXY-BAy0lBJk.js} +1 -1
- package/dist-embed/chunks/{chunk-XXDRQBXY-DASCZDLb.js → chunk-XXDRQBXY-fV8doVJJ.js} +1 -1
- package/dist-embed/chunks/{classDiagram-ZZMXUADV-BUcYJSYu.js → classDiagram-ZZMXUADV-B0pbDswj.js} +1 -1
- package/dist-embed/chunks/{classDiagram-ZZMXUADV-DXK_VS6x.js → classDiagram-ZZMXUADV-CGdcKCOI.js} +1 -1
- package/dist-embed/chunks/{classDiagram-f62afe4f-D_XtspOB.js → classDiagram-f62afe4f-tD890DEl.js} +1 -1
- package/dist-embed/chunks/{classDiagram-v2-604399ef-DmVGURP4.js → classDiagram-v2-604399ef-DReIuoeI.js} +1 -1
- package/dist-embed/chunks/{classDiagram-v2-VYDZK3BY-BUcYJSYu.js → classDiagram-v2-VYDZK3BY-B0pbDswj.js} +1 -1
- package/dist-embed/chunks/{classDiagram-v2-VYDZK3BY-DXK_VS6x.js → classDiagram-v2-VYDZK3BY-CGdcKCOI.js} +1 -1
- package/dist-embed/chunks/{code-block-IT6T5CEO-CLFy43wi.js → code-block-IT6T5CEO-DD7hwbHA.js} +1 -1
- package/dist-embed/chunks/{component-BABP_IeE.js → component-BWDcVpKW.js} +1 -1
- package/dist-embed/chunks/{cose-bilkent-JH36ORCC-DkllT3uc.js → cose-bilkent-JH36ORCC-BS_pJML-.js} +1 -1
- package/dist-embed/chunks/{cose-bilkent-JH36ORCC-zloY56Dd.js → cose-bilkent-JH36ORCC-BsK2pWDL.js} +1 -1
- package/dist-embed/chunks/{createText-aed3d8b3-B_AmUgWn.js → createText-aed3d8b3-1eVJ8jxH.js} +2 -2
- package/dist-embed/chunks/{cs-CZ-2BRQDIVT-DzWWfN4P.js → cs-CZ-2BRQDIVT-Fr-SpqHD.js} +1 -1
- package/dist-embed/chunks/{cynefinDiagram-5FMLGOSQ-CT11o-tV.js → cynefinDiagram-5FMLGOSQ-AxJwZ7KT.js} +1 -1
- package/dist-embed/chunks/{cynefinDiagram-5FMLGOSQ-Benlx8nr.js → cynefinDiagram-5FMLGOSQ-vmheD_S2.js} +1 -1
- package/dist-embed/chunks/{da-DK-5WZEPLOC-CaeirLFF.js → da-DK-5WZEPLOC-DO_sAXvt.js} +1 -1
- package/dist-embed/chunks/{dagre-GXQ25YYZ-B2PPWFKB.js → dagre-GXQ25YYZ-B8Ip03td.js} +1 -1
- package/dist-embed/chunks/{dagre-GXQ25YYZ-qys4evHY.js → dagre-GXQ25YYZ-BgrGEY09.js} +1 -1
- package/dist-embed/chunks/{de-DE-XR44H4JA-DBkebtzo.js → de-DE-XR44H4JA-4JnXB_iM.js} +1 -1
- package/dist-embed/chunks/{diagram-S7CK7UJ4-C1EHbNes.js → diagram-S7CK7UJ4-BxRBCYVP.js} +1 -1
- package/dist-embed/chunks/{diagram-S7CK7UJ4-CBkf-BrM.js → diagram-S7CK7UJ4-hQvZziAN.js} +1 -1
- package/dist-embed/chunks/{diagram-UQ7AKVKN-CKsxaZCe.js → diagram-UQ7AKVKN-BFkOO3Wu.js} +1 -1
- package/dist-embed/chunks/{diagram-UQ7AKVKN-C9zuKZ5Y.js → diagram-UQ7AKVKN-BvgP6_rf.js} +1 -1
- package/dist-embed/chunks/{diagram-VSXAHHWV-Cd8pBAf-.js → diagram-VSXAHHWV-Cy8iWh4H.js} +1 -1
- package/dist-embed/chunks/{diagram-VSXAHHWV-Dd_PlC0S.js → diagram-VSXAHHWV-WVuzjdxU.js} +1 -1
- package/dist-embed/chunks/{diagram-VX7I27RA-DZTLEsKe.js → diagram-VX7I27RA-CCx8R8FK.js} +1 -1
- package/dist-embed/chunks/{diagram-VX7I27RA-D5qf5Kw-.js → diagram-VX7I27RA-_LUOsaBb.js} +1 -1
- package/dist-embed/chunks/{diagram-Z3DM3KII-DlsBShb0.js → diagram-Z3DM3KII-CY856Sry.js} +1 -1
- package/dist-embed/chunks/{diagram-Z3DM3KII-B2zosfsY.js → diagram-Z3DM3KII-Dqcrl8-1.js} +1 -1
- package/dist-embed/chunks/{ebnfDiagram-PWID7BFC-VhBXkHc8.js → ebnfDiagram-PWID7BFC-DC-Zam6d.js} +1 -1
- package/dist-embed/chunks/{ebnfDiagram-PWID7BFC-sUXnKXhD.js → ebnfDiagram-PWID7BFC-kqD9RLAA.js} +1 -1
- package/dist-embed/chunks/{edges-b2856ca0-cYsFYCgh.js → edges-b2856ca0-B3ybuHDU.js} +1 -1
- package/dist-embed/chunks/{el-GR-BZB4AONW-DkmsSwGL.js → el-GR-BZB4AONW-MydAlwHl.js} +1 -1
- package/dist-embed/chunks/{erDiagram-5d81789a-DHzqp69u.js → erDiagram-5d81789a-HZ-VLc2f.js} +1 -1
- package/dist-embed/chunks/{erDiagram-RLTQ6QDP-DPzcAUZq.js → erDiagram-RLTQ6QDP-CNO4pVhU.js} +1 -1
- package/dist-embed/chunks/{erDiagram-RLTQ6QDP-BRf7HEXF.js → erDiagram-RLTQ6QDP-zwXEFcAp.js} +1 -1
- package/dist-embed/chunks/{es-ES-U4NZUMDT-Dvnvh6dW.js → es-ES-U4NZUMDT-rQmnr_uu.js} +1 -1
- package/dist-embed/chunks/{eu-ES-A7QVB2H4-DYX6hpyz.js → eu-ES-A7QVB2H4-j5Hf8ngk.js} +1 -1
- package/dist-embed/chunks/{fa-IR-HGAKTJCU-Dmlm1ZjK.js → fa-IR-HGAKTJCU-DMJRRSBp.js} +1 -1
- package/dist-embed/chunks/{fi-FI-Z5N7JZ37-2ov9-9H3.js → fi-FI-Z5N7JZ37-BFLC0BFd.js} +1 -1
- package/dist-embed/chunks/{flowDb-185abca5-vnPYmNxZ.js → flowDb-185abca5-7Nn2obHG.js} +1 -1
- package/dist-embed/chunks/{flowDiagram-1629c991-D_P7IhnT.js → flowDiagram-1629c991-CnvM_psw.js} +1 -1
- package/dist-embed/chunks/{flowDiagram-HODETNUW-BUuZtbKx.js → flowDiagram-HODETNUW-BrbR1EkW.js} +1 -1
- package/dist-embed/chunks/{flowDiagram-HODETNUW-Dqms2kHK.js → flowDiagram-HODETNUW-Bsl5oOFb.js} +1 -1
- package/dist-embed/chunks/{flowDiagram-v2-1d953310-jyYNkbVD.js → flowDiagram-v2-1d953310-TkF25UVC.js} +1 -1
- package/dist-embed/chunks/{flowchart-elk-definition-6df44142-CkUTQpED.js → flowchart-elk-definition-6df44142-CwiGfEuJ.js} +1 -1
- package/dist-embed/chunks/{fr-FR-RHASNOE6-BUlHGdL2.js → fr-FR-RHASNOE6-CxjhSJC1.js} +1 -1
- package/dist-embed/chunks/{ganttDiagram-3b0b3873-CDk8PUcC.js → ganttDiagram-3b0b3873-DeouFDZE.js} +1 -1
- package/dist-embed/chunks/{ganttDiagram-EL5Y4UJY-D4fzILsk.js → ganttDiagram-EL5Y4UJY-BeK3rGHM.js} +1 -1
- package/dist-embed/chunks/{ganttDiagram-EL5Y4UJY-Tsk8dNyJ.js → ganttDiagram-EL5Y4UJY-DfJDZVnm.js} +1 -1
- package/dist-embed/chunks/{gitGraphDiagram-WWUBYQGX-DSJR8KGU.js → gitGraphDiagram-WWUBYQGX-BujqTwbf.js} +1 -1
- package/dist-embed/chunks/{gitGraphDiagram-WWUBYQGX-XOpfU7hY.js → gitGraphDiagram-WWUBYQGX-DkYi8eWr.js} +1 -1
- package/dist-embed/chunks/{gitGraphDiagram-f01e8bc2-C7QWh6IZ.js → gitGraphDiagram-f01e8bc2-mCCRVzIs.js} +1 -1
- package/dist-embed/chunks/{gl-ES-HMX3MZ6V-T3hKsmlm.js → gl-ES-HMX3MZ6V-BuuMpTaX.js} +1 -1
- package/dist-embed/chunks/{he-IL-6SHJWFNN-DoePgaFj.js → he-IL-6SHJWFNN-Cv3Nrcgu.js} +1 -1
- package/dist-embed/chunks/{hi-IN-IWLTKZ5I-B_E7TPlk.js → hi-IN-IWLTKZ5I-Sddst60F.js} +1 -1
- package/dist-embed/chunks/{hu-HU-A5ZG7DT2-Bu8X3BrR.js → hu-HU-A5ZG7DT2-ehrXVpD0.js} +1 -1
- package/dist-embed/chunks/{id-ID-SAP4L64H-jOs7pgj2.js → id-ID-SAP4L64H-Gfb1UYxZ.js} +1 -1
- package/dist-embed/chunks/{index-JF61_zqs.js → index-5NOGMVjz.js} +1 -1
- package/dist-embed/chunks/{index-BzgczmKp.js → index-6zxVHKca.js} +10 -10
- package/dist-embed/chunks/{index-9bae90f3-BywpAnlj.js → index-9bae90f3-CzUk5Hhq.js} +1 -1
- package/dist-embed/chunks/{index-DvHqo_Qj.js → index-AHAhJxOc.js} +1 -1
- package/dist-embed/chunks/{index-7hNcqUR-.js → index-B9Ya6z2n.js} +1 -1
- package/dist-embed/chunks/{index-BwyZ8O-M.js → index-BOEhatkt.js} +1 -1
- package/dist-embed/chunks/{index-BYo3uv0g.js → index-BOGJMsUN.js} +2 -2
- package/dist-embed/chunks/{index-Bmo-OFNb.js → index-BaBNw6X5.js} +4 -4
- package/dist-embed/chunks/{index-BR58wzgU.js → index-BfvZMC2B.js} +1 -1
- package/dist-embed/chunks/{index-DnqWNX5L.js → index-BiuABva5.js} +1 -1
- package/dist-embed/chunks/{index-0m4vhMAR.js → index-BjfpYq_l.js} +1 -1
- package/dist-embed/chunks/{index-BI_0cBab.js → index-BuXVVl_h.js} +7 -7
- package/dist-embed/chunks/{index-fBSCurWE.js → index-By5Ku2wm.js} +4 -4
- package/dist-embed/chunks/{index-Bw1BRX9C.js → index-CNpJ8Y2y.js} +1 -1
- package/dist-embed/chunks/{index-zrM_sbHt.js → index-Cw1r0WFc.js} +1 -1
- package/dist-embed/chunks/{index-CS3mm6qN.js → index-D8x0MQWQ.js} +1 -1
- package/dist-embed/chunks/{index-BqpOM6Mx.js → index-DDnf06e_.js} +1 -1
- package/dist-embed/chunks/{index-B3fpdUTu.js → index-DGefzKhT.js} +1 -1
- package/dist-embed/chunks/{index-CgCcVxV_.js → index-DN6Cori6.js} +1 -1
- package/dist-embed/chunks/{index-_z7rhr9l.js → index-DQ-v6JVz.js} +4 -4
- package/dist-embed/chunks/{index-C2JsK59r.js → index-DTYZzbES.js} +1 -1
- package/dist-embed/chunks/{index-MfJ2dN-o.js → index-DWkIO3YS.js} +1 -1
- package/dist-embed/chunks/{index-CL2J1VY_.js → index-DZwyICkp.js} +1 -1
- package/dist-embed/chunks/{index-CoVJiT-h.js → index-D_vehxcD.js} +1 -1
- package/dist-embed/chunks/{index-wqOJuJys.js → index-DiTcTB7Y.js} +1 -1
- package/dist-embed/chunks/{index-COPak822.js → index-DmpLE1d4.js} +1 -1
- package/dist-embed/chunks/{index-Ca5wn1F-.js → index-Do4nOAaR.js} +1 -1
- package/dist-embed/chunks/{index-DBRbrQr1.js → index-DobaF_Ee.js} +1 -1
- package/dist-embed/chunks/{index-BfuxhQsr.js → index-DvwQdrde.js} +1 -1
- package/dist-embed/chunks/{index-KC9furSU.js → index-DzMYyq8T.js} +1 -1
- package/dist-embed/chunks/{index-Cz0vwY93.js → index-QHmZQlKN.js} +6 -6
- package/dist-embed/chunks/{index-C00mEIpi.js → index-hxIHgkzg.js} +1 -1
- package/dist-embed/chunks/{index-B27olYsx.js → index-nMwnYxTd.js} +1 -1
- package/dist-embed/chunks/{index-NvC9D0Mh.js → index-umwkqggg.js} +1 -1
- package/dist-embed/chunks/{index-3JfFVSno.js → index-yMppJWrQ.js} +1 -1
- package/dist-embed/chunks/{index.esm-BbIi4n-Y.js → index.esm-CC457Cyg.js} +1 -1
- package/dist-embed/chunks/{index.esm-ePira_es.js → index.esm-DFDbLGof.js} +1 -1
- package/dist-embed/chunks/{infoDiagram-27XIBGKW-CvSw0Uqm.js → infoDiagram-27XIBGKW-C18Zz25F.js} +1 -1
- package/dist-embed/chunks/{infoDiagram-27XIBGKW-BagqSEKB.js → infoDiagram-27XIBGKW-DiC5_yjB.js} +1 -1
- package/dist-embed/chunks/{infoDiagram-a29d40f1-CY6P-RB2.js → infoDiagram-a29d40f1-DRVyx4Bf.js} +1 -1
- package/dist-embed/chunks/{ishikawaDiagram-5VMMS53U-CJjl4-N0.js → ishikawaDiagram-5VMMS53U-3WGbru46.js} +1 -1
- package/dist-embed/chunks/{ishikawaDiagram-5VMMS53U-DQfqd5pn.js → ishikawaDiagram-5VMMS53U-DrEzfSK9.js} +1 -1
- package/dist-embed/chunks/{it-IT-JPQ66NNP-CrGtxCjf.js → it-IT-JPQ66NNP-BehLHkar.js} +1 -1
- package/dist-embed/chunks/{ja-JP-DBVTYXUO-MhHoMhnM.js → ja-JP-DBVTYXUO-BZvqIigI.js} +1 -1
- package/dist-embed/chunks/{journeyDiagram-3NMN7TZE-B186toLf.js → journeyDiagram-3NMN7TZE-BZWmkUfk.js} +1 -1
- package/dist-embed/chunks/{journeyDiagram-3NMN7TZE-fMuL5yIV.js → journeyDiagram-3NMN7TZE-DpWKIFIN.js} +1 -1
- package/dist-embed/chunks/{journeyDiagram-95396277-Bt2VFr_f.js → journeyDiagram-95396277-D_QLiVq4.js} +1 -1
- package/dist-embed/chunks/{kaa-6HZHGXH3-otexWzw0.js → kaa-6HZHGXH3-DgAIF6rN.js} +1 -1
- package/dist-embed/chunks/{kab-KAB-ZGHBKWFO-Bk_pPM_n.js → kab-KAB-ZGHBKWFO-DW4thPSJ.js} +1 -1
- package/dist-embed/chunks/{kanban-definition-UXKFOSKX-tkyZOsyz.js → kanban-definition-UXKFOSKX-B84ZaZEy.js} +1 -1
- package/dist-embed/chunks/{kanban-definition-UXKFOSKX-DyX3lLGq.js → kanban-definition-UXKFOSKX-DxbTprYr.js} +1 -1
- package/dist-embed/chunks/{kk-KZ-P5N5QNE5-DuPx0Ivn.js → kk-KZ-P5N5QNE5-CCy_nSJ7.js} +1 -1
- package/dist-embed/chunks/{km-KH-HSX4SM5Z-DfW3Tv6Q.js → km-KH-HSX4SM5Z-kpXyoxjS.js} +1 -1
- package/dist-embed/chunks/{ko-KR-MTYHY66A-CWeM03UD.js → ko-KR-MTYHY66A-CFm6WtQG.js} +1 -1
- package/dist-embed/chunks/{ku-TR-6OUDTVRD-BpZVGVBG.js → ku-TR-6OUDTVRD-CKF85mOv.js} +1 -1
- package/dist-embed/chunks/{layout-i1FLEqsi.js → layout-DYytgC9r.js} +1 -1
- package/dist-embed/chunks/{layout-P_H-0ax9.js → layout-Dx5Hzkor.js} +1 -1
- package/dist-embed/chunks/{lexicalHooks-BjTCfdUi.js → lexicalHooks-DbTGOMyq.js} +1 -1
- package/dist-embed/chunks/{lt-LT-XHIRWOB4-LavcVuZR.js → lt-LT-XHIRWOB4-CO9Bo5qJ.js} +1 -1
- package/dist-embed/chunks/{lv-LV-5QDEKY6T-DWoheFP4.js → lv-LV-5QDEKY6T-CvZszc5p.js} +1 -1
- package/dist-embed/chunks/{mermaid.core-Cltl6__q.js → mermaid.core-D0955PCw.js} +5 -5
- package/dist-embed/chunks/{mermaid.core-Bd5egiDP.js → mermaid.core-D98kc0OO.js} +3 -3
- package/dist-embed/chunks/{mindmap-definition-YA3MSWOX-BmuUH3a3.js → mindmap-definition-YA3MSWOX-D86IPkt3.js} +1 -1
- package/dist-embed/chunks/{mindmap-definition-YA3MSWOX-Di0Xac42.js → mindmap-definition-YA3MSWOX-_1SBIPav.js} +1 -1
- package/dist-embed/chunks/{mindmap-definition-e4c1d938-D0Ep5LxZ.js → mindmap-definition-e4c1d938-UbbfpF-a.js} +1 -1
- package/dist-embed/chunks/{mr-IN-CRQNXWMA-G-1tBL4-.js → mr-IN-CRQNXWMA-Cio_dB9M.js} +1 -1
- package/dist-embed/chunks/{my-MM-5M5IBNSE-DpmzmQ2W.js → my-MM-5M5IBNSE-Z0RQ5Vbz.js} +1 -1
- package/dist-embed/chunks/{nb-NO-T6EIAALU-DFU_SPCx.js → nb-NO-T6EIAALU-BEQ0YP9J.js} +1 -1
- package/dist-embed/chunks/{nl-NL-IS3SIHDZ-Dlz_okxD.js → nl-NL-IS3SIHDZ-YtkJnS_J.js} +1 -1
- package/dist-embed/chunks/{nn-NO-6E72VCQL-D9E-BpHw.js → nn-NO-6E72VCQL-C1j2s3qO.js} +1 -1
- package/dist-embed/chunks/{oc-FR-POXYY2M6-CVonm6mx.js → oc-FR-POXYY2M6-CinnjccW.js} +1 -1
- package/dist-embed/chunks/{pa-IN-N4M65BXN-a5ExTB9v.js → pa-IN-N4M65BXN-c_6OtC6L.js} +1 -1
- package/dist-embed/chunks/{pegDiagram-XKGWAZYB-BYznG-ZK.js → pegDiagram-XKGWAZYB-BBVcHZ8T.js} +1 -1
- package/dist-embed/chunks/{pegDiagram-XKGWAZYB-Cptotyez.js → pegDiagram-XKGWAZYB-BJAdJVqh.js} +1 -1
- package/dist-embed/chunks/{percentages-BXMCSKIN-C2-svgs_.js → percentages-BXMCSKIN-VqMxh8LK.js} +5 -5
- package/dist-embed/chunks/{pieDiagram-E7YTZNPT-BYEkkWvq.js → pieDiagram-E7YTZNPT-C55wHgO0.js} +1 -1
- package/dist-embed/chunks/{pieDiagram-E7YTZNPT-D51avc4V.js → pieDiagram-E7YTZNPT-EvMxJb2S.js} +1 -1
- package/dist-embed/chunks/{pieDiagram-c941bede-Bcau8_Gm.js → pieDiagram-c941bede-DTmViAsB.js} +1 -1
- package/dist-embed/chunks/{pl-PL-T2D74RX3-BaHKKcOg.js → pl-PL-T2D74RX3-Cn_9xZgM.js} +1 -1
- package/dist-embed/chunks/{pt-BR-5N22H2LF-DZEHszX8.js → pt-BR-5N22H2LF-Da6r-Pp1.js} +1 -1
- package/dist-embed/chunks/{pt-PT-UZXXM6DQ-BbJKz8vE.js → pt-PT-UZXXM6DQ-D6lhcuX9.js} +1 -1
- package/dist-embed/chunks/{quadrantDiagram-AXDQQJYC-BfWK8wgJ.js → quadrantDiagram-AXDQQJYC-BCeMrGXB.js} +1 -1
- package/dist-embed/chunks/{quadrantDiagram-AXDQQJYC-CcMIo23m.js → quadrantDiagram-AXDQQJYC-rFaTvNlk.js} +1 -1
- package/dist-embed/chunks/{quadrantDiagram-cf8b8fe0-Db1y7cGB.js → quadrantDiagram-cf8b8fe0-BZAbhmbg.js} +1 -1
- package/dist-embed/chunks/{railroadDiagram-O6MQD6OU-BzqhRF47.js → railroadDiagram-O6MQD6OU-BAXhb26s.js} +1 -1
- package/dist-embed/chunks/{railroadDiagram-O6MQD6OU-DCRFdpxj.js → railroadDiagram-O6MQD6OU-bR7xXZGS.js} +1 -1
- package/dist-embed/chunks/{renderer-CM-Z_1Uj.js → renderer-DfML3j-s.js} +1 -1
- package/dist-embed/chunks/{requirementDiagram-53bda41b-Dj564NwS.js → requirementDiagram-53bda41b-DNqx3JRF.js} +1 -1
- package/dist-embed/chunks/{requirementDiagram-BXWQKSXE-dma0a-bN.js → requirementDiagram-BXWQKSXE-B0SL6Gqb.js} +1 -1
- package/dist-embed/chunks/{requirementDiagram-BXWQKSXE-CIFZt_cP.js → requirementDiagram-BXWQKSXE-DHLQ_9Lw.js} +1 -1
- package/dist-embed/chunks/{ro-RO-JPDTUUEW-szdAFgjr.js → ro-RO-JPDTUUEW-BFss9e8X.js} +1 -1
- package/dist-embed/chunks/{ru-RU-B4JR7IUQ-CbdtKkxy.js → ru-RU-B4JR7IUQ-DIruW2gS.js} +1 -1
- package/dist-embed/chunks/{sankeyDiagram-P5KCCOFB-8ur8k-HP.js → sankeyDiagram-P5KCCOFB-CktuQIU1.js} +1 -1
- package/dist-embed/chunks/{sankeyDiagram-P5KCCOFB-DRxZFl9I.js → sankeyDiagram-P5KCCOFB-Nk71fRsK.js} +1 -1
- package/dist-embed/chunks/{sankeyDiagram-c3ef121a-Da81kIDr.js → sankeyDiagram-c3ef121a-4-5C_fXA.js} +1 -1
- package/dist-embed/chunks/{sequenceDiagram-82a5b84f-DM8BTW5K.js → sequenceDiagram-82a5b84f-DedJ5qnD.js} +1 -1
- package/dist-embed/chunks/{sequenceDiagram-WJ2MYXX4-BH0Y4uG3.js → sequenceDiagram-WJ2MYXX4-BBGHED3s.js} +1 -1
- package/dist-embed/chunks/{sequenceDiagram-WJ2MYXX4-CNwXBdZi.js → sequenceDiagram-WJ2MYXX4-Dm3QM01Z.js} +1 -1
- package/dist-embed/chunks/{sessions-DlvFLGbP.js → sessions-lT1zQJEG.js} +2 -2
- package/dist-embed/chunks/{si-LK-N5RQ5JYF-DfCWfEQf.js → si-LK-N5RQ5JYF-Dom-aTTE.js} +1 -1
- package/dist-embed/chunks/{sizeCapture-INFHLROL-D-nX-7Hv.js → sizeCapture-INFHLROL-BNuVN7vX.js} +1 -1
- package/dist-embed/chunks/{sizeCapture-INFHLROL-Tw2tvJ1W.js → sizeCapture-INFHLROL-BW7unDBA.js} +1 -1
- package/dist-embed/chunks/{sk-SK-C5VTKIMK-CTeAwA1b.js → sk-SK-C5VTKIMK-CLRU9TNq.js} +1 -1
- package/dist-embed/chunks/{sl-SI-NN7IZMDC-eFw2lQcd.js → sl-SI-NN7IZMDC-BKLCNVXA.js} +1 -1
- package/dist-embed/chunks/{stateDiagram-43e79a5f-H8oVn7EH.js → stateDiagram-43e79a5f-C-TVhCrM.js} +1 -1
- package/dist-embed/chunks/{stateDiagram-D77RDMKH-DS-byRyy.js → stateDiagram-D77RDMKH-mLSMGpPQ.js} +1 -1
- package/dist-embed/chunks/{stateDiagram-D77RDMKH-CGEuq_3Z.js → stateDiagram-D77RDMKH-tqnmMQUf.js} +1 -1
- package/dist-embed/chunks/{stateDiagram-v2-2041ed4f-D7zd-PeH.js → stateDiagram-v2-2041ed4f-TVcKzajK.js} +1 -1
- package/dist-embed/chunks/{stateDiagram-v2-MP3YSRHH-Bbn7CxXx.js → stateDiagram-v2-MP3YSRHH-C3MNIg5B.js} +1 -1
- package/dist-embed/chunks/{stateDiagram-v2-MP3YSRHH-CllCmLuo.js → stateDiagram-v2-MP3YSRHH-C6TftAzE.js} +1 -1
- package/dist-embed/chunks/{styles-455b33cd-CYP0pxwM.js → styles-455b33cd-CIILXOoF.js} +1 -1
- package/dist-embed/chunks/{styles-f932cba9-dXHjU5Mc.js → styles-f932cba9-CVBMDsh6.js} +1 -1
- package/dist-embed/chunks/{styles-fcc2142b-CrgFTq7b.js → styles-fcc2142b-CTOmFTKK.js} +1 -1
- package/dist-embed/chunks/{subset-shared.chunk-BCNcfBdp.js → subset-shared.chunk-zIH7OLsP.js} +1 -1
- package/dist-embed/chunks/{subset-worker.chunk-nY71AE9b.js → subset-worker.chunk-b9j7PKPe.js} +1 -1
- package/dist-embed/chunks/{sv-SE-XGPEYMSR-B3BAd7ic.js → sv-SE-XGPEYMSR-D0UV0HV7.js} +1 -1
- package/dist-embed/chunks/{svgDrawCommon-148a3cd9-DY-6e2w2.js → svgDrawCommon-148a3cd9-BCgvh5nL.js} +1 -1
- package/dist-embed/chunks/{swimlanes-42K2YHIH-CpFqKR23.js → swimlanes-42K2YHIH-BQTDK2Ta.js} +1 -1
- package/dist-embed/chunks/{swimlanes-42K2YHIH-BoshoQYI.js → swimlanes-42K2YHIH-DHcV40DB.js} +1 -1
- package/dist-embed/chunks/{swimlanesDiagram-VR7AAH4N-BNalU-se.js → swimlanesDiagram-VR7AAH4N-BV8Vb5g2.js} +1 -1
- package/dist-embed/chunks/{swimlanesDiagram-VR7AAH4N-CUEoZUeR.js → swimlanesDiagram-VR7AAH4N-CQ7d-sbG.js} +1 -1
- package/dist-embed/chunks/{ta-IN-2NMHFXQM-Ch7Coorh.js → ta-IN-2NMHFXQM-C-EJ3jDE.js} +1 -1
- package/dist-embed/chunks/{th-TH-HPSO5L25-gmc7tguq.js → th-TH-HPSO5L25-CfQh62Qa.js} +1 -1
- package/dist-embed/chunks/{timeline-definition-24CTP7MA-BD_Hd7OM.js → timeline-definition-24CTP7MA-CKtubk73.js} +1 -1
- package/dist-embed/chunks/{timeline-definition-24CTP7MA-CLQC5Soj.js → timeline-definition-24CTP7MA-DJcFE1jT.js} +1 -1
- package/dist-embed/chunks/{timeline-definition-7545f45a-CBNPBc2S.js → timeline-definition-7545f45a-CLycxRtq.js} +1 -1
- package/dist-embed/chunks/{tr-TR-DEFEU3FU-DoKmjhCn.js → tr-TR-DEFEU3FU-Lz7Ka2Zr.js} +1 -1
- package/dist-embed/chunks/{uk-UA-QMV73CPH-uzMCDuv6.js → uk-UA-QMV73CPH-DU0hsGUJ.js} +1 -1
- package/dist-embed/chunks/{vennDiagram-4TSXK5OY-Clhmiu8L.js → vennDiagram-4TSXK5OY-BMmQ-DIV.js} +1 -1
- package/dist-embed/chunks/{vennDiagram-4TSXK5OY-BxbIHKUM.js → vennDiagram-4TSXK5OY-Bq0xMhnH.js} +1 -1
- package/dist-embed/chunks/{vi-VN-M7AON7JQ-UC9RyOt8.js → vi-VN-M7AON7JQ-CDvS0SiL.js} +1 -1
- package/dist-embed/chunks/{wardleyDiagram-VM6X3IG4-HuiHAtr-.js → wardleyDiagram-VM6X3IG4-C1VKw6YX.js} +1 -1
- package/dist-embed/chunks/{wardleyDiagram-VM6X3IG4-un-PuqHe.js → wardleyDiagram-VM6X3IG4-DL5LgQWr.js} +1 -1
- package/dist-embed/chunks/{xychartDiagram-3f383b91-3k3NdPbU.js → xychartDiagram-3f383b91-B-BTwetN.js} +1 -1
- package/dist-embed/chunks/{xychartDiagram-S5SC5T6Z-CIDOTVoZ.js → xychartDiagram-S5SC5T6Z-BQHFHk-x.js} +1 -1
- package/dist-embed/chunks/{xychartDiagram-S5SC5T6Z-CvZAV0KM.js → xychartDiagram-S5SC5T6Z-BXkM4beH.js} +1 -1
- package/dist-embed/chunks/{zh-CN-LNUGB5OW-DFA0PCzk.js → zh-CN-LNUGB5OW-CWE-bF0d.js} +1 -1
- package/dist-embed/chunks/{zh-HK-E62DVLB3-WzEwoBkd.js → zh-HK-E62DVLB3-pEfL2bds.js} +1 -1
- package/dist-embed/chunks/{zh-TW-RAJ6MFWO-B7w1h39x.js → zh-TW-RAJ6MFWO-Cp6UFUuD.js} +1 -1
- package/dist-embed/datalayer-app-main.js +107 -106
- package/lib/apps/apps/records.d.ts +21 -4
- package/lib/apps/apps/records.js +8 -6
- package/lib/apps/apps/threads.d.ts +11 -1
- package/lib/apps/apps/threads.js +17 -0
- package/lib/apps/core/index.d.ts +71 -0
- package/lib/apps/core/index.js +22 -0
- package/lib/apps/plugins/app-activity/AppActivity.js +10 -4
- package/lib/apps/plugins/chat/ChatView.js +123 -6
- package/lib/apps/plugins/chat/SessionActionsMenu.d.ts +40 -0
- package/lib/apps/plugins/chat/SessionActionsMenu.js +73 -0
- package/lib/apps/plugins/chat/SessionChooseDialog.d.ts +22 -0
- package/lib/apps/plugins/chat/SessionChooseDialog.js +39 -0
- package/lib/apps/plugins/chat/index.js +8 -1
- package/lib/apps/plugins/chat/sessionActions.d.ts +65 -0
- package/lib/apps/plugins/chat/sessionActions.js +184 -0
- package/lib/chat/Chat.d.ts +42 -2
- package/lib/chat/Chat.js +148 -2
- package/lib/chat/base/ChatBase.js +33 -6
- package/lib/chat/index.d.ts +1 -1
- package/lib/chat/messages/ChatMessageList.d.ts +3 -1
- package/lib/chat/messages/ChatMessageList.js +21 -2
- package/lib/portable/activity.d.ts +91 -2
- package/lib/portable/activity.js +143 -4
- package/lib/portable/fixtures.d.ts +1 -1
- package/lib/portable/fixtures.js +17 -7
- package/lib/portable/index.d.ts +1 -1
- package/lib/portable/index.js +3 -2
- package/lib/portable/sessions.d.ts +25 -1
- package/lib/portable/sessions.js +62 -4
- package/lib/specs/harnesses.js +96 -0
- package/lib/specs/index.d.ts +1 -0
- package/lib/specs/index.js +1 -0
- package/lib/specs/sessionFiles.d.ts +123 -0
- package/lib/specs/sessionFiles.js +578 -0
- package/lib/types/agentspecs.d.ts +26 -0
- package/lib/types/chat.d.ts +38 -0
- package/package.json +1 -1
- package/scripts/codegen/generate_agents.py +1 -0
- package/scripts/codegen/generate_harnesses.py +70 -0
- package/scripts/codegen/generate_session_files.py +296 -0
- package/dist-embed/chunks/ChatView-B_EEvtKi.js +0 -32
- package/dist-embed/chunks/SchemaForm-Dg9uk6m3.js +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { FormControl, Select, Text } from '@primer/react';
|
|
4
|
+
import { Dialog } from '@primer/react/experimental';
|
|
5
|
+
import { Box } from '@datalayer/primer-addons';
|
|
6
|
+
export const CHOOSE_WORDS = {
|
|
7
|
+
confirm: 'Switch',
|
|
8
|
+
cancel: 'Keep it',
|
|
9
|
+
};
|
|
10
|
+
export function SessionChooseDialog({ question, onPick, }) {
|
|
11
|
+
const [picked, setPicked] = useState(question.options[0]?.id ?? '');
|
|
12
|
+
const [says, setSays] = useState('');
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
let current = true;
|
|
15
|
+
if (!question.says || !picked) {
|
|
16
|
+
setSays('');
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
question.says(picked).then(sentence => current && setSays(sentence), () => current && setSays(''));
|
|
20
|
+
return () => {
|
|
21
|
+
current = false;
|
|
22
|
+
};
|
|
23
|
+
}, [picked, question]);
|
|
24
|
+
const chosen = question.options.find(option => option.id === picked);
|
|
25
|
+
return (_jsx(Dialog, { title: question.title, onClose: () => onPick(undefined), width: "medium", footerButtons: [
|
|
26
|
+
{
|
|
27
|
+
buttonType: 'default',
|
|
28
|
+
content: CHOOSE_WORDS.cancel,
|
|
29
|
+
onClick: () => onPick(undefined),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
buttonType: 'primary',
|
|
33
|
+
content: CHOOSE_WORDS.confirm,
|
|
34
|
+
disabled: !picked,
|
|
35
|
+
onClick: () => onPick(picked || undefined),
|
|
36
|
+
},
|
|
37
|
+
], children: _jsxs(Box, { display: "grid", gap: 3, "data-session-choose": "", children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: question.title }), _jsx(Select, { value: picked, onChange: event => setPicked(event.target.value), block: true, children: question.options.map(option => (_jsx(Select.Option, { value: option.id, children: option.label }, option.id))) })] }), chosen?.description ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: chosen.description })) : null, says ? (_jsx(Text, { as: "p", sx: { m: 0, fontSize: 1, fontStyle: 'italic' }, "data-session-choose-says": "", children: says })) : null] }) }));
|
|
38
|
+
}
|
|
39
|
+
export default SessionChooseDialog;
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { CommentDiscussionIcon, FoldIcon, SparkleFillIcon, SyncIcon, } from '@primer/octicons-react';
|
|
11
11
|
import { contribution, definePlugin } from '@datalayer/reactor';
|
|
12
|
-
import { LoopAgentGate, LoopChatComposer, LoopChatExtras, LoopChatHeader, LoopChatSuggestion, LoopChatTurn, LoopCommand, LoopFrontendTool, LoopDocumentToolbarItem, LoopNotebookToolbarItem, LoopViewType, } from '../../core';
|
|
12
|
+
import { LoopAgentGate, LoopChatComposer, LoopChatExtras, LoopChatHeader, LoopChatSuggestion, LoopChatTurn, LoopCommand, LoopFrontendTool, LoopDocumentToolbarItem, LoopNotebookToolbarItem, LoopSessionAction, LoopViewType, } from '../../core';
|
|
13
13
|
import { createTurnFeed, feedWriters } from './turnState';
|
|
14
|
+
import { CHAT_SESSION_ACTIONS } from './sessionActions';
|
|
14
15
|
/**
|
|
15
16
|
* An editor toolbar button that asks an agent to do something.
|
|
16
17
|
*
|
|
@@ -93,6 +94,12 @@ export const ChatPlugin = definePlugin({
|
|
|
93
94
|
return {};
|
|
94
95
|
},
|
|
95
96
|
contributes: [
|
|
97
|
+
// The thread's menu entries (MH-F08): each says with `when` whether it
|
|
98
|
+
// applies; the chat draws what the registry holds, a host adds its own.
|
|
99
|
+
...CHAT_SESSION_ACTIONS.map(entry => contribution(LoopSessionAction, entry, {
|
|
100
|
+
id: entry.id,
|
|
101
|
+
order: entry.order,
|
|
102
|
+
})),
|
|
96
103
|
contribution(LoopViewType, {
|
|
97
104
|
viewType: 'chat',
|
|
98
105
|
title: 'Chat',
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat's entries on a thread's menu (`loop.session.action`): *Switch
|
|
3
|
+
* agent…*, *Clone from here*, *Export*, *Import…*, *Resume* — each saying
|
|
4
|
+
* with `when` whether it applies to the session as it stands, each doing
|
|
5
|
+
* its work through the runtime's session API and the page's ways (a
|
|
6
|
+
* picker, a file, a download, opening a thread). *Clone from here* is also
|
|
7
|
+
* on each turn's row, where it names the turn. A host adds its own entries
|
|
8
|
+
* by contributing to the same point; nothing here is copied.
|
|
9
|
+
*
|
|
10
|
+
* Every refusal of the runtime is said as it is — a turn still running, a
|
|
11
|
+
* turn the session does not have, a file this runtime does not read, an
|
|
12
|
+
* agent it lacks — and nothing falls back to a default.
|
|
13
|
+
*
|
|
14
|
+
* @module apps/plugins/chat/sessionActions
|
|
15
|
+
*/
|
|
16
|
+
import type { SessionActionContext, SessionActionContribution, SessionFacts } from '../../core';
|
|
17
|
+
/** The file a session is exported as. */
|
|
18
|
+
export declare const sessionFileName: (session: Pick<SessionFacts, "uid">) => string;
|
|
19
|
+
/** What the entries say, in a person's words. */
|
|
20
|
+
export declare const SESSION_ACTION_WORDS: {
|
|
21
|
+
readonly switchAgent: "Switch agent…";
|
|
22
|
+
readonly switchTitle: (agent: string) => string;
|
|
23
|
+
readonly noPicker: "Switching the agent needs a picker this page has not: use `loop sessions swap`.";
|
|
24
|
+
readonly noAgents: "No other agent of the catalogue runs on a harness.";
|
|
25
|
+
readonly cloneFromHere: "Clone from here";
|
|
26
|
+
readonly cloned: (atTurn: number, uid: string) => string;
|
|
27
|
+
readonly export: "Export";
|
|
28
|
+
readonly exported: (turns: number, redactions: number, name: string) => string;
|
|
29
|
+
readonly import: "Import…";
|
|
30
|
+
readonly noFilePicker: "Importing a session needs a file picker this page has not: use `loop sessions import`.";
|
|
31
|
+
readonly imported: (uid: string, turns: number, redactions: number) => string;
|
|
32
|
+
readonly resume: "Resume";
|
|
33
|
+
readonly resumed: (uid: string) => string;
|
|
34
|
+
};
|
|
35
|
+
/** One agent a session may be switched to. */
|
|
36
|
+
export type AgentChoice = {
|
|
37
|
+
id: string;
|
|
38
|
+
label: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The agents a session may be switched to: the catalogue's harness agents
|
|
43
|
+
* — each harness offered by the catalogue agent that runs on it, as the
|
|
44
|
+
* Studio's toolbox offers them — the session's own agent left out. A swap
|
|
45
|
+
* may cross kinds (a model agent to a harness and back): what the person
|
|
46
|
+
* chooses among is what the catalogue has.
|
|
47
|
+
*/
|
|
48
|
+
export declare function agentChoices(session: Pick<SessionFacts, 'agent'>): AgentChoice[];
|
|
49
|
+
/**
|
|
50
|
+
* What the new agent is told, shown before the swap is sent: the sentence
|
|
51
|
+
* the runtime says on the swap, in its first two clauses; the runtime's own
|
|
52
|
+
* `said` — whose last clause follows what the old harness can load again —
|
|
53
|
+
* is shown once the swap is done.
|
|
54
|
+
*/
|
|
55
|
+
export declare function swapSentence(session: Pick<SessionFacts, 'agent' | 'harness' | 'turns'>, to: AgentChoice): string;
|
|
56
|
+
/** The redactions a session file's first line counts. */
|
|
57
|
+
export declare function redactionsOf(text: string): number;
|
|
58
|
+
export declare const SWITCH_AGENT: SessionActionContribution;
|
|
59
|
+
export declare const CLONE_FROM_HERE: SessionActionContribution;
|
|
60
|
+
export declare const EXPORT: SessionActionContribution;
|
|
61
|
+
export declare const IMPORT: SessionActionContribution;
|
|
62
|
+
export declare const RESUME: SessionActionContribution;
|
|
63
|
+
/** The chat's entries, in the order they are drawn. */
|
|
64
|
+
export declare const CHAT_SESSION_ACTIONS: readonly SessionActionContribution[];
|
|
65
|
+
export type { SessionActionContext };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { listAgentspecs } from '../../../specs/agents';
|
|
6
|
+
import { listHarnesses } from '../../../specs/harnesses';
|
|
7
|
+
/** The file a session is exported as. */
|
|
8
|
+
export const sessionFileName = (session) => `${session.uid}.session.jsonl`;
|
|
9
|
+
/** What the entries say, in a person's words. */
|
|
10
|
+
export const SESSION_ACTION_WORDS = {
|
|
11
|
+
switchAgent: 'Switch agent…',
|
|
12
|
+
switchTitle: (agent) => `Switch ${agent} to`,
|
|
13
|
+
noPicker: 'Switching the agent needs a picker this page has not: use `loop sessions swap`.',
|
|
14
|
+
noAgents: 'No other agent of the catalogue runs on a harness.',
|
|
15
|
+
cloneFromHere: 'Clone from here',
|
|
16
|
+
cloned: (atTurn, uid) => `Cloned from turn ${atTurn} as ${uid}: opened here, the source untouched.`,
|
|
17
|
+
export: 'Export',
|
|
18
|
+
exported: (turns, redactions, name) => `Exported ${turns} turn${turns === 1 ? '' : 's'}, ${redactions} redaction${redactions === 1 ? '' : 's'} → ${name}.`,
|
|
19
|
+
import: 'Import…',
|
|
20
|
+
noFilePicker: 'Importing a session needs a file picker this page has not: use `loop sessions import`.',
|
|
21
|
+
imported: (uid, turns, redactions) => `Imported as ${uid} (${turns} turn${turns === 1 ? '' : 's'}, ${redactions} redaction${redactions === 1 ? '' : 's'}): opened here.`,
|
|
22
|
+
resume: 'Resume',
|
|
23
|
+
resumed: (uid) => `Resumed ${uid}.`,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The agents a session may be switched to: the catalogue's harness agents
|
|
27
|
+
* — each harness offered by the catalogue agent that runs on it, as the
|
|
28
|
+
* Studio's toolbox offers them — the session's own agent left out. A swap
|
|
29
|
+
* may cross kinds (a model agent to a harness and back): what the person
|
|
30
|
+
* chooses among is what the catalogue has.
|
|
31
|
+
*/
|
|
32
|
+
export function agentChoices(session) {
|
|
33
|
+
const specs = listAgentspecs();
|
|
34
|
+
return listHarnesses()
|
|
35
|
+
.filter(harness => harness.id !== 'custom' && harness.enabled)
|
|
36
|
+
.flatMap(harness => {
|
|
37
|
+
const agent = specs.find(spec => spec.harness === harness.id);
|
|
38
|
+
if (!agent || agent.id === session.agent) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
id: agent.id,
|
|
44
|
+
label: `${agent.name} (${harness.name})`,
|
|
45
|
+
description: harness.description,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** A harness's name, or the agent's id when it runs on none. */
|
|
51
|
+
const spokenAs = (agent, harness) => {
|
|
52
|
+
const known = harness
|
|
53
|
+
? listHarnesses().find(h => h.id === harness)
|
|
54
|
+
: undefined;
|
|
55
|
+
return known?.name ?? (harness || agent);
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* What the new agent is told, shown before the swap is sent: the sentence
|
|
59
|
+
* the runtime says on the swap, in its first two clauses; the runtime's own
|
|
60
|
+
* `said` — whose last clause follows what the old harness can load again —
|
|
61
|
+
* is shown once the swap is done.
|
|
62
|
+
*/
|
|
63
|
+
export function swapSentence(session, to) {
|
|
64
|
+
const from = spokenAs(session.agent, session.harness);
|
|
65
|
+
const target = to.label.replace(/\s*\(.*\)$/, '');
|
|
66
|
+
return `This conversation was with ${from} until turn ${session.turns}; from here it is with ${target}. What was said stays.`;
|
|
67
|
+
}
|
|
68
|
+
/** An open session whose turn is idle: the only one whose agent is swapped. */
|
|
69
|
+
const idle = (session) => session.state === 'open' && session.turn === 'idle';
|
|
70
|
+
/** The redactions a session file's first line counts. */
|
|
71
|
+
export function redactionsOf(text) {
|
|
72
|
+
const head = text.split('\n')[0] ?? '';
|
|
73
|
+
try {
|
|
74
|
+
return Number(JSON.parse(head).redactions ?? 0) || 0;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export const SWITCH_AGENT = {
|
|
81
|
+
id: 'switch-agent',
|
|
82
|
+
label: SESSION_ACTION_WORDS.switchAgent,
|
|
83
|
+
order: 10,
|
|
84
|
+
when: idle,
|
|
85
|
+
run: async (session, context) => {
|
|
86
|
+
if (!context.choose) {
|
|
87
|
+
context.say(SESSION_ACTION_WORDS.noPicker);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const options = agentChoices(session);
|
|
91
|
+
if (options.length === 0) {
|
|
92
|
+
context.say(SESSION_ACTION_WORDS.noAgents);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const chosen = await context.choose({
|
|
96
|
+
title: SESSION_ACTION_WORDS.switchTitle(session.agent),
|
|
97
|
+
options,
|
|
98
|
+
says: async (id) => {
|
|
99
|
+
const choice = options.find(option => option.id === id);
|
|
100
|
+
return choice ? swapSentence(session, choice) : '';
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
if (!chosen) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const answer = await context.client.swap(session.uid, chosen);
|
|
107
|
+
context.say(String(answer.said ?? `Swapped to ${chosen}.`));
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
export const CLONE_FROM_HERE = {
|
|
111
|
+
id: 'clone-from-here',
|
|
112
|
+
label: SESSION_ACTION_WORDS.cloneFromHere,
|
|
113
|
+
order: 20,
|
|
114
|
+
placement: 'both',
|
|
115
|
+
when: session => session.turns > 0,
|
|
116
|
+
run: async (session, context) => {
|
|
117
|
+
const upToTurn = context.atTurn ?? session.turns;
|
|
118
|
+
const answer = await context.client.clone(session.uid, { upToTurn });
|
|
119
|
+
const uid = String(answer.uid ?? '');
|
|
120
|
+
if (!uid) {
|
|
121
|
+
throw new Error(`The runtime cloned session ${session.uid} and named no new session.`);
|
|
122
|
+
}
|
|
123
|
+
context.say(SESSION_ACTION_WORDS.cloned(upToTurn, uid));
|
|
124
|
+
context.openThread?.(uid);
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
export const EXPORT = {
|
|
128
|
+
id: 'export',
|
|
129
|
+
label: SESSION_ACTION_WORDS.export,
|
|
130
|
+
order: 30,
|
|
131
|
+
when: session => session.turns > 0,
|
|
132
|
+
run: async (session, context) => {
|
|
133
|
+
const text = await context.client.exportFile(session.uid);
|
|
134
|
+
const name = sessionFileName(session);
|
|
135
|
+
context.download?.(name, text, 'application/x-ndjson');
|
|
136
|
+
context.say(SESSION_ACTION_WORDS.exported(session.turns, redactionsOf(text), name));
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
export const IMPORT = {
|
|
140
|
+
id: 'import',
|
|
141
|
+
label: SESSION_ACTION_WORDS.import,
|
|
142
|
+
order: 35,
|
|
143
|
+
when: () => true,
|
|
144
|
+
run: async (_session, context) => {
|
|
145
|
+
if (!context.pickFile) {
|
|
146
|
+
context.say(SESSION_ACTION_WORDS.noFilePicker);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const text = await context.pickFile('.jsonl,application/x-ndjson');
|
|
150
|
+
if (!text) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const answer = await context.client.importFile(text);
|
|
154
|
+
const uid = String(answer.uid ?? '');
|
|
155
|
+
if (!uid) {
|
|
156
|
+
throw new Error('The runtime imported the file and named no session.');
|
|
157
|
+
}
|
|
158
|
+
context.say(SESSION_ACTION_WORDS.imported(uid, Number(answer.turns ?? 0) || 0, Number(answer.redactions ?? 0) || 0));
|
|
159
|
+
context.openThread?.(uid);
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
export const RESUME = {
|
|
163
|
+
id: 'resume',
|
|
164
|
+
label: SESSION_ACTION_WORDS.resume,
|
|
165
|
+
order: 40,
|
|
166
|
+
divider: true,
|
|
167
|
+
when: session => session.state === 'paused',
|
|
168
|
+
run: async (session, context) => {
|
|
169
|
+
await context.client.resume(session.uid, session.agent, {
|
|
170
|
+
onEvent: () => undefined,
|
|
171
|
+
});
|
|
172
|
+
context.say(SESSION_ACTION_WORDS.resumed(session.uid));
|
|
173
|
+
// Drawn again from the runtime, which holds it now.
|
|
174
|
+
context.openThread?.(session.uid);
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
/** The chat's entries, in the order they are drawn. */
|
|
178
|
+
export const CHAT_SESSION_ACTIONS = [
|
|
179
|
+
SWITCH_AGENT,
|
|
180
|
+
CLONE_FROM_HERE,
|
|
181
|
+
EXPORT,
|
|
182
|
+
IMPORT,
|
|
183
|
+
RESUME,
|
|
184
|
+
];
|
package/lib/chat/Chat.d.ts
CHANGED
|
@@ -1,9 +1,49 @@
|
|
|
1
1
|
import type { OAuthProvider, OAuthProviderConfig, Identity } from '../identity';
|
|
2
|
-
import type { ChatCommonProps, Extension, Protocol, ProtocolConfig } from '../types';
|
|
2
|
+
import type { ChatBaseProps, ChatCommonProps, Extension, Protocol, ProtocolConfig, ResumedThread } from '../types';
|
|
3
|
+
import type { SessionActionContext } from '../apps/core';
|
|
4
|
+
/**
|
|
5
|
+
* What a host lends the thread's `⋯` menu (VSCODE VS-24): the ways an
|
|
6
|
+
* entry may use that only the page has — a file saved, a pick, a file
|
|
7
|
+
* picked — and what it is told. The menu itself is drawn from the
|
|
8
|
+
* `loop.session.action` registry of the Reactor registered on the page
|
|
9
|
+
* (`SessionActionsMenu`, the one the apps' chat view draws): nothing of it
|
|
10
|
+
* is copied here, and no Reactor registered means no menu.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChatSessionActions {
|
|
13
|
+
/** Hand the person a file to save, when the host can. */
|
|
14
|
+
download?: SessionActionContext['download'];
|
|
15
|
+
/** Ask the person to pick one of several, when the host can. */
|
|
16
|
+
choose?: SessionActionContext['choose'];
|
|
17
|
+
/** Ask the person for a file, when the host can. */
|
|
18
|
+
pickFile?: SessionActionContext['pickFile'];
|
|
19
|
+
/** Told what an entry said: a swap's sentence, a refusal as the runtime said it. */
|
|
20
|
+
onSaid?: (sentence: string) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Told the thread an entry opened (a clone's, an import's, a resumed
|
|
23
|
+
* one's) — which this chat opens in place too.
|
|
24
|
+
*/
|
|
25
|
+
onOpenThread?: (uid: string) => void;
|
|
26
|
+
}
|
|
3
27
|
/**
|
|
4
28
|
* Chat props — extends ChatCommonProps with transport-specific configuration.
|
|
5
29
|
*/
|
|
6
30
|
export interface ChatProps extends ChatCommonProps {
|
|
31
|
+
/**
|
|
32
|
+
* The conversation to go on with (D-13, VS-24): an application's session,
|
|
33
|
+
* read from its runtime by uid when `fromRuntime` is set (`GET
|
|
34
|
+
* …/apps/sessions/{uid}/messages`, else resumed from its record), and
|
|
35
|
+
* drawn in place of the runtime's history. The chat is remounted on
|
|
36
|
+
* another thread's id; a thread that cannot be opened is said, and a
|
|
37
|
+
* new one starts.
|
|
38
|
+
*/
|
|
39
|
+
thread?: ResumedThread;
|
|
40
|
+
/**
|
|
41
|
+
* The thread's `⋯` menu, drawn when a Reactor is registered on the page:
|
|
42
|
+
* what the host lends its entries. Absent, no menu is drawn.
|
|
43
|
+
*/
|
|
44
|
+
sessionActions?: ChatSessionActions;
|
|
45
|
+
/** Hands the chat's send, stop, new-chat and thread to the host (`ChatBase`'s). */
|
|
46
|
+
onSendReady?: ChatBaseProps['onSendReady'];
|
|
7
47
|
/**
|
|
8
48
|
* Transport to use — REQUIRED.
|
|
9
49
|
*
|
|
@@ -119,5 +159,5 @@ export interface ChatProps extends ChatCommonProps {
|
|
|
119
159
|
* />
|
|
120
160
|
* ```
|
|
121
161
|
*/
|
|
122
|
-
export declare function Chat({ protocol: transport, extensions: _extensions, baseUrl, endpoint: endpointProp, configEndpoint: configEndpointProp, enableConfigQuery: enableConfigQueryProp, wsUrl, agentId, authToken: authTokenProp, placeholder, title, subtitle, brandIcon, autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showNewChatButton, showClearButton, showModelSelector, showToolsMenu, showInput, disableInputPrompt, disabled, disableReason, overlay, launching, launchingMessage, showSkillsMenu, codemodeEnabled, onToggleCodemode, showTokenUsage, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, headerContent, headerActions, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation, chatViewMode, onChatViewModeChange, frontendTools, enableEphemeralNotebook, initialEphemeralNotebookOpen, onEphemeralNotebookOpenChange, enableEphemeralDocument, initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange, collapsed, onExpandFromCollapsed, ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration, ephemeralRuntimeOverride, onToolCallStart, onToolCallComplete, hideMessagesAfterToolUI, contextSnapshot, mcpStatusData, codemodeStatusData, sandboxStatusData, kernel, kernelIndicatorPlacement, kernelEnvironmentName, kernelCpu, kernelMemory, kernelGpu, themeVariant, colorMode, showToolApprovalBanner, pendingApprovals, onApproveApproval, onRejectApproval, disableInternalJupyterTheme, }: ChatProps): import("react").JSX.Element;
|
|
162
|
+
export declare function Chat({ protocol: transport, extensions: _extensions, baseUrl, endpoint: endpointProp, configEndpoint: configEndpointProp, enableConfigQuery: enableConfigQueryProp, wsUrl, agentId, authToken: authTokenProp, placeholder, title, subtitle, brandIcon, autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showNewChatButton, showClearButton, showModelSelector, showToolsMenu, showInput, disableInputPrompt, disabled, disableReason, overlay, launching, launchingMessage, showSkillsMenu, codemodeEnabled, onToggleCodemode, showTokenUsage, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, headerContent, headerActions, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation, chatViewMode, onChatViewModeChange, frontendTools, enableEphemeralNotebook, initialEphemeralNotebookOpen, onEphemeralNotebookOpenChange, enableEphemeralDocument, initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange, collapsed, onExpandFromCollapsed, ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration, ephemeralRuntimeOverride, onToolCallStart, onToolCallComplete, hideMessagesAfterToolUI, contextSnapshot, mcpStatusData, codemodeStatusData, sandboxStatusData, kernel, kernelIndicatorPlacement, kernelEnvironmentName, kernelCpu, kernelMemory, kernelGpu, themeVariant, colorMode, showToolApprovalBanner, pendingApprovals, onApproveApproval, onRejectApproval, disableInternalJupyterTheme, thread: givenThread, sessionActions, onSendReady, onToolCallUpdate, }: ChatProps): import("react").JSX.Element;
|
|
123
163
|
export default Chat;
|
package/lib/chat/Chat.js
CHANGED
|
@@ -24,8 +24,13 @@ import { Text, Button, Spinner, ThemeProvider } from '@primer/react';
|
|
|
24
24
|
import { AlertIcon, SyncIcon } from '@primer/octicons-react';
|
|
25
25
|
import { Box } from '@datalayer/primer-addons';
|
|
26
26
|
import { useConnectedIdentities } from '../identity';
|
|
27
|
+
import { useOptionalReactorPlatform } from '@datalayer/reactor/react';
|
|
27
28
|
import { ChatBase } from './base/ChatBase';
|
|
28
29
|
import { AgentDetails } from '../agents/AgentDetails';
|
|
30
|
+
import { SessionActionsMenu } from '../apps/plugins/chat/SessionActionsMenu';
|
|
31
|
+
import { appSessionsClient } from '../portable/sessions';
|
|
32
|
+
import { openThread, THREAD_WORDS } from '../portable/thread';
|
|
33
|
+
import { generateMessageId } from '../types/messages';
|
|
29
34
|
// Try to get Jupyter settings if available
|
|
30
35
|
let getJupyterSettings;
|
|
31
36
|
try {
|
|
@@ -140,7 +145,7 @@ function getProtocolType(protocol) {
|
|
|
140
145
|
* />
|
|
141
146
|
* ```
|
|
142
147
|
*/
|
|
143
|
-
export function Chat({ protocol: transport, extensions: _extensions, baseUrl = 'http://localhost:8765', endpoint: endpointProp, configEndpoint: configEndpointProp, enableConfigQuery: enableConfigQueryProp, wsUrl, agentId, authToken: authTokenProp, placeholder = 'Type your message...', title, subtitle, brandIcon, autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showNewChatButton = true, showClearButton = true, showModelSelector = true, showToolsMenu = true, showInput = true, disableInputPrompt = false, disabled, disableReason, overlay, launching = false, launchingMessage, showSkillsMenu = true, codemodeEnabled = false, onToggleCodemode, showTokenUsage = true, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, headerContent, headerActions, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation = true, chatViewMode, onChatViewModeChange, frontendTools, enableEphemeralNotebook, initialEphemeralNotebookOpen, onEphemeralNotebookOpenChange, enableEphemeralDocument, initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange, collapsed = false, onExpandFromCollapsed, ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration, ephemeralRuntimeOverride, onToolCallStart, onToolCallComplete, hideMessagesAfterToolUI = false, contextSnapshot, mcpStatusData, codemodeStatusData, sandboxStatusData, kernel, kernelIndicatorPlacement, kernelEnvironmentName, kernelCpu, kernelMemory, kernelGpu, themeVariant, colorMode, showToolApprovalBanner, pendingApprovals, onApproveApproval, onRejectApproval, disableInternalJupyterTheme = false, }) {
|
|
148
|
+
export function Chat({ protocol: transport, extensions: _extensions, baseUrl = 'http://localhost:8765', endpoint: endpointProp, configEndpoint: configEndpointProp, enableConfigQuery: enableConfigQueryProp, wsUrl, agentId, authToken: authTokenProp, placeholder = 'Type your message...', title, subtitle, brandIcon, autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showNewChatButton = true, showClearButton = true, showModelSelector = true, showToolsMenu = true, showInput = true, disableInputPrompt = false, disabled, disableReason, overlay, launching = false, launchingMessage, showSkillsMenu = true, codemodeEnabled = false, onToggleCodemode, showTokenUsage = true, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, headerContent, headerActions, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation = true, chatViewMode, onChatViewModeChange, frontendTools, enableEphemeralNotebook, initialEphemeralNotebookOpen, onEphemeralNotebookOpenChange, enableEphemeralDocument, initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange, collapsed = false, onExpandFromCollapsed, ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration, ephemeralRuntimeOverride, onToolCallStart, onToolCallComplete, hideMessagesAfterToolUI = false, contextSnapshot, mcpStatusData, codemodeStatusData, sandboxStatusData, kernel, kernelIndicatorPlacement, kernelEnvironmentName, kernelCpu, kernelMemory, kernelGpu, themeVariant, colorMode, showToolApprovalBanner, pendingApprovals, onApproveApproval, onRejectApproval, disableInternalJupyterTheme = false, thread: givenThread, sessionActions, onSendReady, onToolCallUpdate, }) {
|
|
144
149
|
const resolvedAgentId = typeof agentId === 'string' && agentId.trim().length > 0
|
|
145
150
|
? agentId.trim()
|
|
146
151
|
: 'default';
|
|
@@ -312,6 +317,142 @@ export function Chat({ protocol: transport, extensions: _extensions, baseUrl = '
|
|
|
312
317
|
lastMessageCountRef.current = nextCount;
|
|
313
318
|
setMessageCount(nextCount);
|
|
314
319
|
}, []);
|
|
320
|
+
/*
|
|
321
|
+
* The thread (VS-24): the host's, or the one a menu entry opened in its
|
|
322
|
+
* place (a clone's, an import's). One read from its runtime is opened
|
|
323
|
+
* here first — held there, else resumed from its record — and drawn in
|
|
324
|
+
* place of the runtime's history; one that cannot be opened is said, and
|
|
325
|
+
* a new one starts.
|
|
326
|
+
*/
|
|
327
|
+
const [actionThread, setActionThread] = useState(undefined);
|
|
328
|
+
const wantedThread = actionThread ?? givenThread;
|
|
329
|
+
const [openedThread, setOpenedThread] = useState(null);
|
|
330
|
+
const opening = Boolean(wantedThread?.fromRuntime && openedThread?.given !== wantedThread.id);
|
|
331
|
+
useEffect(() => {
|
|
332
|
+
if (!wantedThread?.fromRuntime) {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
let current = true;
|
|
336
|
+
void (async () => {
|
|
337
|
+
let failure = '';
|
|
338
|
+
for (let attempt = 0; attempt < 4 && current; attempt += 1) {
|
|
339
|
+
try {
|
|
340
|
+
const messages = await openThread({
|
|
341
|
+
agentBaseUrl: baseUrl,
|
|
342
|
+
agentId: resolvedAgentId,
|
|
343
|
+
uid: wantedThread.id,
|
|
344
|
+
token: authTokenProp,
|
|
345
|
+
});
|
|
346
|
+
if (current) {
|
|
347
|
+
setOpenedThread({
|
|
348
|
+
given: wantedThread.id,
|
|
349
|
+
thread: { ...wantedThread, fromRuntime: false, messages },
|
|
350
|
+
said: '',
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
failure = error instanceof Error ? error.message : String(error);
|
|
357
|
+
// The runtime may still be making the application's agent.
|
|
358
|
+
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (current) {
|
|
362
|
+
setOpenedThread({
|
|
363
|
+
given: wantedThread.id,
|
|
364
|
+
thread: {
|
|
365
|
+
id: generateMessageId(),
|
|
366
|
+
messages: [],
|
|
367
|
+
onStarted: wantedThread.onStarted,
|
|
368
|
+
},
|
|
369
|
+
said: THREAD_WORDS.notOpened(failure),
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
})();
|
|
373
|
+
return () => {
|
|
374
|
+
current = false;
|
|
375
|
+
};
|
|
376
|
+
// By the thread's id: its object is the host's.
|
|
377
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
378
|
+
}, [
|
|
379
|
+
wantedThread?.id,
|
|
380
|
+
wantedThread?.fromRuntime,
|
|
381
|
+
baseUrl,
|
|
382
|
+
resolvedAgentId,
|
|
383
|
+
authTokenProp,
|
|
384
|
+
]);
|
|
385
|
+
const chatThread = wantedThread?.fromRuntime
|
|
386
|
+
? openedThread?.given === wantedThread.id
|
|
387
|
+
? openedThread.thread
|
|
388
|
+
: undefined
|
|
389
|
+
: wantedThread;
|
|
390
|
+
const threadSaid = wantedThread?.fromRuntime && openedThread?.given === wantedThread.id
|
|
391
|
+
? openedThread.said
|
|
392
|
+
: '';
|
|
393
|
+
/*
|
|
394
|
+
* The thread's menu (VS-24): the `loop.session.action` entries of the
|
|
395
|
+
* Reactor registered on the page, for the session the thread is — the
|
|
396
|
+
* uid the next message goes to, as the chat says it (`onSendReady`'s
|
|
397
|
+
* `thread`), kept here so the menu follows the header's +.
|
|
398
|
+
*/
|
|
399
|
+
const reactor = useOptionalReactorPlatform();
|
|
400
|
+
const [threadId, setThreadId] = useState(chatThread?.id ?? '');
|
|
401
|
+
const hostSendReadyRef = useRef(onSendReady);
|
|
402
|
+
hostSendReadyRef.current = onSendReady;
|
|
403
|
+
const handleSendReady = useCallback(controls => {
|
|
404
|
+
if (controls) {
|
|
405
|
+
setThreadId(controls.thread());
|
|
406
|
+
}
|
|
407
|
+
hostSendReadyRef.current?.(controls);
|
|
408
|
+
}, []);
|
|
409
|
+
const threadForBase = useMemo(() => chatThread
|
|
410
|
+
? {
|
|
411
|
+
...chatThread,
|
|
412
|
+
onStarted: started => {
|
|
413
|
+
setThreadId(started);
|
|
414
|
+
chatThread.onStarted?.(started);
|
|
415
|
+
},
|
|
416
|
+
}
|
|
417
|
+
: undefined, [chatThread]);
|
|
418
|
+
const [actionSaid, setActionSaid] = useState('');
|
|
419
|
+
const sessionsClient = useMemo(() => appSessionsClient({
|
|
420
|
+
baseUrl,
|
|
421
|
+
getAccessToken: () => authTokenProp,
|
|
422
|
+
fetch: (input, init) => fetch(input, init),
|
|
423
|
+
}), [baseUrl, authTokenProp]);
|
|
424
|
+
const sessionActionsRef = useRef(sessionActions);
|
|
425
|
+
sessionActionsRef.current = sessionActions;
|
|
426
|
+
const sessionContext = useMemo(() => ({
|
|
427
|
+
client: sessionsClient,
|
|
428
|
+
say: sentence => {
|
|
429
|
+
setActionSaid(sentence);
|
|
430
|
+
sessionActionsRef.current?.onSaid?.(sentence);
|
|
431
|
+
},
|
|
432
|
+
openThread: uid => {
|
|
433
|
+
setActionThread({ id: uid, messages: [], fromRuntime: true });
|
|
434
|
+
sessionActionsRef.current?.onOpenThread?.(uid);
|
|
435
|
+
},
|
|
436
|
+
...(sessionActionsRef.current?.download
|
|
437
|
+
? { download: sessionActionsRef.current.download }
|
|
438
|
+
: {}),
|
|
439
|
+
...(sessionActionsRef.current?.choose
|
|
440
|
+
? { choose: sessionActionsRef.current.choose }
|
|
441
|
+
: {}),
|
|
442
|
+
...(sessionActionsRef.current?.pickFile
|
|
443
|
+
? { pickFile: sessionActionsRef.current.pickFile }
|
|
444
|
+
: {}),
|
|
445
|
+
}), [sessionsClient]);
|
|
446
|
+
const describeSession = useCallback((uid) => sessionsClient.described(uid), [sessionsClient]);
|
|
447
|
+
const menuDrawn = Boolean(sessionActions && reactor);
|
|
448
|
+
const mergedHeaderActions = useMemo(() => menuDrawn ? (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 2, children: [headerActions, _jsx(SessionActionsMenu, { uid: threadId || chatThread?.id || undefined, describe: describeSession, context: sessionContext })] })) : (headerActions), [
|
|
449
|
+
menuDrawn,
|
|
450
|
+
headerActions,
|
|
451
|
+
threadId,
|
|
452
|
+
chatThread?.id,
|
|
453
|
+
describeSession,
|
|
454
|
+
sessionContext,
|
|
455
|
+
]);
|
|
315
456
|
const headerButtons = useMemo(() => ({
|
|
316
457
|
showNewChat: showNewChatButton,
|
|
317
458
|
showClear: showClearButton,
|
|
@@ -338,6 +479,11 @@ export function Chat({ protocol: transport, extensions: _extensions, baseUrl = '
|
|
|
338
479
|
? 'attention.fg'
|
|
339
480
|
: 'danger.fg',
|
|
340
481
|
flex: 1,
|
|
341
|
-
}, children: errorBanner.message })] })),
|
|
482
|
+
}, children: errorBanner.message })] })), threadSaid || actionSaid ? (
|
|
483
|
+
// What opening the thread, or a menu entry, said: a refusal
|
|
484
|
+
// as the runtime said it, a swap's sentence — until dismissed.
|
|
485
|
+
_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 3, py: 2, bg: "attention.subtle", borderBottom: "1px solid", borderColor: "attention.muted", "data-testid": "chat-thread-said", children: [_jsx(Text, { sx: { fontSize: 1, color: 'attention.fg', flex: 1 }, children: actionSaid || threadSaid }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => setActionSaid(''), children: "Dismiss" })] })) : null, opening ? (_jsx(Text, { as: "p", role: "status", sx: { m: 0, p: 3, fontSize: 1, color: 'fg.muted' }, children: THREAD_WORDS.opening })) : (_jsx(ChatBase
|
|
486
|
+
// Another thread is another conversation: remounted on its id.
|
|
487
|
+
, { thread: threadForBase, onSendReady: handleSendReady, onToolCallUpdate: onToolCallUpdate, title: title, subtitle: subtitle, brandIcon: brandIcon, showHeader: showHeader, protocol: protocolConfig, placeholder: placeholder, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, autoFocus: autoFocus, runtimeId: runtimeId, historyEndpoint: historyEndpoint, pendingPrompt: pendingPrompt, showInformation: showInformation, onInformationClick: handleInformationClick, headerContent: headerContent, headerActions: mergedHeaderActions, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showInput: showInput, disableInputPrompt: disableInputPrompt, disabled: disabled, disableReason: disableReason, overlay: overlay, launching: launching, launchingMessage: launchingMessage, autoConnect: autoConnect, showSkillsMenu: showSkillsMenu, showTokenUsage: showTokenUsage, codemodeEnabled: codemodeEnabled, onToggleCodemode: onToggleCodemode, initialModel: initialModel, availableModels: availableModels, mcpServers: mcpServers, initialSkills: initialSkills, connectedIdentities: identitiesForChat, onNewChat: handleNewChat, onMessagesChange: handleMessagesChange, headerButtons: headerButtons, avatarConfig: avatarConfig, backgroundColor: "canvas.default", focusTrigger: focusTrigger, chatViewMode: chatViewMode, onChatViewModeChange: onChatViewModeChange, frontendTools: frontendTools, enableEphemeralNotebook: enableEphemeralNotebook, initialEphemeralNotebookOpen: initialEphemeralNotebookOpen, onEphemeralNotebookOpenChange: onEphemeralNotebookOpenChange, enableEphemeralDocument: enableEphemeralDocument, initialEphemeralSurfaceMode: initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange: onEphemeralSurfaceModeChange, collapsed: collapsed, onExpandFromCollapsed: onExpandFromCollapsed, ephemeralNotebookToolbar: ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems: ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems: ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider: ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId: ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration: ephemeralDocumentCollaboration, ephemeralRuntimeOverride: ephemeralRuntimeOverride, onToolCallStart: onToolCallStart, onToolCallComplete: onToolCallComplete, hideMessagesAfterToolUI: hideMessagesAfterToolUI, contextSnapshot: contextSnapshot, mcpStatusData: mcpStatusData, sandboxStatusData: sandboxStatusData, kernel: kernel, kernelIndicatorPlacement: kernelIndicatorPlacement, kernelEnvironmentName: kernelEnvironmentName, kernelCpu: kernelCpu, kernelMemory: kernelMemory, kernelGpu: kernelGpu, themeVariant: themeVariant, colorMode: colorMode, showToolApprovalBanner: showToolApprovalBanner, pendingApprovals: pendingApprovals, onApproveApproval: onApproveApproval, onRejectApproval: onRejectApproval, disableInternalJupyterTheme: disableInternalJupyterTheme }, chatThread?.id ?? 'own'))] })] }) }) }));
|
|
342
488
|
}
|
|
343
489
|
export default Chat;
|
|
@@ -37,7 +37,7 @@ import { extractChatMessagesFromFullContext } from './fullContextMessages';
|
|
|
37
37
|
import { generateMessageId, createUserMessage } from '../../types/messages';
|
|
38
38
|
import { AI_MODEL_CATALOGUE, DEFAULT_MODEL, isChatModel, } from '../../specs/models';
|
|
39
39
|
import { internalQueryClient, isToolCallMessage, getMessageText, createProtocolAdapter, getApiBaseFromConfig, sanitizeAssistantContent, } from '../../utils';
|
|
40
|
-
import { BROWSER_LIMITS, emptyConversation, reduceConversation, withError, withoutItems, withPrompt, withTurnEnded, } from '../../portable/conversation';
|
|
40
|
+
import { BROWSER_LIMITS, emptyConversation, HARNESS_TOOL_CALL, reduceConversation, withError, withoutItems, withPrompt, withTurnEnded, } from '../../portable/conversation';
|
|
41
41
|
import { conversationEventsOf, snapshotOfMessages, } from '../../portable/adapterEvents';
|
|
42
42
|
import { conversationDrawer, emptyChatLayer, rowIdOf, toolCallOf, } from './conversationItems';
|
|
43
43
|
import { useConfig, useSkills, useSkillActions, useContextSnapshot, useSandbox, } from '../../hooks';
|
|
@@ -426,9 +426,9 @@ function ChatBaseInner({ title, subtitle, showHeader = false, showTokenUsage = t
|
|
|
426
426
|
// Mode selection
|
|
427
427
|
useStore: useStoreMode = true, protocol: protocolRaw, onSendMessage, onSendReady, onLoadingChange, onSpeakingChange, onContextSnapshot, enableStreaming = false,
|
|
428
428
|
// Extended props
|
|
429
|
-
brandIcon, avatarConfig, headerButtons, showPoweredBy = false, poweredByProps, emptyState, renderHeader, showTurnFooter = true, notebookToolSurfacesId, footerContent, welcome, trailingContent, voice, voiceSpeaking = false, voiceSentence, onStopSpeaking, voiceLevel, onReadAloud, showInformation = false, onInformationClick, headerContent, children, borderRadius, backgroundColor, border, boxShadow, compact = false, placeholder, description = 'Start a conversation with the AI agent.', onStateUpdate, onNewChat, onClear, onMessagesChange, onItemsChange, onDisplayItemsChange, autoFocus = false, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, focusTrigger, frontendTools: frontendToolsProp, enableEphemeralNotebook = false, initialEphemeralNotebookOpen = true, onEphemeralNotebookOpenChange, enableEphemeralDocument = false, initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange, collapsed = false, onExpandFromCollapsed, ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration, ephemeralRuntimeOverride,
|
|
429
|
+
brandIcon, avatarConfig, headerButtons, showPoweredBy = false, poweredByProps, emptyState, renderHeader, showTurnFooter = true, renderMessageFooter, notebookToolSurfacesId, footerContent, welcome, trailingContent, voice, voiceSpeaking = false, voiceSentence, onStopSpeaking, voiceLevel, onReadAloud, showInformation = false, onInformationClick, headerContent, children, borderRadius, backgroundColor, border, boxShadow, compact = false, placeholder, description = 'Start a conversation with the AI agent.', onStateUpdate, onNewChat, onClear, onMessagesChange, onItemsChange, onDisplayItemsChange, autoFocus = false, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, focusTrigger, frontendTools: frontendToolsProp, enableEphemeralNotebook = false, initialEphemeralNotebookOpen = true, onEphemeralNotebookOpenChange, enableEphemeralDocument = false, initialEphemeralSurfaceMode, onEphemeralSurfaceModeChange, collapsed = false, onExpandFromCollapsed, ephemeralNotebookToolbar, ephemeralNotebookToolbarExtraItems, ephemeralDocumentToolbarExtraItems, ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId, ephemeralDocumentCollaboration, ephemeralRuntimeOverride,
|
|
430
430
|
// Tool invocation hooks
|
|
431
|
-
onToolCallStart, onToolCallComplete, inspector: inspectorGiven,
|
|
431
|
+
onToolCallStart, onToolCallComplete, onToolCallUpdate, inspector: inspectorGiven,
|
|
432
432
|
// Identity/Authorization props
|
|
433
433
|
onAuthorizationRequired: _onAuthorizationRequired, connectedIdentities,
|
|
434
434
|
// Conversation persistence
|
|
@@ -1803,6 +1803,8 @@ showToolApprovalBanner = true, pendingApprovals: pendingApprovalsProp, onApprove
|
|
|
1803
1803
|
onToolCallStartRef.current = onToolCallStart;
|
|
1804
1804
|
const onToolCallCompleteRef = useRef(onToolCallComplete);
|
|
1805
1805
|
onToolCallCompleteRef.current = onToolCallComplete;
|
|
1806
|
+
const onToolCallUpdateRef = useRef(onToolCallUpdate);
|
|
1807
|
+
onToolCallUpdateRef.current = onToolCallUpdate;
|
|
1806
1808
|
// The Agent Inspector: the turns and tool calls, as spans, as they happen.
|
|
1807
1809
|
const inspectorFromContext = useAgentInspectorTracer();
|
|
1808
1810
|
const inspectorTracer = inspectorGiven ?? inspectorFromContext;
|
|
@@ -2810,6 +2812,24 @@ showToolApprovalBanner = true, pendingApprovals: pendingApprovalsProp, onApprove
|
|
|
2810
2812
|
voiceSayRef.current?.(event.activity);
|
|
2811
2813
|
}
|
|
2812
2814
|
read();
|
|
2815
|
+
// A running row said again with its display (VS-24): the host
|
|
2816
|
+
// drawing it elsewhere follows it as it streams.
|
|
2817
|
+
if (event.activity?.type === HARNESS_TOOL_CALL &&
|
|
2818
|
+
onToolCallUpdateRef.current) {
|
|
2819
|
+
const data = event.activity.data;
|
|
2820
|
+
const toolCallId = data && typeof data === 'object' && 'id' in data
|
|
2821
|
+
? String(data.id ?? '')
|
|
2822
|
+
: '';
|
|
2823
|
+
const row = conversationRef.current.items.find(item => item.kind === 'tool' && item.id === toolCallId);
|
|
2824
|
+
if (row && row.kind === 'tool' && row.display) {
|
|
2825
|
+
onToolCallUpdateRef.current({
|
|
2826
|
+
toolName: row.name,
|
|
2827
|
+
toolCallId,
|
|
2828
|
+
args: row.input ?? {},
|
|
2829
|
+
display: row.display,
|
|
2830
|
+
});
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2813
2833
|
break;
|
|
2814
2834
|
case 'done':
|
|
2815
2835
|
/*
|
|
@@ -3808,10 +3828,17 @@ showToolApprovalBanner = true, pendingApprovals: pendingApprovalsProp, onApprove
|
|
|
3808
3828
|
.reverse()
|
|
3809
3829
|
.find((item) => !isToolCallMessage(item) && item.role === 'assistant')?.id
|
|
3810
3830
|
: undefined;
|
|
3811
|
-
const readAloudFooter = readAnswerAloud || interruptedIds.size
|
|
3812
|
-
? (message) => {
|
|
3831
|
+
const readAloudFooter = readAnswerAloud || interruptedIds.size || renderMessageFooter
|
|
3832
|
+
? (message, at) => {
|
|
3813
3833
|
const text = getMessageText(message);
|
|
3814
|
-
|
|
3834
|
+
// The host's row, asked once: nothing when it draws nothing.
|
|
3835
|
+
const hosts = renderMessageFooter?.(message, at) ?? null;
|
|
3836
|
+
const interrupted = interruptedIds.has(message.id);
|
|
3837
|
+
const reads = Boolean(readAnswerAloud && readsAloud(message, text, writingId));
|
|
3838
|
+
if (!hosts && !interrupted && !reads) {
|
|
3839
|
+
return null;
|
|
3840
|
+
}
|
|
3841
|
+
return (_jsxs(_Fragment, { children: [interrupted ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontStyle: 'italic' }, "data-interrupted": "", children: "interrupted" })) : null, reads && readAnswerAloud ? (_jsx(ReadAloud, { onRead: () => readAnswerAloud(text) })) : null, hosts] }));
|
|
3815
3842
|
}
|
|
3816
3843
|
: undefined;
|
|
3817
3844
|
const messagesContent = children ? (children) : (_jsxs(Box, { ref: saidConversationRef, display: "flex", flexDirection: "column", minHeight: 0,
|