@marimo-team/islands 0.15.2 → 0.15.4

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 (211) hide show
  1. package/dist/{ConnectedDataExplorerComponent-C39nQwtD.js → ConnectedDataExplorerComponent-B68gXlbY.js} +323 -328
  2. package/dist/{ImageComparisonComponent-BhkiyswP.js → ImageComparisonComponent-Cw1oA8Tn.js} +13 -13
  3. package/dist/{_baseUniq-DdHL34FO.js → _baseUniq-CQrhBg_9.js} +67 -67
  4. package/dist/any-language-editor-pzUl6lxp.js +27 -0
  5. package/dist/{arc-BXrety1g.js → arc-BOhn-m2C.js} +1 -1
  6. package/dist/{architectureDiagram-KFL7JDKH-BMy6ywCF.js → architectureDiagram-W76B3OCA-DdYf2VnU.js} +144 -144
  7. package/dist/assets/{worker-COGufAQn.js → worker-BcG8m3h5.js} +33 -29
  8. package/dist/asterisk-DS281yxp.js +271 -0
  9. package/dist/{blockDiagram-ZYB65J3Q-DYT2-nlI.js → blockDiagram-QIGZ2CNN-DmmYotkP.js} +10 -10
  10. package/dist/{c4Diagram-AAMF2YG6-ZiQzioe6.js → c4Diagram-FPNF74CW-Dyz4zMHJ.js} +8 -8
  11. package/dist/{channel-CeuXqUAU.js → channel-CCL8jXAe.js} +1 -1
  12. package/dist/{chunk-ANTBXLJU-BvYnIrdq.js → chunk-4BX2VUAB-BfKwWLfJ.js} +1 -1
  13. package/dist/{chunk-WVR4S24B-DXj8yaUk.js → chunk-55IACEB6-CFQU7zSp.js} +1 -1
  14. package/dist/{chunk-GLLZNHP4-CyFsosAe.js → chunk-FMBD7UC4-DDjZzUcl.js} +1 -1
  15. package/dist/{chunk-JBRWN2VN-DA_EEhy2.js → chunk-K7UQS3LO-nBRjBU1H.js} +117 -117
  16. package/dist/{chunk-NRVI72HA-BYx2jMlI.js → chunk-QN33PNHL-B-g8sJzl.js} +1 -1
  17. package/dist/{chunk-FHKO5MBM-DfCztBk8.js → chunk-QZHKN3VN-B7QSJS3J.js} +1 -1
  18. package/dist/{chunk-LXBSTHXV-Se7vdY6J.js → chunk-TVAH2DTR-pGXll4d1.js} +7 -7
  19. package/dist/{chunk-OMD6QJNC-CqgcPMgL.js → chunk-TZMSLE5B-Dx9h-1mv.js} +1 -1
  20. package/dist/{classDiagram-v2-QTMF73CY-B19A3G1l.js → classDiagram-KNZD7YFC-BXryI7DY.js} +2 -2
  21. package/dist/{classDiagram-3BZAVTQC-B19A3G1l.js → classDiagram-v2-RKCZMP56-BXryI7DY.js} +2 -2
  22. package/dist/{clone-78au0tn1.js → clone-DqwV7ges.js} +1 -1
  23. package/dist/cose-bilkent-S5V4N54A-Di6FNMXz.js +2609 -0
  24. package/dist/{cytoscape.esm-BYnVVhJX.js → cytoscape.esm-DfdJODL8.js} +34 -34
  25. package/dist/{dagre-2BBEFEWP-BfEn3ZUV.js → dagre-5GWH7T2D-BTZPMTey.js} +6 -6
  26. package/dist/{data-grid-overlay-editor-CH_qLkV2.js → data-grid-overlay-editor-ryatXXby.js} +11 -11
  27. package/dist/{diagram-4IRLE6MV-CL8xidnG.js → diagram-N5W7TBWH-D79_zdOu.js} +59 -60
  28. package/dist/{diagram-RP2FKANI-B1BPcUew.js → diagram-QEK2KX5R-DX2A_SD0.js} +15 -15
  29. package/dist/{diagram-GUPCWM2R-CZ5cfqlq.js → diagram-S2PKOQOG-DM6VMTrJ.js} +10 -10
  30. package/dist/dockerfile-BoowzQlp.js +194 -0
  31. package/dist/ebnf-DUPDuY4r.js +78 -0
  32. package/dist/{erDiagram-HZWUO2LU-BEAIww50.js → erDiagram-AWTI2OKA-BBirxtlI.js} +8 -8
  33. package/dist/fcl-CPC2WYrI.js +103 -0
  34. package/dist/{flowDiagram-THRYKUMA-Czs2UAI2.js → flowDiagram-PVAE7QVJ-DyVweEMs.js} +9 -9
  35. package/dist/{ganttDiagram-WV7ZQ7D5-ByYIAVFO.js → ganttDiagram-OWAHRB6G-DTB7FX7r.js} +34 -34
  36. package/dist/{gitGraphDiagram-OJR772UL-BcpDsiyB.js → gitGraphDiagram-NY62KEGX-BrbIb5pD.js} +4 -4
  37. package/dist/{glide-data-editor-CmN6FVyi.js → glide-data-editor-DhMX4nmM.js} +33 -33
  38. package/dist/{graph-77W6heli.js → graph-CuLSrclI.js} +3 -3
  39. package/dist/http-D9LttvKF.js +44 -0
  40. package/dist/{index-BOojn38D.js → index-BNgdUQ2e.js} +7711 -7711
  41. package/dist/index-DIy6LHLJ.js +98 -0
  42. package/dist/{index-CmozKMxx.js → index-Df2dsx1t.js} +6 -6
  43. package/dist/{index-pBmAzQJl.js → index-MCx5v1x0.js} +2 -2
  44. package/dist/{index-Bfk9dnyS.js → index-cz_xaKvT.js} +33090 -32892
  45. package/dist/{infoDiagram-6WOFNB3A-CfzLHHVP.js → infoDiagram-STP46IZ2-CCBHc7-K.js} +2 -2
  46. package/dist/{journeyDiagram-FFXJYRFH-ndAcpkGn.js → journeyDiagram-BIP6EPQ6-LhGSj54j.js} +24 -26
  47. package/dist/{kanban-definition-KOZQBZVT-DcQYzNvc.js → kanban-definition-6OIFK2YF-aegTMFS6.js} +14 -14
  48. package/dist/{layout-XySVHJgD.js → layout-BEARWMhl.js} +81 -81
  49. package/dist/{linear-PbooOqg7.js → linear-fbJq6cdO.js} +35 -35
  50. package/dist/{main-B5yML0bw.js → main-HerZgEhd.js} +76533 -69945
  51. package/dist/main.js +1 -1
  52. package/dist/{mermaid-Cg5IX6Nv.js → mermaid-DxPYK0KX.js} +6160 -7493
  53. package/dist/min-DBJkhObB.js +80 -0
  54. package/dist/mindmap-definition-Q6HEUPPD-A3Fh5XDZ.js +785 -0
  55. package/dist/nginx-zDPm3Z74.js +89 -0
  56. package/dist/{number-overlay-editor-DUhfZqtP.js → number-overlay-editor-USMrY6k3.js} +19 -19
  57. package/dist/{pieDiagram-DBDJKBY4-DTOlNsja.js → pieDiagram-ADFJNKIX-Q9uFlCV0.js} +17 -17
  58. package/dist/{quadrantDiagram-YPSRARAO-BX2d8VS-.js → quadrantDiagram-LMRXKWRM-BuPh-qpK.js} +6 -6
  59. package/dist/{react-plotly-Dcyw-3Sa.js → react-plotly-HSqJPRfa.js} +3577 -3577
  60. package/dist/{requirementDiagram-EGVEC5DT-D1T5u-wG.js → requirementDiagram-4UW4RH46-CHROYNU_.js} +7 -7
  61. package/dist/{sankeyDiagram-HRAUVNP4-G6xDfnp-.js → sankeyDiagram-GR3RE2ED-DkUqHP2d.js} +5 -5
  62. package/dist/sequenceDiagram-C3RYC4MD-YoPTMplP.js +2519 -0
  63. package/dist/{slides-component-BJLlPJSr.js → slides-component-D7CHSR00.js} +66 -66
  64. package/dist/solr-BNlsLglM.js +41 -0
  65. package/dist/spreadsheet-C-cy4P5N.js +49 -0
  66. package/dist/{stateDiagram-UUKSUZ4H-CYXbjaom.js → stateDiagram-KXAO66HF-DEN00mVU.js} +5 -5
  67. package/dist/{stateDiagram-v2-EYPG3UTE-Br1HYKT6.js → stateDiagram-v2-UMBNRL4Z-DlQqSUAa.js} +2 -2
  68. package/dist/style.css +1 -1
  69. package/dist/tiddlywiki-5wqsXtSk.js +155 -0
  70. package/dist/tiki-__Kn3CeS.js +181 -0
  71. package/dist/{time-B9SZnSen.js → time-BtVcKqeD.js} +58 -58
  72. package/dist/{timeline-definition-3HZDQTIS-DeK_ZRD0.js → timeline-definition-XQNQX7LJ-DEteLt8D.js} +10 -12
  73. package/dist/{timer-BYwnU4DF.js → timer-B0-z63CM.js} +16 -16
  74. package/dist/{treemap-75Q7IDZK-CKP4vV_0.js → treemap-75Q7IDZK-8S6podme.js} +14 -14
  75. package/dist/{vega-component-CpgdqX2d.js → vega-component-D35L45kI.js} +30 -30
  76. package/dist/{xychartDiagram-FDP5SA34-AMEPsx_R.js → xychartDiagram-6GGTOJPD-DKwGThyy.js} +7 -7
  77. package/package.json +44 -41
  78. package/src/__mocks__/notebook.ts +3 -0
  79. package/src/__mocks__/requests.ts +3 -0
  80. package/src/__tests__/__snapshots__/CellStatus.test.tsx.snap +12 -12
  81. package/src/__tests__/chat-utils.test.ts +26 -211
  82. package/src/components/ai/ai-model-dropdown.tsx +25 -9
  83. package/src/components/ai/ai-provider-icon.tsx +5 -1
  84. package/src/components/app-config/ai-config.tsx +7 -0
  85. package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +304 -0
  86. package/src/components/chat/acp/__tests__/atoms.test.ts +56 -0
  87. package/src/components/chat/acp/__tests__/prompt.test.ts +12 -0
  88. package/src/components/chat/acp/__tests__/state.test.ts +621 -0
  89. package/src/components/chat/acp/agent-docs.tsx +78 -0
  90. package/src/components/chat/acp/agent-panel.css +23 -0
  91. package/src/components/chat/acp/agent-panel.tsx +715 -0
  92. package/src/components/chat/acp/agent-selector.tsx +138 -0
  93. package/src/components/chat/acp/blocks.tsx +664 -0
  94. package/src/components/chat/acp/common.tsx +198 -0
  95. package/src/components/chat/acp/prompt.ts +284 -0
  96. package/src/components/chat/acp/scroll-to-bottom-button.tsx +50 -0
  97. package/src/components/chat/acp/session-tabs.tsx +138 -0
  98. package/src/components/chat/acp/state.ts +263 -0
  99. package/src/components/chat/acp/thread.tsx +121 -0
  100. package/src/components/chat/acp/types.ts +63 -0
  101. package/src/components/chat/acp/utils.ts +45 -0
  102. package/src/components/chat/chat-components.tsx +71 -0
  103. package/src/components/chat/chat-panel.tsx +481 -291
  104. package/src/components/chat/chat-utils.ts +50 -0
  105. package/src/components/chat/markdown-renderer.tsx +3 -7
  106. package/src/components/chat/tool-call-accordion.tsx +6 -6
  107. package/src/components/datasources/__tests__/utils.test.ts +6 -0
  108. package/src/components/datasources/column-preview.tsx +1 -3
  109. package/src/components/editor/actions/useNotebookActions.tsx +1 -1
  110. package/src/components/editor/ai/add-cell-with-ai.tsx +20 -15
  111. package/src/components/editor/ai/ai-completion-editor.tsx +22 -3
  112. package/src/components/editor/ai/completion-handlers.tsx +2 -4
  113. package/src/components/editor/ai/completion-utils.ts +85 -11
  114. package/src/components/editor/alerts/startup-logs-alert.tsx +72 -0
  115. package/src/components/editor/chrome/panels/datasources-panel.tsx +3 -1
  116. package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +3 -1
  117. package/src/components/editor/chrome/panels/documentation-panel.tsx +3 -1
  118. package/src/components/editor/chrome/panels/error-panel.tsx +3 -1
  119. package/src/components/editor/chrome/panels/file-explorer-panel.tsx +3 -1
  120. package/src/components/editor/chrome/panels/logs-panel.tsx +3 -1
  121. package/src/components/editor/chrome/panels/outline-panel.tsx +3 -1
  122. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -2
  123. package/src/components/editor/chrome/panels/scratchpad-panel.tsx +3 -1
  124. package/src/components/editor/chrome/panels/secrets-panel.tsx +3 -1
  125. package/src/components/editor/chrome/panels/snippets-panel.tsx +3 -1
  126. package/src/components/editor/chrome/panels/tracing-panel.tsx +3 -1
  127. package/src/components/editor/chrome/panels/variable-panel.tsx +3 -1
  128. package/src/components/editor/chrome/types.ts +10 -0
  129. package/src/components/editor/chrome/wrapper/app-chrome.tsx +55 -31
  130. package/src/components/editor/controls/command-palette-button.tsx +1 -1
  131. package/src/components/editor/controls/command-palette.tsx +5 -4
  132. package/src/components/editor/controls/state.ts +4 -0
  133. package/src/components/editor/package-alert.tsx +108 -58
  134. package/src/components/editor/renderers/CellArray.tsx +2 -0
  135. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +0 -1
  136. package/src/components/pages/edit-page.tsx +7 -3
  137. package/src/core/ai/chat-utils.ts +26 -43
  138. package/src/core/ai/config.ts +1 -1
  139. package/src/core/ai/context/__tests__/registry.test.ts +277 -3
  140. package/src/core/ai/context/context.ts +11 -1
  141. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +378 -0
  142. package/src/core/ai/context/providers/__tests__/error.test.ts +3 -2
  143. package/src/core/ai/context/providers/__tests__/file.test.ts +119 -0
  144. package/src/core/ai/context/providers/cell-output.ts +349 -0
  145. package/src/core/ai/context/providers/common.ts +5 -1
  146. package/src/core/ai/context/providers/file.ts +287 -0
  147. package/src/core/ai/context/registry.ts +79 -0
  148. package/src/core/ai/state.ts +22 -5
  149. package/src/core/alerts/state.ts +71 -3
  150. package/src/core/cells/cell.ts +2 -2
  151. package/src/core/cells/cells.ts +1 -1
  152. package/src/core/cells/logs.ts +1 -1
  153. package/src/core/cells/runs.ts +6 -5
  154. package/src/core/codemirror/ai/resources.ts +47 -5
  155. package/src/core/codemirror/ai/state.ts +12 -0
  156. package/src/core/codemirror/language/__tests__/sql.test.ts +45 -0
  157. package/src/core/codemirror/markdown/__tests__/commands.test.ts +1 -0
  158. package/src/core/codemirror/theme/dark.ts +1 -1
  159. package/src/core/config/capabilities.ts +1 -1
  160. package/src/core/config/feature-flag.tsx +2 -0
  161. package/src/core/datasets/__tests__/data-source.test.ts +24 -0
  162. package/src/core/errors/__tests__/errors.test.ts +2 -0
  163. package/src/core/islands/bridge.ts +1 -0
  164. package/src/core/islands/main.ts +1 -0
  165. package/src/core/kernel/messages.ts +12 -6
  166. package/src/core/layout/layout.ts +3 -3
  167. package/src/core/network/requests-network.ts +8 -0
  168. package/src/core/network/requests-static.ts +1 -0
  169. package/src/core/network/requests-toasting.ts +1 -0
  170. package/src/core/network/types.ts +4 -1
  171. package/src/core/wasm/bridge.ts +18 -2
  172. package/src/core/wasm/worker/bootstrap.ts +3 -1
  173. package/src/core/wasm/worker/getMarimoWheel.ts +3 -8
  174. package/src/core/wasm/worker/types.ts +3 -0
  175. package/src/core/websocket/useMarimoWebSocket.tsx +7 -1
  176. package/src/css/app/Cell.css +42 -21
  177. package/src/css/app/codemirror.css +5 -1
  178. package/src/css/globals.css +3 -0
  179. package/src/css/md.css +1 -1
  180. package/src/plugins/impl/MicrophonePlugin.tsx +2 -2
  181. package/src/plugins/impl/chat/ChatPlugin.tsx +2 -9
  182. package/src/plugins/impl/chat/chat-ui.tsx +129 -110
  183. package/src/plugins/impl/chat/types.ts +5 -8
  184. package/src/plugins/impl/code/__tests__/language.test.ts +15 -0
  185. package/src/plugins/impl/code/any-language-editor.tsx +11 -8
  186. package/src/plugins/impl/vega/vega.css +121 -0
  187. package/src/plugins/layout/MimeRenderPlugin.tsx +3 -6
  188. package/src/stories/cell.stories.tsx +6 -0
  189. package/src/stories/layout/vertical/one-column.stories.tsx +215 -0
  190. package/src/theme/useTheme.ts +11 -6
  191. package/src/utils/Logger.ts +5 -6
  192. package/src/utils/__tests__/blob.test.ts +37 -0
  193. package/src/utils/arrays.ts +13 -0
  194. package/src/utils/fileToBase64.ts +21 -6
  195. package/src/utils/json/base64.ts +5 -2
  196. package/src/utils/numbers.ts +9 -7
  197. package/dist/any-language-editor-DC5170DQ.js +0 -45
  198. package/dist/asn1-jKiBa2Ya.js +0 -95
  199. package/dist/clojure-CCKyeQKf.js +0 -800
  200. package/dist/css-BkF-NPzE.js +0 -1553
  201. package/dist/index-5ZH_qS8j.js +0 -288
  202. package/dist/index-U4yn89qO.js +0 -341
  203. package/dist/javascript-C2yteZeJ.js +0 -691
  204. package/dist/min-DS5Jz-hg.js +0 -80
  205. package/dist/mindmap-definition-LNHGMQRG-0aOVaMR8.js +0 -3234
  206. package/dist/mllike-BSnXJBGA.js +0 -272
  207. package/dist/pug-CwAQJzGR.js +0 -248
  208. package/dist/python-BkR3uSy8.js +0 -313
  209. package/dist/rpm-IznJm2Xc.js +0 -57
  210. package/dist/sequenceDiagram-WFGC7UMF-DMhHzllb.js +0 -2284
  211. package/dist/ttcn-cfg-Bac_acMi.js +0 -88
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -17,23 +17,23 @@
17
17
  "./unstable_internal/*": "./src/*"
18
18
  },
19
19
  "dependencies": {
20
- "@ai-sdk/react": "^1.2.12",
20
+ "@ai-sdk/react": "^2.0.30",
21
21
  "@anywidget/types": "^0.2.0",
22
- "@codemirror/autocomplete": "^6.18.6",
22
+ "@codemirror/autocomplete": "^6.18.7",
23
23
  "@codemirror/commands": "^6.8.1",
24
24
  "@codemirror/lang-markdown": "^6.3.4",
25
25
  "@codemirror/lang-python": "^6.2.1",
26
26
  "@codemirror/lang-sql": "^6.9.1",
27
- "@codemirror/language": "^6.11.2",
27
+ "@codemirror/language": "^6.11.3",
28
28
  "@codemirror/language-data": "^6.5.1",
29
29
  "@codemirror/legacy-modes": "^6.5.1",
30
30
  "@codemirror/lint": "^6.8.5",
31
31
  "@codemirror/search": "^6.5.11",
32
32
  "@codemirror/state": "^6.5.2",
33
33
  "@codemirror/theme-one-dark": "^6.1.3",
34
- "@codemirror/view": "^6.38.1",
34
+ "@codemirror/view": "^6.38.2",
35
35
  "@dagrejs/dagre": "^1.1.5",
36
- "@date-fns/tz": "^1.2.0",
36
+ "@date-fns/tz": "^1.4.1",
37
37
  "@dnd-kit/core": "^6.3.1",
38
38
  "@dnd-kit/modifiers": "^9.0.0",
39
39
  "@dnd-kit/sortable": "^10.0.0",
@@ -43,20 +43,20 @@
43
43
  "@glideapps/glide-data-grid": "6.0.4-alpha16",
44
44
  "@hookform/resolvers": "^3.10.0",
45
45
  "@img-comparison-slider/react": "^8.0.2",
46
- "@internationalized/date": "^3.8.2",
46
+ "@internationalized/date": "^3.9.0",
47
47
  "@lezer/common": "^1.2.3",
48
48
  "@lezer/highlight": "^1.2.1",
49
49
  "@lezer/lr": "^1.4.2",
50
50
  "@lezer/markdown": "^1.4.3",
51
51
  "@lezer/python": "^1.1.18",
52
52
  "@marimo-team/codemirror-ai": "^0.3.2",
53
- "@marimo-team/codemirror-languageserver": "^1.15.24",
53
+ "@marimo-team/codemirror-languageserver": "1.15.24",
54
54
  "@marimo-team/codemirror-mcp": "^0.1.5",
55
55
  "@marimo-team/codemirror-sql": "^0.2.1",
56
56
  "@marimo-team/llm-info": "workspace:*",
57
57
  "@marimo-team/marimo-api": "workspace:*",
58
58
  "@marimo-team/react-slotz": "^0.2.0",
59
- "@mui/material": "^6.4.12",
59
+ "@mui/material": "^6.5.0",
60
60
  "@open-rpc/client-js": "^1.8.1",
61
61
  "@paralleldrive/cuid2": "^2.2.2",
62
62
  "@radix-ui/colors": "^3.0.0",
@@ -86,7 +86,7 @@
86
86
  "@radix-ui/react-use-callback-ref": "~1.1.1",
87
87
  "@radix-ui/react-use-controllable-state": "~1.2.2",
88
88
  "@replit/codemirror-vim": "^6.3.0",
89
- "@tailwindcss/postcss": "^4.1.11",
89
+ "@tailwindcss/postcss": "^4.1.12",
90
90
  "@tailwindcss/typography": "^0.5.16",
91
91
  "@tanstack/react-table": "^8.21.3",
92
92
  "@textea/json-viewer": "^4.0.1",
@@ -95,47 +95,48 @@
95
95
  "@types/jsdom": "^21.1.7",
96
96
  "@types/react-grid-layout": "^1.3.5",
97
97
  "@uidotdev/usehooks": "^2.4.1",
98
- "@uiw/codemirror-extensions-langs": "^4.24.2",
99
- "@uiw/react-codemirror": "4.23.14",
98
+ "@uiw/codemirror-extensions-langs": "^4.25.1",
99
+ "@uiw/react-codemirror": "4.25.1",
100
100
  "@uwdata/flechette": "^1.1.2",
101
101
  "@valtown/codemirror-codeium": "^1.1.1",
102
102
  "@xterm/addon-attach": "^0.11.0",
103
103
  "@xterm/addon-fit": "^0.10.0",
104
104
  "@xterm/xterm": "^5.5.0",
105
- "ai": "^4.3.16",
105
+ "@zed-industries/agent-client-protocol": "^0.1.2",
106
+ "ai": "^5.0.30",
106
107
  "ansi_up": "^6.0.6",
107
108
  "class-variance-authority": "^0.7.1",
108
109
  "clsx": "^2.1.1",
109
110
  "cmdk": "^1.1.1",
110
111
  "compassql": "^0.21.2",
111
- "cssnano": "^7.0.7",
112
+ "cssnano": "^7.1.1",
112
113
  "date-fns": "^4.1.0",
113
114
  "dequal": "^2.0.3",
114
115
  "eslint-plugin-header": "^3.1.1",
115
116
  "htm": "^3.1.1",
116
- "html-react-parser": "^5.2.5",
117
+ "html-react-parser": "^5.2.6",
117
118
  "html-to-image": "^1.11.13",
118
119
  "humanize-duration": "^3.33.0",
119
120
  "iconify-icon": "^2.3.0",
120
- "jotai": "^2.12.5",
121
- "jotai-scope": "^0.8.3",
121
+ "jotai": "^2.13.1",
122
+ "jotai-scope": "^0.9.3",
122
123
  "js-cookie": "^3.0.5",
123
124
  "katex": "^0.16.22",
124
125
  "lodash-es": "^4.17.21",
125
126
  "loro-codemirror": "^0.2.0",
126
- "loro-crdt": "^1.5.9",
127
- "lucide-react": "^0.525.0",
127
+ "loro-crdt": "^1.6.0",
128
+ "lucide-react": "^0.542.0",
128
129
  "lz-string": "^1.5.0",
129
130
  "marked": "^15.0.12",
130
- "mermaid": "^11.7.0",
131
- "partysocket": "1.1.4",
132
- "path-to-regexp": "^8.2.0",
131
+ "mermaid": "^11.10.1",
132
+ "partysocket": "1.1.5",
133
+ "path-to-regexp": "^8.3.0",
133
134
  "plotly.js": "^2.35.3",
134
135
  "pyodide": "0.27.7",
135
136
  "react-arborist": "^3.4.3",
136
- "react-aria": "^3.42.0",
137
- "react-aria-components": "^1.11.0",
138
- "react-codemirror-merge": "4.23.14",
137
+ "react-aria": "^3.43.1",
138
+ "react-aria-components": "^1.12.1",
139
+ "react-codemirror-merge": "4.25.1",
139
140
  "react-dropzone": "^14.3.8",
140
141
  "react-error-boundary": "^5.0.0",
141
142
  "react-grid-layout": "^1.5.2",
@@ -144,12 +145,13 @@
144
145
  "react-plotly.js": "^2.6.0",
145
146
  "react-resizable-panels": "2.1.9",
146
147
  "react-use-event-hook": "^0.9.6",
147
- "react-vega": "^7.6.0",
148
- "react-virtuoso": "^4.13.0",
148
+ "react-vega": "^7.7.1",
149
+ "react-virtuoso": "^4.14.0",
149
150
  "reactflow": "^11.11.4",
150
- "remark-gfm": "^4.0.0",
151
+ "remark-gfm": "^4.0.1",
151
152
  "rpc-anywhere": "^1.7.0",
152
153
  "sql-formatter": "^15.6.6",
154
+ "streamdown": "^1.2.0",
153
155
  "string-dedent": "^3.0.2",
154
156
  "swiper": "^11.2.10",
155
157
  "tailwind-merge": "^2.6.0",
@@ -157,13 +159,14 @@
157
159
  "thememirror": "^2.0.1",
158
160
  "timestring": "^7.0.0",
159
161
  "typescript-memoize": "^1.1.1",
162
+ "use-acp": "^0.1.5",
160
163
  "use-resize-observer": "^9.1.0",
161
164
  "vega-lite": "^5.23.0",
162
165
  "vega-loader": "^4.5.3",
163
166
  "vscode-jsonrpc": "^8.2.1",
164
167
  "vscode-languageserver-protocol": "^3.17.5",
165
168
  "web-vitals": "^4.2.4",
166
- "zod": "^3.25.67"
169
+ "zod": "^3.25.76"
167
170
  },
168
171
  "scripts": {
169
172
  "preinstall": "npx only-allow pnpm",
@@ -192,11 +195,11 @@
192
195
  },
193
196
  "devDependencies": {
194
197
  "@babel/plugin-proposal-class-properties": "^7.18.6",
195
- "@babel/plugin-proposal-decorators": "^7.27.1",
198
+ "@babel/plugin-proposal-decorators": "^7.28.0",
196
199
  "@babel/preset-typescript": "^7.25.9",
197
- "@biomejs/biome": "2.0.6",
200
+ "@biomejs/biome": "2.2.2",
198
201
  "@codecov/vite-plugin": "^1.9.1",
199
- "@csstools/postcss-light-dark-function": "^2.0.9",
202
+ "@csstools/postcss-light-dark-function": "^2.0.10",
200
203
  "@playwright/test": "^1.55.0",
201
204
  "@storybook/addon-docs": "^9.1.3",
202
205
  "@storybook/addon-links": "^9.1.3",
@@ -206,16 +209,16 @@
206
209
  "@testing-library/react": "^16.3.0",
207
210
  "@types/katex": "^0.16.7",
208
211
  "@types/lodash-es": "^4.17.12",
209
- "@types/node": "^24.0.10",
210
- "@types/react": "^19.1.8",
211
- "@types/react-dom": "^19.1.6",
212
+ "@types/node": "^24.3.0",
213
+ "@types/react": "^19.1.12",
214
+ "@types/react-dom": "^19.1.9",
212
215
  "@types/react-plotly.js": "^2.6.3",
213
216
  "@types/timestring": "^6.0.5",
214
217
  "@typescript-eslint/eslint-plugin": "^7.15.0",
215
218
  "@typescript-eslint/parser": "^7.15.0",
216
219
  "@vitejs/plugin-react": "^4.7.0",
217
220
  "@vitejs/plugin-react-swc": "^3.11.0",
218
- "babel-plugin-react-compiler": "19.1.0-rc.2",
221
+ "babel-plugin-react-compiler": "19.1.0-rc.3",
219
222
  "blob-polyfill": "^7.0.20220408",
220
223
  "cross-env": "^7.0.3",
221
224
  "eslint": "^8.57.0",
@@ -227,15 +230,15 @@
227
230
  "eslint-plugin-unicorn": "^54.0.0",
228
231
  "eslint-plugin-vitest": "^0.4.1",
229
232
  "jsdom": "^24.1.3",
230
- "msw": "^2.10.2",
233
+ "msw": "^2.11.1",
231
234
  "npm-run-all2": "^6.2.6",
232
235
  "postcss": "^8.5.6",
233
236
  "postcss-plugin-namespace": "^0.0.3",
234
- "react": "^19.1.0",
235
- "react-compiler-runtime": "19.1.0-rc.2",
236
- "react-dom": "^19.1.0",
237
+ "react": "^19.1.1",
238
+ "react-compiler-runtime": "19.1.0-rc.3",
239
+ "react-dom": "^19.1.1",
237
240
  "storybook": "^9.1.3",
238
- "stylelint": "^16.21.0",
241
+ "stylelint": "^16.23.1",
239
242
  "stylelint-config-standard": "^36.0.1",
240
243
  "tailwindcss": "^4.1.12",
241
244
  "vite": "^6.3.5",
@@ -104,12 +104,14 @@ export const MockNotebook = {
104
104
  type: "exception",
105
105
  msg,
106
106
  exception_type,
107
+ raising_cell: null,
107
108
  }),
108
109
 
109
110
  strictException: (msg: string, ref: string): MarimoError => ({
110
111
  type: "strict-exception",
111
112
  msg,
112
113
  ref,
114
+ blamed_cell: null,
113
115
  }),
114
116
 
115
117
  interruption: (): MarimoError => ({
@@ -124,6 +126,7 @@ export const MockNotebook = {
124
126
  unknown: (msg: string): MarimoError => ({
125
127
  type: "unknown",
126
128
  msg,
129
+ error_type: null,
127
130
  }),
128
131
  },
129
132
 
@@ -44,6 +44,9 @@ export const MockRequestClient = {
44
44
  getUsageStats: vi.fn().mockResolvedValue({}),
45
45
  sendPdb: vi.fn().mockResolvedValue({}),
46
46
  sendListFiles: vi.fn().mockResolvedValue({ files: [] }),
47
+ sendSearchFiles: vi
48
+ .fn()
49
+ .mockResolvedValue({ files: [], query: "", total_found: 0 }),
47
50
  sendCreateFileOrFolder: vi.fn().mockResolvedValue({}),
48
51
  sendDeleteFileOrFolder: vi.fn().mockResolvedValue({}),
49
52
  sendRenameFileOrFolder: vi.fn().mockResolvedValue({}),
@@ -39,14 +39,14 @@ exports[`CellStatusComponent > renders disabled and stale state 1`] = `
39
39
  width="24"
40
40
  xmlns="http://www.w3.org/2000/svg"
41
41
  >
42
+ <path
43
+ d="M4.929 4.929 19.07 19.071"
44
+ />
42
45
  <circle
43
46
  cx="12"
44
47
  cy="12"
45
48
  r="10"
46
49
  />
47
- <path
48
- d="m4.9 4.9 14.2 14.2"
49
- />
50
50
  </svg>
51
51
  <div
52
52
  class="second-icon absolute bottom-[-2px] right-[-2px] rounded-full"
@@ -104,14 +104,14 @@ exports[`CellStatusComponent > renders disabled state 1`] = `
104
104
  width="24"
105
105
  xmlns="http://www.w3.org/2000/svg"
106
106
  >
107
+ <path
108
+ d="M4.929 4.929 19.07 19.071"
109
+ />
107
110
  <circle
108
111
  cx="12"
109
112
  cy="12"
110
113
  r="10"
111
114
  />
112
- <path
113
- d="m4.9 4.9 14.2 14.2"
114
- />
115
115
  </svg>
116
116
  </div>
117
117
  </div>
@@ -175,14 +175,14 @@ exports[`CellStatusComponent > renders disabled transitively state 1`] = `
175
175
  width="24"
176
176
  xmlns="http://www.w3.org/2000/svg"
177
177
  >
178
+ <path
179
+ d="M4.929 4.929 19.07 19.071"
180
+ />
178
181
  <circle
179
182
  cx="12"
180
183
  cy="12"
181
184
  r="10"
182
185
  />
183
- <path
184
- d="m4.9 4.9 14.2 14.2"
185
- />
186
186
  </svg>
187
187
  </div>
188
188
  </div>
@@ -403,14 +403,14 @@ exports[`CellStatusComponent > renders stale and disabled transitively state 1`]
403
403
  width="24"
404
404
  xmlns="http://www.w3.org/2000/svg"
405
405
  >
406
+ <path
407
+ d="M4.929 4.929 19.07 19.071"
408
+ />
406
409
  <circle
407
410
  cx="12"
408
411
  cy="12"
409
412
  r="10"
410
413
  />
411
- <path
412
- d="m4.9 4.9 14.2 14.2"
413
- />
414
414
  </svg>
415
415
  </div>
416
416
  </div>
@@ -1,22 +1,17 @@
1
1
  /* Copyright 2024 Marimo. All rights reserved. */
2
2
 
3
+ import type { UIMessage } from "ai";
3
4
  import { describe, expect, it } from "vitest";
4
5
  import { Maps } from "@/utils/maps";
5
- import { addMessageToChat } from "../core/ai/chat-utils";
6
+ import { replaceMessagesInChat } from "../core/ai/chat-utils";
6
7
  import type { Chat, ChatId, ChatState } from "../core/ai/state";
7
8
 
8
9
  const CHAT_1 = "chat-1" as ChatId;
9
- const CHAT_2 = "chat-2" as ChatId;
10
-
11
- function first(map: Map<ChatId, Chat>) {
12
- return [...map.values()][0];
13
- }
14
10
 
15
11
  function asMap(list: Iterable<Chat>) {
16
12
  return Maps.keyBy(list, (c) => c.id);
17
13
  }
18
-
19
- describe("addMessageToChat", () => {
14
+ describe("replaceMessagesInChat", () => {
20
15
  const mockChatState: ChatState = {
21
16
  chats: asMap([
22
17
  {
@@ -26,223 +21,43 @@ describe("addMessageToChat", () => {
26
21
  {
27
22
  id: "msg-1",
28
23
  role: "user",
29
- content: "Hello",
30
- timestamp: 1000,
31
- },
32
- {
33
- id: "msg-2",
34
- role: "assistant",
35
- content: "Hi there!",
36
- timestamp: 2000,
24
+ parts: [{ type: "text", text: "Hello" }],
25
+ metadata: { timestamp: 1000 },
37
26
  },
38
27
  ],
39
28
  createdAt: 1000,
40
29
  updatedAt: 2000,
41
30
  },
42
- {
43
- id: CHAT_2,
44
- title: "Test Chat 2",
45
- messages: [
46
- {
47
- id: "msg-3",
48
- role: "user",
49
- content: "How are you?",
50
- timestamp: 3000,
51
- },
52
- ],
53
- createdAt: 3000,
54
- updatedAt: 3000,
55
- },
56
31
  ]),
57
32
  activeChatId: CHAT_1,
58
33
  };
59
34
 
60
- it("should add a new message to an existing chat", () => {
61
- const result = addMessageToChat(
62
- mockChatState,
63
- CHAT_1,
64
- "msg-4",
65
- "user",
66
- "New message",
67
- );
68
-
69
- expect(result.chats).toHaveLength(2);
70
- const updatedChat = result.chats.get(CHAT_1);
71
- expect(updatedChat?.messages).toHaveLength(3);
72
- expect(updatedChat?.messages[2]).toEqual({
73
- id: "msg-4",
74
- role: "user",
75
- content: "New message",
76
- timestamp: expect.any(Number),
35
+ it("replaces messages in a chat", () => {
36
+ const newMessages: UIMessage[] = [
37
+ {
38
+ id: "msg-2",
39
+ role: "assistant",
40
+ parts: [{ type: "text", text: "Hi there!" }],
41
+ metadata: { timestamp: 2000 },
42
+ },
43
+ ];
44
+ const result = replaceMessagesInChat({
45
+ chatState: mockChatState,
46
+ chatId: CHAT_1,
47
+ messages: newMessages,
77
48
  });
78
- expect(updatedChat?.updatedAt).toBeGreaterThan(
79
- first(mockChatState.chats).updatedAt,
49
+ expect(result.chats.get(CHAT_1)?.messages).toEqual(newMessages);
50
+ expect(result.chats.get(CHAT_1)?.updatedAt).toBeGreaterThan(
51
+ mockChatState.chats.get(CHAT_1)?.updatedAt ?? 0,
80
52
  );
81
53
  });
82
54
 
83
- it("should update an existing message", () => {
84
- const result = addMessageToChat(
85
- mockChatState,
86
- CHAT_1,
87
- "msg-1",
88
- "user",
89
- "Updated content",
90
- );
91
-
92
- expect(result.chats).toHaveLength(2);
93
- const updatedChat = result.chats.get(CHAT_1);
94
- expect(updatedChat?.messages).toHaveLength(2);
95
- expect(updatedChat?.messages[0]).toEqual({
96
- id: "msg-1",
97
- role: "user",
98
- content: "Updated content",
99
- timestamp: 1000,
55
+ it("returns unchanged state if chatId is null", () => {
56
+ const result = replaceMessagesInChat({
57
+ chatState: mockChatState,
58
+ chatId: null,
59
+ messages: [],
100
60
  });
101
- expect(updatedChat?.updatedAt).toBeGreaterThan(
102
- first(mockChatState.chats).updatedAt,
103
- );
104
- });
105
-
106
- it("should handle message parts", () => {
107
- const parts = [{ type: "text" as const, text: "Part content" }];
108
- const result = addMessageToChat(
109
- mockChatState,
110
- CHAT_1,
111
- "msg-5",
112
- "assistant",
113
- "Message with parts",
114
- parts,
115
- );
116
-
117
- const updatedChat = result.chats.get(CHAT_1);
118
- expect(updatedChat?.messages[2].parts).toEqual(parts);
119
- });
120
-
121
- it("should update message parts", () => {
122
- const originalParts = [{ type: "text" as const, text: "Original" }];
123
- const updatedParts = [{ type: "text" as const, text: "Updated" }];
124
- const chats = [...mockChatState.chats.values()];
125
-
126
- const stateWithParts: ChatState = {
127
- ...mockChatState,
128
- chats: asMap([
129
- {
130
- ...chats[0],
131
- messages: [
132
- {
133
- ...chats[0].messages[0],
134
- parts: originalParts,
135
- },
136
- chats[0].messages[1],
137
- ],
138
- },
139
- chats[1],
140
- ]),
141
- };
142
-
143
- const result = addMessageToChat(
144
- stateWithParts,
145
- CHAT_1,
146
- "msg-1",
147
- "user",
148
- "Updated content",
149
- updatedParts,
150
- );
151
-
152
- const updatedChat = result.chats.get(CHAT_1);
153
- expect(updatedChat?.messages[0].parts).toEqual(updatedParts);
154
- });
155
-
156
- it("should return unchanged state when chatId is null", () => {
157
- const result = addMessageToChat(
158
- mockChatState,
159
- null,
160
- "msg-4",
161
- "user",
162
- "New message",
163
- );
164
-
165
- expect(result).toEqual(mockChatState);
166
- });
167
-
168
- it("should return unchanged state when chatId does not exist", () => {
169
- const result = addMessageToChat(
170
- mockChatState,
171
- "non-existent-chat" as ChatId,
172
- "msg-4",
173
- "user",
174
- "New message",
175
- );
176
-
177
61
  expect(result).toEqual(mockChatState);
178
62
  });
179
-
180
- it("should not modify other chats when updating a specific chat", () => {
181
- const result = addMessageToChat(
182
- mockChatState,
183
- CHAT_1,
184
- "msg-4",
185
- "user",
186
- "New message",
187
- );
188
-
189
- const unchangedChat = result.chats.get(CHAT_2);
190
- expect(unchangedChat).toEqual([...mockChatState.chats.values()][1]);
191
- });
192
-
193
- it("should preserve message order when adding new messages", () => {
194
- const result = addMessageToChat(
195
- mockChatState,
196
- CHAT_1,
197
- "msg-4",
198
- "user",
199
- "New message",
200
- );
201
-
202
- const updatedChat = result.chats.get(CHAT_1);
203
- expect(updatedChat?.messages[0].id).toBe("msg-1");
204
- expect(updatedChat?.messages[1].id).toBe("msg-2");
205
- expect(updatedChat?.messages[2].id).toBe("msg-4");
206
- });
207
-
208
- it("should handle empty chat messages array", () => {
209
- const chatId = "empty-chat" as ChatId;
210
- const emptyChatState: ChatState = {
211
- chats: asMap([
212
- {
213
- id: chatId,
214
- title: "Empty Chat",
215
- messages: [],
216
- createdAt: 1000,
217
- updatedAt: 1000,
218
- },
219
- ]),
220
- activeChatId: chatId,
221
- };
222
-
223
- const result = addMessageToChat(
224
- emptyChatState,
225
- chatId,
226
- "msg-1",
227
- "user",
228
- "First message",
229
- );
230
-
231
- const updatedChat = result.chats.get(chatId);
232
- expect(updatedChat?.messages).toHaveLength(1);
233
- expect(updatedChat?.messages[0].content).toBe("First message");
234
- });
235
-
236
- it("should handle different message roles", () => {
237
- const result = addMessageToChat(
238
- mockChatState,
239
- CHAT_1,
240
- "msg-4",
241
- "assistant",
242
- "Assistant response",
243
- );
244
-
245
- const updatedChat = result.chats.get(CHAT_1);
246
- expect(updatedChat?.messages[2].role).toBe("assistant");
247
- });
248
63
  });
@@ -10,6 +10,7 @@ import {
10
10
  CircleHelpIcon,
11
11
  } from "lucide-react";
12
12
  import React from "react";
13
+ import { type SupportedRole, useModelChange } from "@/core/ai/config";
13
14
  import {
14
15
  AiModelId,
15
16
  isKnownAIProvider,
@@ -36,12 +37,13 @@ import { getCurrentRoleTooltip, getTagColour } from "./display-helpers";
36
37
  interface AIModelDropdownProps {
37
38
  value?: string;
38
39
  placeholder?: string;
39
- onSelect: (modelId: QualifiedModelId) => void;
40
+ onSelect?: (modelId: QualifiedModelId) => void;
40
41
  triggerClassName?: string;
41
42
  customDropdownContent?: React.ReactNode;
42
43
  iconSize?: "medium" | "small";
43
44
  showAddCustomModelDocs?: boolean;
44
- forRole?: Role;
45
+ displayIconOnly?: boolean;
46
+ forRole: SupportedRole;
45
47
  }
46
48
 
47
49
  export const AIModelDropdown = ({
@@ -53,12 +55,13 @@ export const AIModelDropdown = ({
53
55
  iconSize = "medium",
54
56
  showAddCustomModelDocs = false,
55
57
  forRole,
58
+ displayIconOnly = false,
56
59
  }: AIModelDropdownProps) => {
57
- const currentValue = value ? AiModelId.parse(value) : undefined;
58
60
  const [isOpen, setIsOpen] = React.useState(false);
59
61
 
60
62
  const ai = useAtomValue(aiAtom);
61
63
  const completion = useAtomValue(completionAtom);
64
+ const { saveModelChange } = useModelChange();
62
65
 
63
66
  // Only include autocompleteModel if copilot is set to "custom"
64
67
  const autocompleteModel =
@@ -88,6 +91,13 @@ export const AIModelDropdown = ({
88
91
  ? ai?.models?.edit_model
89
92
  : undefined;
90
93
 
94
+ // If value is provided, use it, otherwise use the active model
95
+ const currentValue = value
96
+ ? AiModelId.parse(value)
97
+ : activeModel
98
+ ? AiModelId.parse(activeModel)
99
+ : undefined;
100
+
91
101
  const iconSizeClass = iconSize === "medium" ? "h-4 w-4" : "h-3 w-3";
92
102
 
93
103
  const renderModelWithRole = (modelId: AiModelId, role: Role) => {
@@ -119,7 +129,11 @@ export const AIModelDropdown = ({
119
129
  };
120
130
 
121
131
  const handleSelect = (modelId: QualifiedModelId) => {
122
- onSelect(modelId);
132
+ if (onSelect) {
133
+ onSelect(modelId);
134
+ } else {
135
+ saveModelChange(modelId, forRole);
136
+ }
123
137
  setIsOpen(false);
124
138
  };
125
139
 
@@ -136,11 +150,13 @@ export const AIModelDropdown = ({
136
150
  provider={currentValue.providerId}
137
151
  className={iconSizeClass}
138
152
  />
139
- <span className="truncate">
140
- {isKnownAIProvider(currentValue.providerId)
141
- ? currentValue.shortModelId
142
- : currentValue.id}
143
- </span>
153
+ {displayIconOnly ? null : (
154
+ <span className="truncate">
155
+ {isKnownAIProvider(currentValue.providerId)
156
+ ? currentValue.shortModelId
157
+ : currentValue.id}
158
+ </span>
159
+ )}
144
160
  </>
145
161
  ) : (
146
162
  <span className="text-muted-foreground truncate">