@marimo-team/islands 0.23.11-dev9 → 0.23.12-dev0
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-Z3RP7Vmm.js → ConnectedDataExplorerComponent-WqG-xX4l.js} +13 -13
- package/dist/{ErrorBoundary-DpbaKVv7.js → ErrorBoundary-BNx_OSVo.js} +2 -2
- package/dist/{any-language-editor-CAgFD4Kd.js → any-language-editor-rPSlOll9.js} +5 -5
- package/dist/assets/__vite-browser-external-DAm_YW43.js +1 -0
- package/dist/assets/{worker-CC0Oul9k.js → worker-DEDLIQQV.js} +2 -2
- package/dist/{button-C5K9fIPF.js → button-vQhauTmO.js} +20 -0
- package/dist/{capabilities-BceAxrAW.js → capabilities-BEHzIS99.js} +1 -1
- package/dist/{chat-ui-c1FdlK-C.js → chat-ui-k2kqhCv5.js} +135 -106
- package/dist/{check-BCaJeT-J.js → check-nrzHDi45.js} +1 -1
- package/dist/{code-visibility-0vPSjYnM.js → code-visibility-BGJLYDS-.js} +81 -68
- package/dist/{copy-UqRYxiOg.js → copy-UhDed7D4.js} +2 -2
- package/dist/{dist-Dk6PV_d3.js → dist-DYGLrbYQ.js} +2 -2
- package/dist/{error-banner-CJXYJ6Sb.js → error-banner-BHAkVFc2.js} +2 -2
- package/dist/{esm-BaH2eg5-.js → esm-Bqu9AE2K.js} +1 -1
- package/dist/{extends-D_hDsj6R.js → extends-9Yl5BEcg.js} +4 -4
- package/dist/{formats-C4wO47tk.js → formats-BV4bOfMI.js} +3 -3
- package/dist/{glide-data-editor-BPkCPs7L.js → glide-data-editor-BDTq6YUb.js} +9 -9
- package/dist/{html-to-image-D5-EpALB.js → html-to-image-C86pQALH.js} +16 -16
- package/dist/{input-OdWHkobi.js → input-AKkGXdyV.js} +6 -6
- package/dist/{label-CC4ytI1X.js → label-E3ZJXHu8.js} +2 -2
- package/dist/{loader-BWLPpjKK.js → loader-YPuQvn1Y.js} +1 -1
- package/dist/main.js +981 -978
- package/dist/{mermaid-BotvIKg9.js → mermaid-QFAR9YgY.js} +5 -5
- package/dist/{process-output-WDZE0cyS.js → process-output-nNw4OpSj.js} +3 -3
- package/dist/{reveal-component-BZpDHGsk.js → reveal-component-B2YCxhmm.js} +10 -10
- package/dist/{spec-X7FwLJni.js → spec-B45_YCNI.js} +4 -4
- package/dist/{strings-J57tzLr3.js → strings-Cq2s9_EQ.js} +4 -4
- package/dist/style.css +1 -1
- package/dist/{swiper-component-B2t5sN1q.js → swiper-component-BNa_4kh2.js} +2 -2
- package/dist/{toDate-d8RCRrRd.js → toDate-Do1xRzAo.js} +3 -3
- package/dist/{tooltip-DpcyNkQ2.js → tooltip-Bz3OAwrU.js} +3 -3
- package/dist/{types-ChtMFmZ2.js → types-D8gEGs4R.js} +1 -1
- package/dist/{useAsyncData-PonK__yh.js → useAsyncData-CL3o2p4i.js} +1 -1
- package/dist/{useDateFormatter-QB-3MpYr.js → useDateFormatter-BC6iSz9g.js} +2 -2
- package/dist/{useDeepCompareMemoize-D3NGWke6.js → useDeepCompareMemoize-BPx2MuOK.js} +1 -1
- package/dist/{useIframeCapabilities-C4JTXTIh.js → useIframeCapabilities-C6Ta3EyP.js} +1 -1
- package/dist/{useLifecycle-00mO3OSS.js → useLifecycle-C3Ec71q0.js} +3 -3
- package/dist/{useTheme-DEhDzATN.js → useTheme-ZhT6uIu3.js} +4 -3
- package/dist/{vega-component-DGPUhbDs.js → vega-component-C3AWYGAL.js} +10 -10
- package/dist/{zod-aLSua2NL.js → zod-DXqkaI_w.js} +1 -1
- package/package.json +1 -1
- package/src/components/ai/ai-model-dropdown.tsx +6 -0
- package/src/components/app-config/ai-config.tsx +73 -55
- package/src/components/app-config/data-form.tsx +33 -43
- package/src/components/app-config/is-overridden.tsx +125 -58
- package/src/components/app-config/user-config-form.tsx +178 -227
- package/src/components/chat/chat-display.tsx +5 -0
- package/src/components/chat/chat-panel.tsx +21 -8
- package/src/components/chat/tool-call/tool-call-view.tsx +4 -0
- package/src/components/chat/tool-call/tool-history-row.tsx +26 -5
- package/src/components/data-table/TableTopBar.tsx +4 -4
- package/src/components/data-table/__tests__/columns.test.tsx +20 -0
- package/src/components/data-table/__tests__/data-table.test.tsx +28 -0
- package/src/components/data-table/columns.tsx +16 -1
- package/src/components/data-table/data-table.tsx +3 -3
- package/src/components/data-table/filters/types.ts +1 -0
- package/src/components/data-table/renderers.tsx +5 -1
- package/src/components/datasources/__tests__/install-package-button.test.tsx +11 -0
- package/src/components/datasources/__tests__/utils.test.ts +127 -2
- package/src/components/datasources/datasources.tsx +44 -17
- package/src/components/datasources/install-package-button.tsx +3 -1
- package/src/components/datasources/utils.ts +45 -0
- package/src/components/editor/actions/useNotebookActions.tsx +62 -21
- package/src/components/editor/actions/useSetCodeVisibility.ts +57 -0
- package/src/components/editor/header/__tests__/status.test.tsx +0 -4
- package/src/components/editor/header/status.tsx +2 -3
- package/src/core/cells/__tests__/cells.test.ts +33 -0
- package/src/core/cells/cells.ts +1 -1
- package/src/core/config/config-schema.ts +6 -1
- package/src/core/edit-app.tsx +14 -0
- package/src/core/hotkeys/hotkeys.ts +20 -0
- package/src/core/websocket/__tests__/useMarimoKernelConnection.test.ts +0 -13
- package/src/core/websocket/types.ts +0 -1
- package/src/core/websocket/useMarimoKernelConnection.tsx +0 -14
- package/src/css/app/print.css +8 -0
- package/src/css/md.css +12 -0
- package/src/plugins/impl/DataTablePlugin.tsx +12 -5
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +1 -1
- package/src/plugins/impl/chat/chat-ui.tsx +1 -0
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -1
- package/dist/assets/__vite-browser-external-eshhtsgZ.js +0 -1
- package/src/components/editor/actions/useHideAllMarkdownCode.ts +0 -53
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
-
import { g as cn, l as useEventListener, t as Button } from "./button-
|
|
2
|
+
import { g as cn, l as useEventListener, t as Button } from "./button-vQhauTmO.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
5
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
6
|
-
import { t as useIframeCapabilities } from "./useIframeCapabilities-
|
|
6
|
+
import { t as useIframeCapabilities } from "./useIframeCapabilities-C6Ta3EyP.js";
|
|
7
7
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
8
8
|
function isObject$2(t2) {
|
|
9
9
|
return typeof t2 == "object" && !!t2 && "constructor" in t2 && t2.constructor === Object;
|
|
@@ -2,11 +2,11 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { t as __commonJSMin } from "./chunk-BNovOVIE.js";
|
|
5
|
-
import { _ as Logger } from "./button-
|
|
5
|
+
import { _ as Logger } from "./button-vQhauTmO.js";
|
|
6
6
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
7
|
-
import { u as createLucideIcon } from "./dist-
|
|
7
|
+
import { u as createLucideIcon } from "./dist-DYGLrbYQ.js";
|
|
8
8
|
import { r as KnownQueryParams } from "./constants-T20xxyNf.js";
|
|
9
|
-
import { b as atom, d as store, m as isIslands, p as waitFor } from "./useTheme-
|
|
9
|
+
import { b as atom, d as store, m as isIslands, p as waitFor } from "./useTheme-ZhT6uIu3.js";
|
|
10
10
|
import { t as invariant } from "./invariant-wRzNXIsJ.js";
|
|
11
11
|
var CircleQuestionMark = createLucideIcon("circle-question-mark", [
|
|
12
12
|
["circle", {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
-
import { f as createSlottable, g as cn, m as useComposedRefs } from "./button-
|
|
2
|
+
import { f as createSlottable, g as cn, m as useComposedRefs } from "./button-vQhauTmO.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { a as createPopperScope, i as Root2, n as Arrow, r as Content, s as Root, t as Anchor } from "./dist-
|
|
5
|
+
import { a as createPopperScope, i as Root2, n as Arrow, r as Content, s as Root, t as Anchor } from "./dist-DYGLrbYQ.js";
|
|
6
6
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
7
|
-
import { Q as withSmartCollisionBoundary, Z as withFullScreenAsRoot, _t as createContextScope, at as Portal, ct as DismissableLayer, dt as useId, et as StyleNamespace, ft as Presence, ht as composeEventHandlers, pt as useControllableState, vt as Primitive } from "./zod-
|
|
7
|
+
import { Q as withSmartCollisionBoundary, Z as withFullScreenAsRoot, _t as createContextScope, at as Portal, ct as DismissableLayer, dt as useId, et as StyleNamespace, ft as Presence, ht as composeEventHandlers, pt as useControllableState, vt as Primitive } from "./zod-DXqkaI_w.js";
|
|
8
8
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1), import_jsx_runtime = /* @__PURE__ */ __toESM(require_jsx_runtime(), 1), [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [createPopperScope]), usePopperScope = createPopperScope(), PROVIDER_NAME = "TooltipProvider", DEFAULT_DELAY_DURATION = 700, TOOLTIP_OPEN = "tooltip.open", [TooltipProviderContextProvider, useTooltipProviderContext] = createTooltipContext(PROVIDER_NAME), TooltipProvider$1 = (n) => {
|
|
9
9
|
let { __scopeTooltip: j, delayDuration: M = DEFAULT_DELAY_DURATION, skipDelayDuration: N = 300, disableHoverableContent: P = false, children: F } = n, I = import_react.useRef(true), L = import_react.useRef(false), R = import_react.useRef(0);
|
|
10
10
|
return import_react.useEffect(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as createLucideIcon } from "./dist-
|
|
1
|
+
import { u as createLucideIcon } from "./dist-DYGLrbYQ.js";
|
|
2
2
|
var Pencil = createLucideIcon("pencil", [["path", {
|
|
3
3
|
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
|
|
4
4
|
key: "1a8usu"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
3
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
4
|
-
import { T as useEvent_default } from "./useTheme-
|
|
4
|
+
import { T as useEvent_default } from "./useTheme-ZhT6uIu3.js";
|
|
5
5
|
import { t as invariant } from "./invariant-wRzNXIsJ.js";
|
|
6
6
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1), Result = {
|
|
7
7
|
error(e, s) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
|
-
import { u as createLucideIcon } from "./dist-
|
|
4
|
-
import { E as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 } from "./strings-
|
|
3
|
+
import { u as createLucideIcon } from "./dist-DYGLrbYQ.js";
|
|
4
|
+
import { E as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 } from "./strings-Cq2s9_EQ.js";
|
|
5
5
|
var ChartPie = createLucideIcon("chart-pie", [["path", {
|
|
6
6
|
d: "M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z",
|
|
7
7
|
key: "pzmjnu"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
|
-
import { w as dequal } from "./useTheme-
|
|
3
|
+
import { w as dequal } from "./useTheme-ZhT6uIu3.js";
|
|
4
4
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
5
5
|
function useDeepCompareMemoize(e) {
|
|
6
6
|
let i = import_react.useRef(e);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
3
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
4
|
-
import { t as getIframeCapabilities } from "./capabilities-
|
|
4
|
+
import { t as getIframeCapabilities } from "./capabilities-BEHzIS99.js";
|
|
5
5
|
var import_compiler_runtime = require_compiler_runtime();
|
|
6
6
|
require_react();
|
|
7
7
|
function useIframeCapabilities() {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
-
import { _ as Logger, g as cn, r as cva } from "./button-
|
|
2
|
+
import { _ as Logger, g as cn, r as cva } from "./button-vQhauTmO.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { u as createLucideIcon } from "./dist-
|
|
5
|
+
import { u as createLucideIcon } from "./dist-DYGLrbYQ.js";
|
|
6
6
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
7
|
-
import { b as atom, v as useSetAtom } from "./useTheme-
|
|
7
|
+
import { b as atom, v as useSetAtom } from "./useTheme-ZhT6uIu3.js";
|
|
8
8
|
var Calendar = createLucideIcon("calendar", [
|
|
9
9
|
["path", {
|
|
10
10
|
d: "M8 2v4",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
-
import { _ as Logger, a as OverridingHotkeyProvider, s as resolvePlatform } from "./button-
|
|
2
|
+
import { _ as Logger, a as OverridingHotkeyProvider, s as resolvePlatform } from "./button-vQhauTmO.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { A as looseObject, B as union, I as record, N as number, P as object, R as string, T as boolean, b as _enum, w as array } from "./zod-
|
|
5
|
+
import { A as looseObject, B as union, I as record, N as number, P as object, R as string, T as boolean, b as _enum, w as array } from "./zod-DXqkaI_w.js";
|
|
6
6
|
import { t as merge_default } from "./merge-Be1CqGnU.js";
|
|
7
7
|
var import_react = /* @__PURE__ */ __toESM(require_react()), useInsertionEffect = typeof window < "u" ? import_react.useInsertionEffect || import_react.useLayoutEffect : () => {
|
|
8
8
|
};
|
|
@@ -539,7 +539,8 @@ var VALID_APP_WIDTHS = [
|
|
|
539
539
|
const COPILOT_MODES = [
|
|
540
540
|
"manual",
|
|
541
541
|
"ask",
|
|
542
|
-
"agent"
|
|
542
|
+
"agent",
|
|
543
|
+
"code_mode"
|
|
543
544
|
];
|
|
544
545
|
var AiConfigSchema = object({
|
|
545
546
|
api_key: string().optional(),
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
-
import { _ as Logger, c as Objects, g as cn, h as Events } from "./button-
|
|
2
|
+
import { _ as Logger, c as Objects, g as cn, h as Events } from "./button-vQhauTmO.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { c as asRemoteURL, v as CircleQuestionMark } from "./toDate-
|
|
5
|
+
import { c as asRemoteURL, v as CircleQuestionMark } from "./toDate-Do1xRzAo.js";
|
|
6
6
|
import "./react-dom-BTJzcVJ9.js";
|
|
7
7
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
8
|
-
import "./zod-
|
|
9
|
-
import { n as ErrorBanner } from "./error-banner-
|
|
10
|
-
import { t as Tooltip } from "./tooltip-
|
|
8
|
+
import "./zod-DXqkaI_w.js";
|
|
9
|
+
import { n as ErrorBanner } from "./error-banner-BHAkVFc2.js";
|
|
10
|
+
import { t as Tooltip } from "./tooltip-Bz3OAwrU.js";
|
|
11
11
|
import { i as debounce_default } from "./constants-T20xxyNf.js";
|
|
12
|
-
import { T as useEvent_default, n as useTheme } from "./useTheme-
|
|
12
|
+
import { T as useEvent_default, n as useTheme } from "./useTheme-ZhT6uIu3.js";
|
|
13
13
|
import { s as uniq } from "./arrays-sEtDRoG4.js";
|
|
14
|
-
import { a as isValid, i as AlertTitle, n as Alert, t as arrow } from "./formats-
|
|
14
|
+
import { a as isValid, i as AlertTitle, n as Alert, t as arrow } from "./formats-BV4bOfMI.js";
|
|
15
15
|
import { n as formats } from "./vega-loader.browser-CZ-J8Py3.js";
|
|
16
|
-
import { a as getContainerWidth, n as vegaLoadData, s as tooltipHandler } from "./loader-
|
|
16
|
+
import { a as getContainerWidth, n as vegaLoadData, s as tooltipHandler } from "./loader-YPuQvn1Y.js";
|
|
17
17
|
import { t as j } from "./react-vega-B0sAlDTL.js";
|
|
18
18
|
import "./defaultLocale-u-3osm0P.js";
|
|
19
19
|
import "./defaultLocale-BoHTsDG6.js";
|
|
20
|
-
import { t as useAsyncData } from "./useAsyncData-
|
|
21
|
-
import { t as useDeepCompareMemoize } from "./useDeepCompareMemoize-
|
|
20
|
+
import { t as useAsyncData } from "./useAsyncData-CL3o2p4i.js";
|
|
21
|
+
import { t as useDeepCompareMemoize } from "./useDeepCompareMemoize-BPx2MuOK.js";
|
|
22
22
|
import { t as Semaphore } from "./semaphore-CNDGTzkX.js";
|
|
23
23
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
24
24
|
function fixRelativeUrl(e) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as __export, s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
|
-
import { d as createSlot, l as useEventListener, m as useComposedRefs } from "./button-
|
|
2
|
+
import { d as createSlot, l as useEventListener, m as useComposedRefs } from "./button-vQhauTmO.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
5
|
import { t as require_react_dom } from "./react-dom-BTJzcVJ9.js";
|
package/package.json
CHANGED
|
@@ -45,6 +45,7 @@ interface AIModelDropdownProps {
|
|
|
45
45
|
showAddCustomModelDocs?: boolean;
|
|
46
46
|
displayIconOnly?: boolean;
|
|
47
47
|
forRole: SupportedRole;
|
|
48
|
+
disabled?: boolean;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
export const AIModelDropdown = ({
|
|
@@ -57,6 +58,7 @@ export const AIModelDropdown = ({
|
|
|
57
58
|
showAddCustomModelDocs = false,
|
|
58
59
|
forRole,
|
|
59
60
|
displayIconOnly = false,
|
|
61
|
+
disabled = false,
|
|
60
62
|
}: AIModelDropdownProps) => {
|
|
61
63
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
62
64
|
|
|
@@ -131,6 +133,9 @@ export const AIModelDropdown = ({
|
|
|
131
133
|
};
|
|
132
134
|
|
|
133
135
|
const handleSelect = (modelId: QualifiedModelId) => {
|
|
136
|
+
if (disabled) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
134
139
|
if (onSelect) {
|
|
135
140
|
onSelect(modelId);
|
|
136
141
|
} else {
|
|
@@ -142,6 +147,7 @@ export const AIModelDropdown = ({
|
|
|
142
147
|
return (
|
|
143
148
|
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
|
144
149
|
<DropdownMenuTrigger
|
|
150
|
+
disabled={disabled}
|
|
145
151
|
className={`flex items-center justify-between px-2 py-0.5 border rounded-md
|
|
146
152
|
hover:bg-accent hover:text-accent-foreground ${triggerClassName}`}
|
|
147
153
|
>
|
|
@@ -79,7 +79,11 @@ import { Tooltip } from "../ui/tooltip";
|
|
|
79
79
|
import { formItemClasses, SettingSubtitle } from "./common";
|
|
80
80
|
import { AWS_REGIONS } from "./constants";
|
|
81
81
|
import { IncorrectModelId } from "./incorrect-model-id";
|
|
82
|
-
import {
|
|
82
|
+
import {
|
|
83
|
+
IsOverridden,
|
|
84
|
+
OverriddenFormField,
|
|
85
|
+
useConfigOverride,
|
|
86
|
+
} from "./is-overridden";
|
|
83
87
|
import { MCPConfig } from "./mcp-config";
|
|
84
88
|
import { aiSettingsSubTabAtom } from "./state";
|
|
85
89
|
|
|
@@ -99,6 +103,11 @@ interface CustomProviderConfig {
|
|
|
99
103
|
base_url?: string;
|
|
100
104
|
}
|
|
101
105
|
|
|
106
|
+
const SUPPORTED_PROVIDERS_UI = new Set(KNOWN_PROVIDERS);
|
|
107
|
+
// We use deepseek as an example of a custom provider in our docs, so we don't show it in the UI.
|
|
108
|
+
// Else, we would need to wire up the UI and config for it. Consider if many users request.
|
|
109
|
+
SUPPORTED_PROVIDERS_UI.delete("deepseek");
|
|
110
|
+
|
|
102
111
|
export const AiProviderTitle: React.FC<AiProviderTitleProps> = ({
|
|
103
112
|
provider,
|
|
104
113
|
children,
|
|
@@ -123,7 +132,6 @@ interface ApiKeyProps {
|
|
|
123
132
|
|
|
124
133
|
export const ApiKey: React.FC<ApiKeyProps> = ({
|
|
125
134
|
form,
|
|
126
|
-
config,
|
|
127
135
|
name,
|
|
128
136
|
placeholder,
|
|
129
137
|
testId,
|
|
@@ -131,10 +139,10 @@ export const ApiKey: React.FC<ApiKeyProps> = ({
|
|
|
131
139
|
onChange,
|
|
132
140
|
}) => {
|
|
133
141
|
return (
|
|
134
|
-
<
|
|
142
|
+
<OverriddenFormField
|
|
135
143
|
control={form.control}
|
|
136
144
|
name={name}
|
|
137
|
-
render={({ field }) => (
|
|
145
|
+
render={({ field, override }) => (
|
|
138
146
|
<div className="flex flex-col space-y-1">
|
|
139
147
|
<FormItem className={formItemClasses}>
|
|
140
148
|
<FormLabel>API Key</FormLabel>
|
|
@@ -146,7 +154,8 @@ export const ApiKey: React.FC<ApiKeyProps> = ({
|
|
|
146
154
|
placeholder={placeholder}
|
|
147
155
|
type="password"
|
|
148
156
|
{...field}
|
|
149
|
-
value={asStringOrEmpty(
|
|
157
|
+
value={asStringOrEmpty(override.value)}
|
|
158
|
+
disabled={override.isOverridden}
|
|
150
159
|
onChange={(e) => {
|
|
151
160
|
const value = e.target.value;
|
|
152
161
|
if (!value.includes("*")) {
|
|
@@ -157,7 +166,7 @@ export const ApiKey: React.FC<ApiKeyProps> = ({
|
|
|
157
166
|
/>
|
|
158
167
|
</FormControl>
|
|
159
168
|
<FormMessage />
|
|
160
|
-
<IsOverridden
|
|
169
|
+
<IsOverridden override={override} />
|
|
161
170
|
</FormItem>
|
|
162
171
|
{description && <FormDescription>{description}</FormDescription>}
|
|
163
172
|
</div>
|
|
@@ -191,7 +200,6 @@ function asStringOrEmpty<T>(value: T): string {
|
|
|
191
200
|
|
|
192
201
|
export const BaseUrl: React.FC<BaseUrlProps> = ({
|
|
193
202
|
form,
|
|
194
|
-
config,
|
|
195
203
|
name,
|
|
196
204
|
placeholder,
|
|
197
205
|
testId,
|
|
@@ -200,10 +208,10 @@ export const BaseUrl: React.FC<BaseUrlProps> = ({
|
|
|
200
208
|
onChange,
|
|
201
209
|
}) => {
|
|
202
210
|
return (
|
|
203
|
-
<
|
|
211
|
+
<OverriddenFormField
|
|
204
212
|
control={form.control}
|
|
205
213
|
name={name}
|
|
206
|
-
render={({ field }) => (
|
|
214
|
+
render={({ field, override }) => (
|
|
207
215
|
<div className="flex flex-col space-y-1">
|
|
208
216
|
<FormItem className={formItemClasses}>
|
|
209
217
|
<FormLabel>Base URL</FormLabel>
|
|
@@ -214,8 +222,8 @@ export const BaseUrl: React.FC<BaseUrlProps> = ({
|
|
|
214
222
|
className="m-0 inline-flex h-7"
|
|
215
223
|
placeholder={placeholder}
|
|
216
224
|
{...field}
|
|
217
|
-
value={asStringOrEmpty(
|
|
218
|
-
disabled={disabled}
|
|
225
|
+
value={asStringOrEmpty(override.value)}
|
|
226
|
+
disabled={disabled || override.isOverridden}
|
|
219
227
|
onChange={(e) => {
|
|
220
228
|
field.onChange(e.target.value);
|
|
221
229
|
onChange?.(e.target.value);
|
|
@@ -223,7 +231,7 @@ export const BaseUrl: React.FC<BaseUrlProps> = ({
|
|
|
223
231
|
/>
|
|
224
232
|
</FormControl>
|
|
225
233
|
<FormMessage />
|
|
226
|
-
<IsOverridden
|
|
234
|
+
<IsOverridden override={override} />
|
|
227
235
|
</FormItem>
|
|
228
236
|
{description && <FormDescription>{description}</FormDescription>}
|
|
229
237
|
</div>
|
|
@@ -245,7 +253,6 @@ interface ModelSelectorProps {
|
|
|
245
253
|
|
|
246
254
|
export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|
247
255
|
form,
|
|
248
|
-
config,
|
|
249
256
|
name,
|
|
250
257
|
placeholder,
|
|
251
258
|
description,
|
|
@@ -254,11 +261,12 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|
|
254
261
|
onSubmit,
|
|
255
262
|
}) => {
|
|
256
263
|
return (
|
|
257
|
-
<
|
|
264
|
+
<OverriddenFormField
|
|
258
265
|
control={form.control}
|
|
259
266
|
name={name}
|
|
260
|
-
render={({ field }) => {
|
|
261
|
-
const value = asStringOrEmpty(
|
|
267
|
+
render={({ field, override }) => {
|
|
268
|
+
const value = asStringOrEmpty(override.value);
|
|
269
|
+
const overridden = override.isOverridden;
|
|
262
270
|
|
|
263
271
|
const selectModel = (modelId: QualifiedModelId) => {
|
|
264
272
|
field.onChange(modelId);
|
|
@@ -274,6 +282,7 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|
|
274
282
|
value={value}
|
|
275
283
|
placeholder={placeholder}
|
|
276
284
|
onSelect={selectModel}
|
|
285
|
+
disabled={overridden}
|
|
277
286
|
triggerClassName="text-sm"
|
|
278
287
|
customDropdownContent={
|
|
279
288
|
<>
|
|
@@ -289,7 +298,8 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|
|
289
298
|
className="w-full border-border shadow-none focus-visible:shadow-xs"
|
|
290
299
|
placeholder={placeholder}
|
|
291
300
|
{...field}
|
|
292
|
-
value={
|
|
301
|
+
value={value}
|
|
302
|
+
disabled={overridden}
|
|
293
303
|
onKeyDown={Events.stopPropagation()}
|
|
294
304
|
/>
|
|
295
305
|
{value && (
|
|
@@ -311,7 +321,7 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|
|
311
321
|
return (
|
|
312
322
|
<div className="flex flex-col space-y-1">
|
|
313
323
|
{renderFormItem()}
|
|
314
|
-
<IsOverridden
|
|
324
|
+
<IsOverridden override={override} />
|
|
315
325
|
<IncorrectModelId value={value} />
|
|
316
326
|
{description && <FormDescription>{description}</FormDescription>}
|
|
317
327
|
</div>
|
|
@@ -332,17 +342,16 @@ interface ProviderSelectProps {
|
|
|
332
342
|
|
|
333
343
|
export const ProviderSelect: React.FC<ProviderSelectProps> = ({
|
|
334
344
|
form,
|
|
335
|
-
config,
|
|
336
345
|
name,
|
|
337
346
|
options,
|
|
338
347
|
testId,
|
|
339
348
|
disabled = false,
|
|
340
349
|
}) => {
|
|
341
350
|
return (
|
|
342
|
-
<
|
|
351
|
+
<OverriddenFormField
|
|
343
352
|
control={form.control}
|
|
344
353
|
name={name}
|
|
345
|
-
render={({ field }) => (
|
|
354
|
+
render={({ field, override }) => (
|
|
346
355
|
<div className="flex flex-col space-y-1">
|
|
347
356
|
<FormItem className={formItemClasses}>
|
|
348
357
|
<FormLabel>Provider</FormLabel>
|
|
@@ -357,13 +366,13 @@ export const ProviderSelect: React.FC<ProviderSelectProps> = ({
|
|
|
357
366
|
}
|
|
358
367
|
}}
|
|
359
368
|
value={asStringOrEmpty(
|
|
360
|
-
|
|
369
|
+
override.value === true
|
|
361
370
|
? "github"
|
|
362
|
-
:
|
|
371
|
+
: override.value === false
|
|
363
372
|
? "none"
|
|
364
|
-
:
|
|
373
|
+
: override.value,
|
|
365
374
|
)}
|
|
366
|
-
disabled={disabled}
|
|
375
|
+
disabled={disabled || override.isOverridden}
|
|
367
376
|
className="inline-flex mr-2"
|
|
368
377
|
>
|
|
369
378
|
{options.map((option) => (
|
|
@@ -374,7 +383,7 @@ export const ProviderSelect: React.FC<ProviderSelectProps> = ({
|
|
|
374
383
|
</NativeSelect>
|
|
375
384
|
</FormControl>
|
|
376
385
|
<FormMessage />
|
|
377
|
-
<IsOverridden
|
|
386
|
+
<IsOverridden override={override} />
|
|
378
387
|
</FormItem>
|
|
379
388
|
</div>
|
|
380
389
|
)}
|
|
@@ -386,12 +395,13 @@ const renderCopilotProvider = ({
|
|
|
386
395
|
form,
|
|
387
396
|
config,
|
|
388
397
|
onSubmit,
|
|
398
|
+
copilot,
|
|
389
399
|
}: {
|
|
390
400
|
form: UseFormReturn<UserConfig>;
|
|
391
401
|
config: UserConfig;
|
|
392
402
|
onSubmit: (values: UserConfig) => void;
|
|
403
|
+
copilot: UserConfig["completion"]["copilot"];
|
|
393
404
|
}) => {
|
|
394
|
-
const copilot = form.getValues("completion.copilot");
|
|
395
405
|
if (copilot === false) {
|
|
396
406
|
return null;
|
|
397
407
|
}
|
|
@@ -535,6 +545,15 @@ export const AiCodeCompletionConfig: React.FC<AiConfigProps> = ({
|
|
|
535
545
|
config,
|
|
536
546
|
onSubmit,
|
|
537
547
|
}) => {
|
|
548
|
+
const getOverride = useConfigOverride();
|
|
549
|
+
// Watch (not `getValues`) so the sub-form re-renders when the provider
|
|
550
|
+
// changes, then resolve the effective value so an overridden
|
|
551
|
+
// `completion.copilot` shows the matching sub-form (not the user's saved one).
|
|
552
|
+
const watchedCopilot = useWatch({
|
|
553
|
+
control: form.control,
|
|
554
|
+
name: "completion.copilot",
|
|
555
|
+
});
|
|
556
|
+
const { value: copilot } = getOverride("completion.copilot", watchedCopilot);
|
|
538
557
|
return (
|
|
539
558
|
<SettingGroup>
|
|
540
559
|
<SettingSubtitle>Code Completion</SettingSubtitle>
|
|
@@ -551,7 +570,7 @@ export const AiCodeCompletionConfig: React.FC<AiConfigProps> = ({
|
|
|
551
570
|
testId="copilot-select"
|
|
552
571
|
/>
|
|
553
572
|
|
|
554
|
-
{renderCopilotProvider({ form, config, onSubmit })}
|
|
573
|
+
{renderCopilotProvider({ form, config, onSubmit, copilot })}
|
|
555
574
|
</SettingGroup>
|
|
556
575
|
);
|
|
557
576
|
};
|
|
@@ -608,7 +627,7 @@ export const CustomProvidersConfig: React.FC<AiConfigProps> = ({
|
|
|
608
627
|
const normalizedName = newProviderName.toLowerCase().replaceAll(/\s+/g, "_");
|
|
609
628
|
const customProviders = form.watch("ai.custom_providers");
|
|
610
629
|
const isDuplicate =
|
|
611
|
-
|
|
630
|
+
SUPPORTED_PROVIDERS_UI.has(normalizedName as KnownProviderId) ||
|
|
612
631
|
(customProviders && Object.keys(customProviders).includes(normalizedName));
|
|
613
632
|
const hasInvalidChars = normalizedName.includes(".");
|
|
614
633
|
|
|
@@ -1134,11 +1153,11 @@ export const AiProvidersConfig: React.FC<AiConfigProps> = ({
|
|
|
1134
1153
|
for more details.
|
|
1135
1154
|
</p>
|
|
1136
1155
|
|
|
1137
|
-
<
|
|
1156
|
+
<OverriddenFormField
|
|
1138
1157
|
control={form.control}
|
|
1139
1158
|
disabled={isWasmRuntime}
|
|
1140
1159
|
name="ai.bedrock.region_name"
|
|
1141
|
-
render={({ field }) => (
|
|
1160
|
+
render={({ field, override }) => (
|
|
1142
1161
|
<div className="flex flex-col space-y-1">
|
|
1143
1162
|
<FormItem className={formItemClasses}>
|
|
1144
1163
|
<FormLabel>AWS Region</FormLabel>
|
|
@@ -1147,11 +1166,11 @@ export const AiProvidersConfig: React.FC<AiConfigProps> = ({
|
|
|
1147
1166
|
data-testid="bedrock-region-select"
|
|
1148
1167
|
onChange={(e) => field.onChange(e.target.value)}
|
|
1149
1168
|
value={
|
|
1150
|
-
typeof
|
|
1151
|
-
?
|
|
1169
|
+
typeof override.value === "string"
|
|
1170
|
+
? override.value
|
|
1152
1171
|
: "us-east-1"
|
|
1153
1172
|
}
|
|
1154
|
-
disabled={field.disabled}
|
|
1173
|
+
disabled={field.disabled || override.isOverridden}
|
|
1155
1174
|
className="inline-flex mr-2"
|
|
1156
1175
|
>
|
|
1157
1176
|
{AWS_REGIONS.map((option) => (
|
|
@@ -1162,10 +1181,7 @@ export const AiProvidersConfig: React.FC<AiConfigProps> = ({
|
|
|
1162
1181
|
</NativeSelect>
|
|
1163
1182
|
</FormControl>
|
|
1164
1183
|
<FormMessage />
|
|
1165
|
-
<IsOverridden
|
|
1166
|
-
userConfig={config}
|
|
1167
|
-
name="ai.bedrock.region_name"
|
|
1168
|
-
/>
|
|
1184
|
+
<IsOverridden override={override} />
|
|
1169
1185
|
</FormItem>
|
|
1170
1186
|
<FormDescription>
|
|
1171
1187
|
The AWS region where Bedrock service is available.
|
|
@@ -1174,11 +1190,11 @@ export const AiProvidersConfig: React.FC<AiConfigProps> = ({
|
|
|
1174
1190
|
)}
|
|
1175
1191
|
/>
|
|
1176
1192
|
|
|
1177
|
-
<
|
|
1193
|
+
<OverriddenFormField
|
|
1178
1194
|
control={form.control}
|
|
1179
1195
|
disabled={isWasmRuntime}
|
|
1180
1196
|
name="ai.bedrock.profile_name"
|
|
1181
|
-
render={({ field }) => (
|
|
1197
|
+
render={({ field, override }) => (
|
|
1182
1198
|
<div className="flex flex-col space-y-1">
|
|
1183
1199
|
<FormItem className={formItemClasses}>
|
|
1184
1200
|
<FormLabel>AWS Profile Name (Optional)</FormLabel>
|
|
@@ -1189,14 +1205,12 @@ export const AiProvidersConfig: React.FC<AiConfigProps> = ({
|
|
|
1189
1205
|
className="m-0 inline-flex h-7"
|
|
1190
1206
|
placeholder="default"
|
|
1191
1207
|
{...field}
|
|
1192
|
-
value={
|
|
1208
|
+
value={override.value || ""}
|
|
1209
|
+
disabled={field.disabled || override.isOverridden}
|
|
1193
1210
|
/>
|
|
1194
1211
|
</FormControl>
|
|
1195
1212
|
<FormMessage />
|
|
1196
|
-
<IsOverridden
|
|
1197
|
-
userConfig={config}
|
|
1198
|
-
name="ai.bedrock.profile_name"
|
|
1199
|
-
/>
|
|
1213
|
+
<IsOverridden override={override} />
|
|
1200
1214
|
</FormItem>
|
|
1201
1215
|
<FormDescription>
|
|
1202
1216
|
The AWS profile name from your ~/.aws/credentials file. Leave
|
|
@@ -1380,10 +1394,10 @@ export const AiAssistConfig: React.FC<AiConfigProps> = ({
|
|
|
1380
1394
|
onSubmit={onSubmit}
|
|
1381
1395
|
/>
|
|
1382
1396
|
|
|
1383
|
-
<
|
|
1397
|
+
<OverriddenFormField
|
|
1384
1398
|
control={form.control}
|
|
1385
1399
|
name="ai.rules"
|
|
1386
|
-
render={({ field }) => (
|
|
1400
|
+
render={({ field, override }) => (
|
|
1387
1401
|
<div className="flex flex-col">
|
|
1388
1402
|
<FormItem>
|
|
1389
1403
|
<FormLabel>Custom Rules</FormLabel>
|
|
@@ -1393,11 +1407,12 @@ export const AiAssistConfig: React.FC<AiConfigProps> = ({
|
|
|
1393
1407
|
className="m-0 inline-flex w-full h-32 p-2 text-sm"
|
|
1394
1408
|
placeholder="e.g. Always use type hints; prefer polars over pandas"
|
|
1395
1409
|
{...field}
|
|
1396
|
-
value={
|
|
1410
|
+
value={override.value}
|
|
1411
|
+
disabled={override.isOverridden}
|
|
1397
1412
|
/>
|
|
1398
1413
|
</FormControl>
|
|
1399
1414
|
<FormMessage />
|
|
1400
|
-
<IsOverridden
|
|
1415
|
+
<IsOverridden override={override} />
|
|
1401
1416
|
</FormItem>
|
|
1402
1417
|
<FormDescription>
|
|
1403
1418
|
Custom rules to include in all AI completion prompts.
|
|
@@ -1849,26 +1864,27 @@ export type AiSettingsSubTab =
|
|
|
1849
1864
|
| "ai-models"
|
|
1850
1865
|
| "mcp";
|
|
1851
1866
|
|
|
1852
|
-
const AiEnabledConfig: React.FC<AiConfigProps> = ({ form
|
|
1867
|
+
const AiEnabledConfig: React.FC<AiConfigProps> = ({ form }) => {
|
|
1853
1868
|
return (
|
|
1854
1869
|
<SettingGroup>
|
|
1855
|
-
<
|
|
1870
|
+
<OverriddenFormField
|
|
1856
1871
|
control={form.control}
|
|
1857
1872
|
name="ai.enabled"
|
|
1858
|
-
render={({ field }) => (
|
|
1873
|
+
render={({ field, override }) => (
|
|
1859
1874
|
<div className="flex flex-col gap-y-1">
|
|
1860
1875
|
<FormItem className={formItemClasses}>
|
|
1861
1876
|
<FormLabel className="font-normal">Enable AI features</FormLabel>
|
|
1862
1877
|
<FormControl>
|
|
1863
1878
|
<Checkbox
|
|
1864
1879
|
data-testid="ai-enabled-checkbox"
|
|
1865
|
-
checked={
|
|
1880
|
+
checked={override.value !== false}
|
|
1881
|
+
disabled={override.isOverridden}
|
|
1866
1882
|
onCheckedChange={(checked) =>
|
|
1867
1883
|
field.onChange(checked === true)
|
|
1868
1884
|
}
|
|
1869
1885
|
/>
|
|
1870
1886
|
</FormControl>
|
|
1871
|
-
<IsOverridden
|
|
1887
|
+
<IsOverridden override={override} />
|
|
1872
1888
|
</FormItem>
|
|
1873
1889
|
<FormDescription>
|
|
1874
1890
|
When disabled, AI actions and panels are hidden from the marimo
|
|
@@ -1889,10 +1905,12 @@ export const AiConfig: React.FC<AiConfigProps> = ({
|
|
|
1889
1905
|
// MCP is not supported in WASM
|
|
1890
1906
|
const wasm = isWasm();
|
|
1891
1907
|
const [activeTab, setActiveTab] = useAtom(aiSettingsSubTabAtom);
|
|
1892
|
-
const
|
|
1908
|
+
const getOverride = useConfigOverride();
|
|
1909
|
+
const watchedAiEnabled = useWatch({
|
|
1893
1910
|
control: form.control,
|
|
1894
1911
|
name: "ai.enabled",
|
|
1895
1912
|
});
|
|
1913
|
+
const { value: aiEnabled } = getOverride("ai.enabled", watchedAiEnabled);
|
|
1896
1914
|
const activeVisibleTab =
|
|
1897
1915
|
aiEnabled === false && activeTab !== "ai-features"
|
|
1898
1916
|
? "ai-features"
|