@marimo-team/islands 0.15.1-dev37 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/{ConnectedDataExplorerComponent-sZjAxlFR.js → ConnectedDataExplorerComponent-DIy_POzQ.js} +2 -2
  2. package/dist/{ImageComparisonComponent-zj3l8Rkn.js → ImageComparisonComponent-4ehfWTqN.js} +1 -1
  3. package/dist/{_baseUniq-Bwhom4Yj.js → _baseUniq-Duh9chhg.js} +1 -1
  4. package/dist/{any-language-editor-C505APdP.js → any-language-editor-Cvakxnzg.js} +1 -1
  5. package/dist/{architectureDiagram-KFL7JDKH-B4sOJakH.js → architectureDiagram-KFL7JDKH-3xVup6Z2.js} +4 -4
  6. package/dist/{blockDiagram-ZYB65J3Q-CGKmsTjj.js → blockDiagram-ZYB65J3Q-eEZ6LTIH.js} +5 -5
  7. package/dist/{c4Diagram-AAMF2YG6-DjKNOD7H.js → c4Diagram-AAMF2YG6-BqjOo55d.js} +2 -2
  8. package/dist/{channel-jybTmR_w.js → channel-BkhHQVue.js} +1 -1
  9. package/dist/{chunk-ANTBXLJU-D2EW55i9.js → chunk-ANTBXLJU-BkLYh6ot.js} +1 -1
  10. package/dist/{chunk-FHKO5MBM-Co50zOMz.js → chunk-FHKO5MBM-BqvR49qe.js} +1 -1
  11. package/dist/{chunk-GLLZNHP4-B_taDc-e.js → chunk-GLLZNHP4-BGaltx6Q.js} +1 -1
  12. package/dist/{chunk-JBRWN2VN-DXVMgMIR.js → chunk-JBRWN2VN-BZ3JgjiU.js} +4 -4
  13. package/dist/{chunk-LXBSTHXV-Bl1kpPyW.js → chunk-LXBSTHXV-CJgOmuuc.js} +3 -3
  14. package/dist/{chunk-NRVI72HA-DsfzBSuC.js → chunk-NRVI72HA-XO3jKXGr.js} +1 -1
  15. package/dist/{chunk-OMD6QJNC-DFwE1lqy.js → chunk-OMD6QJNC-1rwXYaVn.js} +1 -1
  16. package/dist/{chunk-WVR4S24B-DhJsxFqR.js → chunk-WVR4S24B-DpdvazVp.js} +1 -1
  17. package/dist/{classDiagram-v2-QTMF73CY-CerkrRao.js → classDiagram-3BZAVTQC-_BeLc0pY.js} +2 -2
  18. package/dist/{classDiagram-3BZAVTQC-CerkrRao.js → classDiagram-v2-QTMF73CY-_BeLc0pY.js} +2 -2
  19. package/dist/{clone-B8sd-ea0.js → clone-DhXjmfNH.js} +1 -1
  20. package/dist/{dagre-2BBEFEWP-Bnnx_gCi.js → dagre-2BBEFEWP-DoebA2zc.js} +6 -6
  21. package/dist/{data-grid-overlay-editor-HIb_Zyam.js → data-grid-overlay-editor-DYmc5v9I.js} +2 -2
  22. package/dist/{diagram-4IRLE6MV-C8SlNSDm.js → diagram-4IRLE6MV-CxnJ439S.js} +5 -5
  23. package/dist/{diagram-GUPCWM2R-DiC8Dp2v.js → diagram-GUPCWM2R-B7MLfHE7.js} +3 -3
  24. package/dist/{diagram-RP2FKANI-6FkdCebf.js → diagram-RP2FKANI-C-v51IXB.js} +3 -3
  25. package/dist/{erDiagram-HZWUO2LU-CGwpVyJ6.js → erDiagram-HZWUO2LU-Cv1Slpwd.js} +4 -4
  26. package/dist/{flowDiagram-THRYKUMA-CTtIeEF1.js → flowDiagram-THRYKUMA-CnjAkcKg.js} +5 -5
  27. package/dist/{ganttDiagram-WV7ZQ7D5-C4czDpsX.js → ganttDiagram-WV7ZQ7D5-CRQQ5cqP.js} +4 -4
  28. package/dist/{gitGraphDiagram-OJR772UL-Ds-YHIay.js → gitGraphDiagram-OJR772UL-a7Wl_pP8.js} +4 -4
  29. package/dist/{glide-data-editor-Doytu1RZ.js → glide-data-editor-DrSTYUHP.js} +3 -3
  30. package/dist/{graph-DKegM7x4.js → graph-Dq4lx1WI.js} +3 -3
  31. package/dist/{index-D3Xg7lxM.js → index-B_t2cVfJ.js} +3 -3
  32. package/dist/{index-lz3uoKbl.js → index-BhnWrXVh.js} +1 -1
  33. package/dist/{index-CuHR1hKA.js → index-CfrpOVe5.js} +1 -1
  34. package/dist/{index-B9i9c65j.js → index-DIFrY2JV.js} +1 -1
  35. package/dist/{index-BloEnizu.js → index-DSAnCCyV.js} +1 -1
  36. package/dist/{infoDiagram-6WOFNB3A-KfiKRn0m.js → infoDiagram-6WOFNB3A-B4pr_cke.js} +2 -2
  37. package/dist/{journeyDiagram-FFXJYRFH-CbXbRFcR.js → journeyDiagram-FFXJYRFH-CF8H9tcV.js} +3 -3
  38. package/dist/{kanban-definition-KOZQBZVT-C8x6U1-i.js → kanban-definition-KOZQBZVT-BYfBCo4W.js} +2 -2
  39. package/dist/{layout-Ux4YHZl9.js → layout-D8_YOjKz.js} +4 -4
  40. package/dist/{linear-DgEFYNPG.js → linear-Be5SurQB.js} +1 -1
  41. package/dist/{main-Ba_D9mBk.js → main-8IC_V2L6.js} +14131 -14076
  42. package/dist/main.js +1 -1
  43. package/dist/{mermaid-31wfGVj7.js → mermaid-B4v-qVXz.js} +29 -29
  44. package/dist/{min-B0eHy8w_.js → min-Q4QXsXWR.js} +2 -2
  45. package/dist/{mindmap-definition-LNHGMQRG-cxaFXUE3.js → mindmap-definition-LNHGMQRG-CebaDS3t.js} +2 -2
  46. package/dist/{number-overlay-editor-5pzhKRNT.js → number-overlay-editor-XASk1ikZ.js} +2 -2
  47. package/dist/{pieDiagram-DBDJKBY4-DL4THmAM.js → pieDiagram-DBDJKBY4-DhPX65dy.js} +3 -3
  48. package/dist/{quadrantDiagram-YPSRARAO-wDlJOlhf.js → quadrantDiagram-YPSRARAO-BjPa8bg5.js} +2 -2
  49. package/dist/{react-plotly-9tN6KiA0.js → react-plotly-C_6SNkG9.js} +1 -1
  50. package/dist/{requirementDiagram-EGVEC5DT-BT8qPtoc.js → requirementDiagram-EGVEC5DT-CtN_U9bI.js} +3 -3
  51. package/dist/{sankeyDiagram-HRAUVNP4-CHnQQOIb.js → sankeyDiagram-HRAUVNP4-DVi73SZP.js} +1 -1
  52. package/dist/{sequenceDiagram-WFGC7UMF-zu_r3Jmh.js → sequenceDiagram-WFGC7UMF-C8jImRwI.js} +3 -3
  53. package/dist/{slides-component-BJTiClRo.js → slides-component-ML7vxRcD.js} +1 -1
  54. package/dist/{stateDiagram-UUKSUZ4H-CMygQUEj.js → stateDiagram-UUKSUZ4H-qZ62tNIz.js} +4 -4
  55. package/dist/{stateDiagram-v2-EYPG3UTE-BKU-bKRe.js → stateDiagram-v2-EYPG3UTE-BZEyTMgl.js} +2 -2
  56. package/dist/style.css +1 -1
  57. package/dist/{time-DIgCwTPW.js → time-CZ2vTSO2.js} +2 -2
  58. package/dist/{timeline-definition-3HZDQTIS-pUzFxFZ5.js → timeline-definition-3HZDQTIS-DbWMwd1x.js} +1 -1
  59. package/dist/{treemap-75Q7IDZK-Ign8SYM9.js → treemap-75Q7IDZK-CocR-oAZ.js} +5 -5
  60. package/dist/{vega-component-DVvmJHrM.js → vega-component-BrYek_kz.js} +2 -2
  61. package/dist/{xychartDiagram-FDP5SA34-D7qqqxUJ.js → xychartDiagram-FDP5SA34-CYiUdiy5.js} +2 -2
  62. package/package.json +7 -7
  63. package/src/components/ai/ai-model-dropdown.tsx +3 -3
  64. package/src/components/app-config/ai-config.tsx +244 -8
  65. package/src/components/chat/markdown-renderer.css +15 -0
  66. package/src/components/chat/markdown-renderer.tsx +2 -1
  67. package/src/components/editor/ai/completion-utils.ts +6 -2
  68. package/src/components/editor/cell/cell-context-menu.tsx +35 -13
  69. package/src/core/ai/__tests__/model-registry.test.ts +28 -0
  70. package/src/core/ai/model-registry.ts +44 -8
  71. package/src/core/codemirror/language/languages/sql/utils.ts +6 -1
  72. package/src/plugins/impl/FileBrowserPlugin.tsx +14 -20
  73. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +19 -2
  74. package/src/plugins/impl/common/error-banner.tsx +3 -0
@@ -13,6 +13,18 @@ import { once } from "@/utils/once";
13
13
  import type { ProviderId } from "./ids/ids";
14
14
  import { AiModelId, type QualifiedModelId, type ShortModelId } from "./ids/ids";
15
15
 
16
+ export const PROVIDER_SORT_ORDER: ProviderId[] = [
17
+ // Sort by popular ones
18
+ "anthropic",
19
+ "openai",
20
+ "google",
21
+ "github",
22
+ "deepseek",
23
+ "azure",
24
+ "bedrock",
25
+ "ollama",
26
+ ];
27
+
16
28
  export interface AiModel extends AiModelType {
17
29
  roles: Role[];
18
30
  model: ShortModelId;
@@ -41,13 +53,21 @@ const getKnownModelMap = once((): ReadonlyMap<QualifiedModelId, AiModel> => {
41
53
  return modelMap;
42
54
  });
43
55
 
44
- const getProviderMap = once((): ReadonlyMap<ProviderId, AiProvider> => {
45
- const providerMap = new Map<ProviderId, AiProvider>();
46
- for (const provider of providers) {
47
- providerMap.set(provider.id as ProviderId, provider);
48
- }
49
- return providerMap;
50
- });
56
+ const getProviderMap = once(
57
+ (): {
58
+ providerMap: ReadonlyMap<ProviderId, AiProvider>;
59
+ providerToOrderIdx: ReadonlyMap<ProviderId, number>;
60
+ } => {
61
+ const providerMap = new Map<ProviderId, AiProvider>();
62
+ const providerToOrderIdx = new Map<ProviderId, number>();
63
+ providers.forEach((provider, idx) => {
64
+ const providerId = provider.id as ProviderId;
65
+ providerMap.set(providerId, provider);
66
+ providerToOrderIdx.set(providerId, idx);
67
+ });
68
+ return { providerMap, providerToOrderIdx };
69
+ },
70
+ );
51
71
 
52
72
  export class AiModelRegistry {
53
73
  private modelsByProviderMap = new MultiMap<ProviderId, AiModel>();
@@ -66,7 +86,8 @@ export class AiModelRegistry {
66
86
  }
67
87
 
68
88
  static getProviderInfo(providerId: ProviderId) {
69
- return getProviderMap().get(providerId);
89
+ const { providerMap } = getProviderMap();
90
+ return providerMap.get(providerId);
70
91
  }
71
92
 
72
93
  /**
@@ -180,6 +201,21 @@ export class AiModelRegistry {
180
201
  return this.modelsByProviderMap;
181
202
  }
182
203
 
204
+ getListModelsByProvider(): Array<[ProviderId, AiModel[]]> {
205
+ const modelsByProvider = this.getGroupedModelsByProvider();
206
+ const arrayModels = [...modelsByProvider.entries()];
207
+ const providerToOrderIdx = getProviderMap().providerToOrderIdx;
208
+
209
+ arrayModels.sort((a, b) => {
210
+ const aProvider = a[0];
211
+ const bProvider = b[0];
212
+ const aOrderIdx = providerToOrderIdx.get(aProvider) ?? 0;
213
+ const bOrderIdx = providerToOrderIdx.get(bProvider) ?? 0;
214
+ return aOrderIdx - bOrderIdx;
215
+ });
216
+ return arrayModels;
217
+ }
218
+
183
219
  getModelsMap() {
184
220
  return this.modelsMap;
185
221
  }
@@ -12,7 +12,10 @@ import {
12
12
  SQLite,
13
13
  StandardSQL,
14
14
  } from "@codemirror/lang-sql";
15
- import { DuckDBDialect } from "@marimo-team/codemirror-sql/dialects";
15
+ import {
16
+ BigQueryDialect,
17
+ DuckDBDialect,
18
+ } from "@marimo-team/codemirror-sql/dialects";
16
19
  import type { DataSourceConnection } from "@/core/kernel/messages";
17
20
 
18
21
  export function guessDialect(
@@ -38,6 +41,8 @@ export function guessDialect(
38
41
  case "oracledb":
39
42
  case "oracle":
40
43
  return PLSQL;
44
+ case "bigquery":
45
+ return BigQueryDialect;
41
46
  default:
42
47
  return undefined;
43
48
  }
@@ -17,13 +17,13 @@ import { toast } from "@/components/ui/use-toast";
17
17
  import { useAsyncData } from "@/hooks/useAsyncData";
18
18
  import { useInternalStateWithSync } from "@/hooks/useInternalStateWithSync";
19
19
  import { cn } from "@/utils/cn";
20
- import { Logger } from "@/utils/Logger";
21
20
  import { type FilePath, PathBuilder, Paths } from "@/utils/paths";
22
21
  import { getProtocolAndParentDirectories } from "@/utils/pathUtils";
23
22
  import { PluralWords } from "@/utils/pluralize";
24
23
  import { createPlugin } from "../core/builder";
25
24
  import { renderHTML } from "../core/RenderHTML";
26
25
  import { rpc } from "../core/rpc";
26
+ import { Banner } from "./common/error-banner";
27
27
 
28
28
  /**
29
29
  * Arguments for a file browser component.
@@ -108,6 +108,7 @@ export const FileBrowserPlugin = createPlugin<S>("marimo-file-browser")
108
108
  <FileBrowser
109
109
  {...props.data}
110
110
  {...props.functions}
111
+ host={props.host}
111
112
  value={props.value}
112
113
  setValue={props.setValue}
113
114
  />
@@ -122,6 +123,7 @@ const PARENT_DIRECTORY = "..";
122
123
  interface FileBrowserProps extends Data, PluginFunctions {
123
124
  value: S;
124
125
  setValue: (value: S) => void;
126
+ host: HTMLElement;
125
127
  }
126
128
 
127
129
  /**
@@ -138,27 +140,19 @@ export const FileBrowser = ({
138
140
  label,
139
141
  restrictNavigation,
140
142
  list_directory,
143
+ host,
141
144
  }: FileBrowserProps): JSX.Element | null => {
142
145
  const [path, setPath] = useInternalStateWithSync(initialPath);
143
146
  const [selectAllLabel, setSelectAllLabel] = useState("Select all");
144
147
  const [isUpdatingPath, setIsUpdatingPath] = useState(false);
145
148
 
146
- const { data, error, isPending } = useAsyncData(
147
- () =>
148
- list_directory({
149
- path: path,
150
- }),
151
- [path],
152
- );
149
+ // HACK: use the random-id of the host element to force a re-render
150
+ // when the random-id changes, this means the cell was re-rendered
151
+ const randomId = host.closest("[random-id]")?.getAttribute("random-id");
153
152
 
154
- if (error) {
155
- Logger.error(error);
156
- toast({
157
- title: `Could not load files in directory ${path}`,
158
- description: error.message,
159
- variant: "danger",
160
- });
161
- }
153
+ const { data, error, isPending } = useAsyncData(() => {
154
+ return list_directory({ path: path });
155
+ }, [path, randomId]);
162
156
 
163
157
  if (isPending) {
164
158
  return null;
@@ -413,13 +407,12 @@ export const FileBrowser = ({
413
407
 
414
408
  if (multiple) {
415
409
  return (
416
- <div className="grid grid-cols-2 items-center border">
417
- <div className="justify-self-start mb-1">{labelText}</div>
418
- <div className="justify-self-end">
410
+ <div className="flex items-center justify-between border px-2">
411
+ <div className="mb-1">{labelText}</div>
412
+ <div>
419
413
  <Button
420
414
  size="xs"
421
415
  variant="link"
422
- className="w-full"
423
416
  onClick={
424
417
  selectAllLabel === "Select all"
425
418
  ? () => selectAllFiles()
@@ -438,6 +431,7 @@ export const FileBrowser = ({
438
431
 
439
432
  return (
440
433
  <div>
434
+ {error && <Banner kind="danger">{error.message}</Banner>}
441
435
  {renderHeader()}
442
436
  <NativeSelect
443
437
  className="mt-2 w-full"
@@ -62,12 +62,29 @@ const AnyWidgetSlot = (props: Props) => {
62
62
  // JS is an ESM file with a render function on it
63
63
  // export function render({ model, el }) {
64
64
  // ...
65
- const { data: module, error } = useAsyncData(async () => {
65
+ const {
66
+ data: module,
67
+ error,
68
+ refetch,
69
+ } = useAsyncData(async () => {
66
70
  const url = asRemoteURL(jsUrl).toString();
67
71
  return await import(/* @vite-ignore */ url);
68
- // Re-render on jsHash change instead of url change (since URLs may change)
72
+ // Re-render on jsHash change (which is a hash of the contents of the file)
73
+ // instead of a jsUrl change because URLs may change without the contents
74
+ // actually changing (and we don't want to re-render on every change).
75
+ // If there is an error loading the URL (e.g. maybe an invalid or old URL),
76
+ // we also want to re-render.
69
77
  }, [jsHash]);
70
78
 
79
+ // If there is an error and the jsUrl has changed, we want to re-render
80
+ // because the URL may have changed to a valid URL.
81
+ const hasError = Boolean(error);
82
+ useEffect(() => {
83
+ if (hasError && jsUrl) {
84
+ refetch();
85
+ }
86
+ }, [hasError, jsUrl]);
87
+
71
88
  const valueWithBuffer = useMemo(() => {
72
89
  return updateBufferPaths(props.value, bufferPaths);
73
90
  }, [props.value, bufferPaths]);
@@ -17,9 +17,11 @@ import { Logger } from "@/utils/Logger";
17
17
  export const ErrorBanner = ({
18
18
  error,
19
19
  className,
20
+ action,
20
21
  }: {
21
22
  error: Error | string;
22
23
  className?: string;
24
+ action?: React.ReactNode;
23
25
  }) => {
24
26
  const [open, setOpen] = useState(false);
25
27
 
@@ -39,6 +41,7 @@ export const ErrorBanner = ({
39
41
  onClick={() => setOpen(true)}
40
42
  >
41
43
  <span className="line-clamp-4">{message}</span>
44
+ {action && <div className="flex justify-end">{action}</div>}
42
45
  </Banner>
43
46
  <AlertDialog open={open} onOpenChange={setOpen}>
44
47
  <AlertDialogContent className="max-w-[80%] max-h-[80%] overflow-hidden flex flex-col">