@marimo-team/islands 0.23.7-dev4 → 0.23.7-dev42

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 (513) hide show
  1. package/dist/{ConnectedDataExplorerComponent-PmilQqXR.js → ConnectedDataExplorerComponent-2lBNiUv6.js} +14 -14
  2. package/dist/{ErrorBoundary-Da4UeYxT.js → ErrorBoundary-D3wrPNma.js} +1 -1
  3. package/dist/{any-language-editor-BVR0l12r.js → any-language-editor-VWs_7v27.js} +15 -15
  4. package/dist/apl-Bdc61P1y.js +4 -0
  5. package/dist/{arc-CHF8PiiF.js → arc-DfkSnvZm.js} +2 -2
  6. package/dist/{architecture-7HQA4BMR-D0JB_3hE.js → architecture-7HQA4BMR-CS9jOrqM.js} +1 -1
  7. package/dist/{architectureDiagram-VXUJARFQ-BXQEUDtK.js → architectureDiagram-VXUJARFQ-CXVJxFhH.js} +16 -16
  8. package/dist/asciiarmor-DVRHDGzT.js +4 -0
  9. package/dist/asn1-BmuKfkfu.js +4 -0
  10. package/dist/assets/__vite-browser-external-CAdMKBac.js +1 -0
  11. package/dist/assets/worker-CpBbwbQo.js +73 -0
  12. package/dist/{blockDiagram-VD42YOAC-DhJe-Y9i.js → blockDiagram-VD42YOAC-DGDaxR8I.js} +11 -11
  13. package/dist/brainfuck-DPrRpyTV.js +4 -0
  14. package/dist/{button-CA5pI2YF.js → button-Dj4BTre0.js} +5 -0
  15. package/dist/{c4Diagram-YG6GDRKO-9dSfzOFR.js → c4Diagram-YG6GDRKO-C2hc6ne8.js} +5 -5
  16. package/dist/{capabilities-6laDasij.js → capabilities-C9rrYCzf.js} +1 -1
  17. package/dist/{channel-MqYIiKgS.js → channel-BBoIVUrJ.js} +1 -1
  18. package/dist/{chat-ui-B-gbqk_F.js → chat-ui-CufH8sfF.js} +626 -234
  19. package/dist/{check-CFM2mVDr.js → check-BcUIXnUT.js} +1 -1
  20. package/dist/{chunk-4BX2VUAB-BwfrWBqN.js → chunk-4BX2VUAB-CzXltWHN.js} +1 -1
  21. package/dist/{chunk-55IACEB6-D8THf2mi.js → chunk-55IACEB6-B-1mjMMC.js} +1 -1
  22. package/dist/{chunk-5FQGJX7Z-CO1e63h_.js → chunk-5FQGJX7Z-BOg95xG5.js} +2 -2
  23. package/dist/{chunk-ABZYJK2D-BrBb_0yY.js → chunk-ABZYJK2D-D0cLy8Bb.js} +2 -2
  24. package/dist/{chunk-ATLVNIR6-D-0XqNah.js → chunk-ATLVNIR6-BXsEjlHF.js} +2 -2
  25. package/dist/{chunk-B4BG7PRW-8iRKvugR.js → chunk-B4BG7PRW-Q1usn6T3.js} +7 -7
  26. package/dist/{chunk-CVBHYZKI-B6xhgaBd.js → chunk-CVBHYZKI-B_c5YBcW.js} +1 -1
  27. package/dist/{chunk-DI55MBZ5-C0_2D4m4.js → chunk-DI55MBZ5-D1qLYNrb.js} +6 -6
  28. package/dist/{chunk-EXTU4WIE-Jiw9ca1u.js → chunk-EXTU4WIE-BKNXdLmD.js} +2 -2
  29. package/dist/{chunk-FMBD7UC4-CHdus51S.js → chunk-FMBD7UC4-Ie8M9q0W.js} +1 -1
  30. package/dist/{chunk-HN2XXSSU-2Vfbq-kU.js → chunk-HN2XXSSU-E3n-Ys7Z.js} +1 -1
  31. package/dist/{chunk-JA3XYJ7Z-6wbaigKe.js → chunk-JA3XYJ7Z-D6c6cOBG.js} +3 -3
  32. package/dist/{chunk-JZLCHNYA-_rfptlUP.js → chunk-JZLCHNYA-BvsPHJmL.js} +6 -6
  33. package/dist/{chunk-MI3HLSF2-Do0-KRc0.js → chunk-MI3HLSF2-CUYEasXO.js} +1 -1
  34. package/dist/{chunk-N4CR4FBY-DIZG9dVD.js → chunk-N4CR4FBY-8ycT-O9a.js} +7 -7
  35. package/dist/{chunk-QN33PNHL-Cc64y40m.js → chunk-QN33PNHL-Bb-eUBW3.js} +2 -2
  36. package/dist/{chunk-QXUST7PY-BDG0-0Or.js → chunk-QXUST7PY-DV8yRwBd.js} +10 -10
  37. package/dist/{chunk-QZHKN3VN-B_Mdb8GC.js → chunk-QZHKN3VN-DRjXVwuJ.js} +1 -1
  38. package/dist/{chunk-S3R3BYOJ-DphMP0FA.js → chunk-S3R3BYOJ-mQeCz5CE.js} +4 -4
  39. package/dist/{chunk-TZMSLE5B-C9LUoYkc.js → chunk-TZMSLE5B-BqW10dHe.js} +3 -3
  40. package/dist/classDiagram-2ON5EDUG--Yh__LHb.js +30 -0
  41. package/dist/classDiagram-v2-WZHVMYZB-BC7X7Xtc.js +30 -0
  42. package/dist/{clike-sBZrGeF8.js → clike-DTxNUn7l.js} +1 -1
  43. package/dist/clojure-DEttQW5T.js +4 -0
  44. package/dist/cmake-jNlx_DaM.js +4 -0
  45. package/dist/cobol-BvvIm5MJ.js +4 -0
  46. package/dist/{code-block-37QAKDTI-0JNwiPGv.js → code-block-37QAKDTI-BsGy1AOJ.js} +1 -1
  47. package/dist/{code-visibility-zYxaYsuj.js → code-visibility-CTdccsPx.js} +573 -585
  48. package/dist/coffeescript-DTpBMyFU.js +4 -0
  49. package/dist/commonlisp-BmmUG8jb.js +4 -0
  50. package/dist/{copy-TGGAUEWp.js → copy-DLf4aN7I.js} +2 -2
  51. package/dist/{cose-bilkent-S5V4N54A-DXHZkJKX.js → cose-bilkent-S5V4N54A-kjoZoid4.js} +2 -2
  52. package/dist/crystal-BxyqmEWC.js +4 -0
  53. package/dist/css-BGoCtuG3.js +4 -0
  54. package/dist/cypher-BmCbdl3u.js +4 -0
  55. package/dist/d-CFrlbjZt.js +4 -0
  56. package/dist/{dagre-6UL2VRFP-tH87fkPA.js → dagre-6UL2VRFP-DRBWoQUw.js} +10 -10
  57. package/dist/{data-grid-overlay-editor-CWUN78-s.js → data-grid-overlay-editor-efe5ZagF.js} +2 -2
  58. package/dist/{diagram-PSM6KHXK-2VjPSCDn.js → diagram-PSM6KHXK-H66ATWP2.js} +18 -18
  59. package/dist/{diagram-QEK2KX5R-CiLmNyta.js → diagram-QEK2KX5R-DItl5Wns.js} +14 -14
  60. package/dist/{diagram-S2PKOQOG-Zha_1CLx.js → diagram-S2PKOQOG-CtuW_ZuL.js} +14 -14
  61. package/dist/diff-D6XwL6P8.js +4 -0
  62. package/dist/{dist-Brkazupz.js → dist--sWVZwjW.js} +1 -1
  63. package/dist/{dist-FN0ZA_8F.js → dist-21ButRCu.js} +1 -1
  64. package/dist/{dist-BetEKbPG.js → dist-B8RaFTRF.js} +1 -1
  65. package/dist/dist-BoHGySTM.js +5 -0
  66. package/dist/dist-ByAz19Qc.js +5 -0
  67. package/dist/dist-C93EysN4.js +5 -0
  68. package/dist/{dist-BHnX0ia_.js → dist-CY-lVor6.js} +1 -1
  69. package/dist/{dist-YP-G7W0f.js → dist-CYDuv4bR.js} +1 -1
  70. package/dist/{dist-CMjD5MQb.js → dist-Cfo5EE2t.js} +1 -1
  71. package/dist/dist-CjivSDvN.js +5 -0
  72. package/dist/dist-Cqwx-MH7.js +5 -0
  73. package/dist/{dist-ESg7xyoD.js → dist-D3ZI9nhS.js} +2 -2
  74. package/dist/{dist-DkC6YEo0.js → dist-DMZNjfX4.js} +1 -1
  75. package/dist/{dist-ChC1BhqM.js → dist-DbpcoFAV.js} +1 -1
  76. package/dist/dist-FUNenbiQ.js +5 -0
  77. package/dist/{dist-BEOU2g1b.js → dist-zhSud5X3.js} +1 -1
  78. package/dist/{dockerfile-COvlVLcE.js → dockerfile-twL37N91.js} +1 -1
  79. package/dist/dtd-Bw0lRN0-.js +4 -0
  80. package/dist/dylan-B55eBHTt.js +4 -0
  81. package/dist/ecl-C8G4p0wn.js +4 -0
  82. package/dist/eiffel-BmH46VJl.js +4 -0
  83. package/dist/elm-DhzeFqkl.js +4 -0
  84. package/dist/{erDiagram-Q2GNP2WA-biHZS05w.js → erDiagram-Q2GNP2WA--19X2kU5.js} +14 -14
  85. package/dist/erlang-CY-wdlsU.js +4 -0
  86. package/dist/{error-banner-DnBPzEWg.js → error-banner-CVkfBUT3.js} +2 -2
  87. package/dist/{esm-Dd1z1auZ.js → esm-CWp0KQeK.js} +1 -1
  88. package/dist/{esm-CYEyrE3Y.js → esm-DjNnlmpf.js} +96 -96
  89. package/dist/{extends-CzJgxo2J.js → extends-vAi97cpa.js} +4 -4
  90. package/dist/{factor-C2GT7jfQ.js → factor-CajWS6mS.js} +1 -1
  91. package/dist/factor-DWkgl0xw.js +4 -0
  92. package/dist/{flowDiagram-NV44I4VS-CWWlUpBR.js → flowDiagram-NV44I4VS-DQmWlo7f.js} +16 -16
  93. package/dist/{formats-CgaK7Gmx.js → formats-CpgZM9BM.js} +3 -3
  94. package/dist/forth-Cij_ie2t.js +4 -0
  95. package/dist/fortran-Br3X9cfm.js +4 -0
  96. package/dist/{ganttDiagram-JELNMOA3-D7B2c4Z9.js → ganttDiagram-JELNMOA3-BOGXJ8Lk.js} +7 -7
  97. package/dist/gas-DYsGcMN2.js +4 -0
  98. package/dist/gherkin-eVgXQ0fQ.js +4 -0
  99. package/dist/{gitGraph-G5XIXVHT-BdepdFa_.js → gitGraph-G5XIXVHT-DGlbae5m.js} +1 -1
  100. package/dist/{gitGraphDiagram-V2S2FVAM-CtLvNR1S.js → gitGraphDiagram-V2S2FVAM-DjzxfF0P.js} +14 -14
  101. package/dist/{glide-data-editor-CvlvtPWJ.js → glide-data-editor-BK9s_dqy.js} +13 -13
  102. package/dist/groovy-_NFHIXG7.js +4 -0
  103. package/dist/haskell-D6xNG_bH.js +4 -0
  104. package/dist/haxe-sU_rzAwn.js +5 -0
  105. package/dist/{html-to-image-hMMPiNe_.js → html-to-image-DxWM1HVj.js} +2395 -2301
  106. package/dist/idl-Ds_VbrUx.js +4 -0
  107. package/dist/{info-VBDWY6EO--JNA2rNu.js → info-VBDWY6EO-D2lvLLw5.js} +1 -1
  108. package/dist/{infoDiagram-HS3SLOUP-BbZyOxsP.js → infoDiagram-HS3SLOUP-ChNufFsP.js} +12 -12
  109. package/dist/{input-BAOe64zx.js → input-Cc1Vvw9A.js} +6 -6
  110. package/dist/javascript-CztfIl0i.js +4 -0
  111. package/dist/{journeyDiagram-XKPGCS4Q-BU2mjjzl.js → journeyDiagram-XKPGCS4Q-BO_O4Ij1.js} +6 -6
  112. package/dist/julia-DDv40QMV.js +4 -0
  113. package/dist/{kanban-definition-3W4ZIXB7-BlmczUuw.js → kanban-definition-3W4ZIXB7-CPpiiiWk.js} +11 -11
  114. package/dist/{katex-qPqrBHZ8.js → katex-9-9QRhxz.js} +1 -1
  115. package/dist/{label-BCWi-Oqu.js → label-BLqV33b1.js} +2 -2
  116. package/dist/{line-BWRi3U3S.js → line-C5s_12ee.js} +3 -3
  117. package/dist/{linear-DnHwODZa.js → linear-2NnK4cxi.js} +2 -2
  118. package/dist/livescript-BEOngLLc.js +4 -0
  119. package/dist/{loader-BvW0-YWZ.js → loader-Dr8Qem8p.js} +1 -1
  120. package/dist/lua-9-7BhQ4Y.js +4 -0
  121. package/dist/main.js +1175 -1142
  122. package/dist/mathematica-DDa0Pfxm.js +4 -0
  123. package/dist/mbox-iO03mmoE.js +4 -0
  124. package/dist/{mermaid-4DMBBIKO-CG1ECj5W.js → mermaid-4DMBBIKO-B7VQMwJx.js} +1 -1
  125. package/dist/{mermaid-CEbzCxCc.js → mermaid-DO-Daq7u.js} +46 -46
  126. package/dist/{mermaid-parser.core-CleJseNW.js → mermaid-parser.core-DreccfmS.js} +7 -7
  127. package/dist/{mhchem-BwoRNwg_.js → mhchem-yiCCuiEF.js} +1 -1
  128. package/dist/{mindmap-definition-VGOIOE7T-CcSYqYP9.js → mindmap-definition-VGOIOE7T-CC1_Vl0f.js} +13 -13
  129. package/dist/mirc-C9z5LT4X.js +4 -0
  130. package/dist/mllike-jGJbdm_C.js +6 -0
  131. package/dist/modelica-DzF7oIEL.js +4 -0
  132. package/dist/mscgen-DB-u125o.js +6 -0
  133. package/dist/mumps-CRTFHhzh.js +4 -0
  134. package/dist/nsis-C4NPTuox.js +4 -0
  135. package/dist/{nsis-B5K1qoyo.js → nsis-ClF3r5Tr.js} +1 -1
  136. package/dist/ntriples-BCOoGph1.js +4 -0
  137. package/dist/{number-overlay-editor-_GnlYFHC.js → number-overlay-editor-CpKi64Fy.js} +1 -1
  138. package/dist/octave-DTwNlazz.js +4 -0
  139. package/dist/{ordinal-2jIulmcR.js → ordinal-B43ZeR68.js} +1 -1
  140. package/dist/oz-DD38AzSz.js +4 -0
  141. package/dist/{packet-DYOGHKS2-CBxXGWNr.js → packet-DYOGHKS2-CmWtF3uO.js} +1 -1
  142. package/dist/pascal-BohSp9jV.js +4 -0
  143. package/dist/perl-f5OutoPM.js +4 -0
  144. package/dist/{pie-VRWISCQL-Bmdnqjip.js → pie-VRWISCQL-B6u8vus8.js} +1 -1
  145. package/dist/{pieDiagram-ADFJNKIX-DNyLF5H2.js → pieDiagram-ADFJNKIX-Di34MOFQ.js} +19 -19
  146. package/dist/pig-Dv7wSmHb.js +4 -0
  147. package/dist/powershell-rYgjKB39.js +4 -0
  148. package/dist/{process-output-Bza_GK7Q.js → process-output-DBYxXdrN.js} +30 -25
  149. package/dist/properties-BFUNLRDN.js +4 -0
  150. package/dist/protobuf-B9QJQPPv.js +4 -0
  151. package/dist/{pug-tjbzJCFk.js → pug-B_rby2yb.js} +1 -1
  152. package/dist/pug-DzvWpaMC.js +4 -0
  153. package/dist/puppet-B_K-n_xK.js +4 -0
  154. package/dist/python-CAiFcaA2.js +4 -0
  155. package/dist/q-cLeFIBLK.js +4 -0
  156. package/dist/{quadrantDiagram-AYHSOK5B-rXwjifrj.js → quadrantDiagram-AYHSOK5B-B9kVk1ny.js} +3 -3
  157. package/dist/r-04Y-Wco3.js +4 -0
  158. package/dist/{radar-ZZBFDIW7-BmCWDffL.js → radar-ZZBFDIW7-XAmXSa8s.js} +1 -1
  159. package/dist/{react-vega-B-rkEqtS.js → react-vega-Cavbrg4l.js} +1 -1
  160. package/dist/{react-vega-k9ODWPlI.js → react-vega-Dh6-UKKe.js} +13 -13
  161. package/dist/{requirementDiagram-UZGBJVZJ-DBdrMVbs.js → requirementDiagram-UZGBJVZJ-BxGfGYEx.js} +13 -13
  162. package/dist/{reveal-component-h0_DDpxE.js → reveal-component-BpKkH57S.js} +10 -10
  163. package/dist/rpm-FUdrIia9.js +5 -0
  164. package/dist/ruby-DMjFXuEW.js +4 -0
  165. package/dist/{sankeyDiagram-TZEHDZUN-CxmzalGv.js → sankeyDiagram-TZEHDZUN-D09PBJ-n.js} +4 -4
  166. package/dist/sas-DzHZxjXK.js +4 -0
  167. package/dist/scheme-DxHd_Rb9.js +4 -0
  168. package/dist/semaphore-CNDGTzkX.js +46 -0
  169. package/dist/{sequenceDiagram-WL72ISMW-CVCDsJ9h.js → sequenceDiagram-WL72ISMW-t_Dpemj0.js} +7 -7
  170. package/dist/shell-C8Kwypgf.js +4 -0
  171. package/dist/sieve-DdyqOKXZ.js +4 -0
  172. package/dist/smalltalk-pB7X1D9y.js +4 -0
  173. package/dist/sparql-NhBO6oOa.js +4 -0
  174. package/dist/{spec-DSIuqd3f.js → spec-hVaaZsY5.js} +4 -4
  175. package/dist/{src-BY0BGg6V.js → src-Bf2iLOlr.js} +1 -1
  176. package/dist/{stateDiagram-FKZM4ZOC-D_2djEhW.js → stateDiagram-FKZM4ZOC-B18gTP_j.js} +16 -16
  177. package/dist/stateDiagram-v2-4FDKWEC3-B6e_t14A.js +29 -0
  178. package/dist/{step-DGAGWg3y.js → step-CWipAYTY.js} +1 -1
  179. package/dist/{strings-B_FOH6eV.js → strings-BiIhGaI8.js} +4 -4
  180. package/dist/style.css +1 -1
  181. package/dist/stylus-SfWSnzPv.js +4 -0
  182. package/dist/swift-jRPdq2zR.js +4 -0
  183. package/dist/{swiper-component-KkEVUDd3.js → swiper-component-DlD2GU2g.js} +2 -2
  184. package/dist/tcl-_hpTHGX3.js +4 -0
  185. package/dist/textile-C9h8slqH.js +4 -0
  186. package/dist/{time-CMdrp3hw.js → time-C1SGcFMH.js} +2 -2
  187. package/dist/{timeline-definition-IT6M3QCI-E4NzxCs3.js → timeline-definition-IT6M3QCI-DJnh1ks5.js} +3 -3
  188. package/dist/{toDate-CHtl9vts.js → toDate-CJWlVNGD.js} +3 -3
  189. package/dist/toml-DWvtinD4.js +4 -0
  190. package/dist/{tooltip-B0mtKTXm.js → tooltip-DRaMBu06.js} +3 -3
  191. package/dist/{treemap-GDKQZRPO-CoKHPxa7.js → treemap-GDKQZRPO-Du95DV6u.js} +1 -1
  192. package/dist/troff-Dwo_A0y7.js +4 -0
  193. package/dist/ttcn-V--CPFKq.js +4 -0
  194. package/dist/ttcn-cfg-CPSMchTG.js +4 -0
  195. package/dist/turtle-B4rPGBWu.js +4 -0
  196. package/dist/{types-DBtDeUKD.js → types-Dzuoc3LN.js} +1 -1
  197. package/dist/{useAsyncData-B6hCGywC.js → useAsyncData-C56Khv_R.js} +1 -1
  198. package/dist/{useDateFormatter-B3mCQMP3.js → useDateFormatter-B_9k85Ex.js} +2 -2
  199. package/dist/{useDeepCompareMemoize-CmwDuYUH.js → useDeepCompareMemoize-Dt98v2ua.js} +1 -1
  200. package/dist/{useIframeCapabilities-DbdLoEDm.js → useIframeCapabilities-BkYHTrss.js} +1 -1
  201. package/dist/{useLifecycle-CjMjllqy.js → useLifecycle-BF6-z62y.js} +3 -3
  202. package/dist/{useTheme-CByZUW0p.js → useTheme-DykuNHR2.js} +2 -2
  203. package/dist/vb-DaMBBd4j.js +4 -0
  204. package/dist/vbscript-BMJQqcE2.js +4 -0
  205. package/dist/{vega-component-CC8TqWWV.js → vega-component-BtvQ-Kc4.js} +26 -24
  206. package/dist/velocity-CGq2QRq2.js +4 -0
  207. package/dist/verilog-CUNo8F5u.js +4 -0
  208. package/dist/vhdl-CCzA0msW.js +4 -0
  209. package/dist/webidl-CqIMDIBL.js +4 -0
  210. package/dist/xquery-XC5Kbr-1.js +4 -0
  211. package/dist/{xychartDiagram-PRI3JC2R-CuxTvjw5.js → xychartDiagram-PRI3JC2R-Dk2d_bX0.js} +10 -10
  212. package/dist/yacas-CGOv7Dzy.js +4 -0
  213. package/dist/z80-CXhVmi-f.js +4 -0
  214. package/dist/{zod-BxdsqRPd.js → zod-BWkcDORu.js} +1 -1
  215. package/package.json +3 -3
  216. package/src/components/chat/chat-components.tsx +47 -0
  217. package/src/components/chat/chat-display.tsx +41 -7
  218. package/src/components/chat/chat-panel.tsx +37 -10
  219. package/src/components/chat/chat-utils.ts +42 -20
  220. package/src/components/chat/reasoning-accordion.tsx +14 -3
  221. package/src/components/chat/tool-call/shared.ts +13 -0
  222. package/src/components/chat/tool-call/tool-approval-card.tsx +62 -0
  223. package/src/components/chat/tool-call/tool-args.tsx +26 -0
  224. package/src/components/chat/tool-call/tool-call-view.tsx +99 -0
  225. package/src/components/chat/tool-call/tool-error-card.tsx +81 -0
  226. package/src/components/chat/tool-call/tool-history-row.tsx +153 -0
  227. package/src/components/chat/tool-call/tool-result.tsx +101 -0
  228. package/src/components/data-table/TableTopBar.tsx +5 -1
  229. package/src/components/data-table/data-table.tsx +5 -0
  230. package/src/components/data-table/download-policy/atoms.ts +10 -0
  231. package/src/components/data-table/export-actions.tsx +31 -4
  232. package/src/components/editor/actions/useNotebookActions.tsx +3 -1
  233. package/src/components/editor/app-container.tsx +7 -1
  234. package/src/components/editor/chrome/panels/context-aware-panel/context-aware-panel.tsx +10 -2
  235. package/src/components/editor/chrome/wrapper/app-chrome.tsx +1 -0
  236. package/src/components/editor/chrome/wrapper/footer.tsx +4 -1
  237. package/src/components/editor/chrome/wrapper/panels.tsx +4 -1
  238. package/src/components/editor/chrome/wrapper/sidebar.tsx +4 -1
  239. package/src/components/editor/controls/Controls.tsx +11 -3
  240. package/src/components/editor/file-tree/requesting-tree.tsx +27 -25
  241. package/src/components/editor/file-tree/upload.tsx +23 -24
  242. package/src/components/editor/header/__tests__/status.test.tsx +108 -0
  243. package/src/components/editor/header/status.tsx +44 -10
  244. package/src/components/editor/navigation/__tests__/clipboard.test.ts +106 -0
  245. package/src/components/editor/navigation/__tests__/navigation.test.ts +70 -0
  246. package/src/components/editor/navigation/clipboard.ts +99 -25
  247. package/src/components/editor/navigation/navigation.ts +15 -1
  248. package/src/components/editor/notebook-cell.tsx +3 -0
  249. package/src/components/home/components.tsx +6 -0
  250. package/src/components/pages/run-page.tsx +4 -1
  251. package/src/core/ai/tools/__tests__/registry.test.ts +10 -12
  252. package/src/core/ai/tools/registry.ts +9 -5
  253. package/src/core/cells/__tests__/cells.test.ts +187 -0
  254. package/src/core/cells/__tests__/pending-cut-service.test.tsx +123 -0
  255. package/src/core/cells/cells.ts +102 -17
  256. package/src/core/cells/document-changes.ts +6 -1
  257. package/src/core/cells/pending-cut-service.ts +55 -0
  258. package/src/core/cells/utils.ts +11 -0
  259. package/src/core/codemirror/cells/extensions.ts +10 -0
  260. package/src/core/codemirror/markdown/__tests__/commands.test.ts +3 -3
  261. package/src/core/codemirror/markdown/commands.ts +1 -2
  262. package/src/core/edit-app.tsx +2 -1
  263. package/src/core/hotkeys/hotkeys.ts +5 -0
  264. package/src/core/islands/worker/worker.tsx +3 -2
  265. package/src/core/network/requests-network.ts +21 -3
  266. package/src/core/network/types.ts +12 -1
  267. package/src/core/run-app.tsx +2 -1
  268. package/src/core/wasm/__tests__/utils.test.ts +34 -0
  269. package/src/core/wasm/bridge.ts +14 -1
  270. package/src/core/wasm/utils.ts +14 -0
  271. package/src/core/wasm/worker/bootstrap.ts +3 -2
  272. package/src/core/wasm/worker/worker.ts +3 -2
  273. package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +155 -0
  274. package/src/core/websocket/__tests__/useMarimoKernelConnection.test.ts +137 -0
  275. package/src/core/websocket/transports/basic.ts +2 -0
  276. package/src/core/websocket/transports/transport.ts +1 -0
  277. package/src/core/websocket/useMarimoKernelConnection.tsx +130 -55
  278. package/src/core/websocket/useWebSocket.tsx +5 -2
  279. package/src/css/app/Cell.css +10 -0
  280. package/src/plugins/impl/DataTablePlugin.tsx +12 -0
  281. package/src/plugins/impl/TabsPlugin.tsx +35 -7
  282. package/src/plugins/impl/__tests__/TabsPlugin.test.tsx +154 -0
  283. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +6 -0
  284. package/src/plugins/impl/vega/resolve-data.ts +8 -1
  285. package/src/utils/__tests__/id-tree.test.ts +71 -0
  286. package/src/utils/__tests__/semaphore.test.ts +218 -0
  287. package/src/utils/fileToBase64.ts +8 -7
  288. package/src/utils/id-tree.tsx +89 -0
  289. package/src/utils/semaphore.ts +88 -0
  290. package/dist/apl-BKoVld9y.js +0 -4
  291. package/dist/asciiarmor-DQrKIjoo.js +0 -4
  292. package/dist/asn1-BZvnj0dq.js +0 -4
  293. package/dist/assets/__vite-browser-external-rrUYDKRl.js +0 -1
  294. package/dist/assets/worker-Bfy15ViQ.js +0 -73
  295. package/dist/brainfuck-D558nlUv.js +0 -4
  296. package/dist/classDiagram-2ON5EDUG-CBHMR6ZU.js +0 -30
  297. package/dist/classDiagram-v2-WZHVMYZB-BsUtUGM_.js +0 -30
  298. package/dist/clojure-Cq8mTSrE.js +0 -4
  299. package/dist/cmake-D8HCovWK.js +0 -4
  300. package/dist/cobol-UolN-9iU.js +0 -4
  301. package/dist/coffeescript-VdNuWrt5.js +0 -4
  302. package/dist/commonlisp-ALX7fpDc.js +0 -4
  303. package/dist/crystal-PbyO9Q_s.js +0 -4
  304. package/dist/css-DFklJkr_.js +0 -4
  305. package/dist/cypher-BifNeYlv.js +0 -4
  306. package/dist/d-BA-JP4PJ.js +0 -4
  307. package/dist/diff-CtkDpav4.js +0 -4
  308. package/dist/dist-BuBwsFva.js +0 -5
  309. package/dist/dist-BzmEQ9u7.js +0 -5
  310. package/dist/dist-Cih01ssx.js +0 -5
  311. package/dist/dist-CqfONiY9.js +0 -5
  312. package/dist/dist-D0iD0Fi9.js +0 -5
  313. package/dist/dist-DtNLXm8d.js +0 -5
  314. package/dist/dtd-DW3_UFEG.js +0 -4
  315. package/dist/dylan-pDhodO2N.js +0 -4
  316. package/dist/ecl-BJT8-YD7.js +0 -4
  317. package/dist/eiffel-Dmns-9vS.js +0 -4
  318. package/dist/elm-Da4sO4Bz.js +0 -4
  319. package/dist/erlang-C-zBsDi7.js +0 -4
  320. package/dist/factor-4xPWlWB5.js +0 -4
  321. package/dist/forth-l-c75zSd.js +0 -4
  322. package/dist/fortran-DIujSODW.js +0 -4
  323. package/dist/gas-CXnG5g_b.js +0 -4
  324. package/dist/gherkin-VPeqd4-X.js +0 -4
  325. package/dist/groovy-CphhZQgg.js +0 -4
  326. package/dist/haskell-CCvlS5Iq.js +0 -4
  327. package/dist/haxe-C_bi66fP.js +0 -5
  328. package/dist/idl-1DcP4Dm8.js +0 -4
  329. package/dist/javascript-DUIGhBvO.js +0 -4
  330. package/dist/julia-Cs2G4PQi.js +0 -4
  331. package/dist/livescript-DMtVFaAN.js +0 -4
  332. package/dist/lua-BAoLtdJg.js +0 -4
  333. package/dist/mathematica-C_NoFtbo.js +0 -4
  334. package/dist/mbox-DcFJFYrH.js +0 -4
  335. package/dist/mirc-71dccf_u.js +0 -4
  336. package/dist/mllike-CWcOFVDq.js +0 -6
  337. package/dist/modelica-Ape2VXxx.js +0 -4
  338. package/dist/mscgen-Cc6TwbSN.js +0 -6
  339. package/dist/mumps-h-ZbdkJ9.js +0 -4
  340. package/dist/nsis-C0p3m7JW.js +0 -4
  341. package/dist/ntriples-c9lEeT5w.js +0 -4
  342. package/dist/octave-DzEgB_74.js +0 -4
  343. package/dist/oz-CAxvHkyQ.js +0 -4
  344. package/dist/pascal-BJzu1sgP.js +0 -4
  345. package/dist/perl--IrOzZ2Z.js +0 -4
  346. package/dist/pig-CiBKKNhC.js +0 -4
  347. package/dist/powershell-KY0j6Qop.js +0 -4
  348. package/dist/properties-BW8q3ziV.js +0 -4
  349. package/dist/protobuf-BGaeuTGV.js +0 -4
  350. package/dist/pug-DjOKK-4J.js +0 -4
  351. package/dist/puppet-DWm2o6zX.js +0 -4
  352. package/dist/python-Bp2gezZy.js +0 -4
  353. package/dist/q-DljPshos.js +0 -4
  354. package/dist/r-BajPMnEu.js +0 -4
  355. package/dist/rpm-BKx-ZZ62.js +0 -5
  356. package/dist/ruby-DJq_HNKc.js +0 -4
  357. package/dist/sas-WANvpcOU.js +0 -4
  358. package/dist/scheme-CliBbhGF.js +0 -4
  359. package/dist/shell-BwhrNUvM.js +0 -4
  360. package/dist/sieve-BIVePvMp.js +0 -4
  361. package/dist/smalltalk-D6G48JmY.js +0 -4
  362. package/dist/sparql-jjc3BmEP.js +0 -4
  363. package/dist/stateDiagram-v2-4FDKWEC3-Cv9Av10H.js +0 -29
  364. package/dist/stylus-WPBPQ4PE.js +0 -4
  365. package/dist/swift-O1Qy6iCm.js +0 -4
  366. package/dist/tcl-BAFdhvsi.js +0 -4
  367. package/dist/textile-DFuzhNLG.js +0 -4
  368. package/dist/toml-DRSTeely.js +0 -4
  369. package/dist/troff-B_ZjwBW0.js +0 -4
  370. package/dist/ttcn-CAyiB3ic.js +0 -4
  371. package/dist/ttcn-cfg-BS5_BGBJ.js +0 -4
  372. package/dist/turtle-CUBEDy3E.js +0 -4
  373. package/dist/vb-DY9S6-U2.js +0 -4
  374. package/dist/vbscript-gaHC39Jq.js +0 -4
  375. package/dist/velocity-TfCOtJZ_.js +0 -4
  376. package/dist/verilog-c2JOX8mv.js +0 -4
  377. package/dist/vhdl-dHBirRiO.js +0 -4
  378. package/dist/webidl-Bauj-i07.js +0 -4
  379. package/dist/xquery-CtaEAOt8.js +0 -4
  380. package/dist/yacas-BZ85agQP.js +0 -4
  381. package/dist/z80-hCgR-L4U.js +0 -4
  382. package/src/components/chat/tool-call-accordion.tsx +0 -247
  383. /package/dist/{ImageComparisonComponent-DaocPIse.js → ImageComparisonComponent-CNHIsPDj.js} +0 -0
  384. /package/dist/{Plot-PIeIvFnD.js → Plot-4wn-lMVn.js} +0 -0
  385. /package/dist/{apl-Dt8GMXYg.js → apl-BCgCq9iM.js} +0 -0
  386. /package/dist/{array-B-MVxRIF.js → array-tvvEqPy7.js} +0 -0
  387. /package/dist/{asciiarmor-CitDQ85h.js → asciiarmor-BtqU-KJQ.js} +0 -0
  388. /package/dist/{asn1-abrf9SMK.js → asn1-Dmb-dTMx.js} +0 -0
  389. /package/dist/{asterisk-BUZwqih-.js → asterisk-DaVJJDnV.js} +0 -0
  390. /package/dist/{brainfuck-BL-Boof0.js → brainfuck-C1HoZKlE.js} +0 -0
  391. /package/dist/{chunk-4F5CHEZ2-C6tO9vjs.js → chunk-4F5CHEZ2-BZq7Kom7.js} +0 -0
  392. /package/dist/{chunk-B2363JML-Ds8wZXyP.js → chunk-B2363JML-D9-XOau1.js} +0 -0
  393. /package/dist/{chunk-DR5Q36YT-CP69aZS_.js → chunk-DR5Q36YT-BflwErH1.js} +0 -0
  394. /package/dist/{chunk-FRFDVMJY-BgQv1HBE.js → chunk-FRFDVMJY-BSBUAX7r.js} +0 -0
  395. /package/dist/{chunk-PL6DKKU2-DHfTUHy8.js → chunk-PL6DKKU2-B0MTXvyc.js} +0 -0
  396. /package/dist/{chunk-SJTYNZTY-Diciw4sx.js → chunk-SJTYNZTY-CEG4F0pB.js} +0 -0
  397. /package/dist/{chunk-TQ3KTPDO-CQfP9npd.js → chunk-TQ3KTPDO-DiCtqVSi.js} +0 -0
  398. /package/dist/{chunk-UMXZTB3W-MSKeGL7W.js → chunk-UMXZTB3W-97iS1iEl.js} +0 -0
  399. /package/dist/{click-outside-container-BZgN7xS_.js → click-outside-container-BDd67_1U.js} +0 -0
  400. /package/dist/{clike-RWg7anhx.js → clike-CdT0yHjt.js} +0 -0
  401. /package/dist/{clojure-DaojKHow.js → clojure-CdyrCpUv.js} +0 -0
  402. /package/dist/{cmake-DN-_v0XE.js → cmake-BFlPxym7.js} +0 -0
  403. /package/dist/{cobol-C3VpMyux.js → cobol-CcJXewp8.js} +0 -0
  404. /package/dist/{coffeescript-DIkz3Tbt.js → coffeescript-DnKuIKRo.js} +0 -0
  405. /package/dist/{colors-Cn2p_FA3.js → colors-CQAOa8cK.js} +0 -0
  406. /package/dist/{common-keywords-hbLeU7VU.js → common-keywords-FBrXPTcz.js} +0 -0
  407. /package/dist/{commonlisp-CB1boOiP.js → commonlisp-B-kok83Z.js} +0 -0
  408. /package/dist/{crystal-DI2oCml6.js → crystal-FYRYjI1I.js} +0 -0
  409. /package/dist/{css-BdEVwQDV.js → css-B45lc2V3.js} +0 -0
  410. /package/dist/{cypher-BNHToqxU.js → cypher-DZMLyVY_.js} +0 -0
  411. /package/dist/{cytoscape.esm-WbbDoCfu.js → cytoscape.esm-ayF70frT.js} +0 -0
  412. /package/dist/{d-D7we7I1b.js → d-x-VVT4o9.js} +0 -0
  413. /package/dist/{diff-Cia6fzjN.js → diff-Dxe2mpXk.js} +0 -0
  414. /package/dist/{dist-BK-3fF4P.js → dist-B4LJpMEg.js} +0 -0
  415. /package/dist/{dist-CxdUraQr.js → dist-B507mf_I.js} +0 -0
  416. /package/dist/{dist-C89sHDXk.js → dist-BGdYVvOu.js} +0 -0
  417. /package/dist/{dist-DquyVv5H.js → dist-BNyrZfqT.js} +0 -0
  418. /package/dist/{dist-Zn0KNbo9.js → dist-Bc5pmZIw.js} +0 -0
  419. /package/dist/{dist-C-J0pt5p.js → dist-BvCfQQQE.js} +0 -0
  420. /package/dist/{dist-D9r7Cmw7.js → dist-C2ej4eOH.js} +0 -0
  421. /package/dist/{dist-HVuryI1a.js → dist-C34oIrQ9.js} +0 -0
  422. /package/dist/{dist-CGLzXdrt.js → dist-CDFZi-QD.js} +0 -0
  423. /package/dist/{dist-C9fmTOin.js → dist-CYEylvZA.js} +0 -0
  424. /package/dist/{dist-DadjmS-4.js → dist-DJ6zJQZ4.js} +0 -0
  425. /package/dist/{dist-CtCY55Jf.js → dist-Dh3wkoyH.js} +0 -0
  426. /package/dist/{dist-C474qFoq.js → dist-Dhk6FMb0.js} +0 -0
  427. /package/dist/{dist-DZjQ_MBo.js → dist-KnujRhFL.js} +0 -0
  428. /package/dist/{dist-CinA9Enb.js → dist-WdPUFc56.js} +0 -0
  429. /package/dist/{dist-DBLeRrPp.js → dist-t_qL7eB8.js} +0 -0
  430. /package/dist/{dist-CyFFzJTb.js → dist-usPCDYx8.js} +0 -0
  431. /package/dist/{dtd-H4Hubdwp.js → dtd-C9VM_Wfu.js} +0 -0
  432. /package/dist/{duckdb-keywords-CZ_ZTscu.js → duckdb-keywords-CvJhR_Yd.js} +0 -0
  433. /package/dist/{dylan-fVO6rnq3.js → dylan-DTSnEIFO.js} +0 -0
  434. /package/dist/{ebnf-WEXPLEWb.js → ebnf-2D4Ctp3y.js} +0 -0
  435. /package/dist/{ecl-B94VPjNR.js → ecl-N04ptnRK.js} +0 -0
  436. /package/dist/{eiffel-C_R6TusS.js → eiffel-Dd8rpqr_.js} +0 -0
  437. /package/dist/{elm-DzCHbO2g.js → elm-GT2E866W.js} +0 -0
  438. /package/dist/{erlang-BGNkx6JU.js → erlang-Cf0Bp5pY.js} +0 -0
  439. /package/dist/{esm-Bb_hbWan.js → esm-BaaaPNGl.js} +0 -0
  440. /package/dist/{fcl-B_Gv5Jfx.js → fcl-Ccj8Z5Xd.js} +0 -0
  441. /package/dist/{forth-Bybw0cJ7.js → forth-wd_XzGTg.js} +0 -0
  442. /package/dist/{fortran-C6PoCLkI.js → fortran-DcwUTZFe.js} +0 -0
  443. /package/dist/{gas-BBlhenj4.js → gas-DeALIER3.js} +0 -0
  444. /package/dist/{gherkin-NXtNG85X.js → gherkin-CKTqaJNX.js} +0 -0
  445. /package/dist/{groovy-BoFYK9xM.js → groovy-Bwdp_d8D.js} +0 -0
  446. /package/dist/{haskell-BtBdvQ1n.js → haskell-DCdCcPLK.js} +0 -0
  447. /package/dist/{haxe-D--o6dr0.js → haxe-DAyktQWJ.js} +0 -0
  448. /package/dist/{http-Dc2fv19V.js → http-_DVAYWoR.js} +0 -0
  449. /package/dist/{idl-AqTq5l7e.js → idl-CBuZiRYu.js} +0 -0
  450. /package/dist/{init-D-g0ONX1.js → init-uv0kkh4g.js} +0 -0
  451. /package/dist/{javascript-DvwNVye9.js → javascript-DzigE11c.js} +0 -0
  452. /package/dist/{julia-DoKiagZC.js → julia-PwfB-0Cm.js} +0 -0
  453. /package/dist/{katex-B7pMJpE0.js → katex-C_XRmjAP.js} +0 -0
  454. /package/dist/{livescript-DxBZMiWB.js → livescript-BJLz1EbT.js} +0 -0
  455. /package/dist/{lua-DmS_0NTu.js → lua-ZC-XC2jf.js} +0 -0
  456. /package/dist/{math-BYK36kWZ.js → math-DFcdCCU8.js} +0 -0
  457. /package/dist/{mathematica-ChlDFeIC.js → mathematica-DCYMx6qB.js} +0 -0
  458. /package/dist/{mbox-CguZuODr.js → mbox-OxMK_9XI.js} +0 -0
  459. /package/dist/{mirc-CFtY8dqz.js → mirc-nJVyhA0H.js} +0 -0
  460. /package/dist/{mllike-C0EJrEOk.js → mllike-DRO89bsU.js} +0 -0
  461. /package/dist/{modelica-C1kO1nfS.js → modelica-Don3E6ZD.js} +0 -0
  462. /package/dist/{mscgen-DEYdr7AY.js → mscgen-DJfqD3bN.js} +0 -0
  463. /package/dist/{mumps-B3NVJs2V.js → mumps-SjGTvDYL.js} +0 -0
  464. /package/dist/{nginx-ComVAAGN.js → nginx-DasThI7R.js} +0 -0
  465. /package/dist/{node-sql-parser-DNGGJ-Rw.js → node-sql-parser-B8nBD36q.js} +0 -0
  466. /package/dist/{ntriples-DHol9X9H.js → ntriples-CNBKRl3I.js} +0 -0
  467. /package/dist/{octave-CYGz0bfo.js → octave-DdeVHNlx.js} +0 -0
  468. /package/dist/{oz-kPxb2ni5.js → oz-CcKSoNvN.js} +0 -0
  469. /package/dist/{pascal-bZ0yrJKy.js → pascal-6leftwNj.js} +0 -0
  470. /package/dist/{path-Du6n3sOU.js → path-BGaWgPKg.js} +0 -0
  471. /package/dist/{perl-z4hvqyqz.js → perl-BhJIwWzN.js} +0 -0
  472. /package/dist/{pig-DZO8QDF9.js → pig-r-xDHqRf.js} +0 -0
  473. /package/dist/{powershell-BSuaDQEC.js → powershell-D-BELeNi.js} +0 -0
  474. /package/dist/{properties-BXhGLlIx.js → properties-CnuDhbll.js} +0 -0
  475. /package/dist/{protobuf-DM6iybWV.js → protobuf-CO8RBhvX.js} +0 -0
  476. /package/dist/{puppet-Bn05sQT8.js → puppet-NmXHjLy8.js} +0 -0
  477. /package/dist/{python-Cvnhm0g7.js → python-DAQXi720.js} +0 -0
  478. /package/dist/{q-B9V8hzex.js → q-DlikXfV0.js} +0 -0
  479. /package/dist/{r-Cf0gFqmq.js → r-CuohilwT.js} +0 -0
  480. /package/dist/{rpm-D-LMkTV1.js → rpm-0Pjwp0Pb.js} +0 -0
  481. /package/dist/{ruby-DeuPikpK.js → ruby-Dq8NJTDG.js} +0 -0
  482. /package/dist/{sas-C9tjgAo9.js → sas-CuwonyVP.js} +0 -0
  483. /package/dist/{scheme-D1_bUF0G.js → scheme-CYU-RRIf.js} +0 -0
  484. /package/dist/{shell-CJBmnks3.js → shell-COPmX2qE.js} +0 -0
  485. /package/dist/{sieve-1fSV75CF.js → sieve-B_3zyLne.js} +0 -0
  486. /package/dist/{simple-mode-B90Wdavj.js → simple-mode-DSBniks8.js} +0 -0
  487. /package/dist/{smalltalk-sZNPD0HO.js → smalltalk-DRft7iPv.js} +0 -0
  488. /package/dist/{solr-DTkyqJ-Z.js → solr-RZ9uTl59.js} +0 -0
  489. /package/dist/{sparql-oHc1nm77.js → sparql-CN6qj55H.js} +0 -0
  490. /package/dist/{spreadsheet-CER0raqY.js → spreadsheet-BNNUNXA2.js} +0 -0
  491. /package/dist/{sql-ByOoEONQ.js → sql-B4x8IkwU.js} +0 -0
  492. /package/dist/{stylus-KzkX6zRB.js → stylus-Bn_ZjOQ3.js} +0 -0
  493. /package/dist/{swift-DqVxZvKo.js → swift-BLUJhMbz.js} +0 -0
  494. /package/dist/{tcl-BtWSwXfA.js → tcl-C86fxecl.js} +0 -0
  495. /package/dist/{textile-CWDbn9Ql.js → textile-DmHh2rsK.js} +0 -0
  496. /package/dist/{tiddlywiki-Cr9xyOY1.js → tiddlywiki-DI0mF2WJ.js} +0 -0
  497. /package/dist/{tiki-D5JONyfZ.js → tiki-2HU6XLLn.js} +0 -0
  498. /package/dist/{timer-D7JVdX9U.js → timer-YZl28NYN.js} +0 -0
  499. /package/dist/{toml-BfehlgmL.js → toml-GWANRNAD.js} +0 -0
  500. /package/dist/{treemap-qFGzn7xk.js → treemap-D-ka1hvx.js} +0 -0
  501. /package/dist/{troff-BZBk6AAu.js → troff-BHTsomIy.js} +0 -0
  502. /package/dist/{ttcn-DVwvXg0_.js → ttcn-DQuhn5Mn.js} +0 -0
  503. /package/dist/{ttcn-cfg-gjbVLf1L.js → ttcn-cfg-HjFYtdB-.js} +0 -0
  504. /package/dist/{turtle-CgxKXorV.js → turtle-nCay33Nv.js} +0 -0
  505. /package/dist/{vb-B9kSwTdM.js → vb-BG-XlqqJ.js} +0 -0
  506. /package/dist/{vbscript-DrUKSCdb.js → vbscript-B6vyW0-D.js} +0 -0
  507. /package/dist/{velocity-AlMYTnMy.js → velocity-CWegueqO.js} +0 -0
  508. /package/dist/{verilog-DLUaM05j.js → verilog-CzSQm4cG.js} +0 -0
  509. /package/dist/{vhdl-DUJOtSmO.js → vhdl-DqnNVL7r.js} +0 -0
  510. /package/dist/{webidl-CQp4aHk_.js → webidl-DXEUpDWH.js} +0 -0
  511. /package/dist/{xquery-IxkjlwOD.js → xquery-Ba_NB5bD.js} +0 -0
  512. /package/dist/{yacas-Bnctn5w8.js → yacas-HKQU6hyk.js} +0 -0
  513. /package/dist/{z80-DrFwhx53.js → z80-CXkHXLdj.js} +0 -0
@@ -4,7 +4,13 @@ import type { UIMessage } from "@ai-sdk/react";
4
4
  import { useChat } from "@ai-sdk/react";
5
5
  import { storePrompt } from "@marimo-team/codemirror-ai";
6
6
  import type { ReactCodeMirrorRef } from "@uiw/react-codemirror";
7
- import { DefaultChatTransport, type FileUIPart, type TextUIPart } from "ai";
7
+ import {
8
+ type ChatAddToolApproveResponseFunction,
9
+ DefaultChatTransport,
10
+ type FileUIPart,
11
+ safeValidateUIMessages,
12
+ type TextUIPart,
13
+ } from "ai";
8
14
  import { useAtom, useAtomValue, useSetAtom, useStore } from "jotai";
9
15
  import {
10
16
  BotMessageSquareIcon,
@@ -131,10 +137,18 @@ interface ChatMessageProps {
131
137
  onEdit: (index: number, newValue: string) => void;
132
138
  isStreamingReasoning: boolean;
133
139
  isLast: boolean;
140
+ addToolApprovalResponse?: ChatAddToolApproveResponseFunction;
134
141
  }
135
142
 
136
143
  const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
137
- ({ message, index, onEdit, isStreamingReasoning, isLast }) => {
144
+ ({
145
+ message,
146
+ index,
147
+ onEdit,
148
+ isStreamingReasoning,
149
+ isLast,
150
+ addToolApprovalResponse,
151
+ }) => {
138
152
  const renderUserMessage = (message: UIMessage) => {
139
153
  const textParts = message.parts?.filter(
140
154
  (p): p is TextUIPart => p.type === "text",
@@ -181,7 +195,12 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
181
195
  <div className="absolute right-1 top-1 opacity-0 group-hover:opacity-100 transition-opacity">
182
196
  <CopyClipboardIcon className="h-3 w-3" value={content || ""} />
183
197
  </div>
184
- {renderUIMessage({ message, isStreamingReasoning, isLast })}
198
+ {renderUIMessage({
199
+ message,
200
+ isStreamingReasoning,
201
+ isLast,
202
+ addToolApprovalResponse,
203
+ })}
185
204
  </div>
186
205
  );
187
206
  };
@@ -458,6 +477,7 @@ const ChatPanelBody = () => {
458
477
  regenerate,
459
478
  stop,
460
479
  addToolOutput,
480
+ addToolApprovalResponse,
461
481
  id: chatId,
462
482
  } = useChat({
463
483
  id: activeChatId,
@@ -467,6 +487,19 @@ const ChatPanelBody = () => {
467
487
  api: runtimeManager.getAiURL("chat").toString(),
468
488
  headers: () => runtimeManager.headers(),
469
489
  prepareSendMessagesRequest: async (options) => {
490
+ // Canary: flag outgoing messages that don't match the AI SDK's own
491
+ // schema. The server-side sanitizer in `_pydantic_ai_utils.py` corrects these before validation;
492
+ // this log surfaces drift early without affecting the request.
493
+ const validation = await safeValidateUIMessages({
494
+ messages: options.messages,
495
+ });
496
+ if (!validation.success) {
497
+ Logger.debug(
498
+ "Outgoing chat messages failed AI SDK schema validation",
499
+ validation.error,
500
+ );
501
+ }
502
+
470
503
  const completionBody = await buildCompletionRequestBody(
471
504
  options.messages,
472
505
  );
@@ -495,13 +528,6 @@ const ChatPanelBody = () => {
495
528
  });
496
529
  },
497
530
  onToolCall: async ({ toolCall }) => {
498
- // Dynamic tool calls will throw an error for toolName
499
- // https://ai-sdk.dev/docs/ai-sdk-ui/chatbot-tool-usage#client-side-page
500
- if (toolCall.dynamic) {
501
- Logger.debug("Skipping dynamic tool call", toolCall);
502
- return;
503
- }
504
-
505
531
  await handleToolCall({
506
532
  invokeAiTool,
507
533
  addToolOutput,
@@ -712,6 +738,7 @@ const ChatPanelBody = () => {
712
738
  onEdit={handleMessageEdit}
713
739
  isStreamingReasoning={isStreamingReasoning}
714
740
  isLast={idx === messages.length - 1}
741
+ addToolApprovalResponse={addToolApprovalResponse}
715
742
  />
716
743
  ))}
717
744
 
@@ -1,11 +1,12 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import type { components } from "@marimo-team/marimo-api";
4
- import type {
5
- ChatAddToolOutputFunction,
6
- FileUIPart,
7
- ToolUIPart,
8
- UIMessage,
4
+ import {
5
+ type ChatAddToolOutputFunction,
6
+ type FileUIPart,
7
+ isToolUIPart,
8
+ type ToolUIPart,
9
+ type UIMessage,
9
10
  } from "ai";
10
11
  import { useState } from "react";
11
12
  import useEvent from "react-use-event-hook";
@@ -16,6 +17,7 @@ import type {
16
17
  InvokeAiToolRequest,
17
18
  InvokeAiToolResponse,
18
19
  } from "@/core/network/types";
20
+ import { logNever } from "@/utils/assertNever";
19
21
  import { blobToString } from "@/utils/fileToBase64";
20
22
  import { Logger } from "@/utils/Logger";
21
23
  import { getAICompletionBodyWithAttachments } from "../editor/ai/completion-utils";
@@ -134,11 +136,11 @@ export async function handleToolCall({
134
136
  try {
135
137
  if (FRONTEND_TOOL_REGISTRY.has(toolCall.toolName)) {
136
138
  // Invoke the frontend tool
137
- const response = await FRONTEND_TOOL_REGISTRY.invoke(
138
- toolCall.toolName,
139
- toolCall.input,
140
- toolContext,
141
- );
139
+ const response = await FRONTEND_TOOL_REGISTRY.invoke({
140
+ toolName: toolCall.toolName,
141
+ rawArgs: toolCall.input,
142
+ toolContext: toolContext,
143
+ });
142
144
  addToolOutput({
143
145
  tool: toolCall.toolName,
144
146
  toolCallId: toolCall.toolCallId,
@@ -166,9 +168,33 @@ export async function handleToolCall({
166
168
  }
167
169
  }
168
170
 
171
+ /**
172
+ * Returns true if a tool call is "ready to be sent back to the server" — i.e.
173
+ * either it has reached a terminal output state, or the user has just supplied
174
+ * an approval response that the server hasn't seen yet.
175
+ */
176
+ function isToolCallReadyToSend(state: ToolUIPart["state"]): boolean {
177
+ switch (state) {
178
+ case "output-available":
179
+ case "output-error":
180
+ case "output-denied":
181
+ case "approval-responded":
182
+ return true;
183
+ case "input-streaming":
184
+ case "input-available":
185
+ case "approval-requested":
186
+ return false;
187
+ default:
188
+ logNever(state);
189
+ return false;
190
+ }
191
+ }
192
+
169
193
  /**
170
194
  * Checks if we should send a message automatically based on the messages.
171
- * We only want to send a message if all tool calls are completed and there is no reply yet.
195
+ * We auto-send when every tool call on the last assistant message has either
196
+ * finished (output-available/error/denied) or has just received a user
197
+ * approval response, and the assistant hasn't replied yet.
172
198
  */
173
199
  export function hasPendingToolCalls(messages: UIMessage[]): boolean {
174
200
  if (messages.length === 0) {
@@ -188,17 +214,14 @@ export function hasPendingToolCalls(messages: UIMessage[]): boolean {
188
214
  return false;
189
215
  }
190
216
 
191
- const toolParts = parts.filter((part) =>
192
- part.type.startsWith("tool-"),
193
- ) as ToolUIPart[];
217
+ const toolParts = parts.filter(isToolUIPart);
194
218
 
195
- // Guard against no tool parts
196
219
  if (toolParts.length === 0) {
197
220
  return false;
198
221
  }
199
222
 
200
- const allToolCallsCompleted = toolParts.every(
201
- (part) => part.state === "output-available",
223
+ const allToolCallsReady = toolParts.every((part) =>
224
+ isToolCallReadyToSend(part.state),
202
225
  );
203
226
 
204
227
  // Check if the last part has any text content
@@ -206,10 +229,9 @@ export function hasPendingToolCalls(messages: UIMessage[]): boolean {
206
229
  const hasTextContent =
207
230
  lastPart.type === "text" && lastPart.text?.trim().length > 0;
208
231
 
209
- Logger.warn("All tool calls completed: %s", allToolCallsCompleted);
232
+ Logger.debug("All tool calls ready to send: %s", allToolCallsReady);
210
233
 
211
- // Only auto-send if we have completed tool calls and there is no reply yet
212
- return allToolCallsCompleted && !hasTextContent;
234
+ return allToolCallsReady && !hasTextContent;
213
235
  }
214
236
 
215
237
  export function useFileState() {
@@ -21,20 +21,31 @@ export const ReasoningAccordion: React.FC<ReasoningAccordionProps> = ({
21
21
  index = 0,
22
22
  isStreaming = false,
23
23
  }) => {
24
+ const [openItem, setOpenItem] = React.useState<string>("");
25
+
26
+ // Some reasoning models emit a reasoning part with no surfaced content
27
+ // (e.g. OpenAI's o-series, which hides chain-of-thought but still marks
28
+ // its boundaries on the wire). pydantic-ai's Vercel adapter forwards the
29
+ // empty start/end pair, producing a 0-char ReasoningUIPart. Skip it.
30
+ if (!reasoning && !isStreaming) {
31
+ return null;
32
+ }
33
+
24
34
  return (
25
35
  <Accordion
26
36
  key={index}
27
37
  type="single"
28
38
  collapsible={true}
29
39
  className="w-full mb-2"
30
- value={isStreaming ? "reasoning" : undefined}
40
+ value={isStreaming ? "reasoning" : openItem}
41
+ onValueChange={setOpenItem}
31
42
  >
32
43
  <AccordionItem value="reasoning" className="border-0">
33
44
  <AccordionTrigger className="text-xs text-muted-foreground hover:bg-muted/50 px-2 py-1 h-auto rounded-sm [&[data-state=open]>svg]:rotate-180">
34
45
  <span className="flex items-center gap-2">
35
46
  <BotMessageSquareIcon className="h-3 w-3" />
36
- {isStreaming ? "Thinking" : "View reasoning"} ({reasoning.length}{" "}
37
- chars)
47
+ {isStreaming ? "Thinking" : "View reasoning"}
48
+ {reasoning.length > 0 && ` (${reasoning.length} chars)`}
38
49
  </span>
39
50
  </AccordionTrigger>
40
51
  <AccordionContent className="pb-2 px-2">
@@ -0,0 +1,13 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type { ToolUIPart } from "ai";
4
+
5
+ export type ToolState = ToolUIPart["state"];
6
+
7
+ // The AI SDK declares `approval` inline on every variant of `UIToolInvocation`
8
+ // rather than exporting a named type, so we derive ours from there.
9
+ export type ToolApproval = NonNullable<ToolUIPart["approval"]>;
10
+
11
+ export function formatToolName(toolName: string): string {
12
+ return toolName.replace("tool-", "");
13
+ }
@@ -0,0 +1,62 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type { ChatAddToolApproveResponseFunction } from "ai";
4
+ import { ShieldQuestionIcon } from "lucide-react";
5
+ import React from "react";
6
+ import { Button } from "@/components/ui/button";
7
+ import { cn } from "@/utils/cn";
8
+ import { formatToolName, type ToolApproval } from "./shared";
9
+ import { ToolArgsRenderer } from "./tool-args";
10
+
11
+ interface ToolApprovalCardProps {
12
+ toolName: string;
13
+ input: unknown;
14
+ approval: ToolApproval;
15
+ onApprove: ChatAddToolApproveResponseFunction;
16
+ className?: string;
17
+ }
18
+
19
+ export const ToolApprovalCard: React.FC<ToolApprovalCardProps> = ({
20
+ toolName,
21
+ input,
22
+ approval,
23
+ onApprove,
24
+ className,
25
+ }) => {
26
+ return (
27
+ <div
28
+ className={cn(
29
+ "rounded-md border border-(--amber-6) bg-(--amber-2) p-3 space-y-3",
30
+ className,
31
+ )}
32
+ role="alertdialog"
33
+ aria-label={`Approval required for ${formatToolName(toolName)}`}
34
+ >
35
+ <div className="flex items-start gap-2">
36
+ <ShieldQuestionIcon className="h-4 w-4 text-(--amber-11) mt-0.5 shrink-0" />
37
+ <div className="text-xs text-(--amber-11) leading-relaxed">
38
+ <span className="font-semibold">Approval required:</span>{" "}
39
+ <code className="font-mono">{formatToolName(toolName)}</code>
40
+ </div>
41
+ </div>
42
+
43
+ <ToolArgsRenderer input={input} />
44
+
45
+ <div className="flex items-center justify-end gap-2">
46
+ <Button
47
+ size="xs"
48
+ variant="outline"
49
+ onClick={() => onApprove({ id: approval.id, approved: false })}
50
+ >
51
+ Deny
52
+ </Button>
53
+ <Button
54
+ size="xs"
55
+ onClick={() => onApprove({ id: approval.id, approved: true })}
56
+ >
57
+ Approve
58
+ </Button>
59
+ </div>
60
+ </div>
61
+ );
62
+ };
@@ -0,0 +1,26 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import React from "react";
4
+
5
+ interface ToolArgsRendererProps {
6
+ input: unknown;
7
+ label?: string;
8
+ }
9
+
10
+ export const ToolArgsRenderer: React.FC<ToolArgsRendererProps> = ({
11
+ input,
12
+ label = "Tool Request",
13
+ }) => {
14
+ if (input == null) {
15
+ return null;
16
+ }
17
+
18
+ return (
19
+ <div className="space-y-2">
20
+ <h3 className="text-xs font-semibold text-muted-foreground">{label}</h3>
21
+ <pre className="bg-(--slate-2) p-2 text-muted-foreground border border-(--slate-4) rounded text-xs overflow-auto scrollbar-thin max-h-64">
22
+ {JSON.stringify(input, null, 2)}
23
+ </pre>
24
+ </div>
25
+ );
26
+ };
@@ -0,0 +1,99 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type { ChatAddToolApproveResponseFunction } from "ai";
4
+ import React from "react";
5
+ import { logNever } from "@/utils/assertNever";
6
+ import type { ToolApproval, ToolState } from "./shared";
7
+ import { ToolApprovalCard } from "./tool-approval-card";
8
+ import { ToolErrorCard } from "./tool-error-card";
9
+ import { ToolHistoryRow } from "./tool-history-row";
10
+
11
+ interface ToolCallViewProps {
12
+ toolName: string;
13
+ state: ToolState;
14
+ result?: unknown;
15
+ errorText?: string;
16
+ input?: unknown;
17
+ approval?: ToolApproval;
18
+ onApprove?: ChatAddToolApproveResponseFunction;
19
+ index?: number;
20
+ className?: string;
21
+ /**
22
+ * Whether this tool call belongs to the latest message in the conversation.
23
+ * Used by error cards to decide whether to stay expanded (live) or collapse
24
+ * (the user has moved on).
25
+ */
26
+ isLive?: boolean;
27
+ }
28
+
29
+ export const ToolCallView: React.FC<ToolCallViewProps> = ({
30
+ toolName,
31
+ state,
32
+ result,
33
+ errorText,
34
+ input,
35
+ approval,
36
+ onApprove,
37
+ index,
38
+ className,
39
+ isLive = true,
40
+ }) => {
41
+ switch (state) {
42
+ case "approval-requested":
43
+ // Approval is a live, blocking action — render it as a prominent card
44
+ // Fall back to history row if the wiring isn't
45
+ // available (shouldn't happen in practice).
46
+ if (approval != null && onApprove != null) {
47
+ return (
48
+ <ToolApprovalCard
49
+ toolName={toolName}
50
+ input={input}
51
+ approval={approval}
52
+ onApprove={onApprove}
53
+ className={className}
54
+ />
55
+ );
56
+ }
57
+ return (
58
+ <ToolHistoryRow
59
+ toolName={toolName}
60
+ state="input-available"
61
+ input={input}
62
+ index={index}
63
+ className={className}
64
+ />
65
+ );
66
+
67
+ case "output-error":
68
+ return (
69
+ <ToolErrorCard
70
+ toolName={toolName}
71
+ input={input}
72
+ errorText={errorText}
73
+ isLive={isLive}
74
+ className={className}
75
+ />
76
+ );
77
+
78
+ case "input-streaming":
79
+ case "input-available":
80
+ case "approval-responded":
81
+ case "output-available":
82
+ case "output-denied":
83
+ return (
84
+ <ToolHistoryRow
85
+ toolName={toolName}
86
+ state={state}
87
+ input={input}
88
+ result={result}
89
+ approval={approval}
90
+ index={index}
91
+ className={className}
92
+ />
93
+ );
94
+
95
+ default:
96
+ logNever(state);
97
+ return null;
98
+ }
99
+ };
@@ -0,0 +1,81 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { ChevronDownIcon, XCircleIcon } from "lucide-react";
4
+ import React from "react";
5
+ import { cn } from "@/utils/cn";
6
+ import { formatToolName } from "./shared";
7
+ import { ToolArgsRenderer } from "./tool-args";
8
+
9
+ interface ToolErrorCardProps {
10
+ toolName: string;
11
+ input: unknown;
12
+ errorText?: string;
13
+ // When false, defaults to collapsed (the conversation has moved past this).
14
+ isLive: boolean;
15
+ className?: string;
16
+ }
17
+
18
+ export const ToolErrorCard: React.FC<ToolErrorCardProps> = ({
19
+ toolName,
20
+ input,
21
+ errorText,
22
+ isLive,
23
+ className,
24
+ }) => {
25
+ const [open, setOpen] = React.useState(isLive);
26
+
27
+ // Auto-collapse once when the conversation moves past this turn.
28
+ // The user can still re-open manually afterwards; we only do this on the
29
+ // live → not-live transition, never the reverse.
30
+ const wasLive = React.useRef(isLive);
31
+ React.useEffect(() => {
32
+ if (wasLive.current && !isLive) {
33
+ setOpen(false);
34
+ }
35
+ wasLive.current = isLive;
36
+ }, [isLive]);
37
+
38
+ return (
39
+ <div
40
+ className={cn(
41
+ "rounded-md border border-(--red-6) bg-(--red-2)",
42
+ className,
43
+ )}
44
+ >
45
+ <button
46
+ type="button"
47
+ onClick={() => setOpen((prev) => !prev)}
48
+ className="w-full flex items-center gap-2 px-3 py-2 text-xs text-(--red-11) hover:bg-(--red-3) rounded-md transition-colors"
49
+ aria-expanded={open}
50
+ >
51
+ <XCircleIcon className="h-3.5 w-3.5 shrink-0" />
52
+ <span className="flex-1 text-left">
53
+ <span className="font-semibold">Failed:</span>{" "}
54
+ <code className="font-mono">{formatToolName(toolName)}</code>
55
+ </span>
56
+ <ChevronDownIcon
57
+ className={cn(
58
+ "h-3.5 w-3.5 shrink-0 transition-transform",
59
+ open && "rotate-180",
60
+ )}
61
+ />
62
+ </button>
63
+
64
+ {open && (
65
+ <div className="px-3 pb-3 space-y-3 border-t border-(--red-6)/40 pt-3">
66
+ <ToolArgsRenderer input={input} />
67
+ {errorText && (
68
+ <div>
69
+ <h3 className="text-xs font-semibold text-(--red-11) mb-1">
70
+ Error
71
+ </h3>
72
+ <pre className="bg-(--red-2) border border-(--red-6) rounded p-2 text-xs text-(--red-11) leading-relaxed overflow-auto scrollbar-thin max-h-64 whitespace-pre-wrap">
73
+ {errorText}
74
+ </pre>
75
+ </div>
76
+ )}
77
+ </div>
78
+ )}
79
+ </div>
80
+ );
81
+ };
@@ -0,0 +1,153 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { BanIcon, CheckCircleIcon, Loader2, WrenchIcon } from "lucide-react";
4
+ import React from "react";
5
+ import {
6
+ Accordion,
7
+ AccordionContent,
8
+ AccordionItem,
9
+ AccordionTrigger,
10
+ } from "@/components/ui/accordion";
11
+ import { logNever } from "@/utils/assertNever";
12
+ import { cn } from "@/utils/cn";
13
+ import { formatToolName, type ToolApproval, type ToolState } from "./shared";
14
+ import { ToolArgsRenderer } from "./tool-args";
15
+ import { ResultRenderer } from "./tool-result";
16
+
17
+ // States considered "inert" — they represent past or background work that the
18
+ // user does not need to act on.
19
+ export type HistoryState = Exclude<
20
+ ToolState,
21
+ "approval-requested" | "output-error"
22
+ >;
23
+
24
+ const STATUS_LABEL: Record<HistoryState, string> = {
25
+ "input-streaming": "Generating",
26
+ "input-available": "Running",
27
+ "approval-responded": "Awaiting result",
28
+ "output-available": "Done",
29
+ "output-denied": "Denied",
30
+ };
31
+
32
+ const StatusIcon: React.FC<{ state: HistoryState }> = ({ state }) => {
33
+ switch (state) {
34
+ case "input-streaming":
35
+ case "input-available":
36
+ case "approval-responded":
37
+ return <Loader2 className="h-3 w-3 animate-spin" />;
38
+ case "output-available":
39
+ return <CheckCircleIcon className="h-3 w-3 text-(--grass-11)" />;
40
+ case "output-denied":
41
+ return <BanIcon className="h-3 w-3 text-muted-foreground" />;
42
+ default:
43
+ logNever(state);
44
+ return <WrenchIcon className="h-3 w-3" />;
45
+ }
46
+ };
47
+
48
+ function getTriggerToneClass(state: HistoryState): string {
49
+ switch (state) {
50
+ case "output-available":
51
+ return "text-(--grass-11)/80";
52
+ case "output-denied":
53
+ return "text-muted-foreground";
54
+ case "input-streaming":
55
+ case "input-available":
56
+ case "approval-responded":
57
+ return "";
58
+ default:
59
+ logNever(state);
60
+ return "";
61
+ }
62
+ }
63
+
64
+ interface ToolHistoryRowProps {
65
+ toolName: string;
66
+ state: HistoryState;
67
+ input: unknown;
68
+ result?: unknown;
69
+ approval?: ToolApproval;
70
+ index?: number;
71
+ className?: string;
72
+ }
73
+
74
+ export const ToolHistoryRow: React.FC<ToolHistoryRowProps> = ({
75
+ toolName,
76
+ state,
77
+ input,
78
+ result,
79
+ approval,
80
+ index = 0,
81
+ className,
82
+ }) => {
83
+ return (
84
+ <Accordion
85
+ key={`tool-${index}`}
86
+ type="single"
87
+ collapsible={true}
88
+ className={cn("w-full", className)}
89
+ >
90
+ <AccordionItem value="tool-call" className="border-0">
91
+ <AccordionTrigger
92
+ className={cn(
93
+ "h-6 text-xs border-border shadow-none! ring-0! bg-muted/60 hover:bg-muted py-0 px-2 gap-1 rounded-sm [&[data-state=open]>svg]:rotate-180 hover:no-underline",
94
+ getTriggerToneClass(state),
95
+ )}
96
+ >
97
+ <span className="flex items-center gap-1">
98
+ <StatusIcon state={state} />
99
+ {STATUS_LABEL[state]}:
100
+ <code className="font-mono text-xs">
101
+ {formatToolName(toolName)}
102
+ </code>
103
+ </span>
104
+ </AccordionTrigger>
105
+ <AccordionContent className="py-2 px-2">
106
+ <HistoryContent
107
+ state={state}
108
+ input={input}
109
+ result={result}
110
+ approval={approval}
111
+ />
112
+ </AccordionContent>
113
+ </AccordionItem>
114
+ </Accordion>
115
+ );
116
+ };
117
+
118
+ const HistoryContent: React.FC<{
119
+ state: HistoryState;
120
+ input: unknown;
121
+ result?: unknown;
122
+ approval?: ToolApproval;
123
+ }> = ({ state, input, result, approval }) => {
124
+ switch (state) {
125
+ case "input-streaming":
126
+ case "input-available":
127
+ case "approval-responded":
128
+ return <ToolArgsRenderer input={input} />;
129
+
130
+ case "output-available":
131
+ return (
132
+ <div className="space-y-3">
133
+ <ToolArgsRenderer input={input} />
134
+ {result != null && <ResultRenderer result={result} />}
135
+ </div>
136
+ );
137
+
138
+ case "output-denied":
139
+ return (
140
+ <div className="space-y-3">
141
+ <ToolArgsRenderer input={input} />
142
+ <div className="bg-muted/40 border border-border rounded-md p-3 text-xs text-muted-foreground leading-relaxed">
143
+ Tool execution was denied
144
+ {approval?.reason ? `: ${approval.reason}` : "."}
145
+ </div>
146
+ </div>
147
+ );
148
+
149
+ default:
150
+ logNever(state);
151
+ return null;
152
+ }
153
+ };