@gendive/chatllm 0.12.1 → 0.12.2

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.
@@ -1210,6 +1210,37 @@ var formatPollResponse = (question, selectedOptions, otherText) => {
1210
1210
  return `${selectedLabels.join(", ")}\uC744(\uB97C) \uC120\uD0DD\uD588\uC2B5\uB2C8\uB2E4. \uC774 \uC120\uD0DD\uC744 \uBC14\uD0D5\uC73C\uB85C \uC9C4\uD589\uD574\uC8FC\uC138\uC694.`;
1211
1211
  };
1212
1212
 
1213
+ // src/react/utils/sessionCache.ts
1214
+ var buildCacheKey = (storageKey, sessionId) => `${storageKey}_cache_${sessionId}`;
1215
+ var writeSessionCache = (storageKey, session) => {
1216
+ if (typeof window === "undefined") return;
1217
+ try {
1218
+ const key = buildCacheKey(storageKey, session.id);
1219
+ localStorage.setItem(key, JSON.stringify(session));
1220
+ } catch (error) {
1221
+ console.warn("[sessionCache] Failed to write cache:", error);
1222
+ }
1223
+ };
1224
+ var readSessionCache = (storageKey, sessionId) => {
1225
+ if (typeof window === "undefined") return null;
1226
+ try {
1227
+ const key = buildCacheKey(storageKey, sessionId);
1228
+ const data = localStorage.getItem(key);
1229
+ if (!data) return null;
1230
+ return JSON.parse(data);
1231
+ } catch {
1232
+ return null;
1233
+ }
1234
+ };
1235
+ var removeSessionCache = (storageKey, sessionId) => {
1236
+ if (typeof window === "undefined") return;
1237
+ try {
1238
+ const key = buildCacheKey(storageKey, sessionId);
1239
+ localStorage.removeItem(key);
1240
+ } catch {
1241
+ }
1242
+ };
1243
+
1213
1244
  // src/react/hooks/useChatUI.ts
1214
1245
  var DEFAULT_STORAGE_KEY = "chatllm_sessions";
1215
1246
  var DEFAULT_COMPRESSION_THRESHOLD = 20;
@@ -1281,6 +1312,10 @@ var useChatUI = (options) => {
1281
1312
  const [deepResearchProgress, setDeepResearchProgress] = (0, import_react4.useState)(
1282
1313
  null
1283
1314
  );
1315
+ const sessionsRef = (0, import_react4.useRef)(sessions);
1316
+ (0, import_react4.useEffect)(() => {
1317
+ sessionsRef.current = sessions;
1318
+ }, [sessions]);
1284
1319
  const abortControllerRef = (0, import_react4.useRef)(null);
1285
1320
  const skipNextPollParsingRef = (0, import_react4.useRef)(false);
1286
1321
  const skipNextSkillParsingRef = (0, import_react4.useRef)(false);
@@ -1610,7 +1645,7 @@ ${newConversation}
1610
1645
  setIsSessionLoading(true);
1611
1646
  try {
1612
1647
  const sessionDetail = await onLoadSession(id);
1613
- const loadedMessages = sessionDetail.messages.map((m, idx) => ({
1648
+ let loadedMessages = sessionDetail.messages.map((m, idx) => ({
1614
1649
  id: m.id || generateId2("msg"),
1615
1650
  role: typeof m.role === "string" ? m.role.toLowerCase() : m.role,
1616
1651
  // API는 message 필드, 내부는 content 필드 사용
@@ -1620,18 +1655,54 @@ ${newConversation}
1620
1655
  alternatives: m.alternatives,
1621
1656
  sources: m.sources
1622
1657
  }));
1658
+ let resolvedTitle = sessionDetail.title;
1659
+ if (loadedMessages.length === 0) {
1660
+ const cached = readSessionCache(storageKey, id);
1661
+ if (cached && cached.messages.length > 0) {
1662
+ console.warn("[useChatUI] Server returned empty messages, using localStorage cache");
1663
+ loadedMessages = cached.messages;
1664
+ if (!resolvedTitle && cached.title) {
1665
+ resolvedTitle = cached.title;
1666
+ }
1667
+ }
1668
+ }
1623
1669
  setSessions(
1624
1670
  (prev) => prev.map(
1625
- (s) => s.id === id ? { ...s, title: sessionDetail.title, messages: loadedMessages, updatedAt: Date.now() } : s
1671
+ (s) => s.id === id ? { ...s, title: resolvedTitle, messages: loadedMessages, updatedAt: Date.now() } : s
1626
1672
  )
1627
1673
  );
1628
1674
  setCurrentSessionId(id);
1675
+ if (loadedMessages.length > 0) {
1676
+ const existingSession2 = sessions.find((s) => s.id === id);
1677
+ writeSessionCache(storageKey, {
1678
+ id,
1679
+ title: resolvedTitle,
1680
+ messages: loadedMessages,
1681
+ model: existingSession2?.model || initialModel || models[0]?.id || "",
1682
+ createdAt: existingSession2?.createdAt || Date.now(),
1683
+ updatedAt: Date.now()
1684
+ });
1685
+ }
1629
1686
  const existingSession = sessions.find((s) => s.id === id);
1630
1687
  if (existingSession) {
1631
1688
  setSelectedModel(existingSession.model);
1632
1689
  }
1633
1690
  } catch (error) {
1634
1691
  onError?.(error instanceof Error ? error : new Error("Failed to load session"));
1692
+ const cached = readSessionCache(storageKey, id);
1693
+ if (cached && cached.messages.length > 0) {
1694
+ console.warn("[useChatUI] onLoadSession failed, using localStorage cache");
1695
+ setSessions(
1696
+ (prev) => prev.map(
1697
+ (s) => s.id === id ? { ...s, title: cached.title || s.title, messages: cached.messages, updatedAt: Date.now() } : s
1698
+ )
1699
+ );
1700
+ setCurrentSessionId(id);
1701
+ const existingSession = sessions.find((s) => s.id === id);
1702
+ if (existingSession) {
1703
+ setSelectedModel(existingSession.model);
1704
+ }
1705
+ }
1635
1706
  } finally {
1636
1707
  setIsSessionLoading(false);
1637
1708
  }
@@ -1642,11 +1713,12 @@ ${newConversation}
1642
1713
  setCurrentSessionId(id);
1643
1714
  setSelectedModel(session.model);
1644
1715
  }
1645
- }, [sessions, useExternalStorage, onLoadSession, onError]);
1716
+ }, [sessions, useExternalStorage, onLoadSession, onError, storageKey, initialModel, models]);
1646
1717
  const deleteSession = (0, import_react4.useCallback)(async (id) => {
1647
1718
  if (useExternalStorage && onDeleteSessionCallback) {
1648
1719
  try {
1649
1720
  await onDeleteSessionCallback(id);
1721
+ removeSessionCache(storageKey, id);
1650
1722
  setSessions((prev) => {
1651
1723
  const filtered = prev.filter((s) => s.id !== id);
1652
1724
  if (currentSessionId === id) {
@@ -2137,20 +2209,23 @@ ${result.content}
2137
2209
  };
2138
2210
  })
2139
2211
  );
2140
- if (useExternalStorage && onSaveMessages && capturedSessionId) {
2141
- const updatedSession = sessions.find((s) => s.id === capturedSessionId);
2142
- const assistantContent = updatedSession?.messages.find(
2143
- (m) => m.id === assistantMessageId
2144
- )?.content || "";
2145
- if (assistantContent) {
2212
+ if (useExternalStorage && capturedSessionId) {
2213
+ const assistantContentForSave = accumulatedContent;
2214
+ if (assistantContentForSave && onSaveMessages) {
2146
2215
  const messagesToSave = [
2147
2216
  { role: "USER", message: finalContent },
2148
- { role: "ASSISTANT", message: assistantContent }
2217
+ { role: "ASSISTANT", message: assistantContentForSave }
2149
2218
  ];
2150
2219
  onSaveMessages(capturedSessionId, messagesToSave).catch((saveError) => {
2151
2220
  console.error("[useChatUI] Failed to save messages:", saveError);
2152
2221
  });
2153
2222
  }
2223
+ queueMicrotask(() => {
2224
+ const sessionToCache = sessionsRef.current.find((s) => s.id === capturedSessionId);
2225
+ if (sessionToCache && sessionToCache.messages.length > 0) {
2226
+ writeSessionCache(storageKey, sessionToCache);
2227
+ }
2228
+ });
2154
2229
  }
2155
2230
  if (enableAutoExtraction && globalMemory) {
2156
2231
  const currentMsgCount = existingMessages.length + 2;