@marimo-team/islands 0.19.3-dev14 → 0.19.3-dev17

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/main.js CHANGED
@@ -71129,22 +71129,24 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71129
71129
  var import_compiler_runtime$86 = require_compiler_runtime();
71130
71130
  const Chatbot = (e) => {
71131
71131
  var _a2;
71132
- let [r, c] = (0, import_react.useState)(""), [d, f] = (0, import_react.useState)(e.config), [h, _] = (0, import_react.useState)(void 0), v = (0, import_react.useRef)(null), y = (0, import_react.useRef)(null), S = (0, import_react.useRef)(null), w = (0, import_react.useRef)(null), E = (0, import_react.useRef)(d);
71133
- E.current = d;
71134
- let O = (0, import_react.useRef)({
71132
+ let [r, c] = (0, import_react.useState)(""), [d, f] = (0, import_react.useState)(e.config), [h, _] = (0, import_react.useState)(e.config), [v, y] = (0, import_react.useState)(void 0), S = (0, import_react.useRef)(null), w = (0, import_react.useRef)(null), E = (0, import_react.useRef)(null), O = (0, import_react.useRef)(null);
71133
+ Object.keys(e.config).some((r2) => e.config[r2] !== h[r2]) && (f(e.config), _(e.config));
71134
+ let M = (0, import_react.useRef)(d);
71135
+ M.current = d;
71136
+ let I = (0, import_react.useRef)({
71135
71137
  backendMessageId: null,
71136
71138
  frontendMessageIndex: null
71137
- }), M = (0, import_react.useRef)(null), { data: I } = useAsyncData(async () => (await e.get_chat_history({})).messages, []), z = e.value.length > 0 ? e.value : I, { messages: G, sendMessage: q, setMessages: LY, status: RY, stop: zY, error: BY, regenerate: VY, clearError: HY } = useChat({
71139
+ }), z = (0, import_react.useRef)(null), { data: G } = useAsyncData(async () => (await e.get_chat_history({})).messages, []), q = e.value.length > 0 ? e.value : G, { messages: LY, sendMessage: RY, setMessages: zY, status: BY, stop: VY, error: HY, regenerate: UY, clearError: WY } = useChat({
71138
71140
  transport: new DefaultChatTransport({
71139
71141
  fetch: async (r2, c2) => {
71140
71142
  if (c2 === void 0) return fetch(r2);
71141
71143
  let d2 = JSON.parse(c2.body), f2 = c2.signal, h2 = {
71142
- max_tokens: E.current.max_tokens,
71143
- temperature: E.current.temperature,
71144
- top_p: E.current.top_p,
71145
- top_k: E.current.top_k,
71146
- frequency_penalty: E.current.frequency_penalty,
71147
- presence_penalty: E.current.presence_penalty
71144
+ max_tokens: M.current.max_tokens,
71145
+ temperature: M.current.temperature,
71146
+ top_p: M.current.top_p,
71147
+ top_k: M.current.top_k,
71148
+ frequency_penalty: M.current.frequency_penalty,
71149
+ presence_penalty: M.current.presence_penalty
71148
71150
  };
71149
71151
  try {
71150
71152
  let r3 = d2.messages.map((e2) => {
@@ -71157,7 +71159,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71157
71159
  if (e.frontendManaged) {
71158
71160
  let c4 = new ReadableStream({
71159
71161
  start(e2) {
71160
- M.current = e2;
71162
+ z.current = e2;
71161
71163
  let r4 = () => {
71162
71164
  try {
71163
71165
  e2.close();
@@ -71166,14 +71168,14 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71166
71168
  error: e3
71167
71169
  });
71168
71170
  }
71169
- M.current = null;
71171
+ z.current = null;
71170
71172
  };
71171
71173
  return f2 == null ? void 0 : f2.addEventListener("abort", r4), () => {
71172
71174
  f2 == null ? void 0 : f2.removeEventListener("abort", r4);
71173
71175
  };
71174
71176
  },
71175
71177
  cancel() {
71176
- M.current = null;
71178
+ z.current = null;
71177
71179
  }
71178
71180
  });
71179
71181
  return e.send_prompt({
@@ -71181,7 +71183,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71181
71183
  config: h2
71182
71184
  }).catch((e2) => {
71183
71185
  var _a3;
71184
- (_a3 = M.current) == null ? void 0 : _a3.error(e2), M.current = null;
71186
+ (_a3 = z.current) == null ? void 0 : _a3.error(e2), z.current = null;
71185
71187
  }), createUIMessageStreamResponse({
71186
71188
  stream: c4
71187
71189
  });
@@ -71190,7 +71192,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71190
71192
  status: 499
71191
71193
  });
71192
71194
  let c3 = Date.now().toString();
71193
- LY((e2) => [
71195
+ zY((e2) => [
71194
71196
  ...e2,
71195
71197
  {
71196
71198
  id: c3,
@@ -71218,7 +71220,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71218
71220
  response: v2
71219
71221
  }), new Response("Internal server error", {
71220
71222
  status: 500
71221
- })) : (O.current.backendMessageId === null && O.current.frontendMessageIndex === null && LY((e2) => {
71223
+ })) : (I.current.backendMessageId === null && I.current.frontendMessageIndex === null && zY((e2) => {
71222
71224
  let r4 = [
71223
71225
  ...e2
71224
71226
  ], d3 = r4.findIndex((e3) => e3.id === c3);
@@ -71233,7 +71235,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71233
71235
  }), r4;
71234
71236
  }), new Response(v2));
71235
71237
  } catch (e2) {
71236
- if (O.current = {
71238
+ if (I.current = {
71237
71239
  backendMessageId: null,
71238
71240
  frontendMessageIndex: null
71239
71241
  }, e2.name === "AbortError") return new Response("Aborted", {
@@ -71246,15 +71248,15 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71246
71248
  }
71247
71249
  }
71248
71250
  }),
71249
- messages: z,
71251
+ messages: q,
71250
71252
  onFinish: (r2) => {
71251
- _(void 0), v.current && (v.current.value = ""), Logger.debug("Finished streaming message:", r2), O.current = {
71253
+ y(void 0), S.current && (S.current.value = ""), Logger.debug("Finished streaming message:", r2), I.current = {
71252
71254
  backendMessageId: null,
71253
71255
  frontendMessageIndex: null
71254
71256
  }, e.frontendManaged && e.setValue(r2.messages);
71255
71257
  },
71256
71258
  onError: (e2) => {
71257
- Logger.error("An error occurred:", e2), O.current = {
71259
+ Logger.error("An error occurred:", e2), I.current = {
71258
71260
  backendMessageId: null,
71259
71261
  frontendMessageIndex: null
71260
71262
  };
@@ -71264,19 +71266,19 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71264
71266
  let c2 = r2.detail.message;
71265
71267
  if (typeof c2 != "object" || !c2 || !("type" in c2) || c2.type !== "stream_chunk") return;
71266
71268
  if (e.frontendManaged) {
71267
- let e2 = M.current;
71269
+ let e2 = z.current;
71268
71270
  if (!e2) return;
71269
71271
  let r3 = c2;
71270
- r3.content && e2.enqueue(r3.content), r3.is_final && (e2.close(), M.current = null);
71272
+ r3.content && e2.enqueue(r3.content), r3.is_final && (e2.close(), z.current = null);
71271
71273
  return;
71272
71274
  }
71273
71275
  let d2 = c2;
71274
- O.current.backendMessageId === null && LY((e2) => {
71276
+ I.current.backendMessageId === null && zY((e2) => {
71275
71277
  let r3 = [
71276
71278
  ...e2
71277
71279
  ];
71278
71280
  for (let e3 = r3.length - 1; e3 >= 0; e3--) if (r3[e3].role === "assistant") {
71279
- O.current = {
71281
+ I.current = {
71280
71282
  backendMessageId: d2.message_id,
71281
71283
  frontendMessageIndex: e3
71282
71284
  };
@@ -71284,8 +71286,8 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71284
71286
  }
71285
71287
  return r3;
71286
71288
  });
71287
- let f2 = O.current.frontendMessageIndex;
71288
- O.current.backendMessageId === d2.message_id && f2 !== null && (LY((e2) => {
71289
+ let f2 = I.current.frontendMessageIndex;
71290
+ I.current.backendMessageId === d2.message_id && f2 !== null && (zY((e2) => {
71289
71291
  let r3 = [
71290
71292
  ...e2
71291
71293
  ], c3 = f2;
@@ -71302,41 +71304,41 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71302
71304
  });
71303
71305
  }
71304
71306
  return r3;
71305
- }), d2.is_final && (O.current = {
71307
+ }), d2.is_final && (I.current = {
71306
71308
  backendMessageId: null,
71307
71309
  frontendMessageIndex: null
71308
71310
  }));
71309
71311
  });
71310
- let UY = RY === "submitted" || RY === "streaming", WY = (r2) => {
71311
- let c2 = G.findIndex((e2) => e2.id === r2);
71312
+ let GY = BY === "submitted" || BY === "streaming", KY = (r2) => {
71313
+ let c2 = LY.findIndex((e2) => e2.id === r2);
71312
71314
  if (c2 !== -1) {
71313
- let d2 = G.filter((e2) => e2.id !== r2);
71315
+ let d2 = LY.filter((e2) => e2.id !== r2);
71314
71316
  e.delete_chat_message({
71315
71317
  index: c2
71316
- }), LY(d2), e.frontendManaged && e.setValue(d2);
71318
+ }), zY(d2), e.frontendManaged && e.setValue(d2);
71317
71319
  }
71318
- }, GY = Array.isArray(e.allowAttachments) && e.allowAttachments.length > 0 || e.allowAttachments === true, KY = {
71320
+ }, qY = Array.isArray(e.allowAttachments) && e.allowAttachments.length > 0 || e.allowAttachments === true, JY = {
71319
71321
  triggerCompletionRegex: /^\/(\w+)?/,
71320
71322
  completions: e.prompts.map((e2) => ({
71321
71323
  label: `/${e2}`,
71322
71324
  displayLabel: e2,
71323
71325
  apply: e2
71324
71326
  }))
71325
- }, qY = e.prompts.length > 0 ? "Type your message here, / for prompts" : "Type your message here...";
71327
+ }, YY = e.prompts.length > 0 ? "Type your message here, / for prompts" : "Type your message here...";
71326
71328
  (0, import_react.useEffect)(() => {
71327
71329
  var _a3;
71328
- (_a3 = w.current) == null ? void 0 : _a3.scrollTo({
71329
- top: w.current.scrollHeight,
71330
+ (_a3 = O.current) == null ? void 0 : _a3.scrollTo({
71331
+ top: O.current.scrollHeight,
71330
71332
  behavior: "smooth"
71331
71333
  });
71332
71334
  }, [
71333
- G.length,
71334
- w
71335
+ LY.length,
71336
+ O
71335
71337
  ]);
71336
- let JY = (_a2 = S.current) == null ? void 0 : _a2.view, YY = () => {
71337
- if (JY) {
71338
- let e2 = JY.state.doc.length;
71339
- JY.dispatch({
71338
+ let XY = (_a2 = E.current) == null ? void 0 : _a2.view, ZY = () => {
71339
+ if (XY) {
71340
+ let e2 = XY.state.doc.length;
71341
+ XY.dispatch({
71340
71342
  changes: {
71341
71343
  from: 0,
71342
71344
  to: e2,
@@ -71357,9 +71359,9 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71357
71359
  children: (0, import_jsx_runtime.jsx)(Button, {
71358
71360
  variant: "text",
71359
71361
  size: "icon",
71360
- disabled: G.length === 0,
71362
+ disabled: LY.length === 0,
71361
71363
  onClick: () => {
71362
- LY([]), e.setValue([]), e.delete_chat_history({}), HY();
71364
+ zY([]), e.setValue([]), e.delete_chat_history({}), WY();
71363
71365
  },
71364
71366
  children: (0, import_jsx_runtime.jsx)(RotateCw, {
71365
71367
  className: "h-3 w-3"
@@ -71368,9 +71370,9 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71368
71370
  }),
71369
71371
  (0, import_jsx_runtime.jsxs)("div", {
71370
71372
  className: "grow overflow-y-auto gap-4 pt-8 pb-4 px-2 flex flex-col",
71371
- ref: w,
71373
+ ref: O,
71372
71374
  children: [
71373
- G.length === 0 && (0, import_jsx_runtime.jsxs)("div", {
71375
+ LY.length === 0 && (0, import_jsx_runtime.jsxs)("div", {
71374
71376
  className: "flex flex-col items-center justify-center h-full text-muted-foreground text-center p-4",
71375
71377
  children: [
71376
71378
  (0, import_jsx_runtime.jsx)(BotMessageSquare, {
@@ -71386,9 +71388,9 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71386
71388
  })
71387
71389
  ]
71388
71390
  }),
71389
- G.map((e2, r2) => {
71391
+ LY.map((e2, r2) => {
71390
71392
  var _a3;
71391
- let c2 = (_a3 = e2.parts) == null ? void 0 : _a3.filter((e3) => e3.type === "text").map((e3) => e3.text).join("\n"), d2 = r2 === G.length - 1;
71393
+ let c2 = (_a3 = e2.parts) == null ? void 0 : _a3.filter((e3) => e3.type === "text").map((e3) => e3.text).join("\n"), d2 = r2 === LY.length - 1;
71392
71394
  return (0, import_jsx_runtime.jsxs)("div", {
71393
71395
  className: cn("flex flex-col group gap-2", e2.role === "user" ? "items-end" : "items-start"),
71394
71396
  children: [
@@ -71396,7 +71398,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71396
71398
  className: `max-w-[80%] p-3 rounded-lg ${e2.role === "user" ? "bg-(--sky-11) text-(--slate-1) whitespace-pre-wrap" : "bg-(--slate-4) text-(--slate-12)"}`,
71397
71399
  children: renderUIMessage({
71398
71400
  message: e2,
71399
- isStreamingReasoning: RY === "streaming",
71401
+ isStreamingReasoning: BY === "streaming",
71400
71402
  isLast: d2
71401
71403
  })
71402
71404
  }),
@@ -71410,7 +71412,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71410
71412
  }),
71411
71413
  (0, import_jsx_runtime.jsx)("button", {
71412
71414
  type: "button",
71413
- onClick: () => WY(e2.id),
71415
+ onClick: () => KY(e2.id),
71414
71416
  className: "text-xs text-(--slate-9) hover:text-(--slate-11)",
71415
71417
  children: (0, import_jsx_runtime.jsx)(Trash2, {
71416
71418
  className: "h-3 w-3 text-(--red-9)"
@@ -71421,7 +71423,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71421
71423
  ]
71422
71424
  }, e2.id);
71423
71425
  }),
71424
- UY && (0, import_jsx_runtime.jsxs)("div", {
71426
+ GY && (0, import_jsx_runtime.jsxs)("div", {
71425
71427
  className: "flex items-center justify-center space-x-2 mb-4",
71426
71428
  children: [
71427
71429
  (0, import_jsx_runtime.jsx)(Spinner, {
@@ -71430,22 +71432,22 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71430
71432
  (0, import_jsx_runtime.jsx)(Button, {
71431
71433
  variant: "link",
71432
71434
  size: "sm",
71433
- onClick: () => zY(),
71435
+ onClick: () => VY(),
71434
71436
  className: "text-(--red-9) hover:text-(--red-11)",
71435
71437
  children: "Stop"
71436
71438
  })
71437
71439
  ]
71438
71440
  }),
71439
- BY && (0, import_jsx_runtime.jsxs)("div", {
71441
+ HY && (0, import_jsx_runtime.jsxs)("div", {
71440
71442
  className: "flex items-center justify-center space-x-2 mb-4",
71441
71443
  children: [
71442
71444
  (0, import_jsx_runtime.jsx)(ErrorBanner, {
71443
- error: BY
71445
+ error: HY
71444
71446
  }),
71445
71447
  (0, import_jsx_runtime.jsx)(Button, {
71446
71448
  variant: "outline",
71447
71449
  size: "sm",
71448
- onClick: () => VY(),
71450
+ onClick: () => UY(),
71449
71451
  children: "Retry"
71450
71452
  })
71451
71453
  ]
@@ -71455,8 +71457,8 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71455
71457
  (0, import_jsx_runtime.jsxs)("form", {
71456
71458
  onSubmit: async (e2) => {
71457
71459
  e2.preventDefault();
71458
- let c2 = h ? await convertToFileUIPart(h) : void 0;
71459
- q({
71460
+ let c2 = v ? await convertToFileUIPart(v) : void 0;
71461
+ RY({
71460
71462
  role: "user",
71461
71463
  parts: [
71462
71464
  {
@@ -71465,9 +71467,9 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71465
71467
  },
71466
71468
  ...c2 ?? []
71467
71469
  ]
71468
- }), YY();
71470
+ }), ZY();
71469
71471
  },
71470
- ref: y,
71472
+ ref: w,
71471
71473
  className: "flex w-full border-t border-(--slate-6) px-2 py-1 items-center",
71472
71474
  children: [
71473
71475
  e.showConfigurationControls && (0, import_jsx_runtime.jsx)(ConfigPopup, {
@@ -71478,52 +71480,52 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71478
71480
  prompts: e.prompts,
71479
71481
  onSelect: (e2) => {
71480
71482
  c(e2), requestAnimationFrame(() => {
71481
- JY == null ? void 0 : JY.focus(), moveToEndOfEditor(JY);
71483
+ XY == null ? void 0 : XY.focus(), moveToEndOfEditor(XY);
71482
71484
  });
71483
71485
  }
71484
71486
  }),
71485
71487
  (0, import_jsx_runtime.jsx)(PromptInput, {
71486
71488
  className: "rounded-sm mr-2",
71487
- placeholder: qY,
71489
+ placeholder: YY,
71488
71490
  value: r,
71489
- inputRef: S,
71491
+ inputRef: E,
71490
71492
  maxHeight: e.maxHeight ? `${e.maxHeight / 2}px` : void 0,
71491
71493
  onChange: c,
71492
71494
  onSubmit: (e2, r2) => {
71493
71495
  var _a3;
71494
- r2.trim() && ((_a3 = y.current) == null ? void 0 : _a3.requestSubmit());
71496
+ r2.trim() && ((_a3 = w.current) == null ? void 0 : _a3.requestSubmit());
71495
71497
  },
71496
71498
  onClose: () => {
71497
71499
  },
71498
- additionalCompletions: KY
71500
+ additionalCompletions: JY
71499
71501
  }),
71500
- h && h.length === 1 && (0, import_jsx_runtime.jsx)("span", {
71501
- title: h[0].name,
71502
+ v && v.length === 1 && (0, import_jsx_runtime.jsx)("span", {
71503
+ title: v[0].name,
71502
71504
  className: "text-sm text-(--slate-11) truncate shrink-0 w-fit max-w-24",
71503
- children: h[0].name
71505
+ children: v[0].name
71504
71506
  }),
71505
- h && h.length > 1 && (0, import_jsx_runtime.jsxs)("span", {
71507
+ v && v.length > 1 && (0, import_jsx_runtime.jsxs)("span", {
71506
71508
  title: [
71507
- ...h
71509
+ ...v
71508
71510
  ].map((e2) => e2.name).join("\n"),
71509
71511
  className: "text-sm text-(--slate-11) truncate shrink-0",
71510
71512
  children: [
71511
- h.length,
71513
+ v.length,
71512
71514
  " files"
71513
71515
  ]
71514
71516
  }),
71515
- h && h.length > 0 && (0, import_jsx_runtime.jsx)(Button, {
71517
+ v && v.length > 0 && (0, import_jsx_runtime.jsx)(Button, {
71516
71518
  type: "button",
71517
71519
  variant: "text",
71518
71520
  size: "sm",
71519
71521
  onClick: () => {
71520
- _(void 0), v.current && (v.current.value = "");
71522
+ y(void 0), S.current && (S.current.value = "");
71521
71523
  },
71522
71524
  children: (0, import_jsx_runtime.jsx)(X, {
71523
71525
  className: "size-3"
71524
71526
  })
71525
71527
  }),
71526
- GY && (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
71528
+ qY && (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
71527
71529
  children: [
71528
71530
  (0, import_jsx_runtime.jsx)(Button, {
71529
71531
  type: "button",
@@ -71531,7 +71533,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71531
71533
  size: "sm",
71532
71534
  onClick: () => {
71533
71535
  var _a3;
71534
- return (_a3 = v.current) == null ? void 0 : _a3.click();
71536
+ return (_a3 = S.current) == null ? void 0 : _a3.click();
71535
71537
  },
71536
71538
  children: (0, import_jsx_runtime.jsx)(Paperclip, {
71537
71539
  className: "h-4"
@@ -71539,12 +71541,12 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71539
71541
  }),
71540
71542
  (0, import_jsx_runtime.jsx)("input", {
71541
71543
  type: "file",
71542
- ref: v,
71544
+ ref: S,
71543
71545
  className: "hidden",
71544
71546
  multiple: true,
71545
71547
  accept: Array.isArray(e.allowAttachments) ? e.allowAttachments.join(",") : void 0,
71546
71548
  onChange: (e2) => {
71547
- e2.target.files && _([
71549
+ e2.target.files && y([
71548
71550
  ...e2.target.files
71549
71551
  ]);
71550
71552
  }
@@ -71553,7 +71555,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71553
71555
  }),
71554
71556
  (0, import_jsx_runtime.jsx)(Button, {
71555
71557
  type: "submit",
71556
- disabled: UY || !r,
71558
+ disabled: GY || !r,
71557
71559
  variant: "outline",
71558
71560
  size: "sm",
71559
71561
  className: "text-(--slate-11)",
@@ -71600,25 +71602,24 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71600
71602
  description: "Penalizes new tokens (-2: favor, 2: avoid)"
71601
71603
  }
71602
71604
  }, ConfigPopup = (e) => {
71603
- let r = (0, import_compiler_runtime$86.c)(16), { config: c, onChange: d } = e, [f, h] = (0, import_react.useState)(c), [_, v] = (0, import_react.useState)(false), y;
71604
- r[0] !== f || r[1] !== d ? (y = (e2, r2) => {
71605
- let c2 = r2 === null || Number.isNaN(r2) ? null : r2;
71606
- if (c2 !== null) {
71607
- let { min: r3, max: d2 } = configDescriptions[e2];
71608
- c2 = Math.max(r3, Math.min(d2, c2));
71609
- }
71610
- let _2 = {
71611
- ...f,
71612
- [e2]: c2
71613
- };
71614
- h(_2), d(_2);
71615
- }, r[0] = f, r[1] = d, r[2] = y) : y = r[2];
71605
+ let r = (0, import_compiler_runtime$86.c)(16), { config: c, onChange: d } = e, [f, h] = (0, import_react.useState)(false), _;
71606
+ r[0] !== c || r[1] !== d ? (_ = (e2, r2) => {
71607
+ let f2 = r2 === null || Number.isNaN(r2) ? null : r2;
71608
+ if (f2 !== null) {
71609
+ let { min: r3, max: c2 } = configDescriptions[e2];
71610
+ f2 = Math.max(r3, Math.min(c2, f2));
71611
+ }
71612
+ d({
71613
+ ...c,
71614
+ [e2]: f2
71615
+ });
71616
+ }, r[0] = c, r[1] = d, r[2] = _) : _ = r[2];
71617
+ let v = _, y;
71618
+ r[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (y = (e2) => {
71619
+ e2.key === "Enter" && (e2.preventDefault(), h(false));
71620
+ }, r[3] = y) : y = r[3];
71616
71621
  let S = y, w;
71617
- r[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (w = (e2) => {
71618
- e2.key === "Enter" && (e2.preventDefault(), v(false));
71619
- }, r[3] = w) : w = r[3];
71620
- let E = w, O;
71621
- r[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (O = (0, import_jsx_runtime.jsx)(Tooltip, {
71622
+ r[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (w = (0, import_jsx_runtime.jsx)(Tooltip, {
71622
71623
  content: "Configuration",
71623
71624
  children: (0, import_jsx_runtime.jsx)(PopoverTrigger, {
71624
71625
  asChild: true,
@@ -71631,16 +71632,16 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71631
71632
  })
71632
71633
  })
71633
71634
  })
71634
- }), r[4] = O) : O = r[4];
71635
- let M;
71636
- r[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (M = (0, import_jsx_runtime.jsx)("h4", {
71635
+ }), r[4] = w) : w = r[4];
71636
+ let E;
71637
+ r[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (E = (0, import_jsx_runtime.jsx)("h4", {
71637
71638
  className: "font-bold leading-none",
71638
71639
  children: "Configuration"
71639
- }), r[5] = M) : M = r[5];
71640
- let I;
71641
- if (r[6] !== S || r[7] !== f) {
71640
+ }), r[5] = E) : E = r[5];
71641
+ let O;
71642
+ if (r[6] !== c || r[7] !== v) {
71642
71643
  let e2;
71643
- r[9] === S ? e2 = r[10] : (e2 = (e3) => {
71644
+ r[9] === v ? e2 = r[10] : (e2 = (e3) => {
71644
71645
  let [r2, c2] = e3;
71645
71646
  return (0, import_jsx_runtime.jsxs)("div", {
71646
71647
  className: "grid grid-cols-3 items-center gap-1",
@@ -71671,34 +71672,34 @@ Image URL: ${r.imageUrl}`)), contextToXml({
71671
71672
  minValue: configDescriptions[r2].min,
71672
71673
  maxValue: configDescriptions[r2].max,
71673
71674
  step: configDescriptions[r2].step ?? 1,
71674
- onChange: (e4) => S(r2, e4),
71675
- onKeyDown: E,
71675
+ onChange: (e4) => v(r2, e4),
71676
+ onKeyDown: S,
71676
71677
  className: "col-span-3"
71677
71678
  })
71678
71679
  ]
71679
71680
  }, r2);
71680
- }, r[9] = S, r[10] = e2), I = Objects.entries(f).map(e2), r[6] = S, r[7] = f, r[8] = I;
71681
- } else I = r[8];
71682
- let z;
71683
- r[11] === I ? z = r[12] : (z = (0, import_jsx_runtime.jsx)(PopoverContent, {
71681
+ }, r[9] = v, r[10] = e2), O = Objects.entries(c).map(e2), r[6] = c, r[7] = v, r[8] = O;
71682
+ } else O = r[8];
71683
+ let M;
71684
+ r[11] === O ? M = r[12] : (M = (0, import_jsx_runtime.jsx)(PopoverContent, {
71684
71685
  className: "w-70 border",
71685
71686
  children: (0, import_jsx_runtime.jsxs)("div", {
71686
71687
  className: "grid gap-3",
71687
71688
  children: [
71688
- M,
71689
- I
71689
+ E,
71690
+ O
71690
71691
  ]
71691
71692
  })
71692
- }), r[11] = I, r[12] = z);
71693
- let G;
71694
- return r[13] !== _ || r[14] !== z ? (G = (0, import_jsx_runtime.jsxs)(Popover$1, {
71695
- open: _,
71696
- onOpenChange: v,
71693
+ }), r[11] = O, r[12] = M);
71694
+ let I;
71695
+ return r[13] !== f || r[14] !== M ? (I = (0, import_jsx_runtime.jsxs)(Popover$1, {
71696
+ open: f,
71697
+ onOpenChange: h,
71697
71698
  children: [
71698
- O,
71699
- z
71699
+ w,
71700
+ M
71700
71701
  ]
71701
- }), r[13] = _, r[14] = z, r[15] = G) : G = r[15], G;
71702
+ }), r[13] = f, r[14] = M, r[15] = I) : I = r[15], I;
71702
71703
  }, PromptsPopover = (e) => {
71703
71704
  let r = (0, import_compiler_runtime$86.c)(18), { prompts: c, onSelect: d } = e, [f, h] = (0, import_react.useState)(false), [_, v] = (0, import_react.useState)(""), y;
71704
71705
  r[0] === d ? y = r[1] : (y = (e2) => {
@@ -101068,7 +101069,7 @@ Defaulting to \`null\`.`;
101068
101069
  return Logger.warn("Failed to get version from mount config"), null;
101069
101070
  }
101070
101071
  }
101071
- const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.19.3-dev14"), showCodeInRunModeAtom = atom(true);
101072
+ const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.19.3-dev17"), showCodeInRunModeAtom = atom(true);
101072
101073
  atom(null);
101073
101074
  var VIRTUAL_FILE_REGEX = /\/@file\/([^\s"&'/]+)\.([\dA-Za-z]+)/g, VirtualFileTracker = class e {
101074
101075
  constructor() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.19.3-dev14",
3
+ "version": "0.19.3-dev17",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -173,7 +173,7 @@
173
173
  "thememirror": "^2.0.1",
174
174
  "timestring": "^7.0.0",
175
175
  "typescript-memoize": "^1.1.1",
176
- "use-acp": "0.2.5",
176
+ "use-acp": "0.2.6",
177
177
  "use-resize-observer": "^9.1.0",
178
178
  "vega-lite": "6.3.1",
179
179
  "vega-loader": "^5.1.0",
@@ -677,7 +677,7 @@ const AgentPanel: React.FC = () => {
677
677
  ? getAgentWebSocketUrl(selectedTab.agentId)
678
678
  : NO_WS_SET;
679
679
  const { sendUpdateFile, sendFileDetails } = useRequestClient();
680
- const isCreatingNewSession = useRef(false);
680
+ const creatingOrResumingSession = useRef(false);
681
681
 
682
682
  const acpClient = useAcpClient({
683
683
  wsUrl,
@@ -716,6 +716,7 @@ const AgentPanel: React.FC = () => {
716
716
  sessionMode,
717
717
  activeSessionId,
718
718
  agent,
719
+ clearNotifications,
719
720
  } = acpClient;
720
721
 
721
722
  useEffect(() => {
@@ -757,40 +758,42 @@ const AgentPanel: React.FC = () => {
757
758
  return;
758
759
  }
759
760
 
760
- // If there is an active session, we should stop it
761
- if (activeSessionId) {
762
- setActiveSessionId(null);
763
- await agent.cancel({ sessionId: activeSessionId }).catch((error) => {
764
- logger.error("Failed to cancel active session", { error });
765
- });
766
- }
761
+ creatingOrResumingSession.current = true;
762
+
763
+ try {
764
+ // If there is an active session, we should stop it
765
+ if (activeSessionId) {
766
+ await agent.cancel({ sessionId: activeSessionId }).catch((error) => {
767
+ logger.error("Failed to cancel active session", { error });
768
+ });
769
+ clearNotifications(activeSessionId);
770
+ setActiveSessionId(null);
771
+ }
767
772
 
768
- // Get the selected model from the current session state
769
- const currentModel = selectedTab?.selectedModel ?? null;
770
- logger.debug("Creating new agent session", { model: currentModel });
771
- isCreatingNewSession.current = true;
772
- const newSession = await agent
773
- .newSession({
773
+ // Get the selected model from the current session state
774
+ const currentModel = selectedTab?.selectedModel ?? null;
775
+ logger.debug("Creating new agent session", { model: currentModel });
776
+ const newSession = await agent.newSession({
774
777
  cwd: getCwd(),
775
778
  mcpServers: [],
776
779
  _meta: currentModel ? { model: currentModel } : undefined,
777
- })
778
- .finally(() => {
779
- isCreatingNewSession.current = false;
780
780
  });
781
781
 
782
- // Capture models from the response
783
- if (newSession.models) {
784
- logger.debug("Session models received", { models: newSession.models });
785
- setSessionModels(newSession.models);
786
- }
782
+ // Capture models from the response
783
+ if (newSession.models) {
784
+ logger.debug("Session models received", { models: newSession.models });
785
+ setSessionModels(newSession.models);
786
+ }
787
787
 
788
- setSessionState((prev) =>
789
- updateSessionExternalAgentSessionId(
790
- prev,
791
- newSession.sessionId as ExternalAgentSessionId,
792
- ),
793
- );
788
+ setSessionState((prev) =>
789
+ updateSessionExternalAgentSessionId(
790
+ prev,
791
+ newSession.sessionId as ExternalAgentSessionId,
792
+ ),
793
+ );
794
+ } finally {
795
+ creatingOrResumingSession.current = false;
796
+ }
794
797
  });
795
798
 
796
799
  const handleResumeSession = useEvent(
@@ -804,23 +807,28 @@ const AgentPanel: React.FC = () => {
804
807
  if (!agent.loadSession) {
805
808
  throw new Error("Agent does not support loading sessions");
806
809
  }
807
- const loadedSession = await agent.loadSession({
808
- sessionId: previousSessionId,
809
- cwd: getCwd(),
810
- mcpServers: [],
811
- });
812
-
813
- // Capture models from the response if available
814
- if (loadedSession?.models) {
815
- logger.debug("Session models received", {
816
- models: loadedSession.models,
810
+ creatingOrResumingSession.current = true;
811
+ try {
812
+ const loadedSession = await agent.loadSession({
813
+ sessionId: previousSessionId,
814
+ cwd: getCwd(),
815
+ mcpServers: [],
817
816
  });
818
- setSessionModels(loadedSession.models);
819
- }
820
817
 
821
- setSessionState((prev) =>
822
- updateSessionExternalAgentSessionId(prev, previousSessionId),
823
- );
818
+ // Capture models from the response if available
819
+ if (loadedSession?.models) {
820
+ logger.debug("Session models received", {
821
+ models: loadedSession.models,
822
+ });
823
+ setSessionModels(loadedSession.models);
824
+ }
825
+
826
+ setSessionState((prev) =>
827
+ updateSessionExternalAgentSessionId(prev, previousSessionId),
828
+ );
829
+ } finally {
830
+ creatingOrResumingSession.current = false;
831
+ }
824
832
  },
825
833
  );
826
834
 
@@ -838,6 +846,11 @@ const AgentPanel: React.FC = () => {
838
846
  return;
839
847
  }
840
848
 
849
+ // Prevent race conditions
850
+ if (creatingOrResumingSession.current) {
851
+ return;
852
+ }
853
+
841
854
  // If there is an available session, resume it, otherwise create a new one
842
855
  const createOrResumeSession = async () => {
843
856
  const availableSession = tabLastActiveSessionId ?? activeSessionId;
@@ -75,12 +75,26 @@ interface Props extends PluginFunctions {
75
75
  export const Chatbot: React.FC<Props> = (props) => {
76
76
  const [input, setInput] = useState("");
77
77
  const [config, setConfig] = useState<ChatConfig>(props.config);
78
+ const [prevPropsConfig, setPrevPropsConfig] = useState<ChatConfig>(
79
+ props.config,
80
+ );
78
81
  const [files, setFiles] = useState<File[] | undefined>(undefined);
79
82
  const fileInputRef = useRef<HTMLInputElement>(null);
80
83
  const formRef = useRef<HTMLFormElement>(null);
81
84
  const codeMirrorInputRef = useRef<ReactCodeMirrorRef>(null);
82
85
  const scrollContainerRef = useRef<HTMLDivElement>(null);
83
86
 
87
+ const configChanged = Object.keys(props.config).some(
88
+ (key) =>
89
+ props.config[key as keyof ChatConfig] !==
90
+ prevPropsConfig[key as keyof ChatConfig],
91
+ );
92
+
93
+ if (configChanged) {
94
+ setConfig(props.config);
95
+ setPrevPropsConfig(props.config);
96
+ }
97
+
84
98
  // Use a ref to avoid stale closure in the fetch callback
85
99
  const configRef = useRef<ChatConfig>(config);
86
100
  configRef.current = config;
@@ -739,7 +753,6 @@ const ConfigPopup: React.FC<{
739
753
  config: ChatConfig;
740
754
  onChange: (newConfig: ChatConfig) => void;
741
755
  }> = ({ config, onChange }) => {
742
- const [localConfig, setLocalConfig] = useState<ChatConfig>(config);
743
756
  const [open, setOpen] = useState(false);
744
757
 
745
758
  const handleChange = (key: keyof ChatConfig, value: number | null) => {
@@ -754,8 +767,7 @@ const ConfigPopup: React.FC<{
754
767
  finalValue = clampedValue;
755
768
  }
756
769
 
757
- const newConfig = { ...localConfig, [key]: finalValue };
758
- setLocalConfig(newConfig);
770
+ const newConfig = { ...config, [key]: finalValue };
759
771
  onChange(newConfig);
760
772
  };
761
773
 
@@ -782,7 +794,7 @@ const ConfigPopup: React.FC<{
782
794
  <PopoverContent className="w-70 border">
783
795
  <div className="grid gap-3">
784
796
  <h4 className="font-bold leading-none">Configuration</h4>
785
- {Objects.entries(localConfig).map(([key, value]) => (
797
+ {Objects.entries(config).map(([key, value]) => (
786
798
  <div key={key} className="grid grid-cols-3 items-center gap-1">
787
799
  <Label
788
800
  htmlFor={key}