@marimo-team/islands 0.25.1-dev3 → 0.25.1-dev31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedDataExplorerComponent-KVhjDMSe.js → ConnectedDataExplorerComponent-CwMXfDQR.js} +3 -3
- package/dist/{ErrorBoundary-Darui-8r.js → ErrorBoundary-C1YoBc7T.js} +1 -1
- package/dist/{ImageComparisonComponent-Dlm5aWnH.js → ImageComparisonComponent-Cpfz30OZ.js} +51 -52
- package/dist/{abnfDiagram-VCTEODGH-CpN0FRda.js → abnfDiagram-VCTEODGH-AFhOQTt8.js} +3 -3
- package/dist/{architectureDiagram-5GKGNRK7-DDyj5SRB.js → architectureDiagram-5GKGNRK7-BngksAAQ.js} +5 -5
- package/dist/{blockDiagram-I7D4REHJ-BbXEXJRu.js → blockDiagram-I7D4REHJ-CvBmppdy.js} +9 -9
- package/dist/{c4Diagram-7LVT6UL2-DcLsbQmR.js → c4Diagram-7LVT6UL2-EceL4_jH.js} +7 -7
- package/dist/{cells-B5-y5EY3.js → cells-Cksce8br.js} +2 -2
- package/dist/{channel-B5XnTarr.js → channel-z7HZXHwv.js} +1 -1
- package/dist/{chat-ui-HJZsTl7o.js → chat-ui-ruucqBTA.js} +4 -4
- package/dist/{chunk-4HAMMTFA-D2qv8E0X.js → chunk-4HAMMTFA-BPTTOOC5.js} +5 -5
- package/dist/{chunk-75Z2AOVW-5_HsvXwr.js → chunk-75Z2AOVW-C4AOleKf.js} +1 -1
- package/dist/{chunk-DU6HZSFF-BUgAHvnM.js → chunk-DU6HZSFF-1TwWR6gh.js} +1 -1
- package/dist/{chunk-F27PBJKO-DHmYWZXr.js → chunk-F27PBJKO-DMI1PBe4.js} +1 -1
- package/dist/{chunk-GMAD6QVW-Czynz8aA.js → chunk-GMAD6QVW-vStrMz2P.js} +3 -3
- package/dist/{chunk-GVQU2GXP-yQEdulRS.js → chunk-GVQU2GXP-2HwWgs4u.js} +2 -2
- package/dist/{chunk-IMKFNOWR-BfwTebD0.js → chunk-IMKFNOWR-UOVZuZVn.js} +5 -5
- package/dist/{chunk-L3NEJ4N5-DwRWnDDK.js → chunk-L3NEJ4N5-RhC7i0I2.js} +5 -5
- package/dist/{chunk-OSK3NFVY-BBKU_Ign.js → chunk-OSK3NFVY-CZV09N-U.js} +6 -6
- package/dist/{chunk-P2QGCYS3-C0iGU29N.js → chunk-P2QGCYS3-0TAWai9C.js} +1 -1
- package/dist/{chunk-POPQ4Y6H-BCbS3Ozc.js → chunk-POPQ4Y6H-Cc3_56GX.js} +1 -1
- package/dist/{chunk-PWAF6VOD-CTFCL0jI.js → chunk-PWAF6VOD-lNxB9k8z.js} +1 -1
- package/dist/{chunk-SHT3W25Y-BspJEJ5H.js → chunk-SHT3W25Y-CrEPyWy1.js} +7 -7
- package/dist/{chunk-SVP7TREG-DX3rFNTe.js → chunk-SVP7TREG-uIyyySp6.js} +2 -2
- package/dist/{chunk-TICWLB2K-fVF7Uujg.js → chunk-TICWLB2K-DdXM3eg6.js} +5 -5
- package/dist/classDiagram-ZZMXUADV-BiATbBE4.js +30 -0
- package/dist/classDiagram-v2-VYDZK3BY-JnH97GYw.js +30 -0
- package/dist/{code-visibility-XNQy26fz.js → code-visibility-DsnycPAk.js} +2 -2
- package/dist/{common-Dv0F_kZT.js → common-CECP1OPr.js} +13 -13
- package/dist/{cynefinDiagram-5FMLGOSQ-CFQrqzSX.js → cynefinDiagram-5FMLGOSQ-zknaAsGy.js} +3 -3
- package/dist/{dagre-GXQ25YYZ-xHNAUTyG.js → dagre-GXQ25YYZ-BhMOoMGJ.js} +10 -10
- package/dist/{data-grid-overlay-editor-DWIhnG5k.js → data-grid-overlay-editor-DUdHcA0T.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-Bt1rPbAx.js → diagram-S7CK7UJ4-V5-Z-EDY.js} +4 -4
- package/dist/{diagram-UQ7AKVKN-D1sq5FoZ.js → diagram-UQ7AKVKN-qw8AjDal.js} +3 -3
- package/dist/{diagram-VSXAHHWV-BKpmG23x.js → diagram-VSXAHHWV-CR7BJygZ.js} +2 -2
- package/dist/{diagram-VX7I27RA-BMwGFVD6.js → diagram-VX7I27RA-DfuqFb1E.js} +5 -5
- package/dist/{diagram-Z3DM3KII--KLDR9Pl.js → diagram-Z3DM3KII-DpWwlYZB.js} +3 -3
- package/dist/{dist-BaHjhkpZ.js → dist-CcyKTBTF.js} +1 -1
- package/dist/{ebnfDiagram-PWID7BFC-WnG4cvSQ.js → ebnfDiagram-PWID7BFC-C20OnNMZ.js} +3 -3
- package/dist/{erDiagram-RLTQ6QDP-DhzKiYHc.js → erDiagram-RLTQ6QDP-DBXLWO9v.js} +12 -12
- package/dist/{error-entries-Bkbpx0T0.js → error-entries-CvCFdpY2.js} +1 -1
- package/dist/{feedback-button-CxEesO_y.js → feedback-button-C2nIVez1.js} +4 -4
- package/dist/flowDiagram-HODETNUW-DL52nMkt.js +16 -0
- package/dist/{formats-C8rLgZT9.js → formats-Cl_67ghI.js} +1 -1
- package/dist/{ganttDiagram-EL5Y4UJY-DbzEBLbl.js → ganttDiagram-EL5Y4UJY-cRRaDt88.js} +2 -2
- package/dist/{gitGraphDiagram-WWUBYQGX-BMf0iKi1.js → gitGraphDiagram-WWUBYQGX-Pox5k9-Y.js} +2 -2
- package/dist/{glide-data-editor-BlF9ryAS.js → glide-data-editor-BFA_zCBA.js} +3 -3
- package/dist/{globals-BJZNFyuG.js → globals-Coud3OTE.js} +1 -1
- package/dist/{html-to-image-BAgJOlSW.js → html-to-image-CcfkLMrx.js} +2 -2
- package/dist/{infoDiagram-27XIBGKW-BagtCX_5.js → infoDiagram-27XIBGKW-ntpxMfrq.js} +2 -2
- package/dist/{ishikawaDiagram-5VMMS53U-DByDehYy.js → ishikawaDiagram-5VMMS53U-BllIlHE5.js} +3 -3
- package/dist/{journeyDiagram-3NMN7TZE-D2LcKDUO.js → journeyDiagram-3NMN7TZE-EPJDPlt0.js} +2 -2
- package/dist/{kanban-definition-UXKFOSKX-BxwkbBI_.js → kanban-definition-UXKFOSKX-GYtNMjtS.js} +9 -9
- package/dist/{katex-C6D4cX_N.js → katex-BNCmKUol.js} +983 -1120
- package/dist/{loader-D2W4oM-3.js → loader-DEZSzvma.js} +253 -248
- package/dist/main.js +57 -55
- package/dist/{mermaid-DPNuhemn.js → mermaid-Dnzoxjt1.js} +49 -49
- package/dist/{mhchem-DWCF06w9.js → mhchem-BEc7A1or.js} +1 -1
- package/dist/{mindmap-definition-YA3MSWOX-Cgvojw3y.js → mindmap-definition-YA3MSWOX-Cth76xgH.js} +11 -11
- package/dist/{number-overlay-editor-B2xhX-SU.js → number-overlay-editor-BqXXyn5W.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-DahHhYyN.js → pegDiagram-XKGWAZYB-Cu4uOXii.js} +3 -3
- package/dist/{pieDiagram-E7YTZNPT-CCtX0oCK.js → pieDiagram-E7YTZNPT-Bh3eDa9s.js} +3 -3
- package/dist/{process-output-zDX4jbhd.js → process-output-C6apL85F.js} +2 -2
- package/dist/{quadrantDiagram-AXDQQJYC-DftINo6g.js → quadrantDiagram-AXDQQJYC--kqzFC3w.js} +1 -1
- package/dist/{railroadDiagram-O6MQD6OU-Du5NsPUb.js → railroadDiagram-O6MQD6OU-DG-M6Rnc.js} +3 -3
- package/dist/{react-vega-5AcMW8gG.js → react-vega-ewj7q_U5.js} +1 -1
- package/dist/{requirementDiagram-BXWQKSXE-0pmmxL6_.js → requirementDiagram-BXWQKSXE-DCwsThh0.js} +11 -11
- package/dist/{reveal-component-eMtW_LdF.js → reveal-component-_6L78d9I.js} +3 -3
- package/dist/{sankeyDiagram-P5KCCOFB-CDKR5TJH.js → sankeyDiagram-P5KCCOFB-BdzhT0BM.js} +1 -1
- package/dist/{sequenceDiagram-WJ2MYXX4-DB-ChWwU.js → sequenceDiagram-WJ2MYXX4-CbXB1_PU.js} +4 -4
- package/dist/{stateDiagram-D77RDMKH-orN6AwMx.js → stateDiagram-D77RDMKH-A-Zf3Sb2.js} +13 -13
- package/dist/stateDiagram-v2-MP3YSRHH-D9YMnUGx.js +30 -0
- package/dist/style.css +1 -1
- package/dist/{swimlanes-42K2YHIH-BkSDcqDT.js → swimlanes-42K2YHIH-B_pMf0J4.js} +10 -10
- package/dist/swimlanesDiagram-VR7AAH4N-Ctgy-yGP.js +30 -0
- package/dist/{timeline-definition-24CTP7MA-BuqJUIRZ.js → timeline-definition-24CTP7MA-DTXFjTTM.js} +3 -3
- package/dist/{vega-component-CNf5gcrm.js → vega-component-tFOzgarw.js} +4 -4
- package/dist/{vega-embed-container-CbnTccZi.js → vega-embed-container-sSR5hAsy.js} +2 -2
- package/dist/{vega-loader.browser-D95WfUcj.js → vega-loader.browser-DNST6uVf.js} +2 -2
- package/dist/{vennDiagram-4TSXK5OY-CTUlJ2PK.js → vennDiagram-4TSXK5OY-BPHjZo0R.js} +3 -3
- package/dist/{wardleyDiagram-VM6X3IG4-3evLUb0M.js → wardleyDiagram-VM6X3IG4-6fTLYBuD.js} +3 -3
- package/dist/{xychartDiagram-S5SC5T6Z-DL2E3K8-.js → xychartDiagram-S5SC5T6Z-BYjwjrzE.js} +5 -5
- package/package.json +1 -2
- package/src/__mocks__/common.ts +3 -3
- package/src/__tests__/CellStatus.test.tsx +1 -1
- package/src/__tests__/setup.ts +7 -7
- package/src/components/app-config/ai-config.tsx +2 -0
- package/src/components/app-config/optional-features.tsx +1 -1
- package/src/components/chat/chat-panel.tsx +19 -8
- package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +286 -0
- package/src/components/data-table/charts/charts.tsx +26 -13
- package/src/components/data-table/column-summary/chart-spec-model.tsx +4 -4
- package/src/components/dependency-graph/elements.ts +2 -2
- package/src/components/editor/__tests__/package-alert.test.tsx +140 -0
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +107 -0
- package/src/components/editor/actions/pair-with-agent.tsx +119 -0
- package/src/components/editor/actions/useNotebookActions.tsx +2 -1
- package/src/components/editor/ai/add-cell-with-ai.tsx +2 -0
- package/src/components/editor/ai/staged-cell-submission.ts +2 -2
- package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
- package/src/components/editor/chrome/components/contribute-snippet-button.tsx +6 -1
- package/src/components/editor/connections/database/as-code.ts +44 -44
- package/src/components/editor/connections/storage/as-code.ts +3 -3
- package/src/components/editor/file-tree/requesting-tree.tsx +16 -13
- package/src/components/editor/navigation/clipboard.ts +2 -2
- package/src/components/editor/notebook-cell.tsx +2 -2
- package/src/components/editor/output/MarimoTracebackOutput.tsx +1 -1
- package/src/components/editor/output/VideoOutput.tsx +1 -1
- package/src/components/editor/output/ansi-reduce.ts +21 -17
- package/src/components/editor/output/console/text-rendering.tsx +3 -1
- package/src/components/editor/package-alert.tsx +20 -7
- package/src/components/home/components.tsx +1 -0
- package/src/components/pages/run-page.tsx +1 -0
- package/src/components/slides/__tests__/minimap-actions.test.tsx +7 -7
- package/src/components/slides/__tests__/minimap.test.ts +12 -12
- package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +8 -8
- package/src/components/static-html/share-modal.tsx +2 -1
- package/src/components/static-html/static-banner.tsx +2 -2
- package/src/components/ui/links.tsx +6 -1
- package/src/components/ui/typography.tsx +16 -8
- package/src/core/ai/context/__tests__/registry.test.ts +31 -28
- package/src/core/ai/context/providers/cell-output.ts +8 -8
- package/src/core/ai/context/providers/datasource.ts +10 -7
- package/src/core/ai/context/providers/error.ts +7 -7
- package/src/core/ai/context/providers/file.ts +8 -8
- package/src/core/ai/context/providers/tables.ts +7 -7
- package/src/core/ai/context/providers/variable.ts +7 -7
- package/src/core/ai/context/registry.ts +18 -18
- package/src/core/ai/ids/ids.ts +5 -5
- package/src/core/ai/model-registry.ts +12 -9
- package/src/core/ai/staged-cells.ts +6 -6
- package/src/core/ai/tools/base.ts +6 -6
- package/src/core/ai/tools/edit-notebook-tool.ts +6 -6
- package/src/core/ai/tools/registry.ts +4 -4
- package/src/core/ai/tools/run-cells-tool.ts +7 -7
- package/src/core/ai/tools/sample-tool.ts +6 -6
- package/src/core/codemirror/cells/debugger-decorations.ts +13 -7
- package/src/core/codemirror/cells/line-timing-decorations.ts +9 -9
- package/src/core/codemirror/cells/traceback-decorations.ts +7 -4
- package/src/core/codemirror/code-lens/extension.ts +13 -13
- package/src/core/codemirror/copilot/__tests__/language-server.test.ts +6 -6
- package/src/core/codemirror/copilot/__tests__/transport.test.ts +12 -12
- package/src/core/codemirror/copilot/language-server.ts +13 -13
- package/src/core/codemirror/copilot/transport.ts +1 -1
- package/src/core/codemirror/find-replace/search-highlight.ts +5 -5
- package/src/core/codemirror/go-to-definition/underline.ts +3 -3
- package/src/core/codemirror/keymaps/vim.ts +3 -3
- package/src/core/codemirror/language/languages/markdown.ts +8 -8
- package/src/core/codemirror/language/languages/python.ts +7 -7
- package/src/core/codemirror/language/languages/sql/completion-builder.ts +5 -5
- package/src/core/codemirror/language/languages/sql/completion-store.ts +4 -4
- package/src/core/codemirror/language/languages/sql/sql.ts +21 -21
- package/src/core/codemirror/lsp/__tests__/transports.test.ts +10 -10
- package/src/core/codemirror/lsp/federated-lsp.ts +29 -27
- package/src/core/codemirror/lsp/notebook-lsp.ts +21 -21
- package/src/core/codemirror/misc/__tests__/dnd.test.ts +10 -10
- package/src/core/codemirror/misc/__tests__/paste.test.ts +7 -4
- package/src/core/codemirror/reactive-references/extension.ts +3 -3
- package/src/core/codemirror/rtc/loro/awareness.ts +12 -12
- package/src/core/codemirror/rtc/loro/sync.ts +5 -5
- package/src/core/codemirror/vim/cursor-visibility.ts +3 -3
- package/src/core/dom/ui-element.ts +5 -5
- package/src/core/dom/uiregistry.ts +10 -10
- package/src/core/hotkeys/hotkeys.ts +9 -9
- package/src/core/islands/__tests__/bridge.test.ts +4 -4
- package/src/core/islands/__tests__/test-utils.tsx +4 -4
- package/src/core/islands/bridge.ts +85 -82
- package/src/core/islands/components/web-components.tsx +7 -7
- package/src/core/islands/worker/__tests__/controller.test.ts +1 -1
- package/src/core/islands/worker/controller.ts +6 -3
- package/src/core/islands/worker-factory.ts +2 -2
- package/src/core/kernel/RuntimeState.ts +4 -4
- package/src/core/lsp/__tests__/transport.test.ts +19 -19
- package/src/core/lsp/transport.ts +5 -5
- package/src/core/network/CachingRequestRegistry.ts +2 -2
- package/src/core/network/DeferredRequestRegistry.ts +4 -4
- package/src/core/runtime/runtime.ts +25 -20
- package/src/core/static/virtual-file-tracker.ts +5 -5
- package/src/core/wasm/__tests__/bridge.test.ts +2 -2
- package/src/core/wasm/bridge.ts +130 -126
- package/src/core/wasm/router.ts +5 -5
- package/src/core/wasm/store.ts +4 -4
- package/src/core/wasm/worker/bootstrap.ts +8 -5
- package/src/core/wasm/worker/message-buffer.ts +3 -3
- package/src/core/websocket/transports/__tests__/ws.test.ts +8 -8
- package/src/core/websocket/transports/basic.ts +15 -8
- package/src/core/websocket/transports/sse.ts +7 -7
- package/src/core/websocket/transports/transport.ts +3 -3
- package/src/core/websocket/transports/ws.ts +9 -7
- package/src/css/globals.css +18 -21
- package/src/css/katex.min.css +260 -241
- package/src/hooks/__tests__/useOverflowDetection.test.tsx +5 -5
- package/src/hooks/__tests__/useResizeObserver.test.tsx +12 -12
- package/src/plugins/core/registerReactComponent.tsx +5 -5
- package/src/plugins/core/sidebar-element.tsx +2 -2
- package/src/plugins/impl/ButtonPlugin.tsx +3 -3
- package/src/plugins/impl/CheckboxPlugin.tsx +3 -3
- package/src/plugins/impl/CodeEditorPlugin.tsx +3 -3
- package/src/plugins/impl/DatePickerPlugin.tsx +3 -3
- package/src/plugins/impl/DateRangePlugin.tsx +3 -3
- package/src/plugins/impl/DateTimePickerPlugin.tsx +3 -3
- package/src/plugins/impl/DictPlugin.tsx +3 -3
- package/src/plugins/impl/DropdownPlugin.tsx +3 -3
- package/src/plugins/impl/FileUploadPlugin.tsx +3 -3
- package/src/plugins/impl/MatrixPlugin.tsx +4 -4
- package/src/plugins/impl/MicrophonePlugin.tsx +3 -3
- package/src/plugins/impl/MultiselectPlugin.tsx +3 -3
- package/src/plugins/impl/NumberPlugin.tsx +3 -3
- package/src/plugins/impl/RadioPlugin.tsx +3 -3
- package/src/plugins/impl/RangeSliderPlugin.tsx +3 -3
- package/src/plugins/impl/RefreshPlugin.tsx +3 -3
- package/src/plugins/impl/SliderPlugin.tsx +3 -3
- package/src/plugins/impl/SwitchPlugin.tsx +3 -3
- package/src/plugins/impl/TabsPlugin.tsx +3 -3
- package/src/plugins/impl/TextAreaPlugin.tsx +3 -3
- package/src/plugins/impl/TextInputPlugin.tsx +3 -3
- package/src/plugins/impl/__tests__/MatrixPlugin.test.tsx +2 -2
- package/src/plugins/impl/anywidget/model.ts +10 -10
- package/src/plugins/impl/anywidget/registry.ts +12 -9
- package/src/plugins/impl/anywidget/runtime.ts +11 -9
- package/src/plugins/impl/anywidget/widget-binding.ts +6 -6
- package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +7 -6
- package/src/plugins/impl/matplotlib/MatplotlibPlugin.tsx +3 -3
- package/src/plugins/impl/matplotlib/__tests__/matplotlib-renderer.test.ts +2 -2
- package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +2 -2
- package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +10 -10
- package/src/plugins/impl/panel/utils.ts +5 -5
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
- package/src/plugins/impl/vega/VegaPlugin.tsx +3 -3
- package/src/plugins/impl/vega/__tests__/use-vega-container-remeasure.test.ts +7 -7
- package/src/plugins/impl/vega/__tests__/utils.test.ts +16 -1
- package/src/plugins/impl/vega/__tests__/vega.test.ts +37 -0
- package/src/plugins/impl/vega/loader.ts +23 -1
- package/src/plugins/impl/vega/utils.ts +5 -4
- package/src/plugins/layout/AccordionPlugin.tsx +3 -3
- package/src/plugins/layout/CalloutPlugin.tsx +3 -3
- package/src/plugins/layout/ImageComparisonPlugin.tsx +5 -3
- package/src/plugins/layout/JsonOutputPlugin.tsx +3 -3
- package/src/plugins/layout/MimeRenderPlugin.tsx +3 -3
- package/src/plugins/layout/NavigationMenuPlugin.tsx +3 -3
- package/src/plugins/layout/OutlinePlugin.tsx +3 -3
- package/src/plugins/layout/ProgressPlugin.tsx +3 -3
- package/src/plugins/layout/RoutesPlugin.tsx +6 -8
- package/src/plugins/layout/StatPlugin.tsx +3 -3
- package/src/plugins/layout/TexPlugin.tsx +3 -3
- package/src/plugins/layout/carousel/CarouselPlugin.tsx +4 -4
- package/src/plugins/layout/mermaid/MermaidPlugin.tsx +3 -3
- package/src/utils/Deferred.ts +6 -6
- package/src/utils/async-capture-tracker.ts +10 -7
- package/src/utils/errors.ts +5 -5
- package/src/utils/id-tree.tsx +83 -80
- package/src/utils/lru.ts +1 -1
- package/src/utils/multi-map.ts +14 -12
- package/src/utils/paths.ts +6 -6
- package/src/utils/pluralize.ts +3 -3
- package/src/utils/progress.ts +6 -6
- package/src/utils/python-poet/poet.ts +14 -14
- package/src/utils/routes.ts +4 -2
- package/src/utils/semaphore.ts +6 -6
- package/src/utils/storage/storage.ts +6 -6
- package/src/utils/storage/typed.ts +16 -12
- package/src/utils/time.ts +9 -9
- package/src/utils/timed-cache.ts +4 -4
- package/src/utils/tracer.ts +9 -6
- package/dist/classDiagram-ZZMXUADV-Fe-V14Sc.js +0 -30
- package/dist/classDiagram-v2-VYDZK3BY-xTDg7lOs.js +0 -30
- package/dist/flowDiagram-HODETNUW-6dMdB8pR.js +0 -16
- package/dist/katex-DFBiSucW.js +0 -21840
- package/dist/stateDiagram-v2-MP3YSRHH-o05_rJN8.js +0 -30
- package/dist/swimlanesDiagram-VR7AAH4N-D_nFQfRc.js +0 -30
|
@@ -23,9 +23,11 @@ import { Form } from "@/components/ui/form";
|
|
|
23
23
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
24
24
|
import type { CellId } from "@/core/cells/ids";
|
|
25
25
|
import { useAsyncData } from "@/hooks/useAsyncData";
|
|
26
|
+
import { useDeepCompareMemoize } from "@/hooks/useDeepCompareMemoize";
|
|
26
27
|
import { useDebouncedCallback } from "@/hooks/useDebounce";
|
|
27
28
|
import type { GetDataUrl } from "@/plugins/impl/DataTablePlugin";
|
|
28
29
|
import { vegaLoadData } from "@/plugins/impl/vega/loader";
|
|
30
|
+
import { getVegaFieldTypes } from "@/plugins/impl/vega/utils";
|
|
29
31
|
import { useTheme } from "@/theme/useTheme";
|
|
30
32
|
import { uniqueBy } from "@/utils/arrays";
|
|
31
33
|
import { inferFieldTypes } from "../columns";
|
|
@@ -284,6 +286,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
284
286
|
saveChart={saveChart}
|
|
285
287
|
saveChartType={saveChartType}
|
|
286
288
|
getDataUrl={getDataUrl}
|
|
289
|
+
hasSchema={Boolean(fieldTypes?.length)}
|
|
287
290
|
fieldTypes={mergeIndexFields(
|
|
288
291
|
fieldTypes ?? inferFieldTypes(dataTable.props.data),
|
|
289
292
|
rowHeaders,
|
|
@@ -307,6 +310,7 @@ export const ChartPanel: React.FC<{
|
|
|
307
310
|
saveChartType: (chartType: ChartType) => void;
|
|
308
311
|
getDataUrl?: GetDataUrl;
|
|
309
312
|
fieldTypes?: FieldTypesWithExternalType | null;
|
|
313
|
+
hasSchema?: boolean;
|
|
310
314
|
isLargeDataset: boolean;
|
|
311
315
|
}> = ({
|
|
312
316
|
tableData,
|
|
@@ -316,6 +320,7 @@ export const ChartPanel: React.FC<{
|
|
|
316
320
|
saveChartType,
|
|
317
321
|
getDataUrl,
|
|
318
322
|
fieldTypes,
|
|
323
|
+
hasSchema = Boolean(fieldTypes?.length),
|
|
319
324
|
isLargeDataset,
|
|
320
325
|
}) => {
|
|
321
326
|
const { theme } = useTheme();
|
|
@@ -331,6 +336,8 @@ export const ChartPanel: React.FC<{
|
|
|
331
336
|
const [renderLargeCharts, setRenderLargeCharts] = useState(!isLargeDataset);
|
|
332
337
|
|
|
333
338
|
const { ref: chartContainerRef } = useResizeObserver();
|
|
339
|
+
// Sample-inferred types are useful for controls, but not full CSV parsing.
|
|
340
|
+
const csvFieldTypes = useDeepCompareMemoize(hasSchema ? fieldTypes : null);
|
|
334
341
|
|
|
335
342
|
const { data, isPending, error } = useAsyncData(async () => {
|
|
336
343
|
if (!getDataUrl || tableData.length === 0 || !renderLargeCharts) {
|
|
@@ -342,20 +349,26 @@ export const ChartPanel: React.FC<{
|
|
|
342
349
|
return response.data_url;
|
|
343
350
|
}
|
|
344
351
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
352
|
+
let format: Parameters<typeof vegaLoadData>[1];
|
|
353
|
+
if (response.format === "arrow") {
|
|
354
|
+
format = { type: "arrow" };
|
|
355
|
+
} else if (response.format === "json") {
|
|
356
|
+
format = { type: "json" };
|
|
357
|
+
} else {
|
|
358
|
+
format = {
|
|
359
|
+
type: "csv",
|
|
360
|
+
parse: getVegaFieldTypes(
|
|
361
|
+
csvFieldTypes &&
|
|
362
|
+
Object.fromEntries(
|
|
363
|
+
csvFieldTypes.map(([name, [type]]) => [name, type]),
|
|
364
|
+
),
|
|
365
|
+
{ parseDates: true },
|
|
366
|
+
),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
return vegaLoadData(response.data_url, format);
|
|
357
370
|
// Re-run when the data table changes
|
|
358
|
-
}, [tableData, renderLargeCharts]);
|
|
371
|
+
}, [tableData, renderLargeCharts, csvFieldTypes]);
|
|
359
372
|
|
|
360
373
|
const formValues = form.watch();
|
|
361
374
|
|
|
@@ -137,14 +137,14 @@ export class ColumnChartSpecModel<T> {
|
|
|
137
137
|
private legacySourceName: "data_0" | "source_0";
|
|
138
138
|
|
|
139
139
|
private readonly fieldTypes: FieldTypes;
|
|
140
|
-
readonly stats: Record<ColumnName, Partial<ColumnHeaderStats>>;
|
|
141
|
-
readonly binValues: Record<ColumnName, BinValues>;
|
|
142
|
-
readonly valueCounts: Record<ColumnName, ValueCounts>;
|
|
140
|
+
public readonly stats: Record<ColumnName, Partial<ColumnHeaderStats>>;
|
|
141
|
+
public readonly binValues: Record<ColumnName, BinValues>;
|
|
142
|
+
public readonly valueCounts: Record<ColumnName, ValueCounts>;
|
|
143
143
|
private readonly opts: {
|
|
144
144
|
includeCharts: boolean;
|
|
145
145
|
};
|
|
146
146
|
|
|
147
|
-
constructor(
|
|
147
|
+
public constructor(
|
|
148
148
|
data: T[] | string,
|
|
149
149
|
fieldTypes: FieldTypes,
|
|
150
150
|
stats: Record<ColumnName, Partial<ColumnHeaderStats>>,
|
|
@@ -225,7 +225,7 @@ export class VerticalElementsBuilder implements ElementsBuilder {
|
|
|
225
225
|
};
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
createElements(
|
|
228
|
+
public createElements(
|
|
229
229
|
cellIds: CellId[],
|
|
230
230
|
cellAtoms: Atom<CellData>[],
|
|
231
231
|
variables: Variables,
|
|
@@ -311,7 +311,7 @@ export class TreeElementsBuilder implements ElementsBuilder {
|
|
|
311
311
|
};
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
createElements(
|
|
314
|
+
public createElements(
|
|
315
315
|
cellIds: CellId[],
|
|
316
316
|
cellAtoms: Atom<CellData>[],
|
|
317
317
|
variables: Variables,
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import { createStore, Provider } from "jotai";
|
|
5
|
+
import { expect, it, vi } from "vitest";
|
|
6
|
+
import { MockRequestClient } from "@/__mocks__/requests";
|
|
7
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
8
|
+
import { alertAtom } from "@/core/alerts/state";
|
|
9
|
+
import {
|
|
10
|
+
defaultUserConfig,
|
|
11
|
+
type PackageManagerName,
|
|
12
|
+
} from "@/core/config/config-schema";
|
|
13
|
+
import { userConfigAtom } from "@/core/config/config";
|
|
14
|
+
import { requestClientAtom } from "@/core/network/requests";
|
|
15
|
+
import { sandboxAtom } from "@/core/packages/sandbox-state";
|
|
16
|
+
import { PackageAlert } from "../package-alert";
|
|
17
|
+
|
|
18
|
+
vi.mock("@/hooks/usePackageMetadata", () => ({
|
|
19
|
+
usePackageMetadata: () => ({
|
|
20
|
+
data: { versions: ["1.2.3"], extras: [] },
|
|
21
|
+
error: null,
|
|
22
|
+
isPending: false,
|
|
23
|
+
}),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
function mountPackageAlert({
|
|
27
|
+
configuredManager,
|
|
28
|
+
sandboxBackend,
|
|
29
|
+
source = "kernel",
|
|
30
|
+
}: {
|
|
31
|
+
configuredManager: PackageManagerName;
|
|
32
|
+
sandboxBackend: "uv" | "pixi" | null;
|
|
33
|
+
source?: "kernel" | "server";
|
|
34
|
+
}) {
|
|
35
|
+
const store = createStore();
|
|
36
|
+
const client = MockRequestClient.create();
|
|
37
|
+
const config = defaultUserConfig();
|
|
38
|
+
store.set(userConfigAtom, {
|
|
39
|
+
...config,
|
|
40
|
+
package_management: { manager: configuredManager },
|
|
41
|
+
});
|
|
42
|
+
store.set(requestClientAtom, client);
|
|
43
|
+
store.set(
|
|
44
|
+
sandboxAtom,
|
|
45
|
+
sandboxBackend
|
|
46
|
+
? {
|
|
47
|
+
backend: sandboxBackend,
|
|
48
|
+
manifest: "",
|
|
49
|
+
filename: "notebook.py",
|
|
50
|
+
}
|
|
51
|
+
: null,
|
|
52
|
+
);
|
|
53
|
+
store.set(alertAtom, {
|
|
54
|
+
...store.get(alertAtom),
|
|
55
|
+
packageAlert: {
|
|
56
|
+
id: "missing-package",
|
|
57
|
+
kind: "missing",
|
|
58
|
+
packages: ["polars"],
|
|
59
|
+
isolated: true,
|
|
60
|
+
source,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
render(
|
|
64
|
+
<Provider store={store}>
|
|
65
|
+
<TooltipProvider>
|
|
66
|
+
<PackageAlert />
|
|
67
|
+
</TooltipProvider>
|
|
68
|
+
</Provider>,
|
|
69
|
+
);
|
|
70
|
+
return client;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
it.each(["uv", "pixi"] as const)(
|
|
74
|
+
"shows the fixed %s manager for a sandbox",
|
|
75
|
+
(sandboxBackend) => {
|
|
76
|
+
const client = mountPackageAlert({
|
|
77
|
+
configuredManager: sandboxBackend === "uv" ? "pixi" : "uv",
|
|
78
|
+
sandboxBackend,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const managerSelect = screen.getByTestId("install-package-manager-select");
|
|
82
|
+
expect(managerSelect).toHaveValue(sandboxBackend);
|
|
83
|
+
expect(managerSelect).toBeDisabled();
|
|
84
|
+
|
|
85
|
+
fireEvent.click(screen.getByTestId("install-packages-button"));
|
|
86
|
+
expect(client.sendInstallMissingPackages).toHaveBeenCalledWith(
|
|
87
|
+
expect.objectContaining({ manager: sandboxBackend }),
|
|
88
|
+
);
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
it("keeps the configured package manager selectable outside a sandbox", () => {
|
|
93
|
+
mountPackageAlert({ configuredManager: "uv", sandboxBackend: null });
|
|
94
|
+
|
|
95
|
+
const managerSelect = screen.getByTestId("install-package-manager-select");
|
|
96
|
+
expect(managerSelect).toHaveValue("uv");
|
|
97
|
+
expect(managerSelect).not.toBeDisabled();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("installs a selected version in a Pixi sandbox", () => {
|
|
101
|
+
const client = mountPackageAlert({
|
|
102
|
+
configuredManager: "uv",
|
|
103
|
+
sandboxBackend: "pixi",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
fireEvent.change(screen.getByDisplayValue("latest"), {
|
|
107
|
+
target: { value: "1.2.3" },
|
|
108
|
+
});
|
|
109
|
+
fireEvent.click(screen.getByTestId("install-packages-button"));
|
|
110
|
+
expect(client.sendInstallMissingPackages).toHaveBeenCalledExactlyOnceWith({
|
|
111
|
+
manager: "pixi",
|
|
112
|
+
versions: { polars: "1.2.3" },
|
|
113
|
+
source: "kernel",
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("does not offer version selection for Pixi outside a sandbox", () => {
|
|
118
|
+
mountPackageAlert({ configuredManager: "pixi", sandboxBackend: null });
|
|
119
|
+
|
|
120
|
+
expect(screen.queryByDisplayValue("latest")).not.toBeInTheDocument();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("uses the configured package manager for a server installation", () => {
|
|
124
|
+
const client = mountPackageAlert({
|
|
125
|
+
configuredManager: "uv",
|
|
126
|
+
sandboxBackend: "pixi",
|
|
127
|
+
source: "server",
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(
|
|
131
|
+
screen.queryByTestId("install-package-manager-select"),
|
|
132
|
+
).not.toBeInTheDocument();
|
|
133
|
+
|
|
134
|
+
fireEvent.click(screen.getByTestId("install-packages-button"));
|
|
135
|
+
expect(client.sendInstallMissingPackages).toHaveBeenCalledExactlyOnceWith({
|
|
136
|
+
manager: "uv",
|
|
137
|
+
versions: { polars: "" },
|
|
138
|
+
source: "server",
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import { Provider } from "jotai";
|
|
5
|
+
import type React from "react";
|
|
6
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
import { ModalProvider } from "@/components/modal/ImperativeModal";
|
|
8
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
9
|
+
import { store } from "@/core/state/jotai";
|
|
10
|
+
import { PairWithAgentBanner, PairWithAgentButton } from "../pair-with-agent";
|
|
11
|
+
|
|
12
|
+
const mocks = vi.hoisted(() => ({
|
|
13
|
+
isWasm: vi.fn(() => false),
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock("@/core/wasm/utils", () => ({
|
|
17
|
+
isWasm: mocks.isWasm,
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
function wrapper({ children }: { children: React.ReactNode }) {
|
|
21
|
+
return (
|
|
22
|
+
<Provider store={store}>
|
|
23
|
+
<TooltipProvider>
|
|
24
|
+
<ModalProvider>{children}</ModalProvider>
|
|
25
|
+
</TooltipProvider>
|
|
26
|
+
</Provider>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function stubTokenFetch() {
|
|
31
|
+
vi.stubGlobal(
|
|
32
|
+
"fetch",
|
|
33
|
+
vi.fn().mockResolvedValue(new Response(JSON.stringify({ token: null }))),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe("PairWithAgent", () => {
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
vi.unstubAllGlobals();
|
|
40
|
+
mocks.isWasm.mockReset();
|
|
41
|
+
mocks.isWasm.mockReturnValue(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("shows local agent options", () => {
|
|
45
|
+
render(<PairWithAgentBanner />, { wrapper });
|
|
46
|
+
|
|
47
|
+
expect(
|
|
48
|
+
screen.getByRole("group", { name: "Supported agents" }),
|
|
49
|
+
).toBeVisible();
|
|
50
|
+
expect(screen.getByRole("figure", { name: "Claude Code" })).toBeVisible();
|
|
51
|
+
expect(screen.getByRole("figure", { name: "Codex" })).toBeVisible();
|
|
52
|
+
expect(screen.getByRole("figure", { name: "Cursor" })).toBeVisible();
|
|
53
|
+
expect(screen.getByRole("figure", { name: "Gemini CLI" })).toBeVisible();
|
|
54
|
+
expect(screen.getByRole("figure", { name: "OpenCode" })).toBeVisible();
|
|
55
|
+
expect(
|
|
56
|
+
screen.getByRole("figure", { name: "GitHub Copilot" }),
|
|
57
|
+
).toBeVisible();
|
|
58
|
+
expect(
|
|
59
|
+
screen.getByRole("figure", { name: "Any local agent" }),
|
|
60
|
+
).toBeVisible();
|
|
61
|
+
expect(
|
|
62
|
+
screen.getByRole("button", {
|
|
63
|
+
name: "Learn more.",
|
|
64
|
+
}),
|
|
65
|
+
).toBeVisible();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("opens the pairing dialog from the banner description", () => {
|
|
69
|
+
stubTokenFetch();
|
|
70
|
+
render(<PairWithAgentBanner />, { wrapper });
|
|
71
|
+
|
|
72
|
+
fireEvent.click(
|
|
73
|
+
screen.getByRole("button", {
|
|
74
|
+
name: "Learn more.",
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(
|
|
79
|
+
screen.getByRole("dialog", { name: "Pair with an agent" }),
|
|
80
|
+
).toBeVisible();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("opens the pairing dialog and preserves a passed click handler", () => {
|
|
84
|
+
const onClick = vi.fn();
|
|
85
|
+
stubTokenFetch();
|
|
86
|
+
render(<PairWithAgentButton onClick={onClick} />, { wrapper });
|
|
87
|
+
|
|
88
|
+
fireEvent.click(screen.getByRole("button", { name: "Connect your agent" }));
|
|
89
|
+
|
|
90
|
+
expect(onClick).toHaveBeenCalledOnce();
|
|
91
|
+
expect(
|
|
92
|
+
screen.getByRole("dialog", { name: "Pair with an agent" }),
|
|
93
|
+
).toBeVisible();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("hides pairing controls in WASM", () => {
|
|
97
|
+
mocks.isWasm.mockReturnValue(true);
|
|
98
|
+
|
|
99
|
+
const { container, rerender } = render(<PairWithAgentButton />, {
|
|
100
|
+
wrapper,
|
|
101
|
+
});
|
|
102
|
+
expect(container).toBeEmptyDOMElement();
|
|
103
|
+
|
|
104
|
+
rerender(<PairWithAgentBanner />);
|
|
105
|
+
expect(container).toBeEmptyDOMElement();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { BotIcon } from "lucide-react";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { AiProviderIcon } from "@/components/ai/ai-provider-icon";
|
|
6
|
+
import { useImperativeModal } from "@/components/modal/ImperativeModal";
|
|
7
|
+
import { Button, type ButtonProps } from "@/components/ui/button";
|
|
8
|
+
import { isWasm } from "@/core/wasm/utils";
|
|
9
|
+
import { cn } from "@/utils/cn";
|
|
10
|
+
import { PairWithAgentModal } from "./pair-with-agent-modal";
|
|
11
|
+
|
|
12
|
+
const FEATURED_AGENTS = [
|
|
13
|
+
{ id: "claude", label: "Claude Code" },
|
|
14
|
+
{ id: "codex", label: "Codex" },
|
|
15
|
+
{ id: "cursor", label: "Cursor" },
|
|
16
|
+
{ id: "gemini", label: "Gemini CLI" },
|
|
17
|
+
{ id: "opencode", label: "OpenCode" },
|
|
18
|
+
{ id: "github", label: "GitHub Copilot" },
|
|
19
|
+
{ id: "openai-compatible", label: "Any local agent" },
|
|
20
|
+
] as const satisfies ReadonlyArray<{
|
|
21
|
+
id: React.ComponentProps<typeof AiProviderIcon>["provider"];
|
|
22
|
+
label: string;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
export const usePairWithAgentModal = () => {
|
|
26
|
+
const { openModal, closeModal } = useImperativeModal();
|
|
27
|
+
|
|
28
|
+
return React.useCallback(
|
|
29
|
+
() => openModal(<PairWithAgentModal onClose={closeModal} />),
|
|
30
|
+
[openModal, closeModal],
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const PairWithAgentButton: React.FC<
|
|
35
|
+
ButtonProps & { label?: string }
|
|
36
|
+
> = ({ className, label = "Connect your agent", onClick, ...props }) => {
|
|
37
|
+
const openPairWithAgentModal = usePairWithAgentModal();
|
|
38
|
+
|
|
39
|
+
if (isWasm()) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Button
|
|
45
|
+
type="button"
|
|
46
|
+
variant="link"
|
|
47
|
+
size="xs"
|
|
48
|
+
className={cn("h-auto gap-1 px-0", className)}
|
|
49
|
+
onClick={(event) => {
|
|
50
|
+
onClick?.(event);
|
|
51
|
+
if (!event.defaultPrevented) {
|
|
52
|
+
openPairWithAgentModal();
|
|
53
|
+
}
|
|
54
|
+
}}
|
|
55
|
+
{...props}
|
|
56
|
+
>
|
|
57
|
+
{label}
|
|
58
|
+
</Button>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const PairWithAgentBanner: React.FC<{
|
|
63
|
+
label?: string;
|
|
64
|
+
className?: string;
|
|
65
|
+
}> = ({ label = "Connect your agent", className }) => {
|
|
66
|
+
const openPairWithAgentModal = usePairWithAgentModal();
|
|
67
|
+
|
|
68
|
+
if (isWasm()) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div
|
|
74
|
+
className={cn(
|
|
75
|
+
"rounded-lg border border-(--blue-6) bg-(--blue-2)/50 p-3",
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
78
|
+
>
|
|
79
|
+
<div className="flex items-center gap-2 text-sm font-semibold">
|
|
80
|
+
{label}
|
|
81
|
+
<fieldset
|
|
82
|
+
className="m-0 flex min-w-0 -space-x-1.5 border-0 p-0 mb-0.5"
|
|
83
|
+
aria-label="Supported agents"
|
|
84
|
+
>
|
|
85
|
+
{FEATURED_AGENTS.map(({ id, label }) => (
|
|
86
|
+
<figure
|
|
87
|
+
key={id}
|
|
88
|
+
title={label}
|
|
89
|
+
aria-label={label}
|
|
90
|
+
className="flex size-6 items-center justify-center rounded-full border bg-background shadow-xs"
|
|
91
|
+
>
|
|
92
|
+
{id === "openai-compatible" ? (
|
|
93
|
+
<BotIcon className="size-3.5" aria-hidden={true} />
|
|
94
|
+
) : (
|
|
95
|
+
<AiProviderIcon
|
|
96
|
+
provider={id}
|
|
97
|
+
className="size-3.5"
|
|
98
|
+
aria-hidden={true}
|
|
99
|
+
/>
|
|
100
|
+
)}
|
|
101
|
+
</figure>
|
|
102
|
+
))}
|
|
103
|
+
</fieldset>
|
|
104
|
+
</div>
|
|
105
|
+
<div className="mt-1 text-xs leading-relaxed">
|
|
106
|
+
<p className="inline">
|
|
107
|
+
Use your AI coding agent to pair-program on this notebook.
|
|
108
|
+
</p>
|
|
109
|
+
<button
|
|
110
|
+
type="button"
|
|
111
|
+
onClick={openPairWithAgentModal}
|
|
112
|
+
className="text-link hover:underline ml-1"
|
|
113
|
+
>
|
|
114
|
+
Learn more.
|
|
115
|
+
</button>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
@@ -297,11 +297,12 @@ export function useNotebookActions({
|
|
|
297
297
|
|
|
298
298
|
{
|
|
299
299
|
icon: <SparklesIcon size={14} strokeWidth={1.5} />,
|
|
300
|
-
label: "
|
|
300
|
+
label: "Connect your agent",
|
|
301
301
|
hidden: isWasm(),
|
|
302
302
|
handle: async () => {
|
|
303
303
|
openModal(<PairWithAgentModal onClose={closeModal} />);
|
|
304
304
|
},
|
|
305
|
+
additionalKeywords: ["connect"],
|
|
305
306
|
},
|
|
306
307
|
|
|
307
308
|
{
|
|
@@ -29,6 +29,7 @@ import useEvent from "react-use-event-hook";
|
|
|
29
29
|
import { DefaultChatTransport } from "ai";
|
|
30
30
|
import { z } from "zod";
|
|
31
31
|
import { AIModelDropdown } from "@/components/ai/ai-model-dropdown";
|
|
32
|
+
import { PairWithAgentButton } from "@/components/editor/actions/pair-with-agent";
|
|
32
33
|
import {
|
|
33
34
|
AddContextButton,
|
|
34
35
|
AttachFileButton,
|
|
@@ -301,6 +302,7 @@ export const AddCellWithAI: React.FC<{
|
|
|
301
302
|
showAddCustomModelDocs={true}
|
|
302
303
|
/>
|
|
303
304
|
{languageDropdown}
|
|
305
|
+
<PairWithAgentButton />
|
|
304
306
|
</div>
|
|
305
307
|
<div className="flex flex-row items-center">
|
|
306
308
|
{files.length > 0 && (
|
|
@@ -14,13 +14,13 @@ interface SubmissionAttempt {
|
|
|
14
14
|
export class StagedCellSubmissionController {
|
|
15
15
|
private activeAttempt: SubmissionAttempt | null = null;
|
|
16
16
|
|
|
17
|
-
cancel() {
|
|
17
|
+
public cancel() {
|
|
18
18
|
if (this.activeAttempt) {
|
|
19
19
|
this.activeAttempt.cancelled = true;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
async run<T>({ prepare, submit, onError }: SubmissionCallbacks<T>) {
|
|
23
|
+
public async run<T>({ prepare, submit, onError }: SubmissionCallbacks<T>) {
|
|
24
24
|
if (this.activeAttempt !== null) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
@@ -15,7 +15,7 @@ export class StreamingChunkTransport<
|
|
|
15
15
|
> extends DefaultChatTransport<UI_MESSAGE> {
|
|
16
16
|
private onChunkReceived: (chunk: UIMessageChunk) => void;
|
|
17
17
|
|
|
18
|
-
constructor(
|
|
18
|
+
public constructor(
|
|
19
19
|
options: HttpChatTransportInitOptions<UI_MESSAGE>,
|
|
20
20
|
onChunkReceived: (chunk: UIMessageChunk) => void,
|
|
21
21
|
) {
|
|
@@ -40,7 +40,12 @@ const ContributeSnippetModal: React.FC<{
|
|
|
40
40
|
<DialogDescription>
|
|
41
41
|
Have a useful snippet you want to share with the community? Make a
|
|
42
42
|
pull request{" "}
|
|
43
|
-
<a
|
|
43
|
+
<a
|
|
44
|
+
href={Constants.githubPage}
|
|
45
|
+
target="_blank"
|
|
46
|
+
rel="noreferrer"
|
|
47
|
+
className="underline"
|
|
48
|
+
>
|
|
44
49
|
on GitHub
|
|
45
50
|
</a>
|
|
46
51
|
.
|