@gendive/chatllm 0.21.6 → 0.21.8

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.
@@ -54,6 +54,7 @@ __export(index_exports, {
54
54
  Icon: () => Icon,
55
55
  IconSvg: () => IconSvg,
56
56
  ImageContentCard: () => ImageContentCard,
57
+ ImageErrorContext: () => ImageErrorContext,
57
58
  LinkChip: () => LinkChip,
58
59
  MarkdownRenderer: () => MarkdownRenderer,
59
60
  MemoryPanel: () => MemoryPanel,
@@ -75,6 +76,7 @@ __export(index_exports, {
75
76
  useDeepResearch: () => useDeepResearch,
76
77
  useDragResize: () => useDragResize,
77
78
  useFloatingWidget: () => useFloatingWidget,
79
+ useImageError: () => useImageError,
78
80
  useObserver: () => useObserver,
79
81
  useProject: () => useProject,
80
82
  useSkills: () => useSkills
@@ -82,7 +84,7 @@ __export(index_exports, {
82
84
  module.exports = __toCommonJS(index_exports);
83
85
 
84
86
  // src/react/ChatUI.tsx
85
- var import_react23 = __toESM(require("react"));
87
+ var import_react24 = __toESM(require("react"));
86
88
 
87
89
  // src/react/hooks/useChatUI.ts
88
90
  var import_react6 = require("react");
@@ -2327,6 +2329,7 @@ var useChatUI = (options) => {
2327
2329
  onAnalyzePatterns,
2328
2330
  // Image upload
2329
2331
  onUploadImage,
2332
+ onImageError,
2330
2333
  // External storage options
2331
2334
  useExternalStorage = false,
2332
2335
  startWithNewSession = false,
@@ -2433,6 +2436,7 @@ var useChatUI = (options) => {
2433
2436
  const onSessionContextChangeRef = (0, import_react6.useRef)(onSessionContextChange);
2434
2437
  const onLoadModelsRef = (0, import_react6.useRef)(onLoadModels);
2435
2438
  const onUploadImageRef = (0, import_react6.useRef)(onUploadImage);
2439
+ const onImageErrorRef = (0, import_react6.useRef)(onImageError);
2436
2440
  const globalMemoryRef = (0, import_react6.useRef)(null);
2437
2441
  (0, import_react6.useEffect)(() => {
2438
2442
  onSendMessageRef.current = onSendMessage;
@@ -2453,6 +2457,7 @@ var useChatUI = (options) => {
2453
2457
  onSkillCompleteRef.current = onSkillComplete;
2454
2458
  onSessionContextChangeRef.current = onSessionContextChange;
2455
2459
  onUploadImageRef.current = onUploadImage;
2460
+ onImageErrorRef.current = onImageError;
2456
2461
  onLoadModelsRef.current = onLoadModels;
2457
2462
  });
2458
2463
  const abortControllersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
@@ -3542,7 +3547,7 @@ ${finalContent}`;
3542
3547
  if (att.type === "image" && att.file) {
3543
3548
  const dataUri = await fileToDataUri(att.file);
3544
3549
  const imageUrl = onUploadImageRef.current ? await onUploadImageRef.current(dataUri, att.name) : dataUri;
3545
- userContentParts.push({ type: "image", url: imageUrl, alt: att.name });
3550
+ userContentParts.push({ type: "image", url: imageUrl, alt: att.name, fileName: att.name });
3546
3551
  } else {
3547
3552
  userContentParts.push({ type: "file", name: att.name, url: att.previewUrl || "", mimeType: att.mimeType, size: att.size });
3548
3553
  }
@@ -3603,13 +3608,17 @@ ${finalContent}`;
3603
3608
  for (const [skillName, skillConfig] of attachmentSkills) {
3604
3609
  let matchedFiles = currentAttachments.filter((att) => {
3605
3610
  if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
3611
+ const fileName = (att.name || "").toLowerCase();
3612
+ const fileMime = (att.mimeType || "").toLowerCase();
3613
+ const fileExt = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
3606
3614
  return skillConfig.acceptedTypes.some((type) => {
3607
- if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
3608
- if (type.includes("*")) {
3609
- const regex = new RegExp("^" + type.replace("*", ".*") + "$");
3610
- return regex.test(att.mimeType);
3615
+ const t = type.toLowerCase();
3616
+ if (t.startsWith(".")) return fileExt === t || fileName.endsWith(t);
3617
+ if (t.includes("*")) {
3618
+ const regex = new RegExp("^" + t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace("\\*", ".*") + "$");
3619
+ return regex.test(fileMime);
3611
3620
  }
3612
- return att.mimeType === type;
3621
+ return fileMime === t;
3613
3622
  });
3614
3623
  });
3615
3624
  if (skipImageAttachmentSkill) {
@@ -4064,25 +4073,26 @@ ${attachmentContext}
4064
4073
  }
4065
4074
  }
4066
4075
  }
4067
- const saveMessagesOnEarlyReturn = () => {
4076
+ const saveMessagesOnEarlyReturn = (overrideContentParts) => {
4068
4077
  if (!useExternalStorage || !capturedSessionId) return;
4069
- queueMicrotask(() => {
4078
+ setTimeout(() => {
4070
4079
  const latestSession = sessionsRef.current.find((s) => s.id === capturedSessionId);
4071
4080
  if (!latestSession) return;
4072
4081
  const latestMessages = latestSession.messages;
4073
4082
  const assistantMsg = [...latestMessages].reverse().find((m) => m.role === "assistant");
4074
4083
  const userMsg = latestMessages.find((m) => m.role === "user" && m.content === finalContent);
4075
4084
  const assistantContent = assistantMsg?.content || "";
4076
- if (assistantContent && onSaveMessagesRef.current) {
4085
+ const finalContentParts = overrideContentParts || assistantMsg?.contentParts;
4086
+ if ((assistantContent || finalContentParts) && onSaveMessagesRef.current) {
4077
4087
  onSaveMessagesRef.current(capturedSessionId, [
4078
4088
  { role: "user", message: finalContent, ...userMsg?.contentParts && { contentParts: userMsg.contentParts } },
4079
- { role: "assistant", message: assistantContent, ...assistantMsg?.contentParts && { contentParts: assistantMsg.contentParts } }
4089
+ { role: "assistant", message: assistantContent, ...finalContentParts && { contentParts: finalContentParts } }
4080
4090
  ]).catch((e) => console.error("[useChatUI] Failed to save messages:", e));
4081
4091
  }
4082
4092
  if (latestSession.messages.length > 0) {
4083
4093
  writeSessionCache(storageKey, latestSession);
4084
4094
  }
4085
- });
4095
+ }, 0);
4086
4096
  };
4087
4097
  if (!shouldSkipSkillParsing) {
4088
4098
  const assistantContent = accumulatedContent;
@@ -4272,7 +4282,7 @@ ${attachmentContext}
4272
4282
  promoteToSessionContext(capturedSessionId, toolName, result.content, result.metadata, toolLabel || toolName);
4273
4283
  }
4274
4284
  if (resultType === "image" || resultType === "file") {
4275
- saveMessagesOnEarlyReturn();
4285
+ saveMessagesOnEarlyReturn(parts);
4276
4286
  removeLoadingSession(capturedSessionId);
4277
4287
  abortControllersRef.current.delete(capturedSessionId);
4278
4288
  return;
@@ -4283,7 +4293,7 @@ ${attachmentContext}
4283
4293
  shouldContinue = decision === "continue";
4284
4294
  }
4285
4295
  if (!shouldContinue) {
4286
- saveMessagesOnEarlyReturn();
4296
+ saveMessagesOnEarlyReturn(parts);
4287
4297
  removeLoadingSession(capturedSessionId);
4288
4298
  abortControllersRef.current.delete(capturedSessionId);
4289
4299
  return;
@@ -4358,13 +4368,13 @@ ${result.content}
4358
4368
  shouldContinueImgFile = decision === "continue";
4359
4369
  }
4360
4370
  if (!shouldContinueImgFile) {
4361
- saveMessagesOnEarlyReturn();
4371
+ saveMessagesOnEarlyReturn(imgFileParts);
4362
4372
  removeLoadingSession(capturedSessionId);
4363
4373
  abortControllersRef.current.delete(capturedSessionId);
4364
4374
  return;
4365
4375
  }
4366
4376
  skipNextSkillParsingRef.current = true;
4367
- saveMessagesOnEarlyReturn();
4377
+ saveMessagesOnEarlyReturn(imgFileParts);
4368
4378
  const imgFilePrompt = skillResultType === "image" ? `"${detectedSkill.name}" \uC2A4\uD0AC\uB85C \uC774\uBBF8\uC9C0\uAC00 \uC0DD\uC131\uB418\uC5B4 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD45C\uC2DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC774\uBBF8\uC9C0 URL\uC744 \uD14D\uC2A4\uD2B8\uC5D0 \uD3EC\uD568\uD558\uC9C0 \uB9D0\uACE0, \uC0DD\uC131\uB41C \uC774\uBBF8\uC9C0\uC5D0 \uB300\uD574 \uAC04\uB2E8\uD788 \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.` : `"${detectedSkill.name}" \uC2A4\uD0AC\uB85C \uD30C\uC77C\uC774 \uC0DD\uC131\uB418\uC5B4 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD45C\uC2DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD30C\uC77C URL\uC744 \uD14D\uC2A4\uD2B8\uC5D0 \uD3EC\uD568\uD558\uC9C0 \uB9D0\uACE0, \uACB0\uACFC\uC5D0 \uB300\uD574 \uAC04\uB2E8\uD788 \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
4369
4379
  setTimeout(() => {
4370
4380
  sendMessage(imgFilePrompt, { hiddenUserMessage: true });
@@ -5733,8 +5743,13 @@ ${result.content}
5733
5743
  };
5734
5744
  };
5735
5745
 
5746
+ // src/react/contexts/ImageErrorContext.ts
5747
+ var import_react7 = require("react");
5748
+ var ImageErrorContext = (0, import_react7.createContext)(null);
5749
+ var useImageError = () => (0, import_react7.useContext)(ImageErrorContext);
5750
+
5736
5751
  // src/react/components/ChatSidebar.tsx
5737
- var import_react10 = require("react");
5752
+ var import_react11 = require("react");
5738
5753
 
5739
5754
  // src/react/components/Icon.tsx
5740
5755
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -5834,10 +5849,10 @@ var IconSvg = ({
5834
5849
  };
5835
5850
 
5836
5851
  // src/react/components/MarkdownRenderer.tsx
5837
- var import_react8 = __toESM(require("react"));
5852
+ var import_react9 = __toESM(require("react"));
5838
5853
 
5839
5854
  // src/react/components/LinkChip.tsx
5840
- var import_react7 = require("react");
5855
+ var import_react8 = require("react");
5841
5856
  var import_jsx_runtime2 = require("react/jsx-runtime");
5842
5857
  var getDomain = (url) => {
5843
5858
  try {
@@ -5891,7 +5906,7 @@ var LinkChip = ({
5891
5906
  index,
5892
5907
  style
5893
5908
  }) => {
5894
- const [isHovered, setIsHovered] = (0, import_react7.useState)(false);
5909
+ const [isHovered, setIsHovered] = (0, import_react8.useState)(false);
5895
5910
  const domain = getDomain(url);
5896
5911
  const shortName = getShortName(domain);
5897
5912
  const domainColor = getDomainColor(domain);
@@ -6261,8 +6276,8 @@ var parseTableRow = (row) => {
6261
6276
  return row.split("|").slice(1, -1).map((cell) => cell.trim());
6262
6277
  };
6263
6278
  var MarkdownTable = ({ data }) => {
6264
- const [copied, setCopied] = import_react8.default.useState(false);
6265
- const [isHovered, setIsHovered] = import_react8.default.useState(false);
6279
+ const [copied, setCopied] = import_react9.default.useState(false);
6280
+ const [isHovered, setIsHovered] = import_react9.default.useState(false);
6266
6281
  const handleCopy = async () => {
6267
6282
  const headerLine = data.headers.join(" ");
6268
6283
  const bodyLines = data.rows.map((row) => row.join(" "));
@@ -6374,7 +6389,7 @@ var ThinkingSpinner = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6374
6389
  }
6375
6390
  );
6376
6391
  var ThinkingBlock = ({ content, defaultOpen = false }) => {
6377
- const [isOpen, setIsOpen] = import_react8.default.useState(defaultOpen);
6392
+ const [isOpen, setIsOpen] = import_react9.default.useState(defaultOpen);
6378
6393
  const isStreaming = content.trim().endsWith("...");
6379
6394
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
6380
6395
  "details",
@@ -6449,7 +6464,7 @@ var ThinkingBlock = ({ content, defaultOpen = false }) => {
6449
6464
  );
6450
6465
  };
6451
6466
  var CodeBlock = ({ language, code }) => {
6452
- const [copied, setCopied] = import_react8.default.useState(false);
6467
+ const [copied, setCopied] = import_react9.default.useState(false);
6453
6468
  const handleCopy = async () => {
6454
6469
  try {
6455
6470
  await navigator.clipboard.writeText(code);
@@ -6532,9 +6547,20 @@ var CodeBlock = ({ language, code }) => {
6532
6547
  );
6533
6548
  };
6534
6549
  var ImageWithCopyButton = ({ src, alt, imageKey }) => {
6535
- const [isHovered, setIsHovered] = import_react8.default.useState(false);
6536
- const [copyState, setCopyState] = import_react8.default.useState("idle");
6537
- const imgRef = import_react8.default.useRef(null);
6550
+ const [isHovered, setIsHovered] = import_react9.default.useState(false);
6551
+ const [imgSrc, setImgSrc] = import_react9.default.useState(src);
6552
+ const onImageError = useImageError();
6553
+ const handleImageError = import_react9.default.useCallback(async () => {
6554
+ if (onImageError) {
6555
+ const newUrl = await onImageError(imgSrc);
6556
+ if (newUrl) {
6557
+ setImgSrc(newUrl);
6558
+ return;
6559
+ }
6560
+ }
6561
+ }, [onImageError, imgSrc]);
6562
+ const [copyState, setCopyState] = import_react9.default.useState("idle");
6563
+ const imgRef = import_react9.default.useRef(null);
6538
6564
  const getImageBlob = async () => {
6539
6565
  const img = imgRef.current;
6540
6566
  if (img && img.complete && img.naturalWidth > 0) {
@@ -6647,10 +6673,11 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
6647
6673
  "img",
6648
6674
  {
6649
6675
  ref: imgRef,
6650
- src,
6676
+ src: imgSrc,
6651
6677
  alt,
6652
6678
  className: "chatllm-image",
6653
- crossOrigin: src.startsWith("data:") ? void 0 : "anonymous",
6679
+ crossOrigin: imgSrc.startsWith("data:") ? void 0 : "anonymous",
6680
+ onError: handleImageError,
6654
6681
  style: {
6655
6682
  maxWidth: "100%",
6656
6683
  borderRadius: "8px",
@@ -6749,7 +6776,7 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
6749
6776
  );
6750
6777
  };
6751
6778
  var ChoiceButtons = ({ choices, title, onChoiceClick }) => {
6752
- const [hoveredIndex, setHoveredIndex] = import_react8.default.useState(null);
6779
+ const [hoveredIndex, setHoveredIndex] = import_react9.default.useState(null);
6753
6780
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
6754
6781
  "div",
6755
6782
  {
@@ -6879,11 +6906,11 @@ var MarkdownRenderer = ({
6879
6906
  sources,
6880
6907
  inline = false
6881
6908
  }) => {
6882
- const inlineRendered = (0, import_react8.useMemo)(() => {
6909
+ const inlineRendered = (0, import_react9.useMemo)(() => {
6883
6910
  if (!inline) return null;
6884
6911
  return parseInlineElements(content, "inline-md", sources);
6885
6912
  }, [inline, content, sources]);
6886
- const rendered = (0, import_react8.useMemo)(() => {
6913
+ const rendered = (0, import_react9.useMemo)(() => {
6887
6914
  if (inline) return null;
6888
6915
  const elements = [];
6889
6916
  let processedContent = content;
@@ -7036,7 +7063,7 @@ var MarkdownRenderer = ({
7036
7063
  borderRadius: "0 8px 8px 0",
7037
7064
  color: "var(--chatllm-text, #374151)"
7038
7065
  },
7039
- children: blockquoteLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react8.default.Fragment, { children: [
7066
+ children: blockquoteLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react9.default.Fragment, { children: [
7040
7067
  parseInlineElements(line, `bq-line-${i}`, sources),
7041
7068
  i < blockquoteLines.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("br", {})
7042
7069
  ] }, i))
@@ -7280,7 +7307,7 @@ var MarkdownRenderer = ({
7280
7307
  };
7281
7308
 
7282
7309
  // src/react/components/ProjectSelector.tsx
7283
- var import_react9 = require("react");
7310
+ var import_react10 = require("react");
7284
7311
  var import_jsx_runtime4 = require("react/jsx-runtime");
7285
7312
  var ProjectSelector = ({
7286
7313
  projects,
@@ -7289,10 +7316,10 @@ var ProjectSelector = ({
7289
7316
  onNewProject,
7290
7317
  onProjectSettings
7291
7318
  }) => {
7292
- const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
7293
- const dropdownRef = (0, import_react9.useRef)(null);
7319
+ const [isOpen, setIsOpen] = (0, import_react10.useState)(false);
7320
+ const dropdownRef = (0, import_react10.useRef)(null);
7294
7321
  const currentProject = projects.find((p) => p.id === currentProjectId);
7295
- (0, import_react9.useEffect)(() => {
7322
+ (0, import_react10.useEffect)(() => {
7296
7323
  const handleClickOutside = (e) => {
7297
7324
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
7298
7325
  setIsOpen(false);
@@ -7526,10 +7553,10 @@ var ChatSidebar = ({
7526
7553
  isLoading = false
7527
7554
  }) => {
7528
7555
  const sidebarWidth = typeof widthProp === "number" ? `${widthProp}px` : widthProp || "288px";
7529
- const [editingId, setEditingId] = (0, import_react10.useState)(null);
7530
- const [editingTitle, setEditingTitle] = (0, import_react10.useState)("");
7531
- const inputRef = (0, import_react10.useRef)(null);
7532
- (0, import_react10.useEffect)(() => {
7556
+ const [editingId, setEditingId] = (0, import_react11.useState)(null);
7557
+ const [editingTitle, setEditingTitle] = (0, import_react11.useState)("");
7558
+ const inputRef = (0, import_react11.useRef)(null);
7559
+ (0, import_react11.useEffect)(() => {
7533
7560
  if (editingId && inputRef.current) {
7534
7561
  inputRef.current.focus();
7535
7562
  inputRef.current.select();
@@ -7901,7 +7928,7 @@ var ChatSidebar = ({
7901
7928
  };
7902
7929
 
7903
7930
  // src/react/components/ChatHeader.tsx
7904
- var import_react11 = require("react");
7931
+ var import_react12 = require("react");
7905
7932
  var import_jsx_runtime6 = require("react/jsx-runtime");
7906
7933
  var ChatHeader = ({
7907
7934
  title,
@@ -7915,7 +7942,7 @@ var ChatHeader = ({
7915
7942
  showSettings = true,
7916
7943
  renderHeaderExtra
7917
7944
  }) => {
7918
- const [modelDropdownOpen, setModelDropdownOpen] = (0, import_react11.useState)(false);
7945
+ const [modelDropdownOpen, setModelDropdownOpen] = (0, import_react12.useState)(false);
7919
7946
  const currentModel = models.find((m) => m.id === model);
7920
7947
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
7921
7948
  "header",
@@ -8170,7 +8197,7 @@ var ChatHeader = ({
8170
8197
  };
8171
8198
 
8172
8199
  // src/react/components/ChatInput.tsx
8173
- var import_react12 = __toESM(require("react"));
8200
+ var import_react13 = __toESM(require("react"));
8174
8201
  var import_jsx_runtime7 = require("react/jsx-runtime");
8175
8202
  var ChatInput = ({
8176
8203
  value,
@@ -8198,20 +8225,20 @@ var ChatInput = ({
8198
8225
  onDisclaimerClick,
8199
8226
  inline = false
8200
8227
  }) => {
8201
- const [mainMenuOpen, setMainMenuOpen] = import_react12.default.useState(false);
8202
- const textareaRef = (0, import_react12.useRef)(null);
8203
- const fileInputRef = (0, import_react12.useRef)(null);
8204
- const [actionMenuOpen, setActionMenuOpen] = (0, import_react12.useState)(false);
8205
- const [isDragOver, setIsDragOver] = (0, import_react12.useState)(false);
8206
- const mainMenuRef = (0, import_react12.useRef)(null);
8207
- const actionMenuRef = (0, import_react12.useRef)(null);
8208
- (0, import_react12.useEffect)(() => {
8228
+ const [mainMenuOpen, setMainMenuOpen] = import_react13.default.useState(false);
8229
+ const textareaRef = (0, import_react13.useRef)(null);
8230
+ const fileInputRef = (0, import_react13.useRef)(null);
8231
+ const [actionMenuOpen, setActionMenuOpen] = (0, import_react13.useState)(false);
8232
+ const [isDragOver, setIsDragOver] = (0, import_react13.useState)(false);
8233
+ const mainMenuRef = (0, import_react13.useRef)(null);
8234
+ const actionMenuRef = (0, import_react13.useRef)(null);
8235
+ (0, import_react13.useEffect)(() => {
8209
8236
  if (textareaRef.current) {
8210
8237
  textareaRef.current.style.height = "auto";
8211
8238
  textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 200)}px`;
8212
8239
  }
8213
8240
  }, [value]);
8214
- (0, import_react12.useEffect)(() => {
8241
+ (0, import_react13.useEffect)(() => {
8215
8242
  const handleClickOutside = (event) => {
8216
8243
  if (mainMenuRef.current && !mainMenuRef.current.contains(event.target)) {
8217
8244
  setMainMenuOpen(false);
@@ -8933,13 +8960,13 @@ var iconButtonStyle = {
8933
8960
  };
8934
8961
 
8935
8962
  // src/react/components/MessageList.tsx
8936
- var import_react20 = __toESM(require("react"));
8963
+ var import_react21 = __toESM(require("react"));
8937
8964
 
8938
8965
  // src/react/components/MessageBubble.tsx
8939
- var import_react19 = require("react");
8966
+ var import_react20 = require("react");
8940
8967
 
8941
8968
  // src/react/components/DeepResearchProgressUI.tsx
8942
- var import_react13 = __toESM(require("react"));
8969
+ var import_react14 = __toESM(require("react"));
8943
8970
  var import_jsx_runtime8 = require("react/jsx-runtime");
8944
8971
  var StatusIcon = ({ status }) => {
8945
8972
  switch (status) {
@@ -9003,7 +9030,7 @@ var PhaseProgress = ({ phase }) => {
9003
9030
  gap: "8px",
9004
9031
  marginBottom: "16px"
9005
9032
  },
9006
- children: phases.slice(0, 4).map((p, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react13.default.Fragment, { children: [
9033
+ children: phases.slice(0, 4).map((p, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react14.default.Fragment, { children: [
9007
9034
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
9008
9035
  "div",
9009
9036
  {
@@ -9222,7 +9249,7 @@ var DeepResearchProgressUI = ({ progress }) => {
9222
9249
  };
9223
9250
 
9224
9251
  // src/react/components/PollCard.tsx
9225
- var import_react14 = require("react");
9252
+ var import_react15 = require("react");
9226
9253
  var import_jsx_runtime9 = require("react/jsx-runtime");
9227
9254
  var renderInlineMarkdown = (text) => {
9228
9255
  const parts = [];
@@ -9261,12 +9288,12 @@ var PollCard = ({
9261
9288
  onSubmit,
9262
9289
  onSkip
9263
9290
  }) => {
9264
- const [activeTab, setActiveTab] = (0, import_react14.useState)(0);
9265
- const [selections, setSelections] = (0, import_react14.useState)({});
9266
- const [otherTexts, setOtherTexts] = (0, import_react14.useState)({});
9267
- const [otherSelected, setOtherSelected] = (0, import_react14.useState)({});
9291
+ const [activeTab, setActiveTab] = (0, import_react15.useState)(0);
9292
+ const [selections, setSelections] = (0, import_react15.useState)({});
9293
+ const [otherTexts, setOtherTexts] = (0, import_react15.useState)({});
9294
+ const [otherSelected, setOtherSelected] = (0, import_react15.useState)({});
9268
9295
  const currentQuestion = questions[activeTab];
9269
- const handleOptionToggle = (0, import_react14.useCallback)(
9296
+ const handleOptionToggle = (0, import_react15.useCallback)(
9270
9297
  (questionId, optionId, multiSelect) => {
9271
9298
  setSelections((prev) => {
9272
9299
  const current = prev[questionId] || /* @__PURE__ */ new Set();
@@ -9288,7 +9315,7 @@ var PollCard = ({
9288
9315
  },
9289
9316
  []
9290
9317
  );
9291
- const handleOtherToggle = (0, import_react14.useCallback)((questionId, multiSelect) => {
9318
+ const handleOtherToggle = (0, import_react15.useCallback)((questionId, multiSelect) => {
9292
9319
  if (multiSelect) {
9293
9320
  setOtherSelected((prev) => ({ ...prev, [questionId]: !prev[questionId] }));
9294
9321
  } else {
@@ -9296,7 +9323,7 @@ var PollCard = ({
9296
9323
  setOtherSelected((prev) => ({ ...prev, [questionId]: true }));
9297
9324
  }
9298
9325
  }, []);
9299
- const handleSubmit = (0, import_react14.useCallback)(() => {
9326
+ const handleSubmit = (0, import_react15.useCallback)(() => {
9300
9327
  const responses = questions.map((q) => {
9301
9328
  const selected = selections[q.id] || /* @__PURE__ */ new Set();
9302
9329
  const other = otherSelected[q.id] && otherTexts[q.id]?.trim();
@@ -9309,7 +9336,7 @@ var PollCard = ({
9309
9336
  });
9310
9337
  onSubmit(responses);
9311
9338
  }, [questions, selections, otherSelected, otherTexts, onSubmit]);
9312
- const handleSkip = (0, import_react14.useCallback)(() => {
9339
+ const handleSkip = (0, import_react15.useCallback)(() => {
9313
9340
  const responses = questions.map((q) => ({
9314
9341
  questionId: q.id,
9315
9342
  selectedOptions: [],
@@ -9318,7 +9345,7 @@ var PollCard = ({
9318
9345
  onSubmit(responses);
9319
9346
  onSkip?.();
9320
9347
  }, [questions, onSubmit, onSkip]);
9321
- (0, import_react14.useEffect)(() => {
9348
+ (0, import_react15.useEffect)(() => {
9322
9349
  if (typeof window === "undefined") return;
9323
9350
  const handleKeyDown = (e) => {
9324
9351
  if (e.key !== "Escape") return;
@@ -9337,9 +9364,9 @@ var PollCard = ({
9337
9364
  const currentHasSelection = getSelectionCount(currentQuestion.id) > 0;
9338
9365
  const isLastTab = activeTab === questions.length - 1;
9339
9366
  const totalSelected = questions.reduce((sum, q) => sum + getSelectionCount(q.id), 0);
9340
- const [visibleCount, setVisibleCount] = (0, import_react14.useState)(0);
9341
- const [cardVisible, setCardVisible] = (0, import_react14.useState)(false);
9342
- (0, import_react14.useEffect)(() => {
9367
+ const [visibleCount, setVisibleCount] = (0, import_react15.useState)(0);
9368
+ const [cardVisible, setCardVisible] = (0, import_react15.useState)(false);
9369
+ (0, import_react15.useEffect)(() => {
9343
9370
  const fadeTimer = setTimeout(() => setCardVisible(true), 50);
9344
9371
  const totalItems = currentQuestion.options.length + 1;
9345
9372
  const timers = [fadeTimer];
@@ -9348,7 +9375,7 @@ var PollCard = ({
9348
9375
  }
9349
9376
  return () => timers.forEach(clearTimeout);
9350
9377
  }, [currentQuestion.options.length]);
9351
- (0, import_react14.useEffect)(() => {
9378
+ (0, import_react15.useEffect)(() => {
9352
9379
  setVisibleCount(0);
9353
9380
  const totalItems = currentQuestion.options.length + 1;
9354
9381
  const timers = [];
@@ -9357,7 +9384,7 @@ var PollCard = ({
9357
9384
  }
9358
9385
  return () => timers.forEach(clearTimeout);
9359
9386
  }, [activeTab, currentQuestion.options.length]);
9360
- const handleNext = (0, import_react14.useCallback)(() => {
9387
+ const handleNext = (0, import_react15.useCallback)(() => {
9361
9388
  if (!isLastTab) {
9362
9389
  setActiveTab((prev) => prev + 1);
9363
9390
  } else {
@@ -9775,12 +9802,25 @@ var SkillProgressUI = ({
9775
9802
  };
9776
9803
 
9777
9804
  // src/react/components/ImageContentCard.tsx
9778
- var import_react15 = require("react");
9805
+ var import_react16 = require("react");
9779
9806
  var import_jsx_runtime11 = require("react/jsx-runtime");
9780
9807
  var ImageContentCard = ({ part }) => {
9781
- const [isExpanded, setIsExpanded] = (0, import_react15.useState)(false);
9782
- const [isLoaded, setIsLoaded] = (0, import_react15.useState)(false);
9783
- const [hasError, setHasError] = (0, import_react15.useState)(false);
9808
+ const [isExpanded, setIsExpanded] = (0, import_react16.useState)(false);
9809
+ const [isLoaded, setIsLoaded] = (0, import_react16.useState)(false);
9810
+ const [hasError, setHasError] = (0, import_react16.useState)(false);
9811
+ const [imgSrc, setImgSrc] = (0, import_react16.useState)(part.url);
9812
+ const onImageError = useImageError();
9813
+ const handleImageError = (0, import_react16.useCallback)(async () => {
9814
+ if (onImageError) {
9815
+ const newUrl = await onImageError(imgSrc, part.fileName);
9816
+ if (newUrl) {
9817
+ setImgSrc(newUrl);
9818
+ setIsLoaded(false);
9819
+ return;
9820
+ }
9821
+ }
9822
+ setHasError(true);
9823
+ }, [onImageError, imgSrc, part.fileName]);
9784
9824
  if (hasError) {
9785
9825
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
9786
9826
  "div",
@@ -9833,10 +9873,10 @@ var ImageContentCard = ({ part }) => {
9833
9873
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
9834
9874
  "img",
9835
9875
  {
9836
- src: part.url,
9876
+ src: imgSrc,
9837
9877
  alt: part.alt || "",
9838
9878
  onLoad: () => setIsLoaded(true),
9839
- onError: () => setHasError(true),
9879
+ onError: handleImageError,
9840
9880
  style: {
9841
9881
  display: isLoaded ? "block" : "none",
9842
9882
  width: "100%",
@@ -9879,7 +9919,7 @@ var ImageContentCard = ({ part }) => {
9879
9919
  children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
9880
9920
  "img",
9881
9921
  {
9882
- src: part.url,
9922
+ src: imgSrc,
9883
9923
  alt: part.alt || "",
9884
9924
  style: {
9885
9925
  maxWidth: "90vw",
@@ -9983,7 +10023,7 @@ var FileContentCard = ({ part }) => {
9983
10023
  };
9984
10024
 
9985
10025
  // src/react/components/ToolStatusCard.tsx
9986
- var import_react16 = require("react");
10026
+ var import_react17 = require("react");
9987
10027
  var import_jsx_runtime13 = require("react/jsx-runtime");
9988
10028
  var mapIcon2 = (icon) => {
9989
10029
  const iconMap = {
@@ -10016,7 +10056,7 @@ var ToolStatusCard = ({
10016
10056
  sources,
10017
10057
  errorMessage
10018
10058
  }) => {
10019
- const [isExpanded, setIsExpanded] = (0, import_react16.useState)(false);
10059
+ const [isExpanded, setIsExpanded] = (0, import_react17.useState)(false);
10020
10060
  const displayLabel = label || getDefaultLabel(toolName);
10021
10061
  const statusText = getStatusSuffix(displayLabel, status);
10022
10062
  const hasSources = sources && sources.length > 0;
@@ -10147,7 +10187,7 @@ var ToolStatusCard = ({
10147
10187
  };
10148
10188
 
10149
10189
  // src/react/components/ArtifactCard.tsx
10150
- var import_react17 = require("react");
10190
+ var import_react18 = require("react");
10151
10191
  var import_jsx_runtime14 = require("react/jsx-runtime");
10152
10192
  var getThemeStyles = () => {
10153
10193
  const root = document.documentElement;
@@ -10188,10 +10228,10 @@ var getAutoResizeScript = (id) => `
10188
10228
  });
10189
10229
  </script>`;
10190
10230
  var HtmlArtifact = ({ code }) => {
10191
- const iframeRef = (0, import_react17.useRef)(null);
10192
- const [height, setHeight] = (0, import_react17.useState)(200);
10193
- const artifactId = (0, import_react17.useRef)(`artifact-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`);
10194
- (0, import_react17.useEffect)(() => {
10231
+ const iframeRef = (0, import_react18.useRef)(null);
10232
+ const [height, setHeight] = (0, import_react18.useState)(200);
10233
+ const artifactId = (0, import_react18.useRef)(`artifact-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`);
10234
+ (0, import_react18.useEffect)(() => {
10195
10235
  const id = artifactId.current;
10196
10236
  const handleMessage = (e) => {
10197
10237
  if (e.data?.type === "artifact-resize" && e.data.id === id && typeof e.data.height === "number") {
@@ -10237,10 +10277,10 @@ var SvgArtifact = ({ code }) => {
10237
10277
  );
10238
10278
  };
10239
10279
  var MermaidArtifact = ({ code }) => {
10240
- const containerRef = (0, import_react17.useRef)(null);
10241
- const [svgHtml, setSvgHtml] = (0, import_react17.useState)(null);
10242
- const [error, setError] = (0, import_react17.useState)(null);
10243
- const renderMermaid = (0, import_react17.useCallback)(async () => {
10280
+ const containerRef = (0, import_react18.useRef)(null);
10281
+ const [svgHtml, setSvgHtml] = (0, import_react18.useState)(null);
10282
+ const [error, setError] = (0, import_react18.useState)(null);
10283
+ const renderMermaid = (0, import_react18.useCallback)(async () => {
10244
10284
  try {
10245
10285
  let mermaid;
10246
10286
  try {
@@ -10256,7 +10296,7 @@ var MermaidArtifact = ({ code }) => {
10256
10296
  setError(e instanceof Error ? e.message : "Mermaid \uB80C\uB354\uB9C1 \uC2E4\uD328");
10257
10297
  }
10258
10298
  }, [code]);
10259
- (0, import_react17.useEffect)(() => {
10299
+ (0, import_react18.useEffect)(() => {
10260
10300
  renderMermaid();
10261
10301
  }, [renderMermaid]);
10262
10302
  if (error) {
@@ -10332,9 +10372,9 @@ var svgToPngBlob = (svgString, scale = 2) => {
10332
10372
  });
10333
10373
  };
10334
10374
  var ArtifactActions = ({ code, language, containerRef }) => {
10335
- const [showCode, setShowCode] = (0, import_react17.useState)(false);
10336
- const [copied, setCopied] = (0, import_react17.useState)(false);
10337
- const [saving, setSaving] = (0, import_react17.useState)(false);
10375
+ const [showCode, setShowCode] = (0, import_react18.useState)(false);
10376
+ const [copied, setCopied] = (0, import_react18.useState)(false);
10377
+ const [saving, setSaving] = (0, import_react18.useState)(false);
10338
10378
  const handleCopy = async () => {
10339
10379
  try {
10340
10380
  await navigator.clipboard.writeText(code);
@@ -10499,7 +10539,7 @@ var ArtifactActions = ({ code, language, containerRef }) => {
10499
10539
  ] });
10500
10540
  };
10501
10541
  var ArtifactCard = ({ part, index = 0 }) => {
10502
- const contentRef = (0, import_react17.useRef)(null);
10542
+ const contentRef = (0, import_react18.useRef)(null);
10503
10543
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
10504
10544
  "div",
10505
10545
  {
@@ -10624,7 +10664,7 @@ var ContentPartRenderer = ({
10624
10664
  effectiveType === "image" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
10625
10665
  ImageContentCard,
10626
10666
  {
10627
- part: { type: "image", url: result.content, alt: result.metadata?.alt }
10667
+ part: { type: "image", url: result.content, alt: result.metadata?.alt, fileName: result.metadata?.fileName }
10628
10668
  }
10629
10669
  ),
10630
10670
  effectiveType === "file" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -10671,7 +10711,7 @@ var ContentPartRenderer = ({
10671
10711
  };
10672
10712
 
10673
10713
  // src/react/components/ChecklistCard.tsx
10674
- var import_react18 = require("react");
10714
+ var import_react19 = require("react");
10675
10715
  var import_jsx_runtime16 = require("react/jsx-runtime");
10676
10716
  var ChecklistCard = ({
10677
10717
  items,
@@ -10681,8 +10721,8 @@ var ChecklistCard = ({
10681
10721
  onSkipStep,
10682
10722
  onStart
10683
10723
  }) => {
10684
- const [expandedItems, setExpandedItems] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
10685
- const { doneCount, isRunning, hasError, isWaiting } = (0, import_react18.useMemo)(() => {
10724
+ const [expandedItems, setExpandedItems] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
10725
+ const { doneCount, isRunning, hasError, isWaiting } = (0, import_react19.useMemo)(() => {
10686
10726
  const done = items.filter((it) => it.status === "done").length;
10687
10727
  const running = items.some((it) => it.status === "in_progress");
10688
10728
  const waiting = items.every((it) => it.status === "pending");
@@ -11179,9 +11219,9 @@ var MessageBubble = ({
11179
11219
  onToggleChecklistPanel,
11180
11220
  onChecklistStart
11181
11221
  }) => {
11182
- const [showActions, setShowActions] = (0, import_react19.useState)(false);
11183
- const [showModelMenu, setShowModelMenu] = (0, import_react19.useState)(false);
11184
- const [stepExpanded, setStepExpanded] = (0, import_react19.useState)(false);
11222
+ const [showActions, setShowActions] = (0, import_react20.useState)(false);
11223
+ const [showModelMenu, setShowModelMenu] = (0, import_react20.useState)(false);
11224
+ const [stepExpanded, setStepExpanded] = (0, import_react20.useState)(false);
11185
11225
  const isUser = message.role === "user";
11186
11226
  const isAssistant = message.role === "assistant";
11187
11227
  const relevantAlternatives = isUser ? alternatives : message.alternatives;
@@ -11932,14 +11972,14 @@ var MessageList = ({
11932
11972
  onExport,
11933
11973
  onToggleChecklistPanel
11934
11974
  }) => {
11935
- const messagesEndRef = (0, import_react20.useRef)(null);
11936
- const containerRef = (0, import_react20.useRef)(null);
11937
- const [selectedText, setSelectedText] = (0, import_react20.useState)("");
11938
- const [selectionPosition, setSelectionPosition] = (0, import_react20.useState)(null);
11939
- const [showScrollButton, setShowScrollButton] = (0, import_react20.useState)(false);
11940
- const userScrollLockRef = (0, import_react20.useRef)(false);
11975
+ const messagesEndRef = (0, import_react21.useRef)(null);
11976
+ const containerRef = (0, import_react21.useRef)(null);
11977
+ const [selectedText, setSelectedText] = (0, import_react21.useState)("");
11978
+ const [selectionPosition, setSelectionPosition] = (0, import_react21.useState)(null);
11979
+ const [showScrollButton, setShowScrollButton] = (0, import_react21.useState)(false);
11980
+ const userScrollLockRef = (0, import_react21.useRef)(false);
11941
11981
  const SCROLL_THRESHOLD = 100;
11942
- (0, import_react20.useEffect)(() => {
11982
+ (0, import_react21.useEffect)(() => {
11943
11983
  const container = containerRef.current;
11944
11984
  if (!container) return;
11945
11985
  const handleWheel = (e) => {
@@ -11976,7 +12016,7 @@ var MessageList = ({
11976
12016
  container.removeEventListener("touchmove", handleTouchMove);
11977
12017
  };
11978
12018
  }, []);
11979
- const handleScroll = (0, import_react20.useCallback)(() => {
12019
+ const handleScroll = (0, import_react21.useCallback)(() => {
11980
12020
  if (!containerRef.current) return;
11981
12021
  const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
11982
12022
  const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
@@ -11985,14 +12025,14 @@ var MessageList = ({
11985
12025
  setShowScrollButton(false);
11986
12026
  }
11987
12027
  }, []);
11988
- (0, import_react20.useEffect)(() => {
12028
+ (0, import_react21.useEffect)(() => {
11989
12029
  if (userScrollLockRef.current) return;
11990
12030
  containerRef.current?.scrollTo({
11991
12031
  top: containerRef.current.scrollHeight,
11992
12032
  behavior: "smooth"
11993
12033
  });
11994
12034
  }, [messages]);
11995
- const scrollToBottom = (0, import_react20.useCallback)(() => {
12035
+ const scrollToBottom = (0, import_react21.useCallback)(() => {
11996
12036
  userScrollLockRef.current = false;
11997
12037
  setShowScrollButton(false);
11998
12038
  containerRef.current?.scrollTo({
@@ -12000,7 +12040,7 @@ var MessageList = ({
12000
12040
  behavior: "smooth"
12001
12041
  });
12002
12042
  }, []);
12003
- const handleMouseUp = (0, import_react20.useCallback)(() => {
12043
+ const handleMouseUp = (0, import_react21.useCallback)(() => {
12004
12044
  const selection = typeof window !== "undefined" ? window.getSelection() : null;
12005
12045
  const text = selection?.toString().trim();
12006
12046
  if (text && text.length > 0) {
@@ -12101,7 +12141,7 @@ var MessageList = ({
12101
12141
  },
12102
12142
  message.id
12103
12143
  );
12104
- return renderMessage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react20.default.Fragment, { children: renderMessage(message, bubbleElement) }, message.id) : bubbleElement;
12144
+ return renderMessage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react21.default.Fragment, { children: renderMessage(message, bubbleElement) }, message.id) : bubbleElement;
12105
12145
  }),
12106
12146
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: messagesEndRef })
12107
12147
  ]
@@ -12195,7 +12235,7 @@ var MessageList = ({
12195
12235
  };
12196
12236
 
12197
12237
  // src/react/components/SettingsModal.tsx
12198
- var import_react21 = require("react");
12238
+ var import_react22 = require("react");
12199
12239
  var import_jsx_runtime19 = require("react/jsx-runtime");
12200
12240
  var DEFAULT_IMPORT_MEMORY_PROMPT = `Export all of my stored memories and any context you've learned about me from past conversations. Preserve my words verbatim where possible, especially for instructions and preferences.
12201
12241
 
@@ -12260,9 +12300,9 @@ var SettingsModal = ({
12260
12300
  onImportMemory,
12261
12301
  importMemoryPrompt
12262
12302
  }) => {
12263
- const [activeTab, setActiveTab] = (0, import_react21.useState)("general");
12264
- const [localApiKey, setLocalApiKey] = (0, import_react21.useState)(apiKey);
12265
- (0, import_react21.useEffect)(() => {
12303
+ const [activeTab, setActiveTab] = (0, import_react22.useState)("general");
12304
+ const [localApiKey, setLocalApiKey] = (0, import_react22.useState)(apiKey);
12305
+ (0, import_react22.useEffect)(() => {
12266
12306
  setLocalApiKey(apiKey);
12267
12307
  }, [apiKey]);
12268
12308
  if (!isOpen) return null;
@@ -12738,11 +12778,11 @@ var memoryCategoryColors = {
12738
12778
  preference: "#8b5cf6"
12739
12779
  };
12740
12780
  var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "AI \uBA54\uBAA8\uB9AC", emptyMessage = "\uC800\uC7A5\uB41C \uBA54\uBAA8\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4", emptyDescription = "\uB300\uD654\uAC00 \uC9C4\uD589\uB418\uBA74 AI\uAC00 \uC790\uB3D9\uC73C\uB85C \uC815\uBCF4\uB97C \uD559\uC2B5\uD569\uB2C8\uB2E4", onImportMemory, importMemoryPrompt }) => {
12741
- const [activeFilter, setActiveFilter] = (0, import_react21.useState)("all");
12742
- const [expandedId, setExpandedId] = (0, import_react21.useState)(null);
12743
- const [importModalOpen, setImportModalOpen] = (0, import_react21.useState)(false);
12744
- const [importText, setImportText] = (0, import_react21.useState)("");
12745
- const [promptCopied, setPromptCopied] = (0, import_react21.useState)(false);
12781
+ const [activeFilter, setActiveFilter] = (0, import_react22.useState)("all");
12782
+ const [expandedId, setExpandedId] = (0, import_react22.useState)(null);
12783
+ const [importModalOpen, setImportModalOpen] = (0, import_react22.useState)(false);
12784
+ const [importText, setImportText] = (0, import_react22.useState)("");
12785
+ const [promptCopied, setPromptCopied] = (0, import_react22.useState)(false);
12746
12786
  const filteredItems = activeFilter === "all" ? items : items.filter((item) => item.category === activeFilter);
12747
12787
  const formatDate = (timestamp) => {
12748
12788
  const date = new Date(timestamp);
@@ -13199,7 +13239,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
13199
13239
  };
13200
13240
 
13201
13241
  // src/react/components/ProjectSettingsModal.tsx
13202
- var import_react22 = require("react");
13242
+ var import_react23 = require("react");
13203
13243
  var import_jsx_runtime20 = require("react/jsx-runtime");
13204
13244
  var COLOR_PRESETS = [
13205
13245
  "#3584FA",
@@ -13220,12 +13260,12 @@ var ProjectSettingsModal = ({
13220
13260
  onDeleteFile,
13221
13261
  onDeleteProject
13222
13262
  }) => {
13223
- const [activeTab, setActiveTab] = (0, import_react22.useState)("general");
13224
- const [title, setTitle] = (0, import_react22.useState)("");
13225
- const [description, setDescription] = (0, import_react22.useState)("");
13226
- const [instructions, setInstructions] = (0, import_react22.useState)("");
13227
- const [color, setColor] = (0, import_react22.useState)("#3584FA");
13228
- (0, import_react22.useEffect)(() => {
13263
+ const [activeTab, setActiveTab] = (0, import_react23.useState)("general");
13264
+ const [title, setTitle] = (0, import_react23.useState)("");
13265
+ const [description, setDescription] = (0, import_react23.useState)("");
13266
+ const [instructions, setInstructions] = (0, import_react23.useState)("");
13267
+ const [color, setColor] = (0, import_react23.useState)("#3584FA");
13268
+ (0, import_react23.useEffect)(() => {
13229
13269
  if (project) {
13230
13270
  setTitle(project.title);
13231
13271
  setDescription(project.description || "");
@@ -14690,28 +14730,28 @@ var ChatUIView = ({
14690
14730
  handleChecklistSkip,
14691
14731
  activeChecklistMessage
14692
14732
  } = state;
14693
- const [disclaimerOpen, setDisclaimerOpen] = import_react23.default.useState(false);
14694
- const [isMobile, setIsMobile] = import_react23.default.useState(false);
14695
- import_react23.default.useEffect(() => {
14733
+ const [disclaimerOpen, setDisclaimerOpen] = import_react24.default.useState(false);
14734
+ const [isMobile, setIsMobile] = import_react24.default.useState(false);
14735
+ import_react24.default.useEffect(() => {
14696
14736
  if (typeof window === "undefined") return;
14697
14737
  const check = () => setIsMobile(window.innerWidth < 768);
14698
14738
  check();
14699
14739
  window.addEventListener("resize", check);
14700
14740
  return () => window.removeEventListener("resize", check);
14701
14741
  }, []);
14702
- const [checklistPanelDismissed, setChecklistPanelDismissed] = import_react23.default.useState(false);
14742
+ const [checklistPanelDismissed, setChecklistPanelDismissed] = import_react24.default.useState(false);
14703
14743
  const isChecklistPanelOpen = !!activeChecklistMessage && !checklistPanelDismissed;
14704
- const prevChecklistIdRef = import_react23.default.useRef(void 0);
14705
- import_react23.default.useEffect(() => {
14744
+ const prevChecklistIdRef = import_react24.default.useRef(void 0);
14745
+ import_react24.default.useEffect(() => {
14706
14746
  const currentId = activeChecklistMessage?.checklistBlock?.id;
14707
14747
  if (currentId && currentId !== prevChecklistIdRef.current && !activeChecklistMessage?.checklistBlock?.completed) {
14708
14748
  setChecklistPanelDismissed(false);
14709
14749
  }
14710
14750
  prevChecklistIdRef.current = currentId;
14711
14751
  }, [activeChecklistMessage?.checklistBlock?.id, activeChecklistMessage?.checklistBlock?.completed]);
14712
- const [welcomeExiting, setWelcomeExiting] = import_react23.default.useState(false);
14713
- const prevMessageCountRef = import_react23.default.useRef(messages.length);
14714
- import_react23.default.useEffect(() => {
14752
+ const [welcomeExiting, setWelcomeExiting] = import_react24.default.useState(false);
14753
+ const prevMessageCountRef = import_react24.default.useRef(messages.length);
14754
+ import_react24.default.useEffect(() => {
14715
14755
  let timer;
14716
14756
  if (prevMessageCountRef.current === 0 && messages.length > 0) {
14717
14757
  setWelcomeExiting(true);
@@ -14735,7 +14775,7 @@ var ChatUIView = ({
14735
14775
  const handleChoiceClick = (choice) => {
14736
14776
  setInput(choice.text);
14737
14777
  };
14738
- const memoryItems = import_react23.default.useMemo(() => {
14778
+ const memoryItems = import_react24.default.useMemo(() => {
14739
14779
  if (!globalMemory?.state.entries) return [];
14740
14780
  const items = [];
14741
14781
  for (const [key, entry] of globalMemory.state.entries) {
@@ -14749,7 +14789,7 @@ var ChatUIView = ({
14749
14789
  }
14750
14790
  return items;
14751
14791
  }, [globalMemory?.state.entries]);
14752
- const projectMemoryItems = import_react23.default.useMemo(() => {
14792
+ const projectMemoryItems = import_react24.default.useMemo(() => {
14753
14793
  if (!projectMemory?.state.entries) return [];
14754
14794
  const items = [];
14755
14795
  for (const [key, entry] of projectMemory.state.entries) {
@@ -15121,7 +15161,8 @@ var ChatUIWithHook = ({
15121
15161
  onWorkflowSuggested,
15122
15162
  onAnalyzePatterns,
15123
15163
  // Image upload
15124
- onUploadImage
15164
+ onUploadImage,
15165
+ onImageError
15125
15166
  }) => {
15126
15167
  const hookOptions = {
15127
15168
  models,
@@ -15171,10 +15212,11 @@ var ChatUIWithHook = ({
15171
15212
  onWorkflowSuggested,
15172
15213
  onAnalyzePatterns,
15173
15214
  // Image upload
15174
- onUploadImage
15215
+ onUploadImage,
15216
+ onImageError
15175
15217
  };
15176
15218
  const state = useChatUI(hookOptions);
15177
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
15219
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ImageErrorContext.Provider, { value: onImageError || null, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
15178
15220
  ChatUIView,
15179
15221
  {
15180
15222
  state,
@@ -15201,7 +15243,7 @@ var ChatUIWithHook = ({
15201
15243
  onImportMemory,
15202
15244
  importMemoryPrompt
15203
15245
  }
15204
- );
15246
+ ) });
15205
15247
  };
15206
15248
  var ChatUI = (props) => {
15207
15249
  injectStyles();
@@ -15231,7 +15273,7 @@ var ChatUI = (props) => {
15231
15273
  onImportMemory,
15232
15274
  importMemoryPrompt
15233
15275
  } = props;
15234
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
15276
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ImageErrorContext.Provider, { value: props.onImageError || null, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
15235
15277
  ChatUIView,
15236
15278
  {
15237
15279
  state: props.chatState,
@@ -15259,19 +15301,19 @@ var ChatUI = (props) => {
15259
15301
  onImportMemory,
15260
15302
  importMemoryPrompt
15261
15303
  }
15262
- );
15304
+ ) });
15263
15305
  }
15264
15306
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ChatUIWithHook, { ...props });
15265
15307
  };
15266
15308
 
15267
15309
  // src/react/ChatFloatingWidget.tsx
15268
- var import_react31 = require("react");
15310
+ var import_react32 = require("react");
15269
15311
 
15270
15312
  // src/react/hooks/useFloatingWidget.ts
15271
- var import_react25 = require("react");
15313
+ var import_react26 = require("react");
15272
15314
 
15273
15315
  // src/react/hooks/useDragResize.ts
15274
- var import_react24 = require("react");
15316
+ var import_react25 = require("react");
15275
15317
  var DRAG_THRESHOLD = 5;
15276
15318
  var FAB_SIZE = 56;
15277
15319
  var EDGE_MARGIN = 24;
@@ -15339,8 +15381,8 @@ var useDragResize = (options) => {
15339
15381
  maxWidth = DEFAULT_MAX_WIDTH,
15340
15382
  minHeight = DEFAULT_MIN_HEIGHT
15341
15383
  } = options;
15342
- const [isMobile, setIsMobile] = (0, import_react24.useState)(false);
15343
- (0, import_react24.useEffect)(() => {
15384
+ const [isMobile, setIsMobile] = (0, import_react25.useState)(false);
15385
+ (0, import_react25.useEffect)(() => {
15344
15386
  if (typeof window === "undefined") return;
15345
15387
  const mql = window.matchMedia("(max-width: 767px)");
15346
15388
  setIsMobile(mql.matches);
@@ -15355,19 +15397,19 @@ var useDragResize = (options) => {
15355
15397
  panelWidth: initialWidth,
15356
15398
  panelHeight: initialHeight
15357
15399
  });
15358
- const [fabPos, setFabPos] = (0, import_react24.useState)({ x: persisted.fabX, y: persisted.fabY });
15359
- const [panelSize, setPanelSize] = (0, import_react24.useState)({ width: persisted.panelWidth, height: persisted.panelHeight });
15360
- const [isDragging, setIsDragging] = (0, import_react24.useState)(false);
15361
- const [isResizing, setIsResizing] = (0, import_react24.useState)(false);
15362
- const [isDizzy, setIsDizzy] = (0, import_react24.useState)(false);
15363
- const [viewport, setViewport] = (0, import_react24.useState)(() => ({
15400
+ const [fabPos, setFabPos] = (0, import_react25.useState)({ x: persisted.fabX, y: persisted.fabY });
15401
+ const [panelSize, setPanelSize] = (0, import_react25.useState)({ width: persisted.panelWidth, height: persisted.panelHeight });
15402
+ const [isDragging, setIsDragging] = (0, import_react25.useState)(false);
15403
+ const [isResizing, setIsResizing] = (0, import_react25.useState)(false);
15404
+ const [isDizzy, setIsDizzy] = (0, import_react25.useState)(false);
15405
+ const [viewport, setViewport] = (0, import_react25.useState)(() => ({
15364
15406
  width: typeof window !== "undefined" ? window.innerWidth : 1024,
15365
15407
  height: typeof window !== "undefined" ? window.innerHeight : 768
15366
15408
  }));
15367
15409
  const vw = viewport.width;
15368
15410
  const vh = viewport.height;
15369
- const initializedRef = (0, import_react24.useRef)(false);
15370
- (0, import_react24.useEffect)(() => {
15411
+ const initializedRef = (0, import_react25.useRef)(false);
15412
+ (0, import_react25.useEffect)(() => {
15371
15413
  if (initializedRef.current || typeof window === "undefined") return;
15372
15414
  initializedRef.current = true;
15373
15415
  const correctFab = getInitialFabPosition(initialPosition);
@@ -15380,40 +15422,40 @@ var useDragResize = (options) => {
15380
15422
  setFabPos({ x: loaded.fabX, y: loaded.fabY });
15381
15423
  setPanelSize({ width: loaded.panelWidth, height: loaded.panelHeight });
15382
15424
  }, [initialPosition, storageKey, initialWidth, initialHeight]);
15383
- const dragStartRef = (0, import_react24.useRef)(null);
15384
- const isDraggingRef = (0, import_react24.useRef)(false);
15385
- const wasDragRef = (0, import_react24.useRef)(false);
15386
- const userDraggedRef = (0, import_react24.useRef)(false);
15387
- const dragDeltaRef = (0, import_react24.useRef)({ dx: 0, dy: 0 });
15388
- const fabElRef = (0, import_react24.useRef)(null);
15389
- const dragCleanupRef = (0, import_react24.useRef)(null);
15390
- const snapTimerRef = (0, import_react24.useRef)(null);
15391
- const prevDragRef = (0, import_react24.useRef)(null);
15392
- const shakeScoreRef = (0, import_react24.useRef)(0);
15393
- const prevVelocityRef = (0, import_react24.useRef)(null);
15394
- const isDizzyRef = (0, import_react24.useRef)(false);
15395
- const dizzyTimerRef = (0, import_react24.useRef)(null);
15396
- const lastVelocityRef = (0, import_react24.useRef)({ vx: 0, vy: 0, speed: 0 });
15397
- const dragRafRef = (0, import_react24.useRef)(null);
15398
- const animCleanupRef = (0, import_react24.useRef)(null);
15399
- const snapEnabledRef = (0, import_react24.useRef)(snapEnabled);
15400
- const storageKeyRef = (0, import_react24.useRef)(storageKey);
15401
- const panelSizeRef = (0, import_react24.useRef)(panelSize);
15402
- const fabPosRef = (0, import_react24.useRef)(fabPos);
15403
- (0, import_react24.useEffect)(() => {
15425
+ const dragStartRef = (0, import_react25.useRef)(null);
15426
+ const isDraggingRef = (0, import_react25.useRef)(false);
15427
+ const wasDragRef = (0, import_react25.useRef)(false);
15428
+ const userDraggedRef = (0, import_react25.useRef)(false);
15429
+ const dragDeltaRef = (0, import_react25.useRef)({ dx: 0, dy: 0 });
15430
+ const fabElRef = (0, import_react25.useRef)(null);
15431
+ const dragCleanupRef = (0, import_react25.useRef)(null);
15432
+ const snapTimerRef = (0, import_react25.useRef)(null);
15433
+ const prevDragRef = (0, import_react25.useRef)(null);
15434
+ const shakeScoreRef = (0, import_react25.useRef)(0);
15435
+ const prevVelocityRef = (0, import_react25.useRef)(null);
15436
+ const isDizzyRef = (0, import_react25.useRef)(false);
15437
+ const dizzyTimerRef = (0, import_react25.useRef)(null);
15438
+ const lastVelocityRef = (0, import_react25.useRef)({ vx: 0, vy: 0, speed: 0 });
15439
+ const dragRafRef = (0, import_react25.useRef)(null);
15440
+ const animCleanupRef = (0, import_react25.useRef)(null);
15441
+ const snapEnabledRef = (0, import_react25.useRef)(snapEnabled);
15442
+ const storageKeyRef = (0, import_react25.useRef)(storageKey);
15443
+ const panelSizeRef = (0, import_react25.useRef)(panelSize);
15444
+ const fabPosRef = (0, import_react25.useRef)(fabPos);
15445
+ (0, import_react25.useEffect)(() => {
15404
15446
  snapEnabledRef.current = snapEnabled;
15405
15447
  }, [snapEnabled]);
15406
- (0, import_react24.useEffect)(() => {
15448
+ (0, import_react25.useEffect)(() => {
15407
15449
  storageKeyRef.current = storageKey;
15408
15450
  }, [storageKey]);
15409
- (0, import_react24.useEffect)(() => {
15451
+ (0, import_react25.useEffect)(() => {
15410
15452
  panelSizeRef.current = panelSize;
15411
15453
  }, [panelSize]);
15412
- (0, import_react24.useEffect)(() => {
15454
+ (0, import_react25.useEffect)(() => {
15413
15455
  fabPosRef.current = fabPos;
15414
15456
  }, [fabPos]);
15415
- const resizeStartRef = (0, import_react24.useRef)(null);
15416
- (0, import_react24.useEffect)(() => {
15457
+ const resizeStartRef = (0, import_react25.useRef)(null);
15458
+ (0, import_react25.useEffect)(() => {
15417
15459
  return () => {
15418
15460
  dragCleanupRef.current?.();
15419
15461
  if (snapTimerRef.current) clearTimeout(snapTimerRef.current);
@@ -15421,7 +15463,7 @@ var useDragResize = (options) => {
15421
15463
  if (dragRafRef.current) cancelAnimationFrame(dragRafRef.current);
15422
15464
  };
15423
15465
  }, []);
15424
- const handleFabPointerDown = (0, import_react24.useCallback)((e) => {
15466
+ const handleFabPointerDown = (0, import_react25.useCallback)((e) => {
15425
15467
  if (disabled || isMobile) return;
15426
15468
  dragCleanupRef.current?.();
15427
15469
  const el = e.currentTarget;
@@ -15603,7 +15645,7 @@ var useDragResize = (options) => {
15603
15645
  }, [disabled, isMobile]);
15604
15646
  const fabCenterX = fabPos.x + FAB_SIZE / 2;
15605
15647
  const panelDirection = fabCenterX > vw / 2 ? "left" : "right";
15606
- const panelPositionStyle = (0, import_react24.useMemo)(() => {
15648
+ const panelPositionStyle = (0, import_react25.useMemo)(() => {
15607
15649
  if (isMobile || disabled) return {};
15608
15650
  const fabIsTop = fabPos.y < vh / 2;
15609
15651
  let panelBottom;
@@ -15635,7 +15677,7 @@ var useDragResize = (options) => {
15635
15677
  borderRadius: "var(--floating-panel-radius, 16px)"
15636
15678
  };
15637
15679
  }, [isMobile, disabled, fabPos.x, fabPos.y, panelSize.width, panelSize.height, vw, vh, panelDirection, minHeight]);
15638
- const handleResizePointerDown = (0, import_react24.useCallback)((edge, e) => {
15680
+ const handleResizePointerDown = (0, import_react25.useCallback)((edge, e) => {
15639
15681
  if (disabled || isMobile) return;
15640
15682
  e.preventDefault();
15641
15683
  e.stopPropagation();
@@ -15651,7 +15693,7 @@ var useDragResize = (options) => {
15651
15693
  };
15652
15694
  setIsResizing(true);
15653
15695
  }, [disabled, isMobile]);
15654
- const handleResizePointerMove = (0, import_react24.useCallback)((e) => {
15696
+ const handleResizePointerMove = (0, import_react25.useCallback)((e) => {
15655
15697
  if (!resizeStartRef.current) return;
15656
15698
  const { startX, startY, width, height, edge, fabY } = resizeStartRef.current;
15657
15699
  const dx = e.clientX - startX;
@@ -15675,7 +15717,7 @@ var useDragResize = (options) => {
15675
15717
  newHeight = Math.max(minHeight, Math.min(maxH, newHeight));
15676
15718
  setPanelSize({ width: newWidth, height: newHeight });
15677
15719
  }, [minWidth, maxWidth, minHeight]);
15678
- const handleResizePointerUp = (0, import_react24.useCallback)((e) => {
15720
+ const handleResizePointerUp = (0, import_react25.useCallback)((e) => {
15679
15721
  if (!resizeStartRef.current) return;
15680
15722
  e.currentTarget.releasePointerCapture(e.pointerId);
15681
15723
  resizeStartRef.current = null;
@@ -15684,7 +15726,7 @@ var useDragResize = (options) => {
15684
15726
  const fp = fabPosRef.current;
15685
15727
  persistState(storageKeyRef.current, { fabX: fp.x, fabY: fp.y, panelWidth: ps.width, panelHeight: ps.height });
15686
15728
  }, []);
15687
- (0, import_react24.useEffect)(() => {
15729
+ (0, import_react25.useEffect)(() => {
15688
15730
  if (typeof window === "undefined") return;
15689
15731
  const handleResize = () => {
15690
15732
  const newVw = window.innerWidth;
@@ -15746,9 +15788,9 @@ var useFloatingWidget = (options) => {
15746
15788
  maxWidth,
15747
15789
  minHeight
15748
15790
  } = options || {};
15749
- const [isOpen, setIsOpen] = (0, import_react25.useState)(defaultOpen);
15750
- const [activeTab, setActiveTab] = (0, import_react25.useState)(defaultTab);
15751
- const panelRef = (0, import_react25.useRef)(null);
15791
+ const [isOpen, setIsOpen] = (0, import_react26.useState)(defaultOpen);
15792
+ const [activeTab, setActiveTab] = (0, import_react26.useState)(defaultTab);
15793
+ const panelRef = (0, import_react26.useRef)(null);
15752
15794
  const dragResize = useDragResize({
15753
15795
  initialPosition: position,
15754
15796
  initialWidth: width,
@@ -15760,27 +15802,27 @@ var useFloatingWidget = (options) => {
15760
15802
  maxWidth,
15761
15803
  minHeight
15762
15804
  });
15763
- const onOpenRef = (0, import_react25.useRef)(onOpen);
15764
- const onCloseRef = (0, import_react25.useRef)(onClose);
15765
- const onTabChangeRef = (0, import_react25.useRef)(onTabChange);
15766
- (0, import_react25.useEffect)(() => {
15805
+ const onOpenRef = (0, import_react26.useRef)(onOpen);
15806
+ const onCloseRef = (0, import_react26.useRef)(onClose);
15807
+ const onTabChangeRef = (0, import_react26.useRef)(onTabChange);
15808
+ (0, import_react26.useEffect)(() => {
15767
15809
  onOpenRef.current = onOpen;
15768
15810
  }, [onOpen]);
15769
- (0, import_react25.useEffect)(() => {
15811
+ (0, import_react26.useEffect)(() => {
15770
15812
  onCloseRef.current = onClose;
15771
15813
  }, [onClose]);
15772
- (0, import_react25.useEffect)(() => {
15814
+ (0, import_react26.useEffect)(() => {
15773
15815
  onTabChangeRef.current = onTabChange;
15774
15816
  }, [onTabChange]);
15775
- const open = (0, import_react25.useCallback)(() => {
15817
+ const open = (0, import_react26.useCallback)(() => {
15776
15818
  setIsOpen(true);
15777
15819
  onOpenRef.current?.();
15778
15820
  }, []);
15779
- const close = (0, import_react25.useCallback)(() => {
15821
+ const close = (0, import_react26.useCallback)(() => {
15780
15822
  setIsOpen(false);
15781
15823
  onCloseRef.current?.();
15782
15824
  }, []);
15783
- const toggle = (0, import_react25.useCallback)(() => {
15825
+ const toggle = (0, import_react26.useCallback)(() => {
15784
15826
  setIsOpen((prev) => {
15785
15827
  const next = !prev;
15786
15828
  if (next) onOpenRef.current?.();
@@ -15788,15 +15830,15 @@ var useFloatingWidget = (options) => {
15788
15830
  return next;
15789
15831
  });
15790
15832
  }, []);
15791
- const setTab = (0, import_react25.useCallback)((tabKey) => {
15833
+ const setTab = (0, import_react26.useCallback)((tabKey) => {
15792
15834
  setActiveTab(tabKey);
15793
15835
  onTabChangeRef.current?.(tabKey);
15794
15836
  }, []);
15795
- const handleFabInteraction = (0, import_react25.useCallback)(() => {
15837
+ const handleFabInteraction = (0, import_react26.useCallback)(() => {
15796
15838
  if (dragResize.isDragging) return;
15797
15839
  toggle();
15798
15840
  }, [dragResize.isDragging, toggle]);
15799
- (0, import_react25.useEffect)(() => {
15841
+ (0, import_react26.useEffect)(() => {
15800
15842
  if (!isOpen) return;
15801
15843
  const handleKeyDown = (e) => {
15802
15844
  if (e.key === "Escape") {
@@ -15806,7 +15848,7 @@ var useFloatingWidget = (options) => {
15806
15848
  document.addEventListener("keydown", handleKeyDown);
15807
15849
  return () => document.removeEventListener("keydown", handleKeyDown);
15808
15850
  }, [isOpen, close]);
15809
- (0, import_react25.useEffect)(() => {
15851
+ (0, import_react26.useEffect)(() => {
15810
15852
  if (!isOpen) return;
15811
15853
  const handleClickOutside = (e) => {
15812
15854
  if (dragResize.isDragging || dragResize.isResizing) return;
@@ -15822,10 +15864,10 @@ var useFloatingWidget = (options) => {
15822
15864
  };
15823
15865
 
15824
15866
  // src/react/components/floating/FloatingFab.tsx
15825
- var import_react27 = require("react");
15867
+ var import_react28 = require("react");
15826
15868
 
15827
15869
  // src/react/components/floating/DevDiveCharacter.tsx
15828
- var import_react26 = require("react");
15870
+ var import_react27 = require("react");
15829
15871
  var import_jsx_runtime24 = require("react/jsx-runtime");
15830
15872
  var THEMES = {
15831
15873
  dark: { body: "#2ecc71", stroke: "#27ae60", highlight: "#3ddc84", face: "#1a1a2e", eyeLight: "#fff" },
@@ -15846,32 +15888,32 @@ var DevDiveFabCharacter = ({
15846
15888
  isComplete = false
15847
15889
  }) => {
15848
15890
  const c = THEMES[theme];
15849
- const [eyeOffset, setEyeOffset] = (0, import_react26.useState)({ x: 0, y: 0 });
15850
- const [isBlinking, setIsBlinking] = (0, import_react26.useState)(false);
15851
- const [isHappy, setIsHappy] = (0, import_react26.useState)(false);
15852
- const [isPressed, setIsPressed] = (0, import_react26.useState)(false);
15853
- const [mouthOpen, setMouthOpen] = (0, import_react26.useState)(false);
15854
- const [isSleepy, setIsSleepy] = (0, import_react26.useState)(false);
15855
- const [isSurprised, setIsSurprised] = (0, import_react26.useState)(false);
15856
- const [isWinking, setIsWinking] = (0, import_react26.useState)(false);
15857
- const [isCatMouth, setIsCatMouth] = (0, import_react26.useState)(false);
15858
- const [isEntering, setIsEntering] = (0, import_react26.useState)(true);
15859
- const svgRef = (0, import_react26.useRef)(null);
15860
- const cleanupRef = (0, import_react26.useRef)(null);
15861
- const lastActivityRef = (0, import_react26.useRef)(Date.now());
15862
- const isSleepyRef = (0, import_react26.useRef)(false);
15863
- const markActivity = (0, import_react26.useCallback)(() => {
15891
+ const [eyeOffset, setEyeOffset] = (0, import_react27.useState)({ x: 0, y: 0 });
15892
+ const [isBlinking, setIsBlinking] = (0, import_react27.useState)(false);
15893
+ const [isHappy, setIsHappy] = (0, import_react27.useState)(false);
15894
+ const [isPressed, setIsPressed] = (0, import_react27.useState)(false);
15895
+ const [mouthOpen, setMouthOpen] = (0, import_react27.useState)(false);
15896
+ const [isSleepy, setIsSleepy] = (0, import_react27.useState)(false);
15897
+ const [isSurprised, setIsSurprised] = (0, import_react27.useState)(false);
15898
+ const [isWinking, setIsWinking] = (0, import_react27.useState)(false);
15899
+ const [isCatMouth, setIsCatMouth] = (0, import_react27.useState)(false);
15900
+ const [isEntering, setIsEntering] = (0, import_react27.useState)(true);
15901
+ const svgRef = (0, import_react27.useRef)(null);
15902
+ const cleanupRef = (0, import_react27.useRef)(null);
15903
+ const lastActivityRef = (0, import_react27.useRef)(Date.now());
15904
+ const isSleepyRef = (0, import_react27.useRef)(false);
15905
+ const markActivity = (0, import_react27.useCallback)(() => {
15864
15906
  lastActivityRef.current = Date.now();
15865
15907
  if (isSleepyRef.current) {
15866
15908
  isSleepyRef.current = false;
15867
15909
  setIsSleepy(false);
15868
15910
  }
15869
15911
  }, []);
15870
- (0, import_react26.useEffect)(() => {
15912
+ (0, import_react27.useEffect)(() => {
15871
15913
  const t = setTimeout(() => setIsEntering(false), 600);
15872
15914
  return () => clearTimeout(t);
15873
15915
  }, []);
15874
- (0, import_react26.useEffect)(() => {
15916
+ (0, import_react27.useEffect)(() => {
15875
15917
  let timer;
15876
15918
  let blinkTimer;
15877
15919
  const scheduleBlink = () => {
@@ -15887,7 +15929,7 @@ var DevDiveFabCharacter = ({
15887
15929
  clearTimeout(blinkTimer);
15888
15930
  };
15889
15931
  }, []);
15890
- (0, import_react26.useEffect)(() => {
15932
+ (0, import_react27.useEffect)(() => {
15891
15933
  if (!isTalking) {
15892
15934
  setMouthOpen(false);
15893
15935
  return;
@@ -15900,7 +15942,7 @@ var DevDiveFabCharacter = ({
15900
15942
  toggle();
15901
15943
  return () => clearTimeout(timer);
15902
15944
  }, [isTalking]);
15903
- (0, import_react26.useEffect)(() => {
15945
+ (0, import_react27.useEffect)(() => {
15904
15946
  if (typeof window === "undefined") return;
15905
15947
  let rafId = 0;
15906
15948
  const onMouseMove = (e) => {
@@ -15924,7 +15966,7 @@ var DevDiveFabCharacter = ({
15924
15966
  cancelAnimationFrame(rafId);
15925
15967
  };
15926
15968
  }, []);
15927
- (0, import_react26.useEffect)(() => {
15969
+ (0, import_react27.useEffect)(() => {
15928
15970
  let upTimer;
15929
15971
  let surpriseTimer;
15930
15972
  const rafId = requestAnimationFrame(() => {
@@ -15967,10 +16009,10 @@ var DevDiveFabCharacter = ({
15967
16009
  cleanupRef.current?.();
15968
16010
  };
15969
16011
  }, [markActivity]);
15970
- (0, import_react26.useEffect)(() => {
16012
+ (0, import_react27.useEffect)(() => {
15971
16013
  markActivity();
15972
16014
  }, [isOpen, isTalking, markActivity]);
15973
- (0, import_react26.useEffect)(() => {
16015
+ (0, import_react27.useEffect)(() => {
15974
16016
  if (isOpen || isTalking || isDizzy) return;
15975
16017
  const check = setInterval(() => {
15976
16018
  if (Date.now() - lastActivityRef.current > IDLE_TIMEOUT_MS && !isSleepyRef.current) {
@@ -15980,8 +16022,8 @@ var DevDiveFabCharacter = ({
15980
16022
  }, 5e3);
15981
16023
  return () => clearInterval(check);
15982
16024
  }, [isOpen, isTalking, isDizzy]);
15983
- const prevCompleteRef = (0, import_react26.useRef)(false);
15984
- (0, import_react26.useEffect)(() => {
16025
+ const prevCompleteRef = (0, import_react27.useRef)(false);
16026
+ (0, import_react27.useEffect)(() => {
15985
16027
  const wasComplete = prevCompleteRef.current;
15986
16028
  prevCompleteRef.current = isComplete;
15987
16029
  if (wasComplete || !isComplete) return;
@@ -15989,7 +16031,7 @@ var DevDiveFabCharacter = ({
15989
16031
  const t = setTimeout(() => setIsWinking(false), WINK_DURATION_MS);
15990
16032
  return () => clearTimeout(t);
15991
16033
  }, [isComplete]);
15992
- (0, import_react26.useEffect)(() => {
16034
+ (0, import_react27.useEffect)(() => {
15993
16035
  if (isOpen || isTalking || isDizzy || isError || isSleepy) {
15994
16036
  setIsCatMouth(false);
15995
16037
  return;
@@ -16181,12 +16223,12 @@ var FloatingFab = ({
16181
16223
  }) => {
16182
16224
  const isRight = position.includes("right");
16183
16225
  const isBottom = position.includes("bottom");
16184
- const fabRef = (0, import_react27.useRef)(null);
16226
+ const fabRef = (0, import_react28.useRef)(null);
16185
16227
  const isCharacterMode = !icon;
16186
- const [bubbleOnRight, setBubbleOnRight] = (0, import_react27.useState)(!isRight);
16228
+ const [bubbleOnRight, setBubbleOnRight] = (0, import_react28.useState)(!isRight);
16187
16229
  const posLeft = positionStyle?.left;
16188
16230
  const posTop = positionStyle?.top;
16189
- (0, import_react27.useEffect)(() => {
16231
+ (0, import_react28.useEffect)(() => {
16190
16232
  if (!fabRef.current || typeof window === "undefined") {
16191
16233
  setBubbleOnRight(!isRight);
16192
16234
  return;
@@ -16194,14 +16236,14 @@ var FloatingFab = ({
16194
16236
  const rect = fabRef.current.getBoundingClientRect();
16195
16237
  setBubbleOnRight(rect.left + rect.width / 2 < window.innerWidth / 2);
16196
16238
  }, [isRight, posLeft, posTop]);
16197
- const [bubbleText, setBubbleText] = (0, import_react27.useState)(null);
16198
- const [bubbleExiting, setBubbleExiting] = (0, import_react27.useState)(false);
16199
- const bubbleTextRef = (0, import_react27.useRef)(bubbleText);
16239
+ const [bubbleText, setBubbleText] = (0, import_react28.useState)(null);
16240
+ const [bubbleExiting, setBubbleExiting] = (0, import_react28.useState)(false);
16241
+ const bubbleTextRef = (0, import_react28.useRef)(bubbleText);
16200
16242
  bubbleTextRef.current = bubbleText;
16201
- const [displayText, setDisplayText] = (0, import_react27.useState)(null);
16202
- const [isTyping, setIsTyping] = (0, import_react27.useState)(false);
16203
- const typingTimerRef = (0, import_react27.useRef)(null);
16204
- (0, import_react27.useEffect)(() => {
16243
+ const [displayText, setDisplayText] = (0, import_react28.useState)(null);
16244
+ const [isTyping, setIsTyping] = (0, import_react28.useState)(false);
16245
+ const typingTimerRef = (0, import_react28.useRef)(null);
16246
+ (0, import_react28.useEffect)(() => {
16205
16247
  if (notification) {
16206
16248
  setBubbleText(notification);
16207
16249
  setBubbleExiting(false);
@@ -16237,9 +16279,9 @@ var FloatingFab = ({
16237
16279
  }, 300);
16238
16280
  return () => clearTimeout(timer);
16239
16281
  }, [notification]);
16240
- const notifContentRef = (0, import_react27.useRef)(null);
16241
- const [needsMarquee, setNeedsMarquee] = (0, import_react27.useState)(false);
16242
- (0, import_react27.useEffect)(() => {
16282
+ const notifContentRef = (0, import_react28.useRef)(null);
16283
+ const [needsMarquee, setNeedsMarquee] = (0, import_react28.useState)(false);
16284
+ (0, import_react28.useEffect)(() => {
16243
16285
  if (isTyping || !notification) {
16244
16286
  setNeedsMarquee(false);
16245
16287
  return;
@@ -16381,7 +16423,7 @@ var FloatingFab = ({
16381
16423
  };
16382
16424
 
16383
16425
  // src/react/components/floating/FloatingPanel.tsx
16384
- var import_react28 = require("react");
16426
+ var import_react29 = require("react");
16385
16427
  var import_jsx_runtime26 = require("react/jsx-runtime");
16386
16428
  var FloatingPanel = ({
16387
16429
  isOpen,
@@ -16399,8 +16441,8 @@ var FloatingPanel = ({
16399
16441
  }) => {
16400
16442
  const isRight = position.includes("right");
16401
16443
  const themeClass = theme?.mode === "dark" ? "chatllm-dark" : "";
16402
- const [isMobile, setIsMobile] = (0, import_react28.useState)(false);
16403
- (0, import_react28.useEffect)(() => {
16444
+ const [isMobile, setIsMobile] = (0, import_react29.useState)(false);
16445
+ (0, import_react29.useEffect)(() => {
16404
16446
  if (typeof window === "undefined") return;
16405
16447
  const mql = window.matchMedia("(max-width: 767px)");
16406
16448
  setIsMobile(mql.matches);
@@ -16408,10 +16450,10 @@ var FloatingPanel = ({
16408
16450
  mql.addEventListener("change", handler);
16409
16451
  return () => mql.removeEventListener("change", handler);
16410
16452
  }, []);
16411
- const [shouldRender, setShouldRender] = (0, import_react28.useState)(isOpen);
16412
- const [isVisible, setIsVisible] = (0, import_react28.useState)(isOpen);
16413
- const rafRef = (0, import_react28.useRef)(0);
16414
- (0, import_react28.useEffect)(() => {
16453
+ const [shouldRender, setShouldRender] = (0, import_react29.useState)(isOpen);
16454
+ const [isVisible, setIsVisible] = (0, import_react29.useState)(isOpen);
16455
+ const rafRef = (0, import_react29.useRef)(0);
16456
+ (0, import_react29.useEffect)(() => {
16415
16457
  if (isOpen) {
16416
16458
  setShouldRender(true);
16417
16459
  rafRef.current = requestAnimationFrame(() => {
@@ -16426,7 +16468,7 @@ var FloatingPanel = ({
16426
16468
  }
16427
16469
  return () => cancelAnimationFrame(rafRef.current);
16428
16470
  }, [isOpen]);
16429
- (0, import_react28.useEffect)(() => {
16471
+ (0, import_react29.useEffect)(() => {
16430
16472
  if (!isOpen || !isMobile) return;
16431
16473
  const prev = document.body.style.overflow;
16432
16474
  document.body.style.overflow = "hidden";
@@ -16587,10 +16629,10 @@ var FloatingTabBar = ({
16587
16629
  };
16588
16630
 
16589
16631
  // src/react/components/floating/CompactChatView.tsx
16590
- var import_react30 = require("react");
16632
+ var import_react31 = require("react");
16591
16633
 
16592
16634
  // src/react/components/floating/CompactSessionMenu.tsx
16593
- var import_react29 = require("react");
16635
+ var import_react30 = require("react");
16594
16636
  var import_jsx_runtime28 = require("react/jsx-runtime");
16595
16637
  var CompactSessionMenu = ({
16596
16638
  sessions,
@@ -16602,13 +16644,13 @@ var CompactSessionMenu = ({
16602
16644
  onClose,
16603
16645
  isLoading = false
16604
16646
  }) => {
16605
- const menuRef = (0, import_react29.useRef)(null);
16606
- const inputRef = (0, import_react29.useRef)(null);
16607
- const onCloseRef = (0, import_react29.useRef)(onClose);
16647
+ const menuRef = (0, import_react30.useRef)(null);
16648
+ const inputRef = (0, import_react30.useRef)(null);
16649
+ const onCloseRef = (0, import_react30.useRef)(onClose);
16608
16650
  onCloseRef.current = onClose;
16609
- const [editingId, setEditingId] = (0, import_react29.useState)(null);
16610
- const [editingTitle, setEditingTitle] = (0, import_react29.useState)("");
16611
- (0, import_react29.useEffect)(() => {
16651
+ const [editingId, setEditingId] = (0, import_react30.useState)(null);
16652
+ const [editingTitle, setEditingTitle] = (0, import_react30.useState)("");
16653
+ (0, import_react30.useEffect)(() => {
16612
16654
  const handleMouseDown = (e) => {
16613
16655
  if (menuRef.current && !menuRef.current.contains(e.target)) {
16614
16656
  onCloseRef.current();
@@ -16617,7 +16659,7 @@ var CompactSessionMenu = ({
16617
16659
  document.addEventListener("mousedown", handleMouseDown);
16618
16660
  return () => document.removeEventListener("mousedown", handleMouseDown);
16619
16661
  }, []);
16620
- (0, import_react29.useEffect)(() => {
16662
+ (0, import_react30.useEffect)(() => {
16621
16663
  if (editingId && inputRef.current) {
16622
16664
  inputRef.current.focus();
16623
16665
  inputRef.current.select();
@@ -16932,16 +16974,16 @@ var CompactChatView = ({
16932
16974
  const handleChoiceClick = (choice) => {
16933
16975
  setInput(choice.text);
16934
16976
  };
16935
- const [showSessionMenu, setShowSessionMenu] = (0, import_react30.useState)(false);
16936
- const handleSessionSelect = (0, import_react30.useCallback)((id) => {
16977
+ const [showSessionMenu, setShowSessionMenu] = (0, import_react31.useState)(false);
16978
+ const handleSessionSelect = (0, import_react31.useCallback)((id) => {
16937
16979
  selectSession(id);
16938
16980
  setShowSessionMenu(false);
16939
16981
  }, [selectSession]);
16940
- const handleNewSession = (0, import_react30.useCallback)(() => {
16982
+ const handleNewSession = (0, import_react31.useCallback)(() => {
16941
16983
  newSession();
16942
16984
  setShowSessionMenu(false);
16943
16985
  }, [newSession]);
16944
- const handleCloseMenu = (0, import_react30.useCallback)(() => {
16986
+ const handleCloseMenu = (0, import_react31.useCallback)(() => {
16945
16987
  setShowSessionMenu(false);
16946
16988
  }, []);
16947
16989
  const greeting = personalization?.userProfile?.nickname ? `${personalization.userProfile.nickname}\uB2D8, \uBB34\uC5C7\uC774\uB4E0 \uBB3C\uC5B4\uBCF4\uC138\uC694` : "\uBB34\uC5C7\uC774\uB4E0 \uBB3C\uC5B4\uBCF4\uC138\uC694";
@@ -17261,11 +17303,11 @@ var ChatFloatingWidget = ({
17261
17303
  maxWidth,
17262
17304
  minHeight
17263
17305
  });
17264
- const notifObj = (0, import_react31.useMemo)(() => {
17306
+ const notifObj = (0, import_react32.useMemo)(() => {
17265
17307
  if (!notification) return null;
17266
17308
  return typeof notification === "string" ? { text: notification } : notification;
17267
17309
  }, [notification]);
17268
- const handleFabClick = (0, import_react31.useCallback)(() => {
17310
+ const handleFabClick = (0, import_react32.useCallback)(() => {
17269
17311
  if (notifObj?.onClick) {
17270
17312
  notifObj.onClick();
17271
17313
  if (!isOpen) handleFabInteraction();
@@ -17279,7 +17321,7 @@ var ChatFloatingWidget = ({
17279
17321
  }
17280
17322
  handleFabInteraction();
17281
17323
  }, [notifObj, isOpen, handleFabInteraction, setTab, tabs]);
17282
- const allTabs = (0, import_react31.useMemo)(() => {
17324
+ const allTabs = (0, import_react32.useMemo)(() => {
17283
17325
  const chatTab = {
17284
17326
  key: "chat",
17285
17327
  label: "\uCC44\uD305",
@@ -17293,16 +17335,16 @@ var ChatFloatingWidget = ({
17293
17335
  }));
17294
17336
  return [chatTab, ...customTabs];
17295
17337
  }, [tabs]);
17296
- const [unreadBadge, setUnreadBadge] = (0, import_react31.useState)(0);
17297
- const seenMessageIdsRef = (0, import_react31.useRef)(/* @__PURE__ */ new Set());
17298
- (0, import_react31.useEffect)(() => {
17338
+ const [unreadBadge, setUnreadBadge] = (0, import_react32.useState)(0);
17339
+ const seenMessageIdsRef = (0, import_react32.useRef)(/* @__PURE__ */ new Set());
17340
+ (0, import_react32.useEffect)(() => {
17299
17341
  if (seenMessageIdsRef.current.size === 0 && chatState.messages.length > 0) {
17300
17342
  for (const m of chatState.messages) {
17301
17343
  seenMessageIdsRef.current.add(m.id);
17302
17344
  }
17303
17345
  }
17304
17346
  }, [chatState.messages]);
17305
- (0, import_react31.useEffect)(() => {
17347
+ (0, import_react32.useEffect)(() => {
17306
17348
  if (isOpen) {
17307
17349
  for (const m of chatState.messages) {
17308
17350
  seenMessageIdsRef.current.add(m.id);
@@ -17319,7 +17361,7 @@ var ChatFloatingWidget = ({
17319
17361
  }
17320
17362
  }
17321
17363
  }, [chatState.messages, isOpen]);
17322
- (0, import_react31.useEffect)(() => {
17364
+ (0, import_react32.useEffect)(() => {
17323
17365
  if (isOpen) {
17324
17366
  setUnreadBadge(0);
17325
17367
  for (const m of chatState.messages) {
@@ -17327,13 +17369,13 @@ var ChatFloatingWidget = ({
17327
17369
  }
17328
17370
  }
17329
17371
  }, [isOpen, chatState.messages]);
17330
- const totalBadge = (0, import_react31.useMemo)(() => {
17372
+ const totalBadge = (0, import_react32.useMemo)(() => {
17331
17373
  return tabs.reduce((sum, t) => sum + (t.badge || 0), 0) + unreadBadge;
17332
17374
  }, [tabs, unreadBadge]);
17333
- const isTalking = (0, import_react31.useMemo)(() => !!notification || chatState.isLoading, [notification, chatState.isLoading]);
17334
- const prevLoadingRef = (0, import_react31.useRef)(chatState.isLoading);
17335
- const [isComplete, setIsComplete] = (0, import_react31.useState)(false);
17336
- (0, import_react31.useEffect)(() => {
17375
+ const isTalking = (0, import_react32.useMemo)(() => !!notification || chatState.isLoading, [notification, chatState.isLoading]);
17376
+ const prevLoadingRef = (0, import_react32.useRef)(chatState.isLoading);
17377
+ const [isComplete, setIsComplete] = (0, import_react32.useState)(false);
17378
+ (0, import_react32.useEffect)(() => {
17337
17379
  const wasLoading = prevLoadingRef.current;
17338
17380
  prevLoadingRef.current = chatState.isLoading;
17339
17381
  if (!wasLoading || chatState.isLoading || chatState.messages.length === 0) return;
@@ -17449,7 +17491,7 @@ var ChatFloatingWidget = ({
17449
17491
  };
17450
17492
 
17451
17493
  // src/react/hooks/useDeepResearch.ts
17452
- var import_react32 = require("react");
17494
+ var import_react33 = require("react");
17453
17495
  var REPORT_GENERATION_PROMPT2 = `\uB2F9\uC2E0\uC740 \uB9AC\uC11C\uCE58 \uBCF4\uACE0\uC11C \uC791\uC131 \uC804\uBB38\uAC00\uC785\uB2C8\uB2E4.
17454
17496
 
17455
17497
  <collected_sources>
@@ -17500,10 +17542,10 @@ var QUERY_ANALYSIS_PROMPT2 = `\uC0AC\uC6A9\uC790 \uC9C8\uBB38\uC744 \uBD84\uC11D
17500
17542
  - JSON \uC678 \uB2E4\uB978 \uD14D\uC2A4\uD2B8 \uCD9C\uB825 \uAE08\uC9C0`;
17501
17543
  var useDeepResearch = (options) => {
17502
17544
  const { onWebSearch, onExtractContent, apiEndpoint, apiKey, model, provider } = options;
17503
- const [isResearching, setIsResearching] = (0, import_react32.useState)(false);
17504
- const [progress, setProgress] = (0, import_react32.useState)(null);
17505
- const abortControllerRef = (0, import_react32.useRef)(null);
17506
- const callLLM2 = (0, import_react32.useCallback)(
17545
+ const [isResearching, setIsResearching] = (0, import_react33.useState)(false);
17546
+ const [progress, setProgress] = (0, import_react33.useState)(null);
17547
+ const abortControllerRef = (0, import_react33.useRef)(null);
17548
+ const callLLM2 = (0, import_react33.useCallback)(
17507
17549
  async (prompt, stream = false) => {
17508
17550
  const response = await fetch(apiEndpoint, {
17509
17551
  method: "POST",
@@ -17530,7 +17572,7 @@ var useDeepResearch = (options) => {
17530
17572
  },
17531
17573
  [apiEndpoint, apiKey, model, provider]
17532
17574
  );
17533
- const analyzeQuery2 = (0, import_react32.useCallback)(
17575
+ const analyzeQuery2 = (0, import_react33.useCallback)(
17534
17576
  async (query) => {
17535
17577
  const prompt = QUERY_ANALYSIS_PROMPT2.replace("{question}", query);
17536
17578
  const response = await callLLM2(prompt);
@@ -17549,7 +17591,7 @@ var useDeepResearch = (options) => {
17549
17591
  },
17550
17592
  [callLLM2]
17551
17593
  );
17552
- const runSubAgent2 = (0, import_react32.useCallback)(
17594
+ const runSubAgent2 = (0, import_react33.useCallback)(
17553
17595
  async (topic, queries, agentId, updateProgress) => {
17554
17596
  updateProgress({ status: "searching", searchCount: 0, resultsCount: 0 });
17555
17597
  const allResults = [];
@@ -17588,7 +17630,7 @@ var useDeepResearch = (options) => {
17588
17630
  },
17589
17631
  [onWebSearch, onExtractContent]
17590
17632
  );
17591
- const generateReport2 = (0, import_react32.useCallback)(
17633
+ const generateReport2 = (0, import_react33.useCallback)(
17592
17634
  async (query, results, onStreamContent) => {
17593
17635
  const allSources = [];
17594
17636
  const sourcesForPrompt = [];
@@ -17646,7 +17688,7 @@ var useDeepResearch = (options) => {
17646
17688
  },
17647
17689
  [callLLM2]
17648
17690
  );
17649
- const runDeepResearch = (0, import_react32.useCallback)(
17691
+ const runDeepResearch = (0, import_react33.useCallback)(
17650
17692
  async (query, onStreamContent) => {
17651
17693
  abortControllerRef.current = new AbortController();
17652
17694
  setIsResearching(true);
@@ -17749,7 +17791,7 @@ var useDeepResearch = (options) => {
17749
17791
  },
17750
17792
  [analyzeQuery2, runSubAgent2, generateReport2]
17751
17793
  );
17752
- const stopResearch = (0, import_react32.useCallback)(() => {
17794
+ const stopResearch = (0, import_react33.useCallback)(() => {
17753
17795
  abortControllerRef.current?.abort();
17754
17796
  setIsResearching(false);
17755
17797
  setProgress(null);
@@ -17952,7 +17994,7 @@ var EmptyState = ({
17952
17994
  };
17953
17995
 
17954
17996
  // src/react/components/MemoryPanel.tsx
17955
- var import_react33 = require("react");
17997
+ var import_react34 = require("react");
17956
17998
  var import_jsx_runtime33 = require("react/jsx-runtime");
17957
17999
  var categoryLabels = {
17958
18000
  fact: "\uC0AC\uC6A9\uC790 \uC815\uBCF4",
@@ -17972,8 +18014,8 @@ var MemoryPanel = ({
17972
18014
  isOpen,
17973
18015
  onToggle
17974
18016
  }) => {
17975
- const [expandedId, setExpandedId] = (0, import_react33.useState)(null);
17976
- const [activeTab, setActiveTab] = (0, import_react33.useState)("all");
18017
+ const [expandedId, setExpandedId] = (0, import_react34.useState)(null);
18018
+ const [activeTab, setActiveTab] = (0, import_react34.useState)("all");
17977
18019
  const filteredItems = activeTab === "all" ? items : items.filter((item) => item.category === activeTab);
17978
18020
  const formatDate = (timestamp) => {
17979
18021
  const date = new Date(timestamp);
@@ -18315,6 +18357,7 @@ var MemoryPanel = ({
18315
18357
  Icon,
18316
18358
  IconSvg,
18317
18359
  ImageContentCard,
18360
+ ImageErrorContext,
18318
18361
  LinkChip,
18319
18362
  MarkdownRenderer,
18320
18363
  MemoryPanel,
@@ -18336,6 +18379,7 @@ var MemoryPanel = ({
18336
18379
  useDeepResearch,
18337
18380
  useDragResize,
18338
18381
  useFloatingWidget,
18382
+ useImageError,
18339
18383
  useObserver,
18340
18384
  useProject,
18341
18385
  useSkills