@gendive/chatllm 0.17.22 → 0.17.24

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.
@@ -1191,7 +1191,7 @@ var useProject = (options) => {
1191
1191
  }
1192
1192
  };
1193
1193
  loadProjects();
1194
- }, [useExternalStorage, onLoadProjects, onError, storageKey]);
1194
+ }, [enabled, useExternalStorage, onLoadProjects, onError, storageKey]);
1195
1195
  const createProject = useCallback4(
1196
1196
  async (data) => {
1197
1197
  const now = Date.now();
@@ -1433,11 +1433,6 @@ var parsePollFromContent = (content) => {
1433
1433
  allowOther,
1434
1434
  required: false
1435
1435
  };
1436
- console.log("[pollParser] Parsed poll:", {
1437
- question: pollQuestion.question,
1438
- optionsCount: pollQuestion.options.length,
1439
- options: pollQuestion.options.map((o) => o.label)
1440
- });
1441
1436
  polls.push(pollQuestion);
1442
1437
  }
1443
1438
  cleanContent = cleanContent.replace(match[0], "");
@@ -1445,7 +1440,6 @@ var parsePollFromContent = (content) => {
1445
1440
  if (polls.length === 0) {
1446
1441
  return { pollBlock: null, cleanContent: content };
1447
1442
  }
1448
- console.log("[pollParser] Total polls parsed:", polls.length, polls.map((p) => p.question));
1449
1443
  cleanContent = cleanContent.replace(/\n{3,}/g, "\n\n");
1450
1444
  return {
1451
1445
  pollBlock: {
@@ -1730,7 +1724,8 @@ var useChatUI = (options) => {
1730
1724
  }),
1731
1725
  [globalMemoryConfig, storageKey]
1732
1726
  );
1733
- const globalMemory = useGlobalMemoryEnabled ? useGlobalMemory(memoryOptions) : null;
1727
+ const globalMemoryRaw = useGlobalMemory(memoryOptions);
1728
+ const globalMemory = useGlobalMemoryEnabled ? globalMemoryRaw : null;
1734
1729
  const stableToolCall = useCallback5(
1735
1730
  (name, params) => onToolCallRef.current(name, params),
1736
1731
  []
@@ -2349,7 +2344,7 @@ ${finalContent}`;
2349
2344
  ...userContentParts && { contentParts: userContentParts }
2350
2345
  };
2351
2346
  const capturedSessionId = sessionId;
2352
- const currentSession2 = sessions.find((s) => s.id === capturedSessionId);
2347
+ const currentSession2 = sessionsRef.current.find((s) => s.id === capturedSessionId);
2353
2348
  const existingMessages = currentSession2?.messages || [];
2354
2349
  const isFirstMessage = !existingMessages.length;
2355
2350
  const contextSummary = currentSession2?.compressionState?.contextSummary || currentSession2?.contextSummary;
@@ -2366,6 +2361,9 @@ ${finalContent}`;
2366
2361
  setInput("");
2367
2362
  setQuotedText(null);
2368
2363
  setSelectedAction(null);
2364
+ attachments.forEach((a) => {
2365
+ if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
2366
+ });
2369
2367
  setAttachments([]);
2370
2368
  setSessions(
2371
2369
  (prev) => prev.map((s) => {
@@ -2737,6 +2735,26 @@ ${attachmentContext}
2737
2735
  } catch {
2738
2736
  }
2739
2737
  }
2738
+ const saveMessagesOnEarlyReturn = () => {
2739
+ if (!useExternalStorage || !capturedSessionId) return;
2740
+ queueMicrotask(() => {
2741
+ const latestSession = sessionsRef.current.find((s) => s.id === capturedSessionId);
2742
+ if (!latestSession) return;
2743
+ const latestMessages = latestSession.messages;
2744
+ const assistantMsg = [...latestMessages].reverse().find((m) => m.role === "assistant");
2745
+ const userMsg = latestMessages.find((m) => m.role === "user" && m.content === finalContent);
2746
+ const assistantContent = assistantMsg?.content || "";
2747
+ if (assistantContent && onSaveMessagesRef.current) {
2748
+ onSaveMessagesRef.current(capturedSessionId, [
2749
+ { role: "user", message: finalContent, ...userMsg?.contentParts && { contentParts: userMsg.contentParts } },
2750
+ { role: "assistant", message: assistantContent, ...assistantMsg?.contentParts && { contentParts: assistantMsg.contentParts } }
2751
+ ]).catch((e) => console.error("[useChatUI] Failed to save messages:", e));
2752
+ }
2753
+ if (latestSession.messages.length > 0) {
2754
+ writeSessionCache(storageKey, latestSession);
2755
+ }
2756
+ });
2757
+ };
2740
2758
  if (!shouldSkipSkillParsing) {
2741
2759
  const assistantContent = accumulatedContent;
2742
2760
  const { skillCall: detectedSkill, cleanContent: skillCleanContent } = parseSkillCallFromContent(assistantContent);
@@ -2840,6 +2858,7 @@ ${attachmentContext}
2840
2858
  })
2841
2859
  );
2842
2860
  if (resultType === "image" || resultType === "file") {
2861
+ saveMessagesOnEarlyReturn();
2843
2862
  setIsLoading(false);
2844
2863
  abortControllerRef.current = null;
2845
2864
  return;
@@ -2850,11 +2869,13 @@ ${attachmentContext}
2850
2869
  shouldContinue = decision === "continue";
2851
2870
  }
2852
2871
  if (!shouldContinue) {
2872
+ saveMessagesOnEarlyReturn();
2853
2873
  setIsLoading(false);
2854
2874
  abortControllerRef.current = null;
2855
2875
  return;
2856
2876
  }
2857
2877
  skipNextSkillParsingRef.current = true;
2878
+ saveMessagesOnEarlyReturn();
2858
2879
  const feedbackPrompt = resultType === "error" ? `\uB3C4\uAD6C "${toolName}" \uC2E4\uD589 \uC911 \uC624\uB958 \uBC1C\uC0DD: ${result.content}
2859
2880
 
2860
2881
  \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC624\uB958\uB97C \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.` : `\uB3C4\uAD6C "${toolName}" \uACB0\uACFC:
@@ -2890,6 +2911,7 @@ ${result.content}
2890
2911
  })
2891
2912
  );
2892
2913
  if (streamedReport) {
2914
+ saveMessagesOnEarlyReturn();
2893
2915
  setIsLoading(false);
2894
2916
  abortControllerRef.current = null;
2895
2917
  return;
@@ -2900,11 +2922,13 @@ ${result.content}
2900
2922
  shouldContinueSkill = decision === "continue";
2901
2923
  }
2902
2924
  if (!shouldContinueSkill) {
2925
+ saveMessagesOnEarlyReturn();
2903
2926
  setIsLoading(false);
2904
2927
  abortControllerRef.current = null;
2905
2928
  return;
2906
2929
  }
2907
2930
  skipNextSkillParsingRef.current = true;
2931
+ saveMessagesOnEarlyReturn();
2908
2932
  const resultPrompt = `\uC2A4\uD0AC "${detectedSkill.name}" \uC2E4\uD589 \uACB0\uACFC:
2909
2933
 
2910
2934
  ${result.content}
@@ -6441,6 +6465,7 @@ var MarkdownRenderer = ({
6441
6465
  if (hasUnfinishedPoll) {
6442
6466
  processedContent += "\n\xA7POLL_LOADING\xA7";
6443
6467
  }
6468
+ processedContent = processedContent.replace(/<skill_use[^>]*>[\s\S]*?<\/skill_use>/gi, "");
6444
6469
  processedContent = processedContent.replace(UNCLOSED_SKILL_TAG_REGEX, "");
6445
6470
  const codeBlocks = [];
6446
6471
  processedContent = processedContent.replace(CODE_BLOCK_REGEX, (match, lang, code) => {
@@ -6772,7 +6797,7 @@ var MarkdownRenderer = ({
6772
6797
  flushBlockquote();
6773
6798
  flushTable();
6774
6799
  return elements;
6775
- }, [content, onChoiceClick, sources]);
6800
+ }, [content, onChoiceClick, sources, showThinking, thinkingDefaultOpen]);
6776
6801
  return /* @__PURE__ */ jsx7(
6777
6802
  "div",
6778
6803
  {
@@ -7170,7 +7195,10 @@ var PollCard = ({
7170
7195
  useEffect7(() => {
7171
7196
  if (typeof window === "undefined") return;
7172
7197
  const handleKeyDown = (e) => {
7173
- if (e.key === "Escape") handleSkip();
7198
+ if (e.key !== "Escape") return;
7199
+ const modalOpen = document.querySelector(".chatllm-settings-overlay, .chatllm-disclaimer-overlay, .chatllm-project-settings-overlay");
7200
+ if (modalOpen) return;
7201
+ handleSkip();
7174
7202
  };
7175
7203
  window.addEventListener("keydown", handleKeyDown);
7176
7204
  return () => window.removeEventListener("keydown", handleKeyDown);
@@ -8142,13 +8170,6 @@ var MessageBubble = ({
8142
8170
  const displayContent = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.content || message.content : message.content;
8143
8171
  const displayModel = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.model : message.model;
8144
8172
  const displaySources = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.sources : message.sources;
8145
- const handleMouseUp = () => {
8146
- if (!onQuote) return;
8147
- const selection = typeof window !== "undefined" ? window.getSelection() : null;
8148
- const text = selection?.toString().trim();
8149
- if (text && text.length > 0) {
8150
- }
8151
- };
8152
8173
  if (isUser) {
8153
8174
  return /* @__PURE__ */ jsxs14(
8154
8175
  "div",
@@ -8162,7 +8183,6 @@ var MessageBubble = ({
8162
8183
  },
8163
8184
  onMouseEnter: () => setShowActions(true),
8164
8185
  onMouseLeave: () => setShowActions(false),
8165
- onMouseUp: handleMouseUp,
8166
8186
  children: [
8167
8187
  /* @__PURE__ */ jsx15(
8168
8188
  "div",
@@ -8283,7 +8303,6 @@ var MessageBubble = ({
8283
8303
  },
8284
8304
  onMouseEnter: () => setShowActions(true),
8285
8305
  onMouseLeave: () => setShowActions(false),
8286
- onMouseUp: handleMouseUp,
8287
8306
  children: [
8288
8307
  /* @__PURE__ */ jsxs14(
8289
8308
  "div",
@@ -8386,7 +8405,7 @@ var MessageBubble = ({
8386
8405
  ]
8387
8406
  }
8388
8407
  ),
8389
- message.contentParts?.length && /* @__PURE__ */ jsx15("div", { style: { wordBreak: "break-word" }, children: /* @__PURE__ */ jsx15(
8408
+ !!message.contentParts?.length && /* @__PURE__ */ jsx15("div", { style: { wordBreak: "break-word" }, children: /* @__PURE__ */ jsx15(
8390
8409
  ContentPartRenderer,
8391
8410
  {
8392
8411
  parts: message.contentParts,
@@ -8985,7 +9004,7 @@ var MessageList = ({
8985
9004
  };
8986
9005
 
8987
9006
  // src/react/components/SettingsModal.tsx
8988
- import { useState as useState16 } from "react";
9007
+ import { useState as useState16, useEffect as useEffect9 } from "react";
8989
9008
  import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
8990
9009
  var DEFAULT_PERSONALIZATION2 = {
8991
9010
  responseStyle: {
@@ -9023,6 +9042,9 @@ var SettingsModal = ({
9023
9042
  }) => {
9024
9043
  const [activeTab, setActiveTab] = useState16("general");
9025
9044
  const [localApiKey, setLocalApiKey] = useState16(apiKey);
9045
+ useEffect9(() => {
9046
+ setLocalApiKey(apiKey);
9047
+ }, [apiKey]);
9026
9048
  if (!isOpen) return null;
9027
9049
  const updateResponseStyle = (key, value) => {
9028
9050
  onPersonalizationChange({
@@ -9662,7 +9684,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9662
9684
  };
9663
9685
 
9664
9686
  // src/react/components/ProjectSettingsModal.tsx
9665
- import { useState as useState17, useEffect as useEffect9 } from "react";
9687
+ import { useState as useState17, useEffect as useEffect10 } from "react";
9666
9688
  import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
9667
9689
  var COLOR_PRESETS = [
9668
9690
  "#3584FA",
@@ -9688,7 +9710,7 @@ var ProjectSettingsModal = ({
9688
9710
  const [description, setDescription] = useState17("");
9689
9711
  const [instructions, setInstructions] = useState17("");
9690
9712
  const [color, setColor] = useState17("#3584FA");
9691
- useEffect9(() => {
9713
+ useEffect10(() => {
9692
9714
  if (project) {
9693
9715
  setTitle(project.title);
9694
9716
  setDescription(project.description || "");