@marimo-team/frontend 0.15.0 → 0.15.1-dev10
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/assets/{ConnectedDataExplorerComponent-Bl5fR_87.js → ConnectedDataExplorerComponent-BvA88co5.js} +1 -1
- package/dist/assets/{ImageComparisonComponent-CRfr-CiC.js → ImageComparisonComponent-DMstqRhm.js} +1 -1
- package/dist/assets/{VegaLite-Bo_A9ZZm.js → VegaLite-Mesl0wXW.js} +1 -1
- package/dist/assets/{_baseEach-CIMlsWNn.js → _baseEach-4LREA2xJ.js} +1 -1
- package/dist/assets/_baseMap-C6LNFWWn.js +1 -0
- package/dist/assets/{_baseUniq-CGK6su7v.js → _baseUniq-C4wq7Gz_.js} +1 -1
- package/dist/assets/{_createAggregator--z161kAx.js → _createAggregator-Di1sij95.js} +1 -1
- package/dist/assets/{any-language-editor-hSTaStg9.js → any-language-editor-CNdroSlJ.js} +1 -1
- package/dist/assets/{architectureDiagram-KFL7JDKH-CqrWvX5_.js → architectureDiagram-KFL7JDKH-BxXZfRHj.js} +1 -1
- package/dist/assets/{blockDiagram-ZYB65J3Q-CRgdhCYU.js → blockDiagram-ZYB65J3Q-8mg_ND0j.js} +1 -1
- package/dist/assets/{c4Diagram-AAMF2YG6-DUHfB-bk.js → c4Diagram-AAMF2YG6-BH1zFYgt.js} +1 -1
- package/dist/assets/channel-B3CCoyYy.js +1 -0
- package/dist/assets/{chunk-ANTBXLJU-ZgvmG8Pb.js → chunk-ANTBXLJU-wUIE1C6t.js} +1 -1
- package/dist/assets/{chunk-FHKO5MBM-B-EzrMTM.js → chunk-FHKO5MBM-BnGig1B_.js} +1 -1
- package/dist/assets/{chunk-GLLZNHP4-DRBUPzV6.js → chunk-GLLZNHP4-BeuHRwGr.js} +1 -1
- package/dist/assets/{chunk-JBRWN2VN-vkbXs27X.js → chunk-JBRWN2VN-BEuqVuwn.js} +1 -1
- package/dist/assets/{chunk-LXBSTHXV-itspTgVu.js → chunk-LXBSTHXV-DIaccDrz.js} +1 -1
- package/dist/assets/{chunk-NRVI72HA-gO-7Uy2L.js → chunk-NRVI72HA-I0EqNhLo.js} +1 -1
- package/dist/assets/{chunk-OMD6QJNC-CwDxph2q.js → chunk-OMD6QJNC-DBDKfLns.js} +1 -1
- package/dist/assets/{chunk-WVR4S24B-DkjWv9uk.js → chunk-WVR4S24B-D9vksrD4.js} +1 -1
- package/dist/assets/{circle-play-BURxVoHD.js → circle-play-Xdbicaqg.js} +1 -1
- package/dist/assets/classDiagram-3BZAVTQC-CLXskjCP.js +1 -0
- package/dist/assets/classDiagram-v2-QTMF73CY-CLXskjCP.js +1 -0
- package/dist/assets/clone-BCc-guNO.js +1 -0
- package/dist/assets/{compile-CQlZ79Z5.js → compile-D-SKgFzl.js} +1 -1
- package/dist/assets/{dagre-2BBEFEWP-DEiqD84H.js → dagre-2BBEFEWP-Dj4VJDXi.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-CS6yXy6C.js → data-grid-overlay-editor-BHUr5Xhc.js} +1 -1
- package/dist/assets/{diagram-4IRLE6MV-ommhV7Ge.js → diagram-4IRLE6MV-9wayoyRN.js} +1 -1
- package/dist/assets/{diagram-GUPCWM2R-D09B2kyR.js → diagram-GUPCWM2R-5NhVlGLr.js} +1 -1
- package/dist/assets/{diagram-RP2FKANI-D1AZYHbD.js → diagram-RP2FKANI-CNBOj37W.js} +1 -1
- package/dist/assets/{edit-page-DhSV7e13.js → edit-page-D8Xj7wsn.js} +16 -16
- package/dist/assets/{erDiagram-HZWUO2LU-Civ5tj0J.js → erDiagram-HZWUO2LU-KEjz95KS.js} +1 -1
- package/dist/assets/{flowDiagram-THRYKUMA--HeKh8ql.js → flowDiagram-THRYKUMA-9PtbKpm0.js} +1 -1
- package/dist/assets/{ganttDiagram-WV7ZQ7D5-YEcfQSSf.js → ganttDiagram-WV7ZQ7D5-CFXRYmNt.js} +1 -1
- package/dist/assets/{gitGraphDiagram-OJR772UL-DhkURReZ.js → gitGraphDiagram-OJR772UL-hFrAcG26.js} +1 -1
- package/dist/assets/{glide-data-editor-CudlNmdp.js → glide-data-editor-HLSiEHg4.js} +4 -4
- package/dist/assets/{graph-CQvdQbxU.js → graph-iTnwmAye.js} +1 -1
- package/dist/assets/{home-page-_l6RVaRB.js → home-page-DzRg-dzP.js} +1 -1
- package/dist/assets/{index-CAtmZMbK.js → index-B3l0i9L2.js} +1 -1
- package/dist/assets/{index-DZJOZ8C0.js → index-BA1eBtgJ.js} +1 -1
- package/dist/assets/{index-B9dXZoY1.js → index-BMCpi_hV.js} +1 -1
- package/dist/assets/index-BRPMSgmu.css +1 -0
- package/dist/assets/{index-DbsrZX7Q.js → index-Bj_MIGqG.js} +1 -1
- package/dist/assets/{index-QoqjKBP_.js → index-BlHS2xQv.js} +1 -1
- package/dist/assets/{index-DvySElQ5.js → index-BzQQnlIk.js} +1 -1
- package/dist/assets/{index-CvLIL6JV.js → index-BzZRHBMs.js} +1 -1
- package/dist/assets/{index-DMtmziVF.js → index-CEoUSuyW.js} +1 -1
- package/dist/assets/{index-6WfEFtf2.js → index-CJRYE40I.js} +1 -1
- package/dist/assets/{index-nyTtvXGx.js → index-CQ7rf4K7.js} +1 -1
- package/dist/assets/{index-C6CvZyWd.js → index-Cl5g0z7j.js} +1 -1
- package/dist/assets/{index-CbNkOFUU.js → index-Cni7Zj6s.js} +1 -1
- package/dist/assets/{index-CqRTe3S2.js → index-CrltF-5r.js} +1 -1
- package/dist/assets/{index-BCdqiRjH.js → index-CswmrBaY.js} +1 -1
- package/dist/assets/{index-Do3KUHEe.js → index-D1rqBcHl.js} +1 -1
- package/dist/assets/{index-DhRZE5tA.js → index-DApZsb--.js} +1 -1
- package/dist/assets/{index-3z3sI3MY.js → index-DNVhZM1y.js} +1 -1
- package/dist/assets/{index-BvRQ66y_.js → index-DWJwqJmD.js} +1 -1
- package/dist/assets/{index-D-8oCPO1.js → index-DmunXcbP.js} +1 -1
- package/dist/assets/{index-D4bXoNM3.js → index-WZpn7zIz.js} +157 -157
- package/dist/assets/infoDiagram-6WOFNB3A-BvitCnlF.js +2 -0
- package/dist/assets/{journeyDiagram-FFXJYRFH-CC3RaMZl.js → journeyDiagram-FFXJYRFH-BEiF2rN9.js} +1 -1
- package/dist/assets/{kanban-definition-KOZQBZVT-1Z4QU83I.js → kanban-definition-KOZQBZVT-BZZVRqX0.js} +1 -1
- package/dist/assets/{layout-DuQ9W6pS.js → layout-2hUFrdoK.js} +1 -1
- package/dist/assets/{linear-BsI0Wmp7.js → linear-DM7ygpKu.js} +1 -1
- package/dist/assets/{links-D_cg4TpC.js → links-BJFGdYRd.js} +8 -8
- package/dist/assets/{mermaid-D59lkToe.js → mermaid-CxGPSzDz.js} +4 -4
- package/dist/assets/{min-DrLfF3uL.js → min-DS87IVOa.js} +1 -1
- package/dist/assets/{mindmap-definition-LNHGMQRG-ePnX66wd.js → mindmap-definition-LNHGMQRG-C7yfXmRD.js} +1 -1
- package/dist/assets/{number-overlay-editor-CPxl07sM.js → number-overlay-editor-qOf48nx-.js} +1 -1
- package/dist/assets/{pieDiagram-DBDJKBY4-BWYaH6Hi.js → pieDiagram-DBDJKBY4-CRluUHH0.js} +1 -1
- package/dist/assets/{quadrantDiagram-YPSRARAO-BwuEJiK-.js → quadrantDiagram-YPSRARAO-FZO2_Kyx.js} +1 -1
- package/dist/assets/{react-plotly-eq8YBLKm.js → react-plotly-BV6Vu1ZC.js} +1 -1
- package/dist/assets/{requirementDiagram-EGVEC5DT-B0dO70r7.js → requirementDiagram-EGVEC5DT-CFEV56bq.js} +1 -1
- package/dist/assets/{run-page-DP_FNoql.js → run-page-BiiAHZuC.js} +1 -1
- package/dist/assets/{sankeyDiagram-HRAUVNP4-DlbnyCg4.js → sankeyDiagram-HRAUVNP4-cf6xzlF-.js} +1 -1
- package/dist/assets/{sequenceDiagram-WFGC7UMF-BfhFFLfz.js → sequenceDiagram-WFGC7UMF-CEIC5fba.js} +1 -1
- package/dist/assets/{slides-component-Bso9rHdK.js → slides-component-BXl359nW.js} +1 -1
- package/dist/assets/{sortBy-utaS96Bi.js → sortBy-Dv7jjKnm.js} +1 -1
- package/dist/assets/{stateDiagram-UUKSUZ4H-ByVZAeGw.js → stateDiagram-UUKSUZ4H-DLvG9b91.js} +1 -1
- package/dist/assets/stateDiagram-v2-EYPG3UTE-Z_xESMay.js +1 -0
- package/dist/assets/{storage-DrvlAZZd.js → storage-B47VVzw1.js} +3 -3
- package/dist/assets/{terminal-CuPjZ1vE.js → terminal-2p_4lGQJ.js} +1 -1
- package/dist/assets/{time-1P0zCPa4.js → time-OI-T4MiC.js} +1 -1
- package/dist/assets/{timeline-definition-3HZDQTIS-BLUL1ZU4.js → timeline-definition-3HZDQTIS-Da1Ro9aI.js} +1 -1
- package/dist/assets/{tracing-BpM0fbsC.js → tracing-CRxB69vv.js} +2 -2
- package/dist/assets/{trash-D5wptdZI.js → trash-DM7Eop-E.js} +1 -1
- package/dist/assets/{treemap-75Q7IDZK-Bh5pVSmo.js → treemap-75Q7IDZK-DaZTYidc.js} +1 -1
- package/dist/assets/{vega-component-tH6bw1Lr.js → vega-component-D1rpMJYI.js} +1 -1
- package/dist/assets/{xychartDiagram-FDP5SA34-qY_Wo73t.js → xychartDiagram-FDP5SA34-COsO2s8u.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/components/ai/ai-model-dropdown.tsx +165 -41
- package/src/components/datasources/datasources.tsx +19 -2
- package/src/components/ui/dropdown-menu.tsx +11 -10
- package/src/core/ai/__tests__/model-registry.test.ts +12 -12
- package/src/core/ai/model-registry.ts +19 -25
- package/src/core/config/config.ts +4 -0
- package/src/core/config/feature-flag.tsx +1 -5
- package/src/core/datasets/engines.ts +1 -0
- package/src/css/katex.min.css +1 -0
- package/dist/assets/_baseMap-1GEe_WcR.js +0 -1
- package/dist/assets/channel-D31q3TW_.js +0 -1
- package/dist/assets/classDiagram-3BZAVTQC-0O2jYKfn.js +0 -1
- package/dist/assets/classDiagram-v2-QTMF73CY-0O2jYKfn.js +0 -1
- package/dist/assets/clone-DFaYgbfI.js +0 -1
- package/dist/assets/index-CrH6PPjG.css +0 -1
- package/dist/assets/infoDiagram-6WOFNB3A-B7BrcI_a.js +0 -2
- package/dist/assets/stateDiagram-v2-EYPG3UTE-C6PYJGwL.js +0 -1
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import type { Role } from "@marimo-team/llm-info";
|
|
4
|
+
import { useAtomValue } from "jotai";
|
|
4
5
|
import { capitalize } from "lodash-es";
|
|
5
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
BotIcon,
|
|
8
|
+
BrainIcon,
|
|
9
|
+
ChevronDownIcon,
|
|
10
|
+
CircleHelpIcon,
|
|
11
|
+
} from "lucide-react";
|
|
12
|
+
import React from "react";
|
|
6
13
|
import {
|
|
7
14
|
AiModelId,
|
|
8
15
|
isKnownAIProvider,
|
|
@@ -10,7 +17,7 @@ import {
|
|
|
10
17
|
type QualifiedModelId,
|
|
11
18
|
} from "@/core/ai/ids/ids";
|
|
12
19
|
import { type AiModel, AiModelRegistry } from "@/core/ai/model-registry";
|
|
13
|
-
import {
|
|
20
|
+
import { aiAtom, completionAtom } from "@/core/config/config";
|
|
14
21
|
import {
|
|
15
22
|
DropdownMenu,
|
|
16
23
|
DropdownMenuContent,
|
|
@@ -22,6 +29,7 @@ import {
|
|
|
22
29
|
DropdownMenuSubTrigger,
|
|
23
30
|
DropdownMenuTrigger,
|
|
24
31
|
} from "../ui/dropdown-menu";
|
|
32
|
+
import { Tooltip } from "../ui/tooltip";
|
|
25
33
|
import { AiProviderIcon } from "./ai-provider-icon";
|
|
26
34
|
|
|
27
35
|
interface AIModelDropdownProps {
|
|
@@ -46,36 +54,37 @@ export const AIModelDropdown = ({
|
|
|
46
54
|
forRole,
|
|
47
55
|
}: AIModelDropdownProps) => {
|
|
48
56
|
const currentValue = value ? AiModelId.parse(value) : undefined;
|
|
57
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
49
58
|
|
|
50
|
-
const
|
|
51
|
-
const
|
|
59
|
+
const ai = useAtomValue(aiAtom);
|
|
60
|
+
const completion = useAtomValue(completionAtom);
|
|
52
61
|
|
|
53
62
|
// Only include autocompleteModel if copilot is set to "custom"
|
|
54
63
|
const autocompleteModel =
|
|
55
|
-
|
|
56
|
-
?
|
|
64
|
+
completion.copilot === "custom"
|
|
65
|
+
? ai?.models?.autocomplete_model
|
|
57
66
|
: undefined;
|
|
58
67
|
|
|
59
68
|
const aiModelRegistry = AiModelRegistry.create({
|
|
60
69
|
// We add all the custom models and the models used in the editor.
|
|
61
70
|
// If they among the known models, they won't overwrite them.
|
|
62
71
|
customModels: [
|
|
63
|
-
...(
|
|
64
|
-
|
|
72
|
+
...(ai?.models?.custom_models ?? []),
|
|
73
|
+
ai?.models?.chat_model,
|
|
65
74
|
autocompleteModel,
|
|
66
|
-
|
|
75
|
+
ai?.models?.edit_model,
|
|
67
76
|
].filter(Boolean),
|
|
68
|
-
displayedModels:
|
|
77
|
+
displayedModels: ai?.models?.displayed_models,
|
|
69
78
|
});
|
|
70
79
|
const modelsByProvider = aiModelRegistry.getGroupedModelsByProvider();
|
|
71
80
|
|
|
72
81
|
const activeModel =
|
|
73
82
|
forRole === "autocomplete"
|
|
74
|
-
?
|
|
83
|
+
? ai?.models?.autocomplete_model
|
|
75
84
|
: forRole === "chat"
|
|
76
|
-
?
|
|
85
|
+
? ai?.models?.chat_model
|
|
77
86
|
: forRole === "edit"
|
|
78
|
-
?
|
|
87
|
+
? ai?.models?.edit_model
|
|
79
88
|
: undefined;
|
|
80
89
|
|
|
81
90
|
const iconSizeClass = iconSize === "medium" ? "h-4 w-4" : "h-3 w-3";
|
|
@@ -95,19 +104,26 @@ export const AIModelDropdown = ({
|
|
|
95
104
|
</div>
|
|
96
105
|
|
|
97
106
|
<div className="ml-auto flex gap-1">
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
<Tooltip content={getTagTooltip(role)}>
|
|
108
|
+
<span
|
|
109
|
+
key={role}
|
|
110
|
+
className={`text-xs px-1.5 py-0.5 rounded font-medium ${getTagColour(role)}`}
|
|
111
|
+
>
|
|
112
|
+
{role}
|
|
113
|
+
</span>
|
|
114
|
+
</Tooltip>
|
|
104
115
|
</div>
|
|
105
116
|
</div>
|
|
106
117
|
);
|
|
107
118
|
};
|
|
108
119
|
|
|
120
|
+
const handleSelect = (modelId: QualifiedModelId) => {
|
|
121
|
+
onSelect(modelId);
|
|
122
|
+
setIsOpen(false);
|
|
123
|
+
};
|
|
124
|
+
|
|
109
125
|
return (
|
|
110
|
-
<DropdownMenu>
|
|
126
|
+
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
|
111
127
|
<DropdownMenuTrigger
|
|
112
128
|
className={`flex items-center justify-between px-2 py-0.5 border rounded-md
|
|
113
129
|
hover:bg-accent hover:text-accent-foreground ${triggerClassName}`}
|
|
@@ -144,7 +160,7 @@ export const AIModelDropdown = ({
|
|
|
144
160
|
<ProviderDropdownContent
|
|
145
161
|
key={provider}
|
|
146
162
|
provider={provider}
|
|
147
|
-
onSelect={
|
|
163
|
+
onSelect={handleSelect}
|
|
148
164
|
models={models}
|
|
149
165
|
iconSizeClass={iconSizeClass}
|
|
150
166
|
/>
|
|
@@ -177,13 +193,11 @@ const ProviderDropdownContent = ({
|
|
|
177
193
|
provider,
|
|
178
194
|
onSelect,
|
|
179
195
|
models,
|
|
180
|
-
customModelIcon,
|
|
181
196
|
iconSizeClass,
|
|
182
197
|
}: {
|
|
183
198
|
provider: ProviderId;
|
|
184
199
|
onSelect: (modelId: QualifiedModelId) => void;
|
|
185
200
|
models: AiModel[];
|
|
186
|
-
customModelIcon?: React.ReactNode;
|
|
187
201
|
iconSizeClass: string;
|
|
188
202
|
}) => {
|
|
189
203
|
const iconProvider = isKnownAIProvider(provider)
|
|
@@ -207,7 +221,8 @@ const ProviderDropdownContent = ({
|
|
|
207
221
|
<DropdownMenuPortal>
|
|
208
222
|
<DropdownMenuSubContent
|
|
209
223
|
className="max-h-[40vh] overflow-y-auto"
|
|
210
|
-
alignOffset={-90}
|
|
224
|
+
alignOffset={maybeProviderInfo ? -90 : 0}
|
|
225
|
+
sideOffset={5}
|
|
211
226
|
>
|
|
212
227
|
{maybeProviderInfo && (
|
|
213
228
|
<>
|
|
@@ -236,22 +251,21 @@ const ProviderDropdownContent = ({
|
|
|
236
251
|
const qualifiedModelId =
|
|
237
252
|
`${provider}/${model.model}` as QualifiedModelId;
|
|
238
253
|
return (
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
</
|
|
253
|
-
|
|
254
|
-
</DropdownMenuItem>
|
|
254
|
+
<DropdownMenuSub key={qualifiedModelId}>
|
|
255
|
+
<DropdownMenuSubTrigger showChevron={false} className="py-2">
|
|
256
|
+
<div
|
|
257
|
+
className="flex items-center gap-2 w-full cursor-pointer"
|
|
258
|
+
onClick={() => {
|
|
259
|
+
onSelect(qualifiedModelId);
|
|
260
|
+
}}
|
|
261
|
+
>
|
|
262
|
+
<AiModelDropdownItem model={model} provider={provider} />
|
|
263
|
+
</div>
|
|
264
|
+
</DropdownMenuSubTrigger>
|
|
265
|
+
<DropdownMenuSubContent className="p-4 w-80">
|
|
266
|
+
<AiModelInfoDisplay model={model} provider={provider} />
|
|
267
|
+
</DropdownMenuSubContent>
|
|
268
|
+
</DropdownMenuSub>
|
|
255
269
|
);
|
|
256
270
|
})}
|
|
257
271
|
</DropdownMenuSubContent>
|
|
@@ -260,6 +274,99 @@ const ProviderDropdownContent = ({
|
|
|
260
274
|
);
|
|
261
275
|
};
|
|
262
276
|
|
|
277
|
+
const AiModelDropdownItem = ({
|
|
278
|
+
model,
|
|
279
|
+
provider,
|
|
280
|
+
}: {
|
|
281
|
+
model: AiModel;
|
|
282
|
+
provider: ProviderId;
|
|
283
|
+
}) => {
|
|
284
|
+
const iconProvider = isKnownAIProvider(provider)
|
|
285
|
+
? provider
|
|
286
|
+
: "openai-compatible";
|
|
287
|
+
|
|
288
|
+
return (
|
|
289
|
+
<>
|
|
290
|
+
<AiProviderIcon provider={iconProvider} className="h-4 w-4" />
|
|
291
|
+
<div className="flex flex-row w-full items-center">
|
|
292
|
+
<span>{model.name}</span>
|
|
293
|
+
<div className="ml-auto">
|
|
294
|
+
{model.thinking && (
|
|
295
|
+
<Tooltip content="Reasoning model">
|
|
296
|
+
<BrainIcon
|
|
297
|
+
className={`h-5 w-5 rounded-md p-1 ${getTagColour("thinking")}`}
|
|
298
|
+
/>
|
|
299
|
+
</Tooltip>
|
|
300
|
+
)}
|
|
301
|
+
</div>
|
|
302
|
+
</div>
|
|
303
|
+
{model.custom && (
|
|
304
|
+
<Tooltip content="Custom model">
|
|
305
|
+
<BotIcon className="h-5 w-5" />
|
|
306
|
+
</Tooltip>
|
|
307
|
+
)}
|
|
308
|
+
</>
|
|
309
|
+
);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const AiModelInfoDisplay = ({
|
|
313
|
+
model,
|
|
314
|
+
provider,
|
|
315
|
+
}: {
|
|
316
|
+
model: AiModel;
|
|
317
|
+
provider: ProviderId;
|
|
318
|
+
}) => {
|
|
319
|
+
return (
|
|
320
|
+
<div className="space-y-3">
|
|
321
|
+
<div>
|
|
322
|
+
<h4 className="font-semibold text-base text-foreground">
|
|
323
|
+
{model.name}
|
|
324
|
+
</h4>
|
|
325
|
+
<p className="text-xs text-muted-foreground font-mono">{model.model}</p>
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<p className="text-sm text-muted-foreground leading-relaxed">
|
|
329
|
+
{model.description}
|
|
330
|
+
</p>
|
|
331
|
+
|
|
332
|
+
{model.roles.length > 0 && (
|
|
333
|
+
<div>
|
|
334
|
+
<p className="text-xs font-medium text-muted-foreground mb-2">
|
|
335
|
+
Capabilities:
|
|
336
|
+
</p>
|
|
337
|
+
<div className="flex flex-wrap gap-1">
|
|
338
|
+
{model.roles.map((role) => (
|
|
339
|
+
<span
|
|
340
|
+
key={role}
|
|
341
|
+
className={`px-2 py-1 text-xs rounded-md font-medium ${getTagColour(role)}`}
|
|
342
|
+
title={getTagTooltip(role)}
|
|
343
|
+
>
|
|
344
|
+
{role}
|
|
345
|
+
</span>
|
|
346
|
+
))}
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
)}
|
|
350
|
+
|
|
351
|
+
{model.thinking && (
|
|
352
|
+
<div className="flex items-center gap-2">
|
|
353
|
+
<div className="w-2 h-2 bg-purple-500 rounded-full animate-pulse" />
|
|
354
|
+
<span className="text-xs text-muted-foreground">
|
|
355
|
+
Supports thinking mode
|
|
356
|
+
</span>
|
|
357
|
+
</div>
|
|
358
|
+
)}
|
|
359
|
+
|
|
360
|
+
<div className="flex items-center gap-2 pt-2 border-t border-border">
|
|
361
|
+
<AiProviderIcon provider={provider} className="h-4 w-4" />
|
|
362
|
+
<span className="text-xs text-muted-foreground">
|
|
363
|
+
{getProviderLabel(provider)}
|
|
364
|
+
</span>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
);
|
|
368
|
+
};
|
|
369
|
+
|
|
263
370
|
function getProviderLabel(provider: ProviderId): string {
|
|
264
371
|
const providerInfo = AiModelRegistry.getProviderInfo(provider);
|
|
265
372
|
if (providerInfo) {
|
|
@@ -268,7 +375,7 @@ function getProviderLabel(provider: ProviderId): string {
|
|
|
268
375
|
return capitalize(provider);
|
|
269
376
|
}
|
|
270
377
|
|
|
271
|
-
function getTagColour(role: Role): string {
|
|
378
|
+
function getTagColour(role: Role | "thinking"): string {
|
|
272
379
|
switch (role) {
|
|
273
380
|
case "chat":
|
|
274
381
|
return "bg-[var(--purple-3)] text-[var(--purple-11)]";
|
|
@@ -276,6 +383,23 @@ function getTagColour(role: Role): string {
|
|
|
276
383
|
return "bg-[var(--green-3)] text-[var(--green-11)]";
|
|
277
384
|
case "edit":
|
|
278
385
|
return "bg-[var(--blue-3)] text-[var(--blue-11)]";
|
|
386
|
+
case "thinking":
|
|
387
|
+
return "bg-[var(--purple-4)] text-[var(--purple-12)]";
|
|
279
388
|
}
|
|
280
389
|
return "bg-[var(--mauve-3)] text-[var(--mauve-11)]";
|
|
281
390
|
}
|
|
391
|
+
|
|
392
|
+
function getTagTooltip(role: Role): string {
|
|
393
|
+
switch (role) {
|
|
394
|
+
case "chat":
|
|
395
|
+
return "Current model used for chat conversations";
|
|
396
|
+
case "autocomplete":
|
|
397
|
+
return "Current model used for autocomplete autocomplete";
|
|
398
|
+
case "edit":
|
|
399
|
+
return "Current model used for code edits";
|
|
400
|
+
case "rerank":
|
|
401
|
+
return "Current model used for reranking completions";
|
|
402
|
+
case "embed":
|
|
403
|
+
return "Current model used for embedding";
|
|
404
|
+
}
|
|
405
|
+
}
|
|
@@ -30,7 +30,11 @@ import {
|
|
|
30
30
|
type SQLTableContext,
|
|
31
31
|
useDataSourceActions,
|
|
32
32
|
} from "@/core/datasets/data-source-connections";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
DEFAULT_DUCKDB_DATABASE,
|
|
35
|
+
DUCKDB_ENGINE,
|
|
36
|
+
INTERNAL_SQL_ENGINES,
|
|
37
|
+
} from "@/core/datasets/engines";
|
|
34
38
|
import {
|
|
35
39
|
PreviewSQLTable,
|
|
36
40
|
PreviewSQLTableList,
|
|
@@ -101,9 +105,22 @@ const connectionsAtom = atom((get) => {
|
|
|
101
105
|
const dataConnections = new Map(get(dataConnectionsMapAtom));
|
|
102
106
|
|
|
103
107
|
// Filter out the internal engines if it has no databases
|
|
108
|
+
// Or if it has only the in-memory database and no schemas
|
|
104
109
|
for (const engine of INTERNAL_SQL_ENGINES) {
|
|
105
110
|
const connection = dataConnections.get(engine);
|
|
106
|
-
if (connection
|
|
111
|
+
if (!connection) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (connection.databases.length === 0) {
|
|
116
|
+
dataConnections.delete(engine);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (
|
|
120
|
+
connection.databases.length === 1 &&
|
|
121
|
+
connection.databases[0].name === DEFAULT_DUCKDB_DATABASE &&
|
|
122
|
+
connection.databases[0].schemas.length === 0
|
|
123
|
+
) {
|
|
107
124
|
dataConnections.delete(engine);
|
|
108
125
|
}
|
|
109
126
|
}
|
|
@@ -25,25 +25,26 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
|
25
25
|
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
26
26
|
|
|
27
27
|
const DropdownMenuSubTrigger = React.forwardRef<
|
|
28
|
-
React.
|
|
28
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
29
29
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
30
30
|
inset?: boolean;
|
|
31
|
+
showChevron?: boolean;
|
|
31
32
|
}
|
|
32
|
-
>(({ className, inset, children, ...props }, ref) => (
|
|
33
|
+
>(({ className, inset, showChevron = true, children, ...props }, ref) => (
|
|
33
34
|
<DropdownMenuPrimitive.SubTrigger
|
|
34
35
|
ref={ref}
|
|
35
36
|
className={menuSubTriggerVariants({ className, inset })}
|
|
36
37
|
{...props}
|
|
37
38
|
>
|
|
38
39
|
{children}
|
|
39
|
-
<ChevronRight className="ml-auto h-4 w-4" />
|
|
40
|
+
{showChevron && <ChevronRight className="ml-auto h-4 w-4" />}
|
|
40
41
|
</DropdownMenuPrimitive.SubTrigger>
|
|
41
42
|
));
|
|
42
43
|
DropdownMenuSubTrigger.displayName =
|
|
43
44
|
DropdownMenuPrimitive.SubTrigger.displayName;
|
|
44
45
|
|
|
45
46
|
const DropdownMenuSubContent = React.forwardRef<
|
|
46
|
-
React.
|
|
47
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
47
48
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
48
49
|
>(({ className, ...props }, ref) => (
|
|
49
50
|
<DropdownMenuPrimitive.SubContent
|
|
@@ -60,7 +61,7 @@ DropdownMenuSubContent.displayName =
|
|
|
60
61
|
DropdownMenuPrimitive.SubContent.displayName;
|
|
61
62
|
|
|
62
63
|
const DropdownMenuContent = React.forwardRef<
|
|
63
|
-
React.
|
|
64
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Content>,
|
|
64
65
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {
|
|
65
66
|
scrollable?: boolean;
|
|
66
67
|
}
|
|
@@ -90,7 +91,7 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
90
91
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
91
92
|
|
|
92
93
|
const DropdownMenuItem = React.forwardRef<
|
|
93
|
-
React.
|
|
94
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Item>,
|
|
94
95
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> &
|
|
95
96
|
VariantProps<typeof menuItemVariants>
|
|
96
97
|
>(({ className, inset, variant, ...props }, ref) => (
|
|
@@ -103,7 +104,7 @@ const DropdownMenuItem = React.forwardRef<
|
|
|
103
104
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
104
105
|
|
|
105
106
|
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
106
|
-
React.
|
|
107
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
107
108
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
108
109
|
>(({ className, children, checked, ...props }, ref) => (
|
|
109
110
|
<DropdownMenuPrimitive.CheckboxItem
|
|
@@ -124,7 +125,7 @@ DropdownMenuCheckboxItem.displayName =
|
|
|
124
125
|
DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
125
126
|
|
|
126
127
|
const DropdownMenuRadioItem = React.forwardRef<
|
|
127
|
-
React.
|
|
128
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
128
129
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
129
130
|
>(({ className, children, ...props }, ref) => (
|
|
130
131
|
<DropdownMenuPrimitive.RadioItem
|
|
@@ -143,7 +144,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|
|
143
144
|
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
144
145
|
|
|
145
146
|
const DropdownMenuLabel = React.forwardRef<
|
|
146
|
-
React.
|
|
147
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Label>,
|
|
147
148
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
148
149
|
inset?: boolean;
|
|
149
150
|
}
|
|
@@ -157,7 +158,7 @@ const DropdownMenuLabel = React.forwardRef<
|
|
|
157
158
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
158
159
|
|
|
159
160
|
const DropdownMenuSeparator = React.forwardRef<
|
|
160
|
-
React.
|
|
161
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,
|
|
161
162
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
162
163
|
>(({ className, ...props }, ref) => (
|
|
163
164
|
<DropdownMenuPrimitive.Separator
|
|
@@ -66,6 +66,12 @@ describe("AiModelRegistry", () => {
|
|
|
66
66
|
|
|
67
67
|
expect(registry.getCustomModels()).toEqual(new Set(customModels));
|
|
68
68
|
expect(registry.getDisplayedModels()).toEqual(new Set());
|
|
69
|
+
|
|
70
|
+
// Expect custom models to appear first
|
|
71
|
+
expect(registry.getModelsByProvider("openai")[0].name).toBe("custom-gpt");
|
|
72
|
+
expect(registry.getModelsByProvider("anthropic")[0].name).toBe(
|
|
73
|
+
"custom-claude",
|
|
74
|
+
);
|
|
69
75
|
});
|
|
70
76
|
|
|
71
77
|
it("should create registry with displayed models", () => {
|
|
@@ -114,7 +120,7 @@ describe("AiModelRegistry", () => {
|
|
|
114
120
|
|
|
115
121
|
const customModel = openaiModels.find((model) => model.custom);
|
|
116
122
|
expect(customModel).toBeDefined();
|
|
117
|
-
expect(customModel?.name).toBe("
|
|
123
|
+
expect(customModel?.name).toBe("custom-gpt");
|
|
118
124
|
expect(customModel?.model).toBe("custom-gpt");
|
|
119
125
|
expect(customModel?.description).toBe("Custom model");
|
|
120
126
|
expect(customModel?.providers).toEqual(["openai"]);
|
|
@@ -142,16 +148,10 @@ describe("AiModelRegistry", () => {
|
|
|
142
148
|
const openaiModels = registry.getModelsByProvider("openai");
|
|
143
149
|
const anthropicModels = registry.getModelsByProvider("anthropic");
|
|
144
150
|
|
|
145
|
-
expect(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
).toBe(true);
|
|
150
|
-
expect(
|
|
151
|
-
anthropicModels.some(
|
|
152
|
-
(model) => model.custom && model.model === "custom-claude",
|
|
153
|
-
),
|
|
154
|
-
).toBe(false);
|
|
151
|
+
expect(openaiModels.length).toBe(1);
|
|
152
|
+
expect(openaiModels[0].name).toBe("custom-gpt");
|
|
153
|
+
|
|
154
|
+
expect(anthropicModels.length).toBe(0);
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
157
|
|
|
@@ -328,7 +328,7 @@ describe("AiModelRegistry", () => {
|
|
|
328
328
|
"custom": true,
|
|
329
329
|
"description": "Custom model",
|
|
330
330
|
"model": "custom-gpt",
|
|
331
|
-
"name": "
|
|
331
|
+
"name": "custom-gpt",
|
|
332
332
|
"providers": [
|
|
333
333
|
"openai",
|
|
334
334
|
],
|
|
@@ -82,43 +82,22 @@ export class AiModelRegistry {
|
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Builds the maps of models by provider and custom models.
|
|
85
|
-
* Custom models are added first as they are specified by the user, so we want to surface them first.
|
|
86
85
|
*/
|
|
87
86
|
private buildMaps() {
|
|
88
87
|
const displayedModels = this.displayedModels;
|
|
89
88
|
const hasDisplayedModels = displayedModels.size > 0;
|
|
90
89
|
const knownModelMap = getKnownModelMap();
|
|
91
|
-
|
|
90
|
+
const customModelsMap = new Map<QualifiedModelId, AiModel>();
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
if (hasDisplayedModels) {
|
|
95
|
-
for (const model of displayedModels) {
|
|
96
|
-
if (knownModelMap.has(model)) {
|
|
97
|
-
const knownModel = knownModelMap.get(model);
|
|
98
|
-
if (knownModel) {
|
|
99
|
-
modelsMap.set(model, knownModel);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
modelsMap = new Map(knownModelMap);
|
|
105
|
-
}
|
|
92
|
+
let modelsMap = new Map<QualifiedModelId, AiModel>();
|
|
106
93
|
|
|
107
|
-
// Add custom models
|
|
108
94
|
for (const model of this.customModels) {
|
|
109
|
-
// Skip custom models that are not displayed
|
|
110
95
|
if (hasDisplayedModels && !displayedModels.has(model)) {
|
|
111
96
|
continue;
|
|
112
97
|
}
|
|
113
|
-
|
|
114
|
-
// If custom model conflicts with a known model, skip it
|
|
115
|
-
if (modelsMap.has(model)) {
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
98
|
const modelId = AiModelId.parse(model);
|
|
120
99
|
const modelInfo: AiModel = {
|
|
121
|
-
name: modelId.
|
|
100
|
+
name: modelId.shortModelId,
|
|
122
101
|
model: modelId.shortModelId,
|
|
123
102
|
description: "Custom model",
|
|
124
103
|
providers: [modelId.providerId],
|
|
@@ -126,9 +105,24 @@ export class AiModelRegistry {
|
|
|
126
105
|
thinking: false,
|
|
127
106
|
custom: true,
|
|
128
107
|
};
|
|
129
|
-
|
|
108
|
+
customModelsMap.set(model, modelInfo);
|
|
130
109
|
}
|
|
131
110
|
|
|
111
|
+
// Add known models
|
|
112
|
+
if (hasDisplayedModels) {
|
|
113
|
+
for (const model of displayedModels) {
|
|
114
|
+
const modelInfo = knownModelMap.get(model);
|
|
115
|
+
if (modelInfo) {
|
|
116
|
+
modelsMap.set(model, modelInfo);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
modelsMap = new Map(knownModelMap);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Set custom models first, then known models
|
|
124
|
+
modelsMap = new Map([...customModelsMap, ...modelsMap]);
|
|
125
|
+
|
|
132
126
|
// Group by provider
|
|
133
127
|
for (const [qualifiedModelId, model] of modelsMap.entries()) {
|
|
134
128
|
const modelId = AiModelId.parse(qualifiedModelId);
|
|
@@ -48,6 +48,10 @@ export const aiAtom = atom((get) => {
|
|
|
48
48
|
return get(resolvedMarimoConfigAtom).ai;
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
export const completionAtom = atom((get) => {
|
|
52
|
+
return get(resolvedMarimoConfigAtom).completion;
|
|
53
|
+
});
|
|
54
|
+
|
|
51
55
|
export const keymapPresetAtom = atom((get) => {
|
|
52
56
|
return get(resolvedMarimoConfigAtom).keymap.preset;
|
|
53
57
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import type { UserConfig } from "vite";
|
|
4
3
|
import { repl } from "@/utils/repl";
|
|
5
4
|
import { getRequestClient } from "../network/requests";
|
|
6
5
|
import { getResolvedMarimoConfig } from "./config";
|
|
@@ -37,10 +36,7 @@ export function getFeatureFlag<T extends keyof ExperimentalFeatures>(
|
|
|
37
36
|
);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
function setFeatureFlag(
|
|
41
|
-
feature: keyof UserConfig["experimental"],
|
|
42
|
-
value: boolean,
|
|
43
|
-
) {
|
|
39
|
+
function setFeatureFlag(feature: keyof ExperimentalFeatures, value: boolean) {
|
|
44
40
|
const userConfig = getResolvedMarimoConfig();
|
|
45
41
|
userConfig.experimental = userConfig.experimental ?? {};
|
|
46
42
|
userConfig.experimental[feature] = value;
|
|
@@ -8,3 +8,4 @@ export type ConnectionName = TypedString<"ConnectionName">;
|
|
|
8
8
|
// Keep this in sync with the backend name
|
|
9
9
|
export const DUCKDB_ENGINE = "__marimo_duckdb" as ConnectionName;
|
|
10
10
|
export const INTERNAL_SQL_ENGINES = new Set([DUCKDB_ENGINE]);
|
|
11
|
+
export const DEFAULT_DUCKDB_DATABASE = "memory";
|
package/src/css/katex.min.css
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as m}from"./_baseEach-CIMlsWNn.js";import{x as s}from"./index-D4bXoNM3.js";function e(r,o){var a=-1,t=s(r)?Array(r.length):[];return m(r,function(n,f,i){t[++a]=o(n,f,i)}),t}export{e as b};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as s,C as o}from"./mermaid-D59lkToe.js";const n=(a,r)=>s.lang.round(o.parse(a)[r]);export{n as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as t,C as o}from"./chunk-JBRWN2VN-vkbXs27X.js";import{_ as e}from"./mermaid-D59lkToe.js";import"./transform-B8bpuzxV.js";import"./chunk-GLLZNHP4-DRBUPzV6.js";import"./chunk-WVR4S24B-DkjWv9uk.js";import"./chunk-NRVI72HA-gO-7Uy2L.js";import"./index-D4bXoNM3.js";import"./step-BwsUM5iJ.js";import"./timer-BwIYMJWC.js";var i={parser:t,get db(){return new o},renderer:s,styles:a,init:e(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{i as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as t,C as o}from"./chunk-JBRWN2VN-vkbXs27X.js";import{_ as e}from"./mermaid-D59lkToe.js";import"./transform-B8bpuzxV.js";import"./chunk-GLLZNHP4-DRBUPzV6.js";import"./chunk-WVR4S24B-DkjWv9uk.js";import"./chunk-NRVI72HA-gO-7Uy2L.js";import"./index-D4bXoNM3.js";import"./step-BwsUM5iJ.js";import"./timer-BwIYMJWC.js";var i={parser:t,get db(){return new o},renderer:s,styles:a,init:e(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{i as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as n}from"./_baseUniq-CGK6su7v.js";function o(r){return n(r,4)}export{o as c};
|