@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.
@@ -2244,6 +2244,7 @@ var useChatUI = (options) => {
2244
2244
  onAnalyzePatterns,
2245
2245
  // Image upload
2246
2246
  onUploadImage,
2247
+ onImageError,
2247
2248
  // External storage options
2248
2249
  useExternalStorage = false,
2249
2250
  startWithNewSession = false,
@@ -2350,6 +2351,7 @@ var useChatUI = (options) => {
2350
2351
  const onSessionContextChangeRef = useRef5(onSessionContextChange);
2351
2352
  const onLoadModelsRef = useRef5(onLoadModels);
2352
2353
  const onUploadImageRef = useRef5(onUploadImage);
2354
+ const onImageErrorRef = useRef5(onImageError);
2353
2355
  const globalMemoryRef = useRef5(null);
2354
2356
  useEffect4(() => {
2355
2357
  onSendMessageRef.current = onSendMessage;
@@ -2370,6 +2372,7 @@ var useChatUI = (options) => {
2370
2372
  onSkillCompleteRef.current = onSkillComplete;
2371
2373
  onSessionContextChangeRef.current = onSessionContextChange;
2372
2374
  onUploadImageRef.current = onUploadImage;
2375
+ onImageErrorRef.current = onImageError;
2373
2376
  onLoadModelsRef.current = onLoadModels;
2374
2377
  });
2375
2378
  const abortControllersRef = useRef5(/* @__PURE__ */ new Map());
@@ -3459,7 +3462,7 @@ ${finalContent}`;
3459
3462
  if (att.type === "image" && att.file) {
3460
3463
  const dataUri = await fileToDataUri(att.file);
3461
3464
  const imageUrl = onUploadImageRef.current ? await onUploadImageRef.current(dataUri, att.name) : dataUri;
3462
- userContentParts.push({ type: "image", url: imageUrl, alt: att.name });
3465
+ userContentParts.push({ type: "image", url: imageUrl, alt: att.name, fileName: att.name });
3463
3466
  } else {
3464
3467
  userContentParts.push({ type: "file", name: att.name, url: att.previewUrl || "", mimeType: att.mimeType, size: att.size });
3465
3468
  }
@@ -3520,13 +3523,17 @@ ${finalContent}`;
3520
3523
  for (const [skillName, skillConfig] of attachmentSkills) {
3521
3524
  let matchedFiles = currentAttachments.filter((att) => {
3522
3525
  if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
3526
+ const fileName = (att.name || "").toLowerCase();
3527
+ const fileMime = (att.mimeType || "").toLowerCase();
3528
+ const fileExt = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
3523
3529
  return skillConfig.acceptedTypes.some((type) => {
3524
- if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
3525
- if (type.includes("*")) {
3526
- const regex = new RegExp("^" + type.replace("*", ".*") + "$");
3527
- return regex.test(att.mimeType);
3530
+ const t = type.toLowerCase();
3531
+ if (t.startsWith(".")) return fileExt === t || fileName.endsWith(t);
3532
+ if (t.includes("*")) {
3533
+ const regex = new RegExp("^" + t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace("\\*", ".*") + "$");
3534
+ return regex.test(fileMime);
3528
3535
  }
3529
- return att.mimeType === type;
3536
+ return fileMime === t;
3530
3537
  });
3531
3538
  });
3532
3539
  if (skipImageAttachmentSkill) {
@@ -3981,25 +3988,26 @@ ${attachmentContext}
3981
3988
  }
3982
3989
  }
3983
3990
  }
3984
- const saveMessagesOnEarlyReturn = () => {
3991
+ const saveMessagesOnEarlyReturn = (overrideContentParts) => {
3985
3992
  if (!useExternalStorage || !capturedSessionId) return;
3986
- queueMicrotask(() => {
3993
+ setTimeout(() => {
3987
3994
  const latestSession = sessionsRef.current.find((s) => s.id === capturedSessionId);
3988
3995
  if (!latestSession) return;
3989
3996
  const latestMessages = latestSession.messages;
3990
3997
  const assistantMsg = [...latestMessages].reverse().find((m) => m.role === "assistant");
3991
3998
  const userMsg = latestMessages.find((m) => m.role === "user" && m.content === finalContent);
3992
3999
  const assistantContent = assistantMsg?.content || "";
3993
- if (assistantContent && onSaveMessagesRef.current) {
4000
+ const finalContentParts = overrideContentParts || assistantMsg?.contentParts;
4001
+ if ((assistantContent || finalContentParts) && onSaveMessagesRef.current) {
3994
4002
  onSaveMessagesRef.current(capturedSessionId, [
3995
4003
  { role: "user", message: finalContent, ...userMsg?.contentParts && { contentParts: userMsg.contentParts } },
3996
- { role: "assistant", message: assistantContent, ...assistantMsg?.contentParts && { contentParts: assistantMsg.contentParts } }
4004
+ { role: "assistant", message: assistantContent, ...finalContentParts && { contentParts: finalContentParts } }
3997
4005
  ]).catch((e) => console.error("[useChatUI] Failed to save messages:", e));
3998
4006
  }
3999
4007
  if (latestSession.messages.length > 0) {
4000
4008
  writeSessionCache(storageKey, latestSession);
4001
4009
  }
4002
- });
4010
+ }, 0);
4003
4011
  };
4004
4012
  if (!shouldSkipSkillParsing) {
4005
4013
  const assistantContent = accumulatedContent;
@@ -4189,7 +4197,7 @@ ${attachmentContext}
4189
4197
  promoteToSessionContext(capturedSessionId, toolName, result.content, result.metadata, toolLabel || toolName);
4190
4198
  }
4191
4199
  if (resultType === "image" || resultType === "file") {
4192
- saveMessagesOnEarlyReturn();
4200
+ saveMessagesOnEarlyReturn(parts);
4193
4201
  removeLoadingSession(capturedSessionId);
4194
4202
  abortControllersRef.current.delete(capturedSessionId);
4195
4203
  return;
@@ -4200,7 +4208,7 @@ ${attachmentContext}
4200
4208
  shouldContinue = decision === "continue";
4201
4209
  }
4202
4210
  if (!shouldContinue) {
4203
- saveMessagesOnEarlyReturn();
4211
+ saveMessagesOnEarlyReturn(parts);
4204
4212
  removeLoadingSession(capturedSessionId);
4205
4213
  abortControllersRef.current.delete(capturedSessionId);
4206
4214
  return;
@@ -4275,13 +4283,13 @@ ${result.content}
4275
4283
  shouldContinueImgFile = decision === "continue";
4276
4284
  }
4277
4285
  if (!shouldContinueImgFile) {
4278
- saveMessagesOnEarlyReturn();
4286
+ saveMessagesOnEarlyReturn(imgFileParts);
4279
4287
  removeLoadingSession(capturedSessionId);
4280
4288
  abortControllersRef.current.delete(capturedSessionId);
4281
4289
  return;
4282
4290
  }
4283
4291
  skipNextSkillParsingRef.current = true;
4284
- saveMessagesOnEarlyReturn();
4292
+ saveMessagesOnEarlyReturn(imgFileParts);
4285
4293
  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.`;
4286
4294
  setTimeout(() => {
4287
4295
  sendMessage(imgFilePrompt, { hiddenUserMessage: true });
@@ -5650,6 +5658,11 @@ ${result.content}
5650
5658
  };
5651
5659
  };
5652
5660
 
5661
+ // src/react/contexts/ImageErrorContext.ts
5662
+ import { createContext, useContext } from "react";
5663
+ var ImageErrorContext = createContext(null);
5664
+ var useImageError = () => useContext(ImageErrorContext);
5665
+
5653
5666
  // src/react/components/ChatSidebar.tsx
5654
5667
  import { useState as useState9, useRef as useRef7, useEffect as useEffect6 } from "react";
5655
5668
 
@@ -6450,6 +6463,17 @@ var CodeBlock = ({ language, code }) => {
6450
6463
  };
6451
6464
  var ImageWithCopyButton = ({ src, alt, imageKey }) => {
6452
6465
  const [isHovered, setIsHovered] = React2.useState(false);
6466
+ const [imgSrc, setImgSrc] = React2.useState(src);
6467
+ const onImageError = useImageError();
6468
+ const handleImageError = React2.useCallback(async () => {
6469
+ if (onImageError) {
6470
+ const newUrl = await onImageError(imgSrc);
6471
+ if (newUrl) {
6472
+ setImgSrc(newUrl);
6473
+ return;
6474
+ }
6475
+ }
6476
+ }, [onImageError, imgSrc]);
6453
6477
  const [copyState, setCopyState] = React2.useState("idle");
6454
6478
  const imgRef = React2.useRef(null);
6455
6479
  const getImageBlob = async () => {
@@ -6564,10 +6588,11 @@ var ImageWithCopyButton = ({ src, alt, imageKey }) => {
6564
6588
  "img",
6565
6589
  {
6566
6590
  ref: imgRef,
6567
- src,
6591
+ src: imgSrc,
6568
6592
  alt,
6569
6593
  className: "chatllm-image",
6570
- crossOrigin: src.startsWith("data:") ? void 0 : "anonymous",
6594
+ crossOrigin: imgSrc.startsWith("data:") ? void 0 : "anonymous",
6595
+ onError: handleImageError,
6571
6596
  style: {
6572
6597
  maxWidth: "100%",
6573
6598
  borderRadius: "8px",
@@ -8850,7 +8875,7 @@ var iconButtonStyle = {
8850
8875
  };
8851
8876
 
8852
8877
  // src/react/components/MessageList.tsx
8853
- import React14, { useRef as useRef10, useEffect as useEffect10, useCallback as useCallback10, useState as useState18 } from "react";
8878
+ import React14, { useRef as useRef10, useEffect as useEffect10, useCallback as useCallback11, useState as useState18 } from "react";
8854
8879
 
8855
8880
  // src/react/components/MessageBubble.tsx
8856
8881
  import { useState as useState17 } from "react";
@@ -9692,12 +9717,25 @@ var SkillProgressUI = ({
9692
9717
  };
9693
9718
 
9694
9719
  // src/react/components/ImageContentCard.tsx
9695
- import { useState as useState13 } from "react";
9720
+ import { useState as useState13, useCallback as useCallback8 } from "react";
9696
9721
  import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
9697
9722
  var ImageContentCard = ({ part }) => {
9698
9723
  const [isExpanded, setIsExpanded] = useState13(false);
9699
9724
  const [isLoaded, setIsLoaded] = useState13(false);
9700
9725
  const [hasError, setHasError] = useState13(false);
9726
+ const [imgSrc, setImgSrc] = useState13(part.url);
9727
+ const onImageError = useImageError();
9728
+ const handleImageError = useCallback8(async () => {
9729
+ if (onImageError) {
9730
+ const newUrl = await onImageError(imgSrc, part.fileName);
9731
+ if (newUrl) {
9732
+ setImgSrc(newUrl);
9733
+ setIsLoaded(false);
9734
+ return;
9735
+ }
9736
+ }
9737
+ setHasError(true);
9738
+ }, [onImageError, imgSrc, part.fileName]);
9701
9739
  if (hasError) {
9702
9740
  return /* @__PURE__ */ jsxs10(
9703
9741
  "div",
@@ -9750,10 +9788,10 @@ var ImageContentCard = ({ part }) => {
9750
9788
  /* @__PURE__ */ jsx11(
9751
9789
  "img",
9752
9790
  {
9753
- src: part.url,
9791
+ src: imgSrc,
9754
9792
  alt: part.alt || "",
9755
9793
  onLoad: () => setIsLoaded(true),
9756
- onError: () => setHasError(true),
9794
+ onError: handleImageError,
9757
9795
  style: {
9758
9796
  display: isLoaded ? "block" : "none",
9759
9797
  width: "100%",
@@ -9796,7 +9834,7 @@ var ImageContentCard = ({ part }) => {
9796
9834
  children: /* @__PURE__ */ jsx11(
9797
9835
  "img",
9798
9836
  {
9799
- src: part.url,
9837
+ src: imgSrc,
9800
9838
  alt: part.alt || "",
9801
9839
  style: {
9802
9840
  maxWidth: "90vw",
@@ -10064,7 +10102,7 @@ var ToolStatusCard = ({
10064
10102
  };
10065
10103
 
10066
10104
  // src/react/components/ArtifactCard.tsx
10067
- import { useRef as useRef9, useEffect as useEffect9, useState as useState15, useCallback as useCallback8 } from "react";
10105
+ import { useRef as useRef9, useEffect as useEffect9, useState as useState15, useCallback as useCallback9 } from "react";
10068
10106
  import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
10069
10107
  var getThemeStyles = () => {
10070
10108
  const root = document.documentElement;
@@ -10157,7 +10195,7 @@ var MermaidArtifact = ({ code }) => {
10157
10195
  const containerRef = useRef9(null);
10158
10196
  const [svgHtml, setSvgHtml] = useState15(null);
10159
10197
  const [error, setError] = useState15(null);
10160
- const renderMermaid = useCallback8(async () => {
10198
+ const renderMermaid = useCallback9(async () => {
10161
10199
  try {
10162
10200
  let mermaid;
10163
10201
  try {
@@ -10541,7 +10579,7 @@ var ContentPartRenderer = ({
10541
10579
  effectiveType === "image" && /* @__PURE__ */ jsx15(
10542
10580
  ImageContentCard,
10543
10581
  {
10544
- part: { type: "image", url: result.content, alt: result.metadata?.alt }
10582
+ part: { type: "image", url: result.content, alt: result.metadata?.alt, fileName: result.metadata?.fileName }
10545
10583
  }
10546
10584
  ),
10547
10585
  effectiveType === "file" && /* @__PURE__ */ jsx15(
@@ -11893,7 +11931,7 @@ var MessageList = ({
11893
11931
  container.removeEventListener("touchmove", handleTouchMove);
11894
11932
  };
11895
11933
  }, []);
11896
- const handleScroll = useCallback10(() => {
11934
+ const handleScroll = useCallback11(() => {
11897
11935
  if (!containerRef.current) return;
11898
11936
  const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
11899
11937
  const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
@@ -11909,7 +11947,7 @@ var MessageList = ({
11909
11947
  behavior: "smooth"
11910
11948
  });
11911
11949
  }, [messages]);
11912
- const scrollToBottom = useCallback10(() => {
11950
+ const scrollToBottom = useCallback11(() => {
11913
11951
  userScrollLockRef.current = false;
11914
11952
  setShowScrollButton(false);
11915
11953
  containerRef.current?.scrollTo({
@@ -11917,7 +11955,7 @@ var MessageList = ({
11917
11955
  behavior: "smooth"
11918
11956
  });
11919
11957
  }, []);
11920
- const handleMouseUp = useCallback10(() => {
11958
+ const handleMouseUp = useCallback11(() => {
11921
11959
  const selection = typeof window !== "undefined" ? window.getSelection() : null;
11922
11960
  const text = selection?.toString().trim();
11923
11961
  if (text && text.length > 0) {
@@ -15038,7 +15076,8 @@ var ChatUIWithHook = ({
15038
15076
  onWorkflowSuggested,
15039
15077
  onAnalyzePatterns,
15040
15078
  // Image upload
15041
- onUploadImage
15079
+ onUploadImage,
15080
+ onImageError
15042
15081
  }) => {
15043
15082
  const hookOptions = {
15044
15083
  models,
@@ -15088,10 +15127,11 @@ var ChatUIWithHook = ({
15088
15127
  onWorkflowSuggested,
15089
15128
  onAnalyzePatterns,
15090
15129
  // Image upload
15091
- onUploadImage
15130
+ onUploadImage,
15131
+ onImageError
15092
15132
  };
15093
15133
  const state = useChatUI(hookOptions);
15094
- return /* @__PURE__ */ jsx23(
15134
+ return /* @__PURE__ */ jsx23(ImageErrorContext.Provider, { value: onImageError || null, children: /* @__PURE__ */ jsx23(
15095
15135
  ChatUIView,
15096
15136
  {
15097
15137
  state,
@@ -15118,7 +15158,7 @@ var ChatUIWithHook = ({
15118
15158
  onImportMemory,
15119
15159
  importMemoryPrompt
15120
15160
  }
15121
- );
15161
+ ) });
15122
15162
  };
15123
15163
  var ChatUI = (props) => {
15124
15164
  injectStyles();
@@ -15148,7 +15188,7 @@ var ChatUI = (props) => {
15148
15188
  onImportMemory,
15149
15189
  importMemoryPrompt
15150
15190
  } = props;
15151
- return /* @__PURE__ */ jsx23(
15191
+ return /* @__PURE__ */ jsx23(ImageErrorContext.Provider, { value: props.onImageError || null, children: /* @__PURE__ */ jsx23(
15152
15192
  ChatUIView,
15153
15193
  {
15154
15194
  state: props.chatState,
@@ -15176,19 +15216,19 @@ var ChatUI = (props) => {
15176
15216
  onImportMemory,
15177
15217
  importMemoryPrompt
15178
15218
  }
15179
- );
15219
+ ) });
15180
15220
  }
15181
15221
  return /* @__PURE__ */ jsx23(ChatUIWithHook, { ...props });
15182
15222
  };
15183
15223
 
15184
15224
  // src/react/ChatFloatingWidget.tsx
15185
- import { useState as useState28, useRef as useRef17, useEffect as useEffect19, useMemo as useMemo7, useCallback as useCallback15 } from "react";
15225
+ import { useState as useState28, useRef as useRef17, useEffect as useEffect19, useMemo as useMemo7, useCallback as useCallback16 } from "react";
15186
15226
 
15187
15227
  // src/react/hooks/useFloatingWidget.ts
15188
- import { useState as useState22, useCallback as useCallback12, useEffect as useEffect14, useRef as useRef12 } from "react";
15228
+ import { useState as useState22, useCallback as useCallback13, useEffect as useEffect14, useRef as useRef12 } from "react";
15189
15229
 
15190
15230
  // src/react/hooks/useDragResize.ts
15191
- import { useState as useState21, useRef as useRef11, useCallback as useCallback11, useEffect as useEffect13, useMemo as useMemo6 } from "react";
15231
+ import { useState as useState21, useRef as useRef11, useCallback as useCallback12, useEffect as useEffect13, useMemo as useMemo6 } from "react";
15192
15232
  var DRAG_THRESHOLD = 5;
15193
15233
  var FAB_SIZE = 56;
15194
15234
  var EDGE_MARGIN = 24;
@@ -15338,7 +15378,7 @@ var useDragResize = (options) => {
15338
15378
  if (dragRafRef.current) cancelAnimationFrame(dragRafRef.current);
15339
15379
  };
15340
15380
  }, []);
15341
- const handleFabPointerDown = useCallback11((e) => {
15381
+ const handleFabPointerDown = useCallback12((e) => {
15342
15382
  if (disabled || isMobile) return;
15343
15383
  dragCleanupRef.current?.();
15344
15384
  const el = e.currentTarget;
@@ -15552,7 +15592,7 @@ var useDragResize = (options) => {
15552
15592
  borderRadius: "var(--floating-panel-radius, 16px)"
15553
15593
  };
15554
15594
  }, [isMobile, disabled, fabPos.x, fabPos.y, panelSize.width, panelSize.height, vw, vh, panelDirection, minHeight]);
15555
- const handleResizePointerDown = useCallback11((edge, e) => {
15595
+ const handleResizePointerDown = useCallback12((edge, e) => {
15556
15596
  if (disabled || isMobile) return;
15557
15597
  e.preventDefault();
15558
15598
  e.stopPropagation();
@@ -15568,7 +15608,7 @@ var useDragResize = (options) => {
15568
15608
  };
15569
15609
  setIsResizing(true);
15570
15610
  }, [disabled, isMobile]);
15571
- const handleResizePointerMove = useCallback11((e) => {
15611
+ const handleResizePointerMove = useCallback12((e) => {
15572
15612
  if (!resizeStartRef.current) return;
15573
15613
  const { startX, startY, width, height, edge, fabY } = resizeStartRef.current;
15574
15614
  const dx = e.clientX - startX;
@@ -15592,7 +15632,7 @@ var useDragResize = (options) => {
15592
15632
  newHeight = Math.max(minHeight, Math.min(maxH, newHeight));
15593
15633
  setPanelSize({ width: newWidth, height: newHeight });
15594
15634
  }, [minWidth, maxWidth, minHeight]);
15595
- const handleResizePointerUp = useCallback11((e) => {
15635
+ const handleResizePointerUp = useCallback12((e) => {
15596
15636
  if (!resizeStartRef.current) return;
15597
15637
  e.currentTarget.releasePointerCapture(e.pointerId);
15598
15638
  resizeStartRef.current = null;
@@ -15689,15 +15729,15 @@ var useFloatingWidget = (options) => {
15689
15729
  useEffect14(() => {
15690
15730
  onTabChangeRef.current = onTabChange;
15691
15731
  }, [onTabChange]);
15692
- const open = useCallback12(() => {
15732
+ const open = useCallback13(() => {
15693
15733
  setIsOpen(true);
15694
15734
  onOpenRef.current?.();
15695
15735
  }, []);
15696
- const close = useCallback12(() => {
15736
+ const close = useCallback13(() => {
15697
15737
  setIsOpen(false);
15698
15738
  onCloseRef.current?.();
15699
15739
  }, []);
15700
- const toggle = useCallback12(() => {
15740
+ const toggle = useCallback13(() => {
15701
15741
  setIsOpen((prev) => {
15702
15742
  const next = !prev;
15703
15743
  if (next) onOpenRef.current?.();
@@ -15705,11 +15745,11 @@ var useFloatingWidget = (options) => {
15705
15745
  return next;
15706
15746
  });
15707
15747
  }, []);
15708
- const setTab = useCallback12((tabKey) => {
15748
+ const setTab = useCallback13((tabKey) => {
15709
15749
  setActiveTab(tabKey);
15710
15750
  onTabChangeRef.current?.(tabKey);
15711
15751
  }, []);
15712
- const handleFabInteraction = useCallback12(() => {
15752
+ const handleFabInteraction = useCallback13(() => {
15713
15753
  if (dragResize.isDragging) return;
15714
15754
  toggle();
15715
15755
  }, [dragResize.isDragging, toggle]);
@@ -15742,7 +15782,7 @@ var useFloatingWidget = (options) => {
15742
15782
  import { useRef as useRef14, useState as useState24, useEffect as useEffect16 } from "react";
15743
15783
 
15744
15784
  // src/react/components/floating/DevDiveCharacter.tsx
15745
- import { useState as useState23, useEffect as useEffect15, useRef as useRef13, useCallback as useCallback13 } from "react";
15785
+ import { useState as useState23, useEffect as useEffect15, useRef as useRef13, useCallback as useCallback14 } from "react";
15746
15786
  import { Fragment as Fragment10, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
15747
15787
  var THEMES = {
15748
15788
  dark: { body: "#2ecc71", stroke: "#27ae60", highlight: "#3ddc84", face: "#1a1a2e", eyeLight: "#fff" },
@@ -15777,7 +15817,7 @@ var DevDiveFabCharacter = ({
15777
15817
  const cleanupRef = useRef13(null);
15778
15818
  const lastActivityRef = useRef13(Date.now());
15779
15819
  const isSleepyRef = useRef13(false);
15780
- const markActivity = useCallback13(() => {
15820
+ const markActivity = useCallback14(() => {
15781
15821
  lastActivityRef.current = Date.now();
15782
15822
  if (isSleepyRef.current) {
15783
15823
  isSleepyRef.current = false;
@@ -16504,7 +16544,7 @@ var FloatingTabBar = ({
16504
16544
  };
16505
16545
 
16506
16546
  // src/react/components/floating/CompactChatView.tsx
16507
- import { useState as useState27, useCallback as useCallback14 } from "react";
16547
+ import { useState as useState27, useCallback as useCallback15 } from "react";
16508
16548
 
16509
16549
  // src/react/components/floating/CompactSessionMenu.tsx
16510
16550
  import { useState as useState26, useRef as useRef16, useEffect as useEffect18 } from "react";
@@ -16850,15 +16890,15 @@ var CompactChatView = ({
16850
16890
  setInput(choice.text);
16851
16891
  };
16852
16892
  const [showSessionMenu, setShowSessionMenu] = useState27(false);
16853
- const handleSessionSelect = useCallback14((id) => {
16893
+ const handleSessionSelect = useCallback15((id) => {
16854
16894
  selectSession(id);
16855
16895
  setShowSessionMenu(false);
16856
16896
  }, [selectSession]);
16857
- const handleNewSession = useCallback14(() => {
16897
+ const handleNewSession = useCallback15(() => {
16858
16898
  newSession();
16859
16899
  setShowSessionMenu(false);
16860
16900
  }, [newSession]);
16861
- const handleCloseMenu = useCallback14(() => {
16901
+ const handleCloseMenu = useCallback15(() => {
16862
16902
  setShowSessionMenu(false);
16863
16903
  }, []);
16864
16904
  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";
@@ -17182,7 +17222,7 @@ var ChatFloatingWidget = ({
17182
17222
  if (!notification) return null;
17183
17223
  return typeof notification === "string" ? { text: notification } : notification;
17184
17224
  }, [notification]);
17185
- const handleFabClick = useCallback15(() => {
17225
+ const handleFabClick = useCallback16(() => {
17186
17226
  if (notifObj?.onClick) {
17187
17227
  notifObj.onClick();
17188
17228
  if (!isOpen) handleFabInteraction();
@@ -17366,7 +17406,7 @@ var ChatFloatingWidget = ({
17366
17406
  };
17367
17407
 
17368
17408
  // src/react/hooks/useDeepResearch.ts
17369
- import { useState as useState29, useCallback as useCallback16, useRef as useRef18 } from "react";
17409
+ import { useState as useState29, useCallback as useCallback17, useRef as useRef18 } from "react";
17370
17410
  var REPORT_GENERATION_PROMPT2 = `\uB2F9\uC2E0\uC740 \uB9AC\uC11C\uCE58 \uBCF4\uACE0\uC11C \uC791\uC131 \uC804\uBB38\uAC00\uC785\uB2C8\uB2E4.
17371
17411
 
17372
17412
  <collected_sources>
@@ -17420,7 +17460,7 @@ var useDeepResearch = (options) => {
17420
17460
  const [isResearching, setIsResearching] = useState29(false);
17421
17461
  const [progress, setProgress] = useState29(null);
17422
17462
  const abortControllerRef = useRef18(null);
17423
- const callLLM2 = useCallback16(
17463
+ const callLLM2 = useCallback17(
17424
17464
  async (prompt, stream = false) => {
17425
17465
  const response = await fetch(apiEndpoint, {
17426
17466
  method: "POST",
@@ -17447,7 +17487,7 @@ var useDeepResearch = (options) => {
17447
17487
  },
17448
17488
  [apiEndpoint, apiKey, model, provider]
17449
17489
  );
17450
- const analyzeQuery2 = useCallback16(
17490
+ const analyzeQuery2 = useCallback17(
17451
17491
  async (query) => {
17452
17492
  const prompt = QUERY_ANALYSIS_PROMPT2.replace("{question}", query);
17453
17493
  const response = await callLLM2(prompt);
@@ -17466,7 +17506,7 @@ var useDeepResearch = (options) => {
17466
17506
  },
17467
17507
  [callLLM2]
17468
17508
  );
17469
- const runSubAgent2 = useCallback16(
17509
+ const runSubAgent2 = useCallback17(
17470
17510
  async (topic, queries, agentId, updateProgress) => {
17471
17511
  updateProgress({ status: "searching", searchCount: 0, resultsCount: 0 });
17472
17512
  const allResults = [];
@@ -17505,7 +17545,7 @@ var useDeepResearch = (options) => {
17505
17545
  },
17506
17546
  [onWebSearch, onExtractContent]
17507
17547
  );
17508
- const generateReport2 = useCallback16(
17548
+ const generateReport2 = useCallback17(
17509
17549
  async (query, results, onStreamContent) => {
17510
17550
  const allSources = [];
17511
17551
  const sourcesForPrompt = [];
@@ -17563,7 +17603,7 @@ var useDeepResearch = (options) => {
17563
17603
  },
17564
17604
  [callLLM2]
17565
17605
  );
17566
- const runDeepResearch = useCallback16(
17606
+ const runDeepResearch = useCallback17(
17567
17607
  async (query, onStreamContent) => {
17568
17608
  abortControllerRef.current = new AbortController();
17569
17609
  setIsResearching(true);
@@ -17666,7 +17706,7 @@ var useDeepResearch = (options) => {
17666
17706
  },
17667
17707
  [analyzeQuery2, runSubAgent2, generateReport2]
17668
17708
  );
17669
- const stopResearch = useCallback16(() => {
17709
+ const stopResearch = useCallback17(() => {
17670
17710
  abortControllerRef.current?.abort();
17671
17711
  setIsResearching(false);
17672
17712
  setProgress(null);
@@ -18231,6 +18271,7 @@ export {
18231
18271
  Icon,
18232
18272
  IconSvg,
18233
18273
  ImageContentCard,
18274
+ ImageErrorContext,
18234
18275
  LinkChip,
18235
18276
  MarkdownRenderer,
18236
18277
  MemoryPanel,
@@ -18252,6 +18293,7 @@ export {
18252
18293
  useDeepResearch,
18253
18294
  useDragResize,
18254
18295
  useFloatingWidget,
18296
+ useImageError,
18255
18297
  useObserver,
18256
18298
  useProject,
18257
18299
  useSkills