@marimo-team/islands 0.25.3-dev27 → 0.25.3-dev270

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 (847) hide show
  1. package/dist/{ConnectedDataExplorerComponent-DfG3PRaJ.js → ConnectedDataExplorerComponent-eLHPh6uu.js} +120 -116
  2. package/dist/{ErrorBoundary-DKAio_E4.js → ErrorBoundary-BDom11jj.js} +66 -71
  3. package/dist/_baseSet-BfI5FjBM.js +328 -0
  4. package/dist/{abnfDiagram-VCTEODGH-B3w-XWX8.js → abnfDiagram-VCTEODGH-hqd0IBtX.js} +2 -2
  5. package/dist/any-language-editor-DnG26QXh.js +75 -0
  6. package/dist/{architectureDiagram-5GKGNRK7-C18U9A6k.js → architectureDiagram-5GKGNRK7-BzLAFcc0.js} +1 -1
  7. package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
  8. package/dist/assertNever-DIU3JJbt.js +507 -0
  9. package/dist/assets/__vite-browser-external-BKBpimif.js +1 -0
  10. package/dist/assets/worker-CgoMtD-_.js +113 -0
  11. package/dist/{blockDiagram-I7D4REHJ-Cg25UrxT.js → blockDiagram-I7D4REHJ-Dkhe6_PP.js} +1 -1
  12. package/dist/{button-CvjkwdSk.js → button-0-RqY1DW.js} +229 -218
  13. package/dist/{capabilities-CQ5IjhzL.js → capabilities-B6yy_CBN.js} +2 -2
  14. package/dist/{chat-ui-DDJuqS87.js → chat-ui-BWIkve2R.js} +2071 -1780
  15. package/dist/{check-BMKBBrdc.js → check-gUSZbRsl.js} +1 -1
  16. package/dist/{chunk-IMKFNOWR-CrS5bzqW.js → chunk-IMKFNOWR-DOeVvuyE.js} +1 -1
  17. package/dist/{chunk-SHT3W25Y-StpvPvUG.js → chunk-SHT3W25Y-DZoFI8wR.js} +1 -1
  18. package/dist/{chunk-SVP7TREG-CBXjbYZC.js → chunk-SVP7TREG-CWu86PSW.js} +1 -1
  19. package/dist/{chunk-TICWLB2K-Dp6bIb-q.js → chunk-TICWLB2K-BrM0GoP3.js} +1 -1
  20. package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
  21. package/dist/{classDiagram-ZZMXUADV-BFYuxV5g.js → classDiagram-ZZMXUADV-DYi4V2bB.js} +2 -2
  22. package/dist/{classDiagram-v2-VYDZK3BY-D_tjXVMl.js → classDiagram-v2-VYDZK3BY-tN7FIk-m.js} +2 -2
  23. package/dist/{code-visibility-CFvLbCZJ.js → code-visibility-BWNUti7D.js} +43 -50
  24. package/dist/{common-1HUDUr7W.js → common-bFQY94fl.js} +10277 -9719
  25. package/dist/config-BsPruWMR.js +636 -0
  26. package/dist/{copy-icon-BgUO8jsi.js → copy-icon-C2I8sw4h.js} +3 -3
  27. package/dist/createReducer-DdtT_7ji.js +67 -0
  28. package/dist/{cynefinDiagram-5FMLGOSQ-DSgYrHB2.js → cynefinDiagram-5FMLGOSQ-D5nCnDc-.js} +1 -1
  29. package/dist/{dagre-GXQ25YYZ-GYlruCBf.js → dagre-GXQ25YYZ-BHkd7f_i.js} +3 -3
  30. package/dist/{dagre-BGSfXNEb.js → dagre-mqiMAsFY.js} +531 -680
  31. package/dist/{data-grid-overlay-editor-ZxoN8gVB.js → data-grid-overlay-editor-CVQ68_by.js} +5 -5
  32. package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
  33. package/dist/{debounce-C3jyATpc.js → debounce-DrhhziJv.js} +2 -2
  34. package/dist/{diagram-S7CK7UJ4-DRu5LX5_.js → diagram-S7CK7UJ4-D1ALppT2.js} +1 -1
  35. package/dist/{diagram-UQ7AKVKN-DD7uiejP.js → diagram-UQ7AKVKN-DLv0b83L.js} +1 -1
  36. package/dist/{diagram-VX7I27RA-ByH9KAJJ.js → diagram-VX7I27RA-7XJ7J6qg.js} +1 -1
  37. package/dist/{diagram-Z3DM3KII-BsQHPRke.js → diagram-Z3DM3KII-7M7zbHp_.js} +1 -1
  38. package/dist/{dialog-Cc479ZEH.js → dialog-DzCj1qQv.js} +26 -26
  39. package/dist/{dist-Bvs24R_E.js → dist-11T5wq3_.js} +31 -30
  40. package/dist/{dist-F8Ep36rk.js → dist-17ugwGZc.js} +59 -58
  41. package/dist/{dist-BMQf5zIS.js → dist-7cRjf--y.js} +123 -122
  42. package/dist/{dist-diIx5qJW.js → dist-B8pkfkzc.js} +31 -30
  43. package/dist/{dist-CN_BeG2I.js → dist-B9UoM_wq.js} +58 -57
  44. package/dist/{dist-CLdpGQVr.js → dist-BGuMTs1i.js} +118 -117
  45. package/dist/{dist-BK4Oj99o.js → dist-BHW11fni.js} +18 -17
  46. package/dist/dist-BLY4m1Wi.js +850 -0
  47. package/dist/{dist-PXYI_yuP.js → dist-BNlcVoxs.js} +24 -23
  48. package/dist/{dist-D6d86eNJ.js → dist-BQYe5Bju.js} +47 -46
  49. package/dist/{dist-CkTTIdBe.js → dist-BX1mn8na.js} +337 -337
  50. package/dist/{dist-DiDibOYr.js → dist-Bh0PTKUW.js} +151 -150
  51. package/dist/{dist-CSJ0MDRw.js → dist-CKaXK92p.js} +56 -55
  52. package/dist/{dist-C8fAKSH1.js → dist-CLhwfhpJ.js} +53 -52
  53. package/dist/{dist-DoE4XJBC.js → dist-CYeqK4Xw.js} +9801 -10649
  54. package/dist/{dist-BLfKmR-l.js → dist-Cxlp3WH6.js} +16 -15
  55. package/dist/{dist-D-wwqlzJ.js → dist-DSJPGj42.js} +158 -157
  56. package/dist/{dist-BorMD-uX.js → dist-DU9ICsWZ.js} +75 -74
  57. package/dist/{dist-DBtSl3sf.js → dist-DWv0ALBi.js} +47 -46
  58. package/dist/{dist-OR1OnN-y.js → dist-DiBpWEsB.js} +31 -30
  59. package/dist/{dist-CrSP_H1M.js → dist-DiLFTlnl.js} +242 -242
  60. package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
  61. package/dist/{dist-CN8zI-XC.js → dist-X9CsotJl.js} +239 -239
  62. package/dist/{dist-CSbh1PNP.js → dist-cVDV5IuI.js} +23 -22
  63. package/dist/{dist-BuaRHxOc.js → dist-fRfaOoq8.js} +44 -43
  64. package/dist/{dist-Cg7gzw-a.js → dist-gTTI-9Px.js} +78 -77
  65. package/dist/dropdown-menu-CdXE15an.js +6089 -0
  66. package/dist/{ebnfDiagram-PWID7BFC-CQRK5_eT.js → ebnfDiagram-PWID7BFC-DHH1qlmV.js} +2 -2
  67. package/dist/{erDiagram-RLTQ6QDP-BKtWrDVh.js → erDiagram-RLTQ6QDP-fI_0dGef.js} +1 -1
  68. package/dist/{error-banner-CFPHFw4h.js → error-banner-DPc9eIw5.js} +87 -86
  69. package/dist/error-entries-CxN-Nq3V.js +2573 -0
  70. package/dist/{esm-AMFssoNp.js → esm-BDqqT86j.js} +329 -329
  71. package/dist/{esm-D2gTsXEV.js → esm-BgKjMvWw.js} +530 -529
  72. package/dist/feedback-button-D9dvgMiT.js +374 -0
  73. package/dist/{flowDiagram-HODETNUW-1IN-ih2E.js → flowDiagram-HODETNUW-Brg9MA6i.js} +2 -2
  74. package/dist/{formats-Buu00Z2q.js → formats-DbSvAPY-.js} +6 -6
  75. package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
  76. package/dist/{glide-data-editor-BBgCAPbk.js → glide-data-editor-DRBPJNtK.js} +6676 -2890
  77. package/dist/{glide-utils-DM9zBO4W.js → glide-utils-BSw3SSHF.js} +84 -45
  78. package/dist/{globals-DhH_o2tF.js → globals-CDnhWJOj.js} +3 -3
  79. package/dist/{graphlib-BmY_CCV9.js → graphlib-nlwT3Wvy.js} +177 -220
  80. package/dist/hasIn-C20JsQ2m.js +28 -0
  81. package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
  82. package/dist/{error-entries-Cz3yNs7w.js → html-to-image-Bc2AvXHG.js} +26695 -26850
  83. package/dist/{infoDiagram-27XIBGKW-CkB-zr4p.js → infoDiagram-27XIBGKW-E9e403YT.js} +1 -1
  84. package/dist/isArrayLikeObject-B-HXCsex.js +626 -0
  85. package/dist/isEmpty-CdX7MTE1.js +14 -0
  86. package/dist/{ishikawaDiagram-5VMMS53U-wlyLjBmM.js → ishikawaDiagram-5VMMS53U-C-RlYDRo.js} +1 -1
  87. package/dist/{kanban-definition-UXKFOSKX-C2usY0i-.js → kanban-definition-UXKFOSKX-CLFl_uqK.js} +1 -1
  88. package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
  89. package/dist/{loader-BQOfjTIJ.js → loader-BVEtQ4F3.js} +12 -12
  90. package/dist/main.js +10420 -8311
  91. package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
  92. package/dist/{mermaid-BA-Z6wGL.js → mermaid-rd09e1JL.js} +54 -54
  93. package/dist/{mindmap-definition-YA3MSWOX-nKOWS8RR.js → mindmap-definition-YA3MSWOX-BQ8TWtyB.js} +1 -1
  94. package/dist/{now-jM8-M7IR.js → now-BKZCLE5P.js} +12 -13
  95. package/dist/{number-overlay-editor-CvLhxHLb.js → number-overlay-editor-CkcPsvT7.js} +3 -3
  96. package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
  97. package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
  98. package/dist/{pegDiagram-XKGWAZYB-Dac9EIKD.js → pegDiagram-XKGWAZYB-CN8UHFPi.js} +2 -2
  99. package/dist/pencil-DcT8AE0h.js +10 -0
  100. package/dist/pick-tCszMUbm.js +35 -0
  101. package/dist/{pieDiagram-E7YTZNPT-B7S-DsW_.js → pieDiagram-E7YTZNPT-DGuJ0EBd.js} +1 -1
  102. package/dist/precisionRound-DhAzeRcm.js +49 -0
  103. package/dist/{process-output-B-KBO95p.js → process-output-qecD7Dk8.js} +4 -4
  104. package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
  105. package/dist/{railroadDiagram-O6MQD6OU-Cfa5Q-hr.js → railroadDiagram-O6MQD6OU-BPDA8wy8.js} +2 -2
  106. package/dist/{react-vega-BED0DjiB.js → react-vega-C4T9Rb_w.js} +12284 -12270
  107. package/dist/{requirementDiagram-BXWQKSXE-d8zXCJIk.js → requirementDiagram-BXWQKSXE-ChzLGbGW.js} +1 -1
  108. package/dist/{reveal-component-C9BavSsS.js → reveal-component-DMHnoLjA.js} +1131 -1108
  109. package/dist/schemas-CdscWNy_.js +4747 -0
  110. package/dist/select-OxgozOC8.js +1200 -0
  111. package/dist/{sequenceDiagram-WJ2MYXX4-b6pei3lJ.js → sequenceDiagram-WJ2MYXX4-DFX-bE6O.js} +1 -1
  112. package/dist/{spec-BJzgmvVa.js → spec-oJn0RhpQ.js} +41 -11
  113. package/dist/{stateDiagram-D77RDMKH-Be-xSpaZ.js → stateDiagram-D77RDMKH-BR7cI3wK.js} +4 -4
  114. package/dist/{stateDiagram-v2-MP3YSRHH-5Y-FxesJ.js → stateDiagram-v2-MP3YSRHH-oGqB5UDI.js} +2 -2
  115. package/dist/static-state-CuV6Pc3a.js +72 -0
  116. package/dist/style.css +1 -1
  117. package/dist/{swimlanes-42K2YHIH-nRRl4NU0.js → swimlanes-42K2YHIH-DwSZl1yC.js} +1 -1
  118. package/dist/{swimlanesDiagram-VR7AAH4N-BS79510V.js → swimlanesDiagram-VR7AAH4N-BHlcd-Ri.js} +2 -2
  119. package/dist/{swiper-component-DKntyn8p.js → swiper-component-Dvj-goaD.js} +2 -2
  120. package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
  121. package/dist/{timeline-definition-24CTP7MA-Cfzf8WPf.js → timeline-definition-24CTP7MA-DMmP-G2O.js} +1 -1
  122. package/dist/toast-DbBHmxmB.js +491 -0
  123. package/dist/{tooltip-CtBZ5q8p.js → tooltip-BfcDQd2j.js} +329 -305
  124. package/dist/use-restore-focus-CmflVLWJ.js +1672 -0
  125. package/dist/{useAsyncData-BD534XmW.js → useAsyncData-BYIAoMqn.js} +15 -14
  126. package/dist/{useDateFormatter-DkajGwwd.js → useDateFormatter-ButWkdcK.js} +2 -2
  127. package/dist/{useDeepCompareMemoize-C72_RNsu.js → useDeepCompareMemoize-Bz0c5GN6.js} +1 -1
  128. package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-BIolGsF1.js} +1 -1
  129. package/dist/useLifecycle-JjxCC7Vu.js +112 -0
  130. package/dist/useTheme-DPLobSFs.js +339 -0
  131. package/dist/utils-EBklsC5R.js +813 -0
  132. package/dist/{vega-component-nB1kV6sb.js → vega-component-rxIxAAh9.js} +171 -170
  133. package/dist/{vega-embed-container-BNHE18G9.js → vega-embed-container--LYZqguO.js} +2 -2
  134. package/dist/{vega-loader.browser-DNST6uVf.js → vega-loader.browser-B9Pz0EGP.js} +298 -507
  135. package/dist/{vennDiagram-4TSXK5OY-CeY6Z1xZ.js → vennDiagram-4TSXK5OY-Db8GtH1G.js} +1 -1
  136. package/dist/{wardleyDiagram-VM6X3IG4-Cxs9NtVi.js → wardleyDiagram-VM6X3IG4-DmIiC3FU.js} +1 -1
  137. package/dist/{xychartDiagram-S5SC5T6Z-DNWbvPK7.js → xychartDiagram-S5SC5T6Z-DS9OPrNq.js} +2 -2
  138. package/package.json +17 -20
  139. package/src/__mocks__/document.tsx +63 -0
  140. package/src/__mocks__/executions.ts +195 -0
  141. package/src/__mocks__/notebook.ts +3 -5
  142. package/src/__mocks__/partial.ts +26 -0
  143. package/src/__mocks__/requests.ts +1 -4
  144. package/src/__tests__/CellStatus.test.tsx +19 -20
  145. package/src/__tests__/fixtures/pair-config.ts +1 -1
  146. package/src/__tests__/main.test.tsx +24 -1
  147. package/src/__tests__/module-entry.test.ts +44 -0
  148. package/src/__tests__/mount.test.ts +1 -21
  149. package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
  150. package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
  151. package/src/components/ai/ai-model-dropdown.tsx +11 -6
  152. package/src/components/app-config/__tests__/state.test.tsx +50 -0
  153. package/src/components/app-config/ai-config.tsx +156 -150
  154. package/src/components/app-config/app-config-button.tsx +6 -5
  155. package/src/components/app-config/app-config-form.tsx +5 -9
  156. package/src/components/app-config/common.tsx +7 -9
  157. package/src/components/app-config/data-form.tsx +112 -113
  158. package/src/components/app-config/mcp-config.tsx +30 -53
  159. package/src/components/app-config/user-config-form.css +91 -0
  160. package/src/components/app-config/user-config-form.tsx +266 -349
  161. package/src/components/chat/__tests__/capabilities-popover.test.tsx +0 -1
  162. package/src/components/chat/__tests__/chat-display.test.tsx +196 -0
  163. package/src/components/chat/__tests__/chat-markdown.test.tsx +43 -0
  164. package/src/components/chat/__tests__/chat-utils.test.ts +93 -1
  165. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  166. package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
  167. package/src/components/chat/__tests__/turn-timing.test.ts +84 -0
  168. package/src/components/chat/__tests__/use-assistant-turn.test.ts +95 -0
  169. package/src/components/chat/__tests__/user-message.test.tsx +27 -0
  170. package/src/components/chat/acp/__tests__/agent-panel-initialization.test.tsx +1 -1
  171. package/src/components/chat/acp/__tests__/agent-panel.test.tsx +22 -17
  172. package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
  173. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  174. package/src/components/chat/acp/agent-panel.tsx +6 -3
  175. package/src/components/chat/acp/blocks.tsx +13 -12
  176. package/src/components/chat/acp/common.tsx +4 -5
  177. package/src/components/chat/acp/model-selector.tsx +1 -1
  178. package/src/components/chat/acp/session-tabs.tsx +8 -3
  179. package/src/components/chat/agent-activity.tsx +132 -0
  180. package/src/components/chat/capabilities-popover.tsx +2 -11
  181. package/src/components/chat/chat-components.tsx +9 -4
  182. package/src/components/chat/chat-display.tsx +131 -57
  183. package/src/components/chat/chat-history-popover.tsx +6 -1
  184. package/src/components/chat/chat-markdown.tsx +15 -0
  185. package/src/components/chat/chat-panel.tsx +216 -294
  186. package/src/components/chat/chat-typography.css +108 -0
  187. package/src/components/chat/chat-utils.ts +24 -35
  188. package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
  189. package/src/components/chat/notebook-access-selector.tsx +100 -0
  190. package/src/components/chat/tool-call/__tests__/tool-labels.test.ts +76 -0
  191. package/src/components/chat/tool-call/__tests__/tool-step.test.tsx +57 -0
  192. package/src/components/chat/tool-call/shared.ts +6 -0
  193. package/src/components/chat/tool-call/tool-call-view.tsx +22 -76
  194. package/src/components/chat/tool-call/tool-labels.ts +172 -0
  195. package/src/components/chat/tool-call/tool-result.tsx +1 -1
  196. package/src/components/chat/tool-call/tool-step.tsx +145 -0
  197. package/src/components/chat/turn-timing.ts +73 -0
  198. package/src/components/chat/use-assistant-turn.ts +65 -0
  199. package/src/components/chat/use-chat-generation.ts +20 -0
  200. package/src/components/chat/user-message.tsx +145 -0
  201. package/src/components/data-table/TableBottomBar.tsx +4 -1
  202. package/src/components/data-table/TableTopBar.tsx +2 -0
  203. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  204. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  205. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  206. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  207. package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
  208. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  209. package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
  210. package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
  211. package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
  212. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  213. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  214. package/src/components/data-table/cell-selection/feature.ts +2 -2
  215. package/src/components/data-table/cell-selection/types.ts +2 -2
  216. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  217. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  218. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  219. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  220. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  221. package/src/components/data-table/charts/charts.tsx +40 -30
  222. package/src/components/data-table/charts/storage.ts +16 -5
  223. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  224. package/src/components/data-table/column-formatting/types.ts +1 -2
  225. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  226. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  227. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  228. package/src/components/data-table/columns.tsx +45 -46
  229. package/src/components/data-table/context-menu.tsx +36 -20
  230. package/src/components/data-table/data-table.tsx +17 -1
  231. package/src/components/data-table/date-popover.tsx +6 -4
  232. package/src/components/data-table/export-actions.tsx +76 -48
  233. package/src/components/data-table/pagination.tsx +44 -33
  234. package/src/components/data-table/range-focus/atoms.ts +4 -6
  235. package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
  236. package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
  237. package/src/components/data-table/renderers.tsx +16 -7
  238. package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
  239. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
  240. package/src/components/data-table/search-highlight.tsx +79 -0
  241. package/src/components/data-table/types.ts +1 -0
  242. package/src/components/data-table/url-detector.tsx +49 -9
  243. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  244. package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
  245. package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
  246. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  247. package/src/components/datasources/__tests__/utils.test.ts +57 -6
  248. package/src/components/datasources/column-preview.tsx +17 -12
  249. package/src/components/datasources/datasources.tsx +56 -43
  250. package/src/components/datasources/utils.ts +32 -23
  251. package/src/components/debugger/debugger-code.tsx +5 -0
  252. package/src/components/dependency-graph/custom-node.tsx +1 -1
  253. package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
  254. package/src/components/dependency-graph/elements.ts +24 -21
  255. package/src/components/dependency-graph/minimap-content.tsx +15 -20
  256. package/src/components/dependency-graph/panels.tsx +4 -2
  257. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  258. package/src/components/editor/SortableCell.tsx +1 -3
  259. package/src/components/editor/__tests__/Output.test.tsx +50 -32
  260. package/src/{core/attachments/__tests__/toast.test.tsx → components/editor/__tests__/agent-toast.test.tsx} +1 -1
  261. package/src/components/editor/__tests__/data-attributes.test.tsx +28 -21
  262. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  263. package/src/components/editor/__tests__/output-persistence.test.tsx +8 -4
  264. package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
  265. package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
  266. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +21 -40
  267. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +41 -14
  268. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +6 -24
  269. package/src/components/editor/actions/__tests__/useCellActionButton.test.tsx +131 -0
  270. package/src/components/editor/actions/name-cell-input.tsx +4 -3
  271. package/src/components/editor/actions/pair-with-agent-commands.ts +10 -7
  272. package/src/components/editor/actions/pair-with-agent-modal.tsx +29 -30
  273. package/src/components/editor/actions/pair-with-agent.tsx +16 -39
  274. package/src/components/editor/actions/useCellActionButton.tsx +47 -35
  275. package/src/components/editor/actions/useConfigActions.tsx +3 -4
  276. package/src/components/editor/actions/useNotebookActions.tsx +25 -29
  277. package/src/components/editor/actions/useRestartKernel.tsx +1 -1
  278. package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
  279. package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
  280. package/src/components/editor/ai/ai-completion-editor.tsx +2 -1
  281. package/src/components/editor/ai/completion-handlers.tsx +0 -37
  282. package/src/components/editor/ai/prompt-input.tsx +189 -0
  283. package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
  284. package/src/components/editor/alerts/connection-notice.tsx +1 -1
  285. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  286. package/src/components/editor/alerts/stdin-blocking-alert.tsx +4 -2
  287. package/src/components/editor/app-container.tsx +1 -1
  288. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
  289. package/src/components/editor/cell/CellStatus.tsx +23 -19
  290. package/src/components/editor/cell/CreateCellButton.tsx +15 -21
  291. package/src/components/editor/cell/DeleteButton.tsx +3 -2
  292. package/src/components/editor/cell/RunButton.tsx +18 -8
  293. package/src/components/editor/cell/StagedAICell.tsx +52 -137
  294. package/src/components/editor/cell/StopButton.tsx +2 -2
  295. package/src/components/editor/cell/__tests__/useRunCells.test.ts +45 -0
  296. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  297. package/src/components/editor/cell/cell-actions.tsx +12 -1
  298. package/src/components/editor/cell/cell-context-menu.tsx +4 -1
  299. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  300. package/src/components/editor/cell/code/cell-editor.tsx +65 -169
  301. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  302. package/src/components/editor/cell/collapse.tsx +15 -4
  303. package/src/components/editor/cell/useAddCell.ts +4 -8
  304. package/src/components/editor/cell/useDeleteCell.tsx +10 -36
  305. package/src/components/editor/cell/useRunCells.ts +20 -8
  306. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  307. package/src/components/editor/cell/useSplitCell.tsx +10 -6
  308. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
  309. package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
  310. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
  311. package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
  312. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
  313. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  314. package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
  315. package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
  316. package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
  317. package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
  318. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
  319. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  320. package/src/components/editor/chrome/panels/panel-header.tsx +13 -0
  321. package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
  322. package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
  323. package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
  324. package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
  325. package/src/components/editor/chrome/types.ts +1 -1
  326. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +7 -9
  327. package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
  328. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +265 -37
  329. package/src/components/editor/chrome/wrapper/__tests__/useAskAiAboutCell.test.tsx +58 -0
  330. package/src/components/editor/chrome/wrapper/app-chrome.tsx +91 -74
  331. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +4 -4
  332. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
  333. package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
  334. package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
  335. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
  336. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  337. package/src/components/editor/chrome/wrapper/footer.tsx +2 -2
  338. package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
  339. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +143 -72
  340. package/src/components/editor/chrome/wrapper/pending-ai-changes-badge.tsx +25 -0
  341. package/src/components/editor/chrome/wrapper/sidebar.tsx +8 -4
  342. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  343. package/src/components/editor/chrome/wrapper/useAskAiAboutCell.ts +36 -0
  344. package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
  345. package/src/components/editor/columns/cell-column.tsx +1 -1
  346. package/src/components/editor/columns/sortable-column.tsx +2 -2
  347. package/src/components/editor/connections/components.tsx +5 -10
  348. package/src/components/editor/controls/Controls.tsx +4 -4
  349. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  350. package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
  351. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
  352. package/src/components/editor/controls/command-palette.tsx +22 -10
  353. package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
  354. package/src/components/editor/documentation.css +34 -11
  355. package/src/components/editor/dynamic-favicon.tsx +21 -40
  356. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +25 -20
  357. package/src/components/editor/errors/auto-fix.tsx +4 -8
  358. package/src/components/editor/errors/send-error-report-button.tsx +3 -6
  359. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  360. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
  361. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  362. package/src/components/editor/file-tree/file-explorer.tsx +48 -15
  363. package/src/components/editor/file-tree/file-name-input.tsx +1 -0
  364. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  365. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  366. package/src/components/editor/header/__tests__/filename-form.test.tsx +1 -4
  367. package/src/components/editor/header/__tests__/status.test.tsx +5 -3
  368. package/src/components/editor/header/app-header.tsx +1 -1
  369. package/src/components/editor/header/filename-form.tsx +1 -1
  370. package/src/components/editor/header/status.tsx +44 -22
  371. package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
  372. package/src/components/editor/links/cell-link-list.tsx +1 -1
  373. package/src/components/editor/links/cell-link.tsx +21 -11
  374. package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
  375. package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
  376. package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
  377. package/src/components/editor/navigation/clipboard.ts +17 -14
  378. package/src/components/editor/navigation/focus-utils.ts +23 -4
  379. package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
  380. package/src/components/editor/navigation/navigation.ts +74 -72
  381. package/src/components/editor/navigation/selection.ts +30 -29
  382. package/src/components/editor/notebook-banner.tsx +1 -0
  383. package/src/components/editor/notebook-cell.tsx +114 -126
  384. package/src/components/editor/output/MarimoErrorOutput.tsx +2 -1
  385. package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
  386. package/src/components/editor/output/Outputs.css +8 -0
  387. package/src/components/editor/output/VideoOutput.tsx +6 -0
  388. package/src/components/editor/output/__tests__/VideoOutput.test.tsx +131 -0
  389. package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
  390. package/src/components/editor/output/ansi-reduce.ts +33 -20
  391. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  392. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
  393. package/src/components/editor/package-alert.tsx +14 -7
  394. package/src/components/editor/renderers/__tests__/add-cell-buttons.test.tsx +18 -0
  395. package/src/components/editor/renderers/cell-array.tsx +32 -100
  396. package/src/components/editor/renderers/grid-layout/__tests__/grid-layout.test.tsx +75 -0
  397. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +34 -22
  398. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -2
  399. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
  400. package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
  401. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  402. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
  403. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +13 -34
  404. package/src/components/editor/stdin-blocking-alert.tsx +4 -2
  405. package/src/components/home/components.tsx +17 -31
  406. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  407. package/src/components/icons/large-spinner.tsx +3 -14
  408. package/src/components/icons/spinner.tsx +1 -1
  409. package/src/components/markdown/markdown-renderer.tsx +39 -28
  410. package/src/components/mcp/mcp-status-indicator.tsx +18 -14
  411. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  412. package/src/components/pages/edit-page.tsx +19 -17
  413. package/src/components/pages/home-page.tsx +164 -91
  414. package/src/components/scratchpad/scratchpad.test.tsx +89 -0
  415. package/src/components/scratchpad/scratchpad.tsx +47 -33
  416. package/src/components/scratchpad/state.ts +7 -0
  417. package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
  418. package/src/components/slides/__tests__/minimap.test.ts +38 -19
  419. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
  420. package/src/components/slides/minimap.tsx +21 -14
  421. package/src/components/slides/reveal-component.tsx +72 -36
  422. package/src/components/slides/reveal-slides.css +5 -4
  423. package/src/components/slides/slide-cell-view.tsx +32 -29
  424. package/src/components/slides/slide-form.tsx +1 -0
  425. package/src/components/slides/slide-scroll-hint.tsx +3 -1
  426. package/src/components/slides/slide.tsx +3 -4
  427. package/src/components/sort/SortableCellsProvider.tsx +8 -25
  428. package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
  429. package/src/components/tracing/tracing.tsx +46 -42
  430. package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
  431. package/src/components/ui/__tests__/fullscreen.test.tsx +44 -2
  432. package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
  433. package/src/components/ui/alert-dialog.tsx +1 -1
  434. package/src/components/ui/draggable-popover.tsx +24 -2
  435. package/src/components/ui/fullscreen.tsx +25 -1
  436. package/src/components/ui/range-slider.tsx +22 -9
  437. package/src/components/ui/toast.tsx +1 -1
  438. package/src/core/MarimoApp.tsx +3 -1
  439. package/src/core/ai/__tests__/staged-cells.test.ts +89 -608
  440. package/src/core/ai/context/context.ts +2 -0
  441. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
  442. package/src/core/ai/context/providers/__tests__/cell.test.ts +49 -0
  443. package/src/core/ai/context/providers/cell-output.ts +2 -2
  444. package/src/core/ai/context/providers/cell.ts +54 -0
  445. package/src/core/ai/context/providers/datasource.ts +6 -2
  446. package/src/core/ai/staged-cells.ts +56 -323
  447. package/src/core/ai/state.ts +3 -0
  448. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
  449. package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
  450. package/src/core/ai/tools/base.ts +18 -15
  451. package/src/core/ai/tools/edit-notebook-tool.ts +86 -80
  452. package/src/core/ai/tools/registry.ts +13 -10
  453. package/src/core/ai/tools/sample-tool.ts +6 -7
  454. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -426
  455. package/src/core/cells/__tests__/actions.test.ts +624 -35
  456. package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
  457. package/src/core/cells/__tests__/arrange.test.ts +432 -0
  458. package/src/core/cells/__tests__/cell.test.ts +85 -151
  459. package/src/core/cells/__tests__/cells.test.ts +269 -2667
  460. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  461. package/src/core/cells/__tests__/document.test.ts +164 -0
  462. package/src/core/cells/__tests__/editor.test.ts +57 -0
  463. package/src/core/cells/__tests__/flush-document.test.ts +40 -0
  464. package/src/core/cells/__tests__/harness.ts +106 -0
  465. package/src/core/cells/__tests__/layout.test.ts +177 -0
  466. package/src/core/cells/__tests__/notebook-outline.test.ts +122 -0
  467. package/src/core/cells/__tests__/outputs.test.tsx +71 -53
  468. package/src/core/cells/__tests__/pending-delete-service.test.tsx +11 -20
  469. package/src/core/cells/__tests__/session.test.ts +445 -211
  470. package/src/core/cells/__tests__/utils.test.ts +76 -347
  471. package/src/core/cells/actions.ts +678 -6
  472. package/src/core/cells/add-missing-import.ts +47 -43
  473. package/src/core/cells/arrange.ts +529 -0
  474. package/src/core/cells/cell.ts +45 -136
  475. package/src/core/cells/cells.ts +133 -1385
  476. package/src/core/cells/columns.ts +38 -0
  477. package/src/core/cells/document.ts +178 -0
  478. package/src/core/cells/edit.ts +30 -0
  479. package/src/core/cells/editor.ts +82 -0
  480. package/src/core/cells/focus.ts +27 -6
  481. package/src/core/cells/layout.ts +221 -0
  482. package/src/core/cells/outputs.ts +12 -28
  483. package/src/core/cells/pending-delete-service.ts +8 -14
  484. package/src/core/cells/scrollCellIntoView.ts +6 -0
  485. package/src/core/cells/session.ts +76 -53
  486. package/src/core/cells/types.ts +34 -41
  487. package/src/core/cells/utils.ts +46 -75
  488. package/src/core/codemirror/__tests__/format.test.ts +0 -34
  489. package/src/core/codemirror/__tests__/setup.test.ts +61 -29
  490. package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
  491. package/src/core/codemirror/ai/resources.ts +1 -1
  492. package/src/core/codemirror/cells/__tests__/extensions.test.ts +2 -6
  493. package/src/core/codemirror/cells/extensions.ts +30 -28
  494. package/src/core/codemirror/cells/state.ts +2 -6
  495. package/src/core/codemirror/cm.ts +5 -1
  496. package/src/core/codemirror/config/types.ts +1 -1
  497. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
  498. package/src/core/codemirror/copilot/getCodes.ts +2 -2
  499. package/src/core/codemirror/format.ts +6 -23
  500. package/src/core/codemirror/keymaps/vim.ts +4 -8
  501. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  502. package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
  503. package/src/core/codemirror/language/cell-code.ts +114 -0
  504. package/src/core/codemirror/language/extension.ts +52 -35
  505. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  506. package/src/core/codemirror/language/languages/python.ts +19 -13
  507. package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
  508. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  509. package/src/core/codemirror/language/types.ts +7 -7
  510. package/src/core/codemirror/language/utils.ts +9 -39
  511. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
  512. package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
  513. package/src/core/codemirror/lsp/utils.ts +1 -1
  514. package/src/core/codemirror/misc/__tests__/paste.test.ts +3 -1
  515. package/src/core/codemirror/misc/paste.ts +1 -1
  516. package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +75 -0
  517. package/src/core/codemirror/placeholder/extensions.ts +80 -19
  518. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  519. package/src/core/codemirror/readonly/extension.ts +2 -2
  520. package/src/core/codemirror/utils.ts +1 -0
  521. package/src/core/config/__tests__/app-config.test.ts +64 -0
  522. package/src/core/config/__tests__/config-schema.test.ts +56 -6
  523. package/src/core/config/config-schema.ts +17 -4
  524. package/src/core/config/config.ts +65 -20
  525. package/src/core/config/feature-flag.tsx +0 -2
  526. package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
  527. package/src/core/datasets/data-source-discovery.ts +4 -6
  528. package/src/core/documentation/doc-lookup.ts +1 -1
  529. package/src/core/edit-app.tsx +22 -28
  530. package/src/core/errors/error-entries.ts +4 -1
  531. package/src/core/executions/__tests__/atoms.test.ts +99 -0
  532. package/src/core/executions/__tests__/select.test.ts +268 -0
  533. package/src/core/executions/atoms.ts +206 -0
  534. package/src/core/executions/hooks.ts +31 -0
  535. package/src/core/executions/index.ts +31 -0
  536. package/src/core/executions/select.ts +175 -0
  537. package/src/core/export/__tests__/hooks.test.ts +0 -5
  538. package/src/core/export/hooks.ts +1 -1
  539. package/src/core/export/layout.ts +2 -2
  540. package/src/core/hotkeys/actions.ts +2 -4
  541. package/src/core/hotkeys/hotkeys.ts +2 -1
  542. package/src/core/islands/__tests__/bootstrap.test.ts +69 -17
  543. package/src/core/islands/__tests__/bridge.test.ts +85 -27
  544. package/src/core/islands/bootstrap.ts +50 -54
  545. package/src/core/islands/bridge.ts +84 -25
  546. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  547. package/src/core/islands/components/output-wrapper.tsx +5 -5
  548. package/src/core/islands/components/web-components.tsx +1 -1
  549. package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
  550. package/src/core/islands/worker/controller.ts +4 -10
  551. package/src/core/islands/worker/worker.tsx +33 -33
  552. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  553. package/src/core/kernel/__tests__/handlers.test.ts +7 -153
  554. package/src/core/kernel/handlers.ts +17 -79
  555. package/src/core/kernel/state.ts +0 -15
  556. package/src/core/lifecycle/render-policy.ts +12 -26
  557. package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
  558. package/src/core/meta/code-visibility.ts +18 -9
  559. package/src/core/network/__tests__/connection.test.ts +1 -1
  560. package/src/core/network/__tests__/requests-lazy.test.ts +6 -8
  561. package/src/core/network/connection-notice.ts +1 -1
  562. package/src/core/network/connection.ts +1 -1
  563. package/src/core/network/requests-lazy.ts +5 -8
  564. package/src/core/network/requests-network.ts +5 -31
  565. package/src/core/network/requests-static.ts +1 -4
  566. package/src/core/network/requests-toasting.tsx +1 -4
  567. package/src/core/network/types.ts +6 -14
  568. package/src/core/network/useConnectionNotice.ts +8 -2
  569. package/src/core/notebook/__tests__/operations.test.ts +51 -0
  570. package/src/core/notebook/attachments.ts +38 -0
  571. package/src/core/notebook/document/__tests__/codemirror.test.ts +759 -0
  572. package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
  573. package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
  574. package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
  575. package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  576. package/src/core/notebook/document/__tests__/model.test.ts +247 -0
  577. package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
  578. package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
  579. package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
  580. package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
  581. package/src/core/notebook/document/__tests__/state.test.ts +459 -0
  582. package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
  583. package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
  584. package/src/core/notebook/document/__tests__/test-host.ts +247 -0
  585. package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
  586. package/src/core/notebook/document/__tests__/user.ts +61 -0
  587. package/src/core/notebook/document/codemirror.ts +216 -0
  588. package/src/core/notebook/document/draft.ts +502 -0
  589. package/src/core/notebook/document/hooks.tsx +118 -0
  590. package/src/core/notebook/document/index.ts +24 -0
  591. package/src/core/notebook/document/model.ts +102 -0
  592. package/src/core/notebook/document/select.ts +41 -0
  593. package/src/core/notebook/document/state.ts +378 -0
  594. package/src/core/notebook/document/sync.ts +369 -0
  595. package/src/core/notebook/index.ts +19 -0
  596. package/src/core/notebook/operations.ts +30 -0
  597. package/src/core/notebook/replica/AGENTS.md +11 -0
  598. package/src/core/{host → notebook/replica}/__tests__/attachments.test.ts +9 -10
  599. package/src/core/{host → notebook/replica}/__tests__/document.test.ts +18 -16
  600. package/src/core/notebook/replica/__tests__/executions.test.ts +200 -0
  601. package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
  602. package/src/core/notebook/replica/__tests__/replica.test.ts +559 -0
  603. package/src/core/notebook/replica/__tests__/results.test.ts +193 -0
  604. package/src/core/notebook/replica/__tests__/runtime.test.ts +78 -0
  605. package/src/core/notebook/replica/backend.ts +19 -0
  606. package/src/core/notebook/replica/connection.ts +42 -0
  607. package/src/core/notebook/replica/index.ts +20 -0
  608. package/src/core/notebook/replica/replica.ts +336 -0
  609. package/src/core/{host → notebook/replica}/resources/attachments.ts +6 -3
  610. package/src/core/{host → notebook/replica}/resources/document.ts +3 -3
  611. package/src/core/notebook/replica/resources/executions.ts +157 -0
  612. package/src/core/notebook/replica/resources/results.ts +48 -0
  613. package/src/core/notebook/replica/resources/runtime.ts +14 -0
  614. package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
  615. package/src/core/packages/useSandboxController.ts +1 -1
  616. package/src/core/run-app.tsx +49 -51
  617. package/src/core/runtime/__tests__/adapter.test.ts +4 -4
  618. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  619. package/src/core/runtime/__tests__/runtime.test.ts +32 -74
  620. package/src/core/runtime/adapter.ts +5 -5
  621. package/src/core/runtime/config.ts +2 -2
  622. package/src/core/runtime/runtime.ts +33 -46
  623. package/src/core/runtime/types.ts +0 -2
  624. package/src/core/saving/__tests__/document.test.tsx +123 -0
  625. package/src/core/saving/__tests__/state.test.ts +111 -0
  626. package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
  627. package/src/core/saving/document.ts +33 -0
  628. package/src/core/saving/filename.ts +1 -1
  629. package/src/core/saving/save-component.tsx +39 -60
  630. package/src/core/saving/state.ts +38 -39
  631. package/src/core/saving/useAutoSave.ts +17 -53
  632. package/src/core/session/__tests__/backend.test.ts +236 -0
  633. package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +186 -0
  634. package/src/core/{websocket → session}/__tests__/useNotebookSession.hook.test.tsx +247 -262
  635. package/src/core/session/active-notebook.ts +28 -0
  636. package/src/core/session/backend.ts +123 -0
  637. package/src/core/session/embedded.ts +7 -0
  638. package/src/core/{websocket → session}/types.ts +2 -2
  639. package/src/core/session/useNotebookReplica.ts +74 -0
  640. package/src/core/{websocket → session}/useNotebookSession.tsx +85 -67
  641. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  642. package/src/core/state/jotai.ts +1 -1
  643. package/src/core/static/__tests__/files.test.ts +38 -10
  644. package/src/core/static/files.ts +2 -0
  645. package/src/core/{websocket → transports}/__tests__/connection-state.test.ts +1 -13
  646. package/src/core/transports/__tests__/server.test.ts +408 -0
  647. package/src/core/transports/__tests__/static.test.ts +306 -0
  648. package/src/core/transports/__tests__/wasm.test.ts +166 -0
  649. package/src/core/{websocket → transports}/connection-state.ts +9 -16
  650. package/src/core/transports/server.ts +152 -0
  651. package/src/core/transports/static.ts +166 -0
  652. package/src/core/transports/wasm.ts +97 -0
  653. package/src/core/vscode/__tests__/vscode-bindings.test.ts +125 -0
  654. package/src/core/vscode/vscode-bindings.ts +14 -2
  655. package/src/core/wasm/__tests__/bridge.test.ts +210 -64
  656. package/src/core/wasm/__tests__/worker.test.ts +188 -0
  657. package/src/core/wasm/bridge.ts +120 -73
  658. package/src/core/wasm/rpc.ts +15 -3
  659. package/src/core/wasm/store.ts +3 -3
  660. package/src/core/wasm/worker/bootstrap.ts +55 -51
  661. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  662. package/src/core/wasm/worker/save-worker.ts +9 -10
  663. package/src/core/wasm/worker/types.ts +30 -18
  664. package/src/core/wasm/worker/worker.ts +118 -72
  665. package/src/css/app/Cell.css +7 -36
  666. package/src/css/app/codemirror.css +1 -1
  667. package/src/css/common.css +1 -1
  668. package/src/css/globals.css +66 -22
  669. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  670. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  671. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  672. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  673. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  674. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  675. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  676. package/src/hooks/useAsyncData.ts +3 -3
  677. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  678. package/src/hooks/useDebounce.ts +6 -10
  679. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  680. package/src/hooks/useDelayElapsed.ts +14 -10
  681. package/src/hooks/useElapsedTime.ts +3 -3
  682. package/src/hooks/useEventListener.ts +1 -2
  683. package/src/hooks/useInputHistory.ts +4 -7
  684. package/src/hooks/useInternalStateWithSync.ts +6 -6
  685. package/src/hooks/useResizeObserver.ts +4 -7
  686. package/src/hooks/useScript.ts +67 -70
  687. package/src/hooks/useStateForKey.ts +93 -0
  688. package/src/mount.tsx +20 -15
  689. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  690. package/src/plugins/core/RenderHTML.tsx +3 -5
  691. package/src/plugins/core/__test__/RenderHTML-copy.test.tsx +60 -0
  692. package/src/plugins/core/registerReactComponent.tsx +5 -14
  693. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  694. package/src/plugins/impl/DataEditorPlugin.tsx +34 -9
  695. package/src/plugins/impl/DataTablePlugin.tsx +69 -37
  696. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  697. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  698. package/src/plugins/impl/FormPlugin.tsx +1 -1
  699. package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
  700. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  701. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  702. package/src/plugins/impl/__tests__/DataEditorPlugin.test.ts +93 -4
  703. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +387 -1
  704. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  705. package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
  706. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  707. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
  708. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  709. package/src/plugins/impl/anywidget/model.ts +3 -1
  710. package/src/plugins/impl/anywidget/registry.ts +18 -14
  711. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  712. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  713. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  714. package/src/plugins/impl/chat/chat-ui.tsx +17 -15
  715. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  716. package/src/plugins/impl/common/error-banner.tsx +5 -3
  717. package/src/plugins/impl/data-editor/__tests__/column-types.test.ts +37 -0
  718. package/src/plugins/impl/data-editor/__tests__/editor-state.test.ts +52 -1
  719. package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +113 -1
  720. package/src/plugins/impl/data-editor/__tests__/glide-utils.test.ts +116 -0
  721. package/src/plugins/impl/data-editor/column-types.ts +52 -0
  722. package/src/plugins/impl/data-editor/editor-state.ts +18 -2
  723. package/src/plugins/impl/data-editor/glide-data-editor.tsx +73 -12
  724. package/src/plugins/impl/data-editor/glide-utils.ts +33 -10
  725. package/src/plugins/impl/data-editor/types.ts +7 -0
  726. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  727. package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
  728. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  729. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  730. package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
  731. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
  732. package/src/plugins/impl/data-frames/panel.tsx +44 -16
  733. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  734. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  735. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  736. package/src/plugins/impl/panel/utils.ts +17 -0
  737. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  738. package/src/plugins/impl/plotly/selection.ts +25 -19
  739. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  740. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  741. package/src/plugins/layout/DownloadPlugin.tsx +7 -11
  742. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  743. package/src/plugins/layout/__test__/DownloadPlugin.test.tsx +205 -0
  744. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  745. package/src/stories/button.stories.tsx +1 -0
  746. package/src/stories/cell-status.stories.tsx +17 -10
  747. package/src/stories/cell.stories.tsx +2 -36
  748. package/src/stories/data-table.stories.tsx +31 -0
  749. package/src/stories/editor.stories.tsx +24 -17
  750. package/src/stories/form-wrapper.stories.tsx +2 -2
  751. package/src/stories/layout/vertical/one-column.stories.tsx +28 -32
  752. package/src/stories/runtime-story.tsx +23 -17
  753. package/src/stories/select.stories.tsx +2 -2
  754. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  755. package/src/utils/__tests__/arrays.test.ts +35 -0
  756. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  757. package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +127 -1
  758. package/src/utils/__tests__/download.test.tsx +183 -23
  759. package/src/utils/__tests__/numbers.test.ts +105 -1
  760. package/src/utils/__tests__/objects.test.ts +21 -0
  761. package/src/utils/arrays.ts +11 -2
  762. package/src/utils/blob.ts +1 -1
  763. package/src/utils/createReducer.ts +115 -79
  764. package/src/utils/download.ts +67 -6
  765. package/src/utils/maps.ts +0 -3
  766. package/src/utils/numbers.ts +79 -18
  767. package/src/utils/objects.ts +4 -9
  768. package/src/utils/time.ts +10 -0
  769. package/src/utils/tracer.ts +9 -5
  770. package/src/utils/zod-utils.ts +1 -3
  771. package/dist/_baseMerge-BiGRwuqv.js +0 -165
  772. package/dist/any-language-editor-D4q-IFcM.js +0 -76
  773. package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
  774. package/dist/assets/worker-HPY9fbhz.js +0 -114
  775. package/dist/dropdown-menu-DHP9P4VE.js +0 -4678
  776. package/dist/feedback-button-B2JRVQRd.js +0 -379
  777. package/dist/hasIn-o2Us0uVx.js +0 -132
  778. package/dist/html-to-image-DWTzN7q3.js +0 -3251
  779. package/dist/isArrayLikeObject-BZl-15ir.js +0 -450
  780. package/dist/isEmpty-BSZ1LaUo.js +0 -35
  781. package/dist/isSymbol-kQcfYbNX.js +0 -8
  782. package/dist/label-DoysmLMW.js +0 -281
  783. package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
  784. package/dist/pick-CJeoxYOS.js +0 -51
  785. package/dist/precisionRound-DMIVQrt2.js +0 -97
  786. package/dist/select-DemoKT4G.js +0 -1344
  787. package/dist/toDate-CJWU9dyl.js +0 -1185
  788. package/dist/toast-PkdZraM8.js +0 -1830
  789. package/dist/use-restore-focus-CKjfFjLM.js +0 -6369
  790. package/dist/useLifecycle-BGWzTwHK.js +0 -169
  791. package/dist/useTheme-BhQvec43.js +0 -904
  792. package/src/components/chat/reasoning-accordion.tsx +0 -61
  793. package/src/components/chat/tool-call/tool-error-card.tsx +0 -81
  794. package/src/components/chat/tool-call/tool-history-row.tsx +0 -174
  795. package/src/components/editor/ai/__tests__/staged-cell-submission.test.ts +0 -106
  796. package/src/components/editor/ai/add-cell-with-ai.tsx +0 -506
  797. package/src/components/editor/ai/staged-cell-submission.ts +0 -46
  798. package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +0 -64
  799. package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +0 -50
  800. package/src/components/editor/chrome/wrapper/footer-items/rtc-status.tsx +0 -65
  801. package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
  802. package/src/components/editor/navigation/state.ts +0 -65
  803. package/src/components/icons/loading-ellipsis.tsx +0 -46
  804. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
  805. package/src/core/ai/tools/run-cells-tool.ts +0 -303
  806. package/src/core/attachments/state.ts +0 -18
  807. package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
  808. package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
  809. package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
  810. package/src/core/cells/document-changes.ts +0 -944
  811. package/src/core/codemirror/rtc/extension.ts +0 -453
  812. package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +0 -52
  813. package/src/core/codemirror/rtc/loro/awareness.ts +0 -531
  814. package/src/core/codemirror/rtc/loro/colors.ts +0 -38
  815. package/src/core/codemirror/rtc/loro/sync.ts +0 -168
  816. package/src/core/host/AGENTS.md +0 -11
  817. package/src/core/host/__tests__/events.test.ts +0 -46
  818. package/src/core/host/__tests__/fixtures.ts +0 -39
  819. package/src/core/host/__tests__/notebook-client.test.ts +0 -433
  820. package/src/core/host/__tests__/protocol.test.ts +0 -214
  821. package/src/core/host/__tests__/stream.test.ts +0 -209
  822. package/src/core/host/connection.ts +0 -81
  823. package/src/core/host/events.ts +0 -61
  824. package/src/core/host/notebook-client.ts +0 -290
  825. package/src/core/host/protocol.ts +0 -1945
  826. package/src/core/host/resources/resource.ts +0 -47
  827. package/src/core/host/stream.ts +0 -211
  828. package/src/core/rtc/state.ts +0 -34
  829. package/src/core/state/__tests__/jotai.test.ts +0 -25
  830. package/src/core/wasm/worker/message-buffer.ts +0 -33
  831. package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
  832. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -170
  833. package/src/core/websocket/state.ts +0 -7
  834. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  835. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
  836. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  837. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  838. package/src/core/websocket/transports/basic.ts +0 -102
  839. package/src/core/websocket/transports/create.ts +0 -31
  840. package/src/core/websocket/transports/sse.ts +0 -308
  841. package/src/core/websocket/transports/transport.ts +0 -50
  842. package/src/core/websocket/transports/ws.ts +0 -98
  843. package/src/core/websocket/useNotebookClient.ts +0 -88
  844. package/src/utils/__tests__/id-tree.test.ts +0 -2145
  845. package/src/utils/id-tree.tsx +0 -1134
  846. /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
  847. /package/src/core/{websocket → session}/connection-utils.ts +0 -0
@@ -13,28 +13,13 @@ import {
13
13
  import { useAtom, useAtomValue, useSetAtom, useStore } from "jotai";
14
14
  import {
15
15
  BotMessageSquareIcon,
16
- HatGlasses,
17
- ArrowRightIcon,
18
16
  Loader2,
19
- type LucideIcon,
20
- MessageCircleIcon,
21
- NotebookText,
22
17
  PlusIcon,
23
- SparklesIcon,
24
18
  SettingsIcon,
25
- CodeIcon,
26
19
  } from "lucide-react";
27
- import { memo, useEffect, useRef, useState } from "react";
20
+ import { memo, useEffect, useMemo, useRef, useState } from "react";
28
21
  import useEvent from "react-use-event-hook";
29
22
  import { Button } from "@/components/ui/button";
30
- import {
31
- Select,
32
- SelectContent,
33
- SelectGroup,
34
- SelectItem,
35
- SelectLabel,
36
- SelectTrigger,
37
- } from "@/components/ui/select";
38
23
  import { replaceMessagesInChat } from "@/core/ai/chat-utils";
39
24
  import { useAIConfigActions } from "@/core/ai/config";
40
25
  import { AI_SDK_UI_THROTTLE_MS } from "@/core/ai/constants";
@@ -49,37 +34,33 @@ import {
49
34
  pendingAiPromptAtom,
50
35
  } from "@/core/ai/state";
51
36
  import type { ToolNotebookContext } from "@/core/ai/tools/base";
52
- import {
53
- type CopilotMode,
54
- FRONTEND_TOOL_REGISTRY,
55
- } from "@/core/ai/tools/registry";
56
- import { useCellActions } from "@/core/cells/cells";
37
+ import { FRONTEND_TOOL_REGISTRY } from "@/core/ai/tools/registry";
38
+ import { useCellActions } from "@/core/cells/actions";
57
39
  import { aiAtom, aiModelConfiguredAtom } from "@/core/config/config";
58
40
  import { DEFAULT_AI_MODEL } from "@/core/config/config-schema";
59
41
  import { useRequestClient } from "@/core/network/requests";
60
42
  import { useRuntimeManager } from "@/core/runtime/config";
61
43
  import { isWasm } from "@/core/wasm/utils";
62
44
  import { ErrorBanner } from "@/plugins/impl/common/error-banner";
63
- import { cn } from "@/utils/cn";
64
45
  import { Logger } from "@/utils/Logger";
65
46
  import { AIModelDropdown } from "../ai/ai-model-dropdown";
66
47
  import { useOpenSettingsToTab } from "../app-config/state";
67
48
  import {
68
49
  PairWithAgentBanner,
69
- PairWithAgentButton,
50
+ usePairWithAgentModal,
70
51
  } from "../editor/actions/pair-with-agent";
71
- import { PairWithAgentModal } from "../editor/actions/pair-with-agent-modal";
72
- import { PromptInput } from "../editor/ai/add-cell-with-ai";
52
+ import { PromptInput } from "../editor/ai/prompt-input";
53
+ import { PendingAICells } from "../editor/chrome/wrapper/pending-ai-cells";
73
54
  import {
74
55
  addContextCompletion,
75
- CONTEXT_TRIGGER,
76
56
  isContextAttachment,
77
57
  resolveChatContext,
78
58
  } from "../editor/ai/completion-utils";
79
59
  import { StreamingChunkTransport } from "../editor/ai/transport/chat-transport";
60
+ import { PanelHeaderActions } from "../editor/chrome/panels/panel-header";
80
61
  import { PanelEmptyState } from "../editor/chrome/panels/empty-state";
81
62
  import { CopyClipboardIcon } from "../icons/copy-icon";
82
- import { useImperativeModal } from "../modal/ImperativeModal";
63
+ import "./chat-typography.css";
83
64
  import { MCPStatusIndicator } from "../mcp/mcp-status-indicator";
84
65
  import { Tooltip, TooltipProvider } from "../ui/tooltip";
85
66
  import {
@@ -94,9 +75,11 @@ import {
94
75
  getAbortReasonFromChunk,
95
76
  resolveChatAbortReason,
96
77
  } from "./chat-abort";
97
- import { renderUIMessage } from "./chat-display";
78
+ import { AgentActivity } from "./agent-activity";
79
+ import { getAnswerText, renderUIMessage } from "./chat-display";
98
80
  import { ChatHistoryPopover } from "./chat-history-popover";
99
81
  import { CapabilitiesPopover } from "./capabilities-popover";
82
+ import { NotebookAccessSelector } from "./notebook-access-selector";
100
83
  import {
101
84
  type ChatMessagePart,
102
85
  convertToFileUIPart,
@@ -104,7 +87,6 @@ import {
104
87
  handleToolCall,
105
88
  hasPendingToolCalls,
106
89
  hasUnresolvedToolCalls,
107
- isLastMessageReasoning,
108
90
  PROVIDERS_THAT_SUPPORT_ATTACHMENTS,
109
91
  type QueuedUserMessage,
110
92
  shouldFlushQueue,
@@ -115,9 +97,12 @@ import { getCodes } from "@/core/codemirror/copilot/getCodes";
115
97
  import { focusInputAndMoveToEnd } from "@/core/codemirror/utils";
116
98
  import ScrollToBottomButton from "./acp/scroll-to-bottom-button";
117
99
  import { useChatControllerId } from "./use-chat-controller-id";
100
+ import { isChatBusy, useChatGeneration } from "./use-chat-generation";
101
+ import { useAssistantTurn } from "./use-assistant-turn";
102
+ import { UserMessage } from "./user-message";
118
103
 
119
104
  // Default mode for the AI
120
- const DEFAULT_MODE = "manual";
105
+ const DEFAULT_MODE = "ask";
121
106
 
122
107
  const QueuedMessageDisplay = memo(
123
108
  ({ message }: { message: QueuedUserMessage }) => {
@@ -131,7 +116,7 @@ const QueuedMessageDisplay = memo(
131
116
 
132
117
  return (
133
118
  <div className="flex justify-end">
134
- <div className="w-[95%] bg-background border border-dashed p-2 rounded-sm opacity-70">
119
+ <div className="w-[95%] bg-background border border-dashed p-2 rounded-[10px] opacity-70">
135
120
  {fileParts.map((filePart, idx) => (
136
121
  <AttachmentRenderer attachment={filePart} key={idx} />
137
122
  ))}
@@ -164,35 +149,41 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
164
149
  const { handleClick } = useOpenSettingsToTab();
165
150
 
166
151
  return (
167
- <div className="flex border-b px-2 py-1 justify-between shrink-0 items-center">
168
- <Tooltip content="New chat">
169
- <Button variant="text" size="icon" onClick={onNewChat}>
170
- <PlusIcon className="h-4 w-4" />
171
- </Button>
172
- </Tooltip>
173
- <div className="flex items-center gap-2">
174
- <Tooltip content="Connect your agent">
175
- <PairWithAgentButton className="mr-1" label="Connect" />
176
- </Tooltip>
177
- <MCPStatusIndicator />
178
- <Tooltip content="AI Settings">
152
+ <PanelHeaderActions>
153
+ <div className="mo-ai-panel flex w-full shrink-0 items-center font-sans text-sm">
154
+ <div className="flex w-full items-center gap-1">
179
155
  <Button
180
- variant="text"
181
- size="xs"
182
- className="hover:bg-foreground/10 py-2"
183
- onClick={() => handleClick("ai")}
156
+ variant="ghost"
157
+ size="sm"
158
+ className="chat-control gap-1.5 font-normal"
159
+ onClick={onNewChat}
184
160
  >
185
- <SettingsIcon className="h-4 w-4" />
161
+ <PlusIcon className="size-4" aria-hidden={true} />
162
+ New chat
186
163
  </Button>
187
- </Tooltip>
188
- <ChatHistoryPopover
189
- activeChatId={activeChatId}
190
- setActiveChat={setActiveChat}
191
- onDeleteChats={onDeleteChats}
192
- isLoading={isLoading}
193
- />
164
+ <ChatHistoryPopover
165
+ activeChatId={activeChatId}
166
+ setActiveChat={setActiveChat}
167
+ onDeleteChats={onDeleteChats}
168
+ isLoading={isLoading}
169
+ />
170
+ <div className="ml-auto flex items-center gap-2">
171
+ <MCPStatusIndicator />
172
+ <Tooltip content="AI Settings">
173
+ <Button
174
+ className="chat-control"
175
+ aria-label="AI Settings"
176
+ variant="ghost"
177
+ size="icon"
178
+ onClick={() => handleClick("ai")}
179
+ >
180
+ <SettingsIcon className="size-4" aria-hidden={true} />
181
+ </Button>
182
+ </Tooltip>
183
+ </div>
184
+ </div>
194
185
  </div>
195
- </div>
186
+ </PanelHeaderActions>
196
187
  );
197
188
  };
198
189
 
@@ -200,9 +191,9 @@ interface ChatMessageProps {
200
191
  message: UIMessage;
201
192
  index: number;
202
193
  onEdit: (index: number, newValue: string) => void;
203
- isStreamingReasoning: boolean;
204
194
  isLast: boolean;
205
195
  isActive: boolean;
196
+ turnStartedAt: number | null;
206
197
  addToolApprovalResponse?: ChatAddToolApproveResponseFunction;
207
198
  }
208
199
 
@@ -211,78 +202,40 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
211
202
  message,
212
203
  index,
213
204
  onEdit,
214
- isStreamingReasoning,
215
205
  isLast,
216
206
  isActive,
207
+ turnStartedAt,
217
208
  addToolApprovalResponse,
218
209
  }) => {
219
- const renderUserMessage = (message: UIMessage) => {
220
- const textParts = message.parts?.filter(
221
- (p): p is TextUIPart => p.type === "text",
222
- );
223
- const content = textParts?.map((p) => p.text).join("\n");
224
- const fileParts = message.parts?.filter(
225
- (p): p is FileUIPart => p.type === "file",
226
- );
227
-
210
+ if (message.role === "user") {
228
211
  return (
229
- <div className="w-[95%] bg-background border p-1 rounded-sm">
230
- {fileParts?.map((filePart, idx) => (
231
- <AttachmentRenderer attachment={filePart} key={idx} />
232
- ))}
233
- <PromptInput
234
- key={message.id}
235
- value={content}
236
- placeholder="Type your message..."
237
- onChange={() => {
238
- // noop
239
- }}
240
- onSubmit={(_e, newValue) => {
241
- if (!newValue.trim()) {
242
- return;
243
- }
244
- onEdit(index, newValue);
245
- }}
246
- onClose={() => {
247
- // noop
248
- }}
212
+ <div className="group flex justify-end">
213
+ <UserMessage
214
+ message={message}
215
+ canEdit={!isActive}
216
+ onEdit={(newValue) => onEdit(index, newValue)}
249
217
  />
250
218
  </div>
251
219
  );
252
- };
253
-
254
- const renderOtherMessage = (message: UIMessage) => {
255
- const textParts = message.parts.filter(
256
- (p): p is TextUIPart => p.type === "text",
257
- );
258
- const content = textParts.map((p) => p.text).join("\n");
220
+ }
259
221
 
260
- return (
222
+ return (
223
+ <div className="group relative flex justify-start">
261
224
  <div className="w-[95%] wrap-break-word">
262
- <div className="absolute right-1 top-1 opacity-0 group-hover:opacity-100 transition-opacity">
263
- <CopyClipboardIcon className="h-3 w-3" value={content || ""} />
225
+ <div className="absolute right-1 top-1 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity">
226
+ <CopyClipboardIcon
227
+ className="h-3 w-3"
228
+ value={() => getAnswerText(message)}
229
+ />
264
230
  </div>
265
231
  {renderUIMessage({
266
232
  message,
267
- isStreamingReasoning,
268
233
  isLast,
269
234
  isActive,
235
+ turnStartedAt,
270
236
  addToolApprovalResponse,
271
237
  })}
272
238
  </div>
273
- );
274
- };
275
-
276
- return (
277
- <div
278
- className={cn(
279
- "flex group relative",
280
- message.role === "user" ? "justify-end" : "justify-start",
281
- )}
282
- >
283
- {message.role === "user"
284
- ? renderUserMessage(message)
285
- : renderOtherMessage(message)}
286
239
  </div>
287
240
  );
288
241
  },
@@ -316,92 +269,27 @@ const ChatInputFooter: React.FC<ChatInputFooterProps> = memo(
316
269
 
317
270
  const { saveModeChange } = useAIConfigActions();
318
271
 
319
- const modeOptions: {
320
- value: CopilotMode;
321
- label: string;
322
- subtitle: string;
323
- Icon: LucideIcon;
324
- }[] = [
325
- {
326
- value: "manual",
327
- label: "Manual",
328
- subtitle: "Pure chat, no tool usage",
329
- Icon: MessageCircleIcon,
330
- },
331
- {
332
- value: "ask",
333
- label: "Ask",
334
- subtitle: "AI with access to read-only tools like documentation search",
335
- Icon: NotebookText,
336
- },
337
- {
338
- value: "agent",
339
- label: "Agent",
340
- subtitle: "AI with access to read and write tools",
341
- Icon: HatGlasses,
342
- },
343
- {
344
- value: "code_mode",
345
- label: "Code Mode (beta)",
346
- subtitle:
347
- "AI with access to the notebook's kernel. Potentially destructive.",
348
- Icon: CodeIcon,
349
- },
350
- ];
351
-
352
272
  const isAttachmentSupported =
353
273
  PROVIDERS_THAT_SUPPORT_ATTACHMENTS.has(currentProvider);
354
274
 
355
- const currentModeOption = modeOptions.find((o) => o.value === currentMode);
356
- const CurrentModeIcon = currentModeOption?.Icon;
357
- const CurrentModeLabel = currentModeOption?.label;
358
-
359
275
  return (
360
276
  <TooltipProvider>
361
- <div className="px-3 py-2 border-t border-border/20 flex flex-wrap items-center gap-1">
362
- <div className="flex flex-wrap items-center gap-1">
363
- <Select value={currentMode} onValueChange={saveModeChange}>
364
- <SelectTrigger className="h-6 text-xs border-border shadow-none! ring-0! bg-muted hover:bg-muted/30 py-0 px-2 gap-1.5 shrink-0">
365
- {CurrentModeIcon && <CurrentModeIcon className="h-3 w-3" />}
366
- <span className="text-nowrap">{CurrentModeLabel}</span>
367
- </SelectTrigger>
368
- <SelectContent>
369
- <SelectGroup>
370
- <SelectLabel className="text-xs uppercase tracking-wider text-muted-foreground/70 font-medium">
371
- AI Mode
372
- </SelectLabel>
373
- {modeOptions.map((option) => (
374
- <SelectItem
375
- key={option.value}
376
- value={option.value}
377
- className="text-xs py-1"
378
- >
379
- <div className="flex items-start gap-2.5">
380
- <span className="mt-1 text-muted-foreground">
381
- <option.Icon className="h-3 w-3" />
382
- </span>
383
- <div className="flex flex-col gap-0.5">
384
- <span className="font-semibold">{option.label}</span>
385
- <span className="text-muted-foreground">
386
- {option.subtitle}
387
- </span>
388
- </div>
389
- </div>
390
- </SelectItem>
391
- ))}
392
- </SelectGroup>
393
- </SelectContent>
394
- </Select>
277
+ <div className="chat-input-footer px-3 py-2 border-t border-border/20 flex items-center gap-2">
278
+ <div className="chat-input-selectors flex min-w-0 flex-1 items-center gap-1">
279
+ <NotebookAccessSelector
280
+ value={currentMode}
281
+ onValueChange={saveModeChange}
282
+ />
395
283
  <AIModelDropdown
396
284
  placeholder="Model"
397
- triggerClassName="h-6 text-xs shadow-none! ring-0! bg-muted hover:bg-muted/30 rounded-sm max-w-[200px]"
285
+ triggerClassName="chat-control chat-selector h-6 text-xs rounded-sm min-w-0 max-w-[200px] flex-1"
398
286
  iconSize="small"
399
287
  showAddCustomModelDocs={true}
400
288
  forRole="chat"
401
289
  />
402
- <CapabilitiesPopover />
403
290
  </div>
404
- <div className="flex flex-row ml-auto">
291
+ <div className="chat-input-actions flex shrink-0 items-center gap-0.5 ml-auto">
292
+ <CapabilitiesPopover />
405
293
  <AddContextButton
406
294
  handleAddContext={onAddContext}
407
295
  isLoading={isLoading}
@@ -429,9 +317,7 @@ const ChatInputFooter: React.FC<ChatInputFooterProps> = memo(
429
317
  ChatInputFooter.displayName = "ChatInputFooter";
430
318
 
431
319
  interface ChatInputProps {
432
- placeholder?: string;
433
320
  input: string;
434
- inputClassName?: string;
435
321
  setInput: (value: string) => void;
436
322
  onSubmit: (e: KeyboardEvent | undefined, value: string) => void;
437
323
  inputRef: React.RefObject<ReactCodeMirrorRef | null>;
@@ -444,9 +330,7 @@ interface ChatInputProps {
444
330
 
445
331
  const ChatInput: React.FC<ChatInputProps> = memo(
446
332
  ({
447
- placeholder,
448
333
  input,
449
- inputClassName,
450
334
  setInput,
451
335
  onSubmit,
452
336
  inputRef,
@@ -456,6 +340,20 @@ const ChatInput: React.FC<ChatInputProps> = memo(
456
340
  onAddFiles,
457
341
  onClose,
458
342
  }) => {
343
+ const openPairWithAgentModal = usePairWithAgentModal();
344
+ const placeholderAction = useMemo(
345
+ () =>
346
+ isWasm()
347
+ ? undefined
348
+ : {
349
+ beforeText: "Type your message or ",
350
+ linkText: "pair your own coding agent",
351
+ afterText: ". Use @ to reference variables and cells.",
352
+ onClick: openPairWithAgentModal,
353
+ },
354
+ [openPairWithAgentModal],
355
+ );
356
+
459
357
  const handleSendClick = useEvent(() => {
460
358
  if (input.trim()) {
461
359
  onSubmit(undefined, input);
@@ -463,8 +361,8 @@ const ChatInput: React.FC<ChatInputProps> = memo(
463
361
  });
464
362
 
465
363
  return (
466
- <div className="relative shrink-0 flex flex-col border-t">
467
- <div className={cn("px-2 py-1.5", inputClassName)}>
364
+ <div className="relative shrink-0 flex flex-col">
365
+ <div className="px-2 py-1.5">
468
366
  <PromptInput
469
367
  className="max-h-[400px]"
470
368
  inputRef={inputRef}
@@ -473,7 +371,8 @@ const ChatInput: React.FC<ChatInputProps> = memo(
473
371
  onSubmit={onSubmit}
474
372
  onClose={onClose}
475
373
  onAddFiles={onAddFiles}
476
- placeholder={placeholder || "Type your message..."}
374
+ placeholder="Type your message. Use @ to reference variables and cells."
375
+ placeholderAction={placeholderAction}
477
376
  />
478
377
  </div>
479
378
  <ChatInputFooter
@@ -492,26 +391,6 @@ const ChatInput: React.FC<ChatInputProps> = memo(
492
391
 
493
392
  ChatInput.displayName = "ChatInput";
494
393
 
495
- const PairWithAgentCallout: React.FC<{
496
- onPairWithAgent: () => void;
497
- }> = ({ onPairWithAgent }) => {
498
- if (isWasm()) {
499
- return null;
500
- }
501
-
502
- return (
503
- <Button
504
- variant="text"
505
- className="gap-1.5 text-sm text-link hover:underline"
506
- onClick={onPairWithAgent}
507
- >
508
- <SparklesIcon className="h-3.5 w-3.5 shrink-0" />
509
- <span>Connect your own agent to this notebook</span>
510
- <ArrowRightIcon className="h-3 w-3 shrink-0" />
511
- </Button>
512
- );
513
- };
514
-
515
394
  const ChatPanel = () => {
516
395
  const aiConfigured = useAtomValue(aiModelConfiguredAtom);
517
396
  const { handleClick } = useOpenSettingsToTab();
@@ -567,9 +446,10 @@ const ChatPanelBody = () => {
567
446
  lastAbortReasonRef.current = null;
568
447
  setAbortNotice(null);
569
448
  });
449
+ const turn = useAssistantTurn();
450
+ const resetTurn = turn.reset;
570
451
  const runtimeManager = useRuntimeManager();
571
- const { invokeAiTool, sendRun } = useRequestClient();
572
- const { openModal, closeModal } = useImperativeModal();
452
+ const { invokeAiTool } = useRequestClient();
573
453
 
574
454
  const activeChatId = activeChat?.id;
575
455
  const { chatControllerId, renewDraftChatId } =
@@ -577,12 +457,10 @@ const ChatPanelBody = () => {
577
457
  const store = useStore();
578
458
 
579
459
  const { addStagedCell } = useStagedAICellsActions();
580
- const { createNewCell, prepareForRun } = useCellActions();
460
+ const { createCell } = useCellActions();
581
461
  const toolContext: ToolNotebookContext = {
582
462
  addStagedCell,
583
- createNewCell,
584
- prepareForRun,
585
- sendRun,
463
+ createCell,
586
464
  store,
587
465
  };
588
466
 
@@ -592,6 +470,7 @@ const ChatPanelBody = () => {
592
470
  error,
593
471
  status,
594
472
  regenerate,
473
+ setMessages,
595
474
  stop,
596
475
  addToolOutput,
597
476
  addToolApprovalResponse,
@@ -599,7 +478,8 @@ const ChatPanelBody = () => {
599
478
  } = useChat({
600
479
  id: chatControllerId,
601
480
  throttle: AI_SDK_UI_THROTTLE_MS,
602
- sendAutomaticallyWhen: ({ messages }) => hasPendingToolCalls(messages),
481
+ sendAutomaticallyWhen: ({ messages }) =>
482
+ !turn.hasEnded && hasPendingToolCalls(messages),
603
483
  messages: activeChat?.messages || [], // initial messages
604
484
  transport: new StreamingChunkTransport(
605
485
  {
@@ -646,7 +526,26 @@ const ChatPanelBody = () => {
646
526
  }
647
527
  },
648
528
  ),
649
- onFinish: ({ messages, isError, isAbort, finishReason }) => {
529
+ onFinish: ({
530
+ messages: finishedMessages,
531
+ isError,
532
+ isAbort,
533
+ finishReason,
534
+ }) => {
535
+ // useChat routes every chat's callbacks to the latest one. Its
536
+ // setMessages isn't a React setter: the updater runs synchronously.
537
+ const finished: { messages?: typeof finishedMessages } = {};
538
+ setMessages((current) => {
539
+ if (current.at(-1)?.id !== finishedMessages.at(-1)?.id) {
540
+ return current;
541
+ }
542
+ finished.messages = turn.finish(finishedMessages, { isAbort, isError });
543
+ return finished.messages;
544
+ });
545
+ const { messages } = finished;
546
+ if (!messages) {
547
+ return;
548
+ }
650
549
  setChatState((prev) => {
651
550
  return replaceMessagesInChat({
652
551
  chatState: prev,
@@ -691,6 +590,7 @@ const ChatPanelBody = () => {
691
590
 
692
591
  const sendUserMessage = useEvent((parts: ChatMessagePart[]) => {
693
592
  clearAbortState();
593
+ turn.start();
694
594
  sendMessage({ role: "user", parts });
695
595
  });
696
596
 
@@ -715,15 +615,43 @@ const ChatPanelBody = () => {
715
615
  },
716
616
  );
717
617
 
718
- const isLoading = status === "submitted" || status === "streaming";
719
- // Read via a ref so the queue-vs-send decision stays correct even when it is
720
- // made after an `await` (e.g. resolving @-context), by which point the render
721
- // closure's `isLoading` may be stale.
722
- const isLoadingRef = useRef(isLoading);
723
- isLoadingRef.current = isLoading;
618
+ const isLoading = isChatBusy(status);
619
+ const isTurnActive = turn.isActive({
620
+ isLoading,
621
+ hasError: error != null,
622
+ messages,
623
+ });
624
+ useChatGeneration(isTurnActive);
625
+
626
+ const stopTurn = useEvent(() => {
627
+ if (isLoading) {
628
+ turn.stop();
629
+ void stop();
630
+ return;
631
+ }
632
+ // Between requests there is no stream to abort, so `onFinish` won't run.
633
+ const stopped = turn.finish(messages, { isAbort: true, isError: false });
634
+ setMessages(stopped);
635
+ setChatState((prev) =>
636
+ replaceMessagesInChat({
637
+ chatState: prev,
638
+ chatId: prev.activeChatId,
639
+ messages: stopped,
640
+ }),
641
+ );
642
+ tryFlushQueuedMessages(stopped, { isError: false, isAbort: true });
643
+ });
724
644
 
645
+ const respondToApproval = useEvent(
646
+ (response: Parameters<ChatAddToolApproveResponseFunction>[0]) => {
647
+ turn.resume(messages.at(-1));
648
+ return addToolApprovalResponse(response);
649
+ },
650
+ );
651
+ // useEvent reads the latest loading state, even when called after an await
652
+ // (e.g. resolving @-context) that outlives the original render's closure.
725
653
  const submitOrQueue = useEvent((parts: ChatMessagePart[]) => {
726
- if (isLoadingRef.current || hasQueuedRef.current) {
654
+ if (isTurnActive || hasQueuedRef.current) {
727
655
  enqueueUserMessage(parts);
728
656
  } else {
729
657
  sendUserMessage(parts);
@@ -756,10 +684,6 @@ const ChatPanelBody = () => {
756
684
  });
757
685
  });
758
686
 
759
- // Check if we're currently streaming reasoning in the latest message
760
- const isStreamingReasoning =
761
- isLoading && messages.length > 0 && isLastMessageReasoning(messages);
762
-
763
687
  // Pin to the bottom while the user is already there.
764
688
  useEffect(() => {
765
689
  setIsScrolledToBottom(true);
@@ -767,6 +691,11 @@ const ChatPanelBody = () => {
767
691
  clearAbortState();
768
692
  }, [activeChatId, clearQueuedMessages, clearAbortState]);
769
693
 
694
+ // Creating a chat keeps the draft's controller, so its turn survives.
695
+ useEffect(() => {
696
+ resetTurn();
697
+ }, [chatControllerId, resetTurn]);
698
+
770
699
  useEffect(() => {
771
700
  if (!isScrolledToBottom) {
772
701
  return;
@@ -821,6 +750,7 @@ const ChatPanelBody = () => {
821
750
  const { contextPart, attachments } =
822
751
  await resolveChatContext(initialMessage);
823
752
 
753
+ turn.start();
824
754
  sendMessage({
825
755
  role: "user",
826
756
  parts: [
@@ -865,10 +795,6 @@ const ChatPanelBody = () => {
865
795
  });
866
796
  });
867
797
 
868
- const handlePairWithAgent = useEvent(() => {
869
- openModal(<PairWithAgentModal onClose={closeModal} />);
870
- });
871
-
872
798
  const handleMessageEdit = useEvent(
873
799
  async (index: number, newValue: string) => {
874
800
  const editedMessage = messages[index];
@@ -882,6 +808,7 @@ const ChatPanelBody = () => {
882
808
  const { contextPart, attachments } = await resolveChatContext(newValue);
883
809
 
884
810
  const messageId = editedMessage.id;
811
+ turn.start();
885
812
  sendMessage({
886
813
  messageId: messageId, // replace the message
887
814
  role: "user",
@@ -920,6 +847,7 @@ const ChatPanelBody = () => {
920
847
 
921
848
  const handleReload = () => {
922
849
  clearAbortState();
850
+ turn.start();
923
851
  regenerate();
924
852
  };
925
853
 
@@ -959,14 +887,20 @@ const ChatPanelBody = () => {
959
887
  return;
960
888
  }
961
889
  setPendingPrompt(null);
962
- const { prompt, submit } = pendingPrompt;
890
+ const { prompt, submit, append } = pendingPrompt;
891
+ const applyPrompt = (draft: string) =>
892
+ append
893
+ ? draft.includes(prompt.trim())
894
+ ? draft
895
+ : `${draft}${draft ? " " : ""}${prompt}`
896
+ : prompt;
963
897
  if (submit) {
964
898
  void submitPendingPrompt(prompt);
965
899
  } else if (isNewThread) {
966
- setNewThreadInput(prompt);
900
+ setNewThreadInput(applyPrompt);
967
901
  focusInputAndMoveToEnd(newThreadInputRef);
968
902
  } else {
969
- setInput(prompt);
903
+ setInput(applyPrompt);
970
904
  focusInputAndMoveToEnd(newMessageInputRef);
971
905
  }
972
906
  }, [pendingPrompt, setPendingPrompt, isNewThread, submitPendingPrompt]);
@@ -974,14 +908,12 @@ const ChatPanelBody = () => {
974
908
  const chatInput = isNewThread ? (
975
909
  <ChatInput
976
910
  key="new-thread-input"
977
- placeholder={`Ask anything, ${CONTEXT_TRIGGER} to include context about tables or dataframes`}
978
911
  input={newThreadInput}
979
912
  inputRef={newThreadInputRef}
980
- inputClassName="px-1 py-0"
981
913
  setInput={setNewThreadInput}
982
914
  onSubmit={handleNewThreadSubmit}
983
- isLoading={isLoading}
984
- onStop={stop}
915
+ isLoading={isTurnActive}
916
+ onStop={stopTurn}
985
917
  fileInputRef={fileInputRef}
986
918
  onAddFiles={addFiles}
987
919
  onClose={handleOnCloseThread}
@@ -992,8 +924,8 @@ const ChatPanelBody = () => {
992
924
  setInput={setInput}
993
925
  onSubmit={handleChatInputSubmit}
994
926
  inputRef={newMessageInputRef}
995
- isLoading={isLoading}
996
- onStop={stop}
927
+ isLoading={isTurnActive}
928
+ onStop={stopTurn}
997
929
  onClose={() => newMessageInputRef.current?.editor?.blur()}
998
930
  fileInputRef={fileInputRef}
999
931
  onAddFiles={addFiles}
@@ -1001,12 +933,7 @@ const ChatPanelBody = () => {
1001
933
  );
1002
934
 
1003
935
  const filesPills = files && files.length > 0 && (
1004
- <div
1005
- className={cn(
1006
- "flex flex-row gap-1 flex-wrap p-1",
1007
- isNewThread && "py-2 px-1",
1008
- )}
1009
- >
936
+ <div className="flex flex-row gap-1 flex-wrap px-3 pt-2">
1010
937
  {files?.map((file) => (
1011
938
  <FileAttachmentPill
1012
939
  file={file}
@@ -1017,8 +944,15 @@ const ChatPanelBody = () => {
1017
944
  </div>
1018
945
  );
1019
946
 
947
+ const composer = (
948
+ <div className="@container rounded-[10px] border border-border bg-background">
949
+ {filesPills}
950
+ {chatInput}
951
+ </div>
952
+ );
953
+
1020
954
  return (
1021
- <div className="flex flex-col h-[calc(100%-53px)]">
955
+ <div className="mo-ai-panel flex flex-col flex-1 min-h-0 font-prose text-sm leading-6">
1022
956
  <TooltipProvider>
1023
957
  <ChatHeader
1024
958
  onNewChat={handleNewChat}
@@ -1031,43 +965,44 @@ const ChatPanelBody = () => {
1031
965
 
1032
966
  <div className="flex-1 flex flex-col overflow-hidden relative min-h-0">
1033
967
  <div
1034
- className="flex-1 px-3 bg-(--slate-1) gap-4 py-3 flex flex-col overflow-y-auto"
968
+ className="flex-1 px-3 bg-background gap-4 py-3 flex flex-col overflow-y-auto"
1035
969
  ref={scrollContainerRef}
1036
970
  onScroll={handleScroll}
1037
971
  >
1038
- {isNewThread && (
1039
- <div className="flex flex-col gap-2">
1040
- <div className="rounded-md border bg-background">
1041
- {filesPills}
1042
- {chatInput}
1043
- </div>
1044
- <PairWithAgentCallout onPairWithAgent={handlePairWithAgent} />
1045
- </div>
1046
- )}
1047
-
1048
- {messages.map((message, idx) => (
1049
- <ChatMessageDisplay
1050
- key={message.id}
1051
- message={message}
1052
- index={idx}
1053
- onEdit={handleMessageEdit}
1054
- isStreamingReasoning={isStreamingReasoning}
1055
- isLast={idx === messages.length - 1}
1056
- isActive={isLoading}
1057
- addToolApprovalResponse={addToolApprovalResponse}
972
+ <TooltipProvider>
973
+ {messages.map((message, idx) => {
974
+ const isLast = idx === messages.length - 1;
975
+ return (
976
+ <ChatMessageDisplay
977
+ key={message.id}
978
+ message={message}
979
+ index={idx}
980
+ onEdit={handleMessageEdit}
981
+ isLast={isLast}
982
+ isActive={isTurnActive}
983
+ turnStartedAt={isLast ? turn.startedAt : null}
984
+ addToolApprovalResponse={respondToApproval}
985
+ />
986
+ );
987
+ })}
988
+ </TooltipProvider>
989
+
990
+ {isTurnActive && messages.at(-1)?.role === "user" && (
991
+ <AgentActivity
992
+ running={true}
993
+ thinking={true}
994
+ timing={
995
+ turn.startedAt == null
996
+ ? undefined
997
+ : { startedAt: turn.startedAt }
998
+ }
1058
999
  />
1059
- ))}
1000
+ )}
1060
1001
 
1061
1002
  {queuedMessages.map((message) => (
1062
1003
  <QueuedMessageDisplay key={message.id} message={message} />
1063
1004
  ))}
1064
1005
 
1065
- {isLoading && (
1066
- <div className="flex justify-center py-4">
1067
- <Loader2 className="h-4 w-4 animate-spin" />
1068
- </div>
1069
- )}
1070
-
1071
1006
  {error && (
1072
1007
  <div className="flex items-center justify-center space-x-2 mb-4">
1073
1008
  <ErrorBanner error={error || new Error("Unknown error")} />
@@ -1095,21 +1030,8 @@ const ChatPanelBody = () => {
1095
1030
  />
1096
1031
  </div>
1097
1032
 
1098
- {isLoading && (
1099
- <div className="w-full flex justify-center items-center z-20 border-t">
1100
- <Button variant="linkDestructive" size="sm" onClick={stop}>
1101
- Stop
1102
- </Button>
1103
- </div>
1104
- )}
1105
-
1106
- {/* For existing threads, we place the chat input at the bottom */}
1107
- {!isNewThread && (
1108
- <>
1109
- {filesPills}
1110
- {chatInput}
1111
- </>
1112
- )}
1033
+ {!isTurnActive && <PendingAICells />}
1034
+ <div className="shrink-0 p-3">{composer}</div>
1113
1035
  </div>
1114
1036
  );
1115
1037
  };