@gendive/chatllm 0.16.1 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/index.d.mts +76 -1
- package/dist/react/index.d.ts +76 -1
- package/dist/react/index.js +296 -67
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +296 -67
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -1133,7 +1133,7 @@ var useProject = (options) => {
|
|
|
1133
1133
|
const currentProject = projects.find((p) => p.id === currentProjectId) || null;
|
|
1134
1134
|
useEffect2(() => {
|
|
1135
1135
|
if (!enabled || useExternalStorage || !initializedRef.current) return;
|
|
1136
|
-
if (projects.length > 0) {
|
|
1136
|
+
if (projects.length > 0 && typeof window !== "undefined") {
|
|
1137
1137
|
localStorage.setItem(storageKey, JSON.stringify(projects));
|
|
1138
1138
|
}
|
|
1139
1139
|
}, [enabled, projects, storageKey, useExternalStorage]);
|
|
@@ -1167,7 +1167,7 @@ var useProject = (options) => {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
} else {
|
|
1169
1169
|
try {
|
|
1170
|
-
const saved = localStorage.getItem(storageKey);
|
|
1170
|
+
const saved = typeof window !== "undefined" ? localStorage.getItem(storageKey) : null;
|
|
1171
1171
|
if (saved) {
|
|
1172
1172
|
const parsed = JSON.parse(saved);
|
|
1173
1173
|
if (!parsed.find((p) => p.id === DEFAULT_PROJECT_ID)) {
|
|
@@ -1469,9 +1469,12 @@ var convertToolsToSkills = (tools, onToolCall) => {
|
|
|
1469
1469
|
for (const tool of tools) {
|
|
1470
1470
|
skillMap[tool.name] = {
|
|
1471
1471
|
description: tool.description,
|
|
1472
|
-
trigger
|
|
1472
|
+
/** @Todo vibecode - tool.trigger 지원 (기본 'both', 'attachment' 가능) */
|
|
1473
|
+
trigger: tool.trigger || "both",
|
|
1473
1474
|
label: tool.label || tool.name,
|
|
1474
1475
|
icon: tool.icon,
|
|
1476
|
+
acceptedTypes: tool.acceptedTypes,
|
|
1477
|
+
autoConvertBase64: tool.autoConvertBase64,
|
|
1475
1478
|
parameters: {
|
|
1476
1479
|
type: "object",
|
|
1477
1480
|
properties: Object.fromEntries(
|
|
@@ -1545,6 +1548,20 @@ var DEFAULT_KEEP_RECENT = 6;
|
|
|
1545
1548
|
var DEFAULT_RECOMPRESSION_THRESHOLD = 10;
|
|
1546
1549
|
var DEFAULT_TOKEN_LIMIT = 8e3;
|
|
1547
1550
|
var generateId3 = (prefix) => `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
1551
|
+
var fileToBase64 = (file) => new Promise((resolve, reject) => {
|
|
1552
|
+
const reader = new FileReader();
|
|
1553
|
+
reader.onload = () => resolve(reader.result.split(",")[1] || "");
|
|
1554
|
+
reader.onerror = reject;
|
|
1555
|
+
reader.readAsDataURL(file);
|
|
1556
|
+
});
|
|
1557
|
+
var convertAttachmentsToBase64 = async (attachments) => Promise.all(
|
|
1558
|
+
attachments.map(async (att) => ({
|
|
1559
|
+
name: att.name,
|
|
1560
|
+
mimeType: att.mimeType,
|
|
1561
|
+
base64: await fileToBase64(att.file),
|
|
1562
|
+
size: att.size
|
|
1563
|
+
}))
|
|
1564
|
+
);
|
|
1548
1565
|
var generateTitle = (messages) => {
|
|
1549
1566
|
const firstUserMessage = messages.find((m) => m.role === "user");
|
|
1550
1567
|
if (!firstUserMessage) return "\uC0C8 \uB300\uD654";
|
|
@@ -1596,7 +1613,12 @@ var useChatUI = (options) => {
|
|
|
1596
1613
|
onUpdateProject,
|
|
1597
1614
|
onDeleteProject,
|
|
1598
1615
|
onAddProjectFile,
|
|
1599
|
-
onDeleteProjectFile
|
|
1616
|
+
onDeleteProjectFile,
|
|
1617
|
+
// Stream control
|
|
1618
|
+
continueAfterToolResult = true,
|
|
1619
|
+
onSkillComplete,
|
|
1620
|
+
// Dynamic model loading
|
|
1621
|
+
onLoadModels
|
|
1600
1622
|
} = options;
|
|
1601
1623
|
const enableAutoExtraction = enableAutoExtractionProp ?? !useExternalStorage;
|
|
1602
1624
|
const [sessions, setSessions] = useState5([]);
|
|
@@ -1620,6 +1642,8 @@ var useChatUI = (options) => {
|
|
|
1620
1642
|
const [isSessionLoading, setIsSessionLoading] = useState5(false);
|
|
1621
1643
|
const [isDeepResearchMode, setIsDeepResearchMode] = useState5(false);
|
|
1622
1644
|
const [attachments, setAttachments] = useState5([]);
|
|
1645
|
+
const [isModelsLoading, setIsModelsLoading] = useState5(false);
|
|
1646
|
+
const [loadedModels, setLoadedModels] = useState5(null);
|
|
1623
1647
|
const [deepResearchProgress, setDeepResearchProgress] = useState5(
|
|
1624
1648
|
null
|
|
1625
1649
|
);
|
|
@@ -1627,6 +1651,40 @@ var useChatUI = (options) => {
|
|
|
1627
1651
|
useEffect3(() => {
|
|
1628
1652
|
sessionsRef.current = sessions;
|
|
1629
1653
|
}, [sessions]);
|
|
1654
|
+
const onSendMessageRef = useRef4(onSendMessage);
|
|
1655
|
+
const onSessionChangeRef = useRef4(onSessionChange);
|
|
1656
|
+
const onErrorRef = useRef4(onError);
|
|
1657
|
+
const onTitleChangeRef = useRef4(onTitleChange);
|
|
1658
|
+
const generateTitleRef = useRef4(generateTitleCallback);
|
|
1659
|
+
const onPersonalizationChangeRef = useRef4(options.onPersonalizationChange);
|
|
1660
|
+
const onPersonalizationSaveRef = useRef4(options.onPersonalizationSave);
|
|
1661
|
+
const onLoadSessionsRef = useRef4(onLoadSessions);
|
|
1662
|
+
const onCreateSessionRef = useRef4(onCreateSession);
|
|
1663
|
+
const onLoadSessionRef = useRef4(onLoadSession);
|
|
1664
|
+
const onDeleteSessionCallbackRef = useRef4(onDeleteSessionCallback);
|
|
1665
|
+
const onUpdateSessionTitleRef = useRef4(onUpdateSessionTitle);
|
|
1666
|
+
const onSaveMessagesRef = useRef4(onSaveMessages);
|
|
1667
|
+
const onToolCallRef = useRef4(onToolCall);
|
|
1668
|
+
const onSkillCompleteRef = useRef4(onSkillComplete);
|
|
1669
|
+
const onLoadModelsRef = useRef4(onLoadModels);
|
|
1670
|
+
useEffect3(() => {
|
|
1671
|
+
onSendMessageRef.current = onSendMessage;
|
|
1672
|
+
onSessionChangeRef.current = onSessionChange;
|
|
1673
|
+
onErrorRef.current = onError;
|
|
1674
|
+
onTitleChangeRef.current = onTitleChange;
|
|
1675
|
+
generateTitleRef.current = generateTitleCallback;
|
|
1676
|
+
onPersonalizationChangeRef.current = options.onPersonalizationChange;
|
|
1677
|
+
onPersonalizationSaveRef.current = options.onPersonalizationSave;
|
|
1678
|
+
onLoadSessionsRef.current = onLoadSessions;
|
|
1679
|
+
onCreateSessionRef.current = onCreateSession;
|
|
1680
|
+
onLoadSessionRef.current = onLoadSession;
|
|
1681
|
+
onDeleteSessionCallbackRef.current = onDeleteSessionCallback;
|
|
1682
|
+
onUpdateSessionTitleRef.current = onUpdateSessionTitle;
|
|
1683
|
+
onSaveMessagesRef.current = onSaveMessages;
|
|
1684
|
+
onToolCallRef.current = onToolCall;
|
|
1685
|
+
onSkillCompleteRef.current = onSkillComplete;
|
|
1686
|
+
onLoadModelsRef.current = onLoadModels;
|
|
1687
|
+
});
|
|
1630
1688
|
const abortControllerRef = useRef4(null);
|
|
1631
1689
|
const skipNextPollParsingRef = useRef4(false);
|
|
1632
1690
|
const skipNextSkillParsingRef = useRef4(false);
|
|
@@ -1642,11 +1700,15 @@ var useChatUI = (options) => {
|
|
|
1642
1700
|
[globalMemoryConfig, storageKey]
|
|
1643
1701
|
);
|
|
1644
1702
|
const globalMemory = useGlobalMemoryEnabled ? useGlobalMemory(memoryOptions) : null;
|
|
1703
|
+
const stableToolCall = useCallback5(
|
|
1704
|
+
(name, params) => onToolCallRef.current(name, params),
|
|
1705
|
+
[]
|
|
1706
|
+
);
|
|
1645
1707
|
const mergedSkills = useMemo2(() => {
|
|
1646
1708
|
if (!tools || !onToolCall) return skills || {};
|
|
1647
|
-
const toolSkills = convertToolsToSkills(tools,
|
|
1709
|
+
const toolSkills = convertToolsToSkills(tools, stableToolCall);
|
|
1648
1710
|
return { ...skills || {}, ...toolSkills };
|
|
1649
|
-
}, [skills, tools, onToolCall]);
|
|
1711
|
+
}, [skills, tools, !!onToolCall, stableToolCall]);
|
|
1650
1712
|
const {
|
|
1651
1713
|
buildSkillsPrompt,
|
|
1652
1714
|
handleSkillCall,
|
|
@@ -1700,9 +1762,9 @@ var useChatUI = (options) => {
|
|
|
1700
1762
|
}, [sessions, enableProjects, projectHook.currentProjectId]);
|
|
1701
1763
|
useEffect3(() => {
|
|
1702
1764
|
if (typeof window === "undefined") return;
|
|
1703
|
-
if (useExternalStorage &&
|
|
1765
|
+
if (useExternalStorage && onLoadSessionsRef.current) {
|
|
1704
1766
|
setIsSessionsLoading(true);
|
|
1705
|
-
|
|
1767
|
+
onLoadSessionsRef.current().then((sessionList) => {
|
|
1706
1768
|
const sessionsWithoutMessages = sessionList.map((s) => ({
|
|
1707
1769
|
id: s.id,
|
|
1708
1770
|
title: s.title,
|
|
@@ -1718,15 +1780,17 @@ var useChatUI = (options) => {
|
|
|
1718
1780
|
setCurrentSessionId(targetId);
|
|
1719
1781
|
}
|
|
1720
1782
|
}).catch((error) => {
|
|
1721
|
-
|
|
1783
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to load sessions"));
|
|
1722
1784
|
}).finally(() => {
|
|
1723
1785
|
setIsSessionsLoading(false);
|
|
1724
1786
|
});
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1787
|
+
if (typeof window !== "undefined") {
|
|
1788
|
+
const savedPersonalization2 = localStorage.getItem(`${storageKey}_personalization`);
|
|
1789
|
+
if (savedPersonalization2) {
|
|
1790
|
+
try {
|
|
1791
|
+
setPersonalization(JSON.parse(savedPersonalization2));
|
|
1792
|
+
} catch {
|
|
1793
|
+
}
|
|
1730
1794
|
}
|
|
1731
1795
|
}
|
|
1732
1796
|
return;
|
|
@@ -1734,6 +1798,7 @@ var useChatUI = (options) => {
|
|
|
1734
1798
|
if (enableProjects) {
|
|
1735
1799
|
migrateSessionsToProjects(storageKey);
|
|
1736
1800
|
}
|
|
1801
|
+
if (typeof window === "undefined") return;
|
|
1737
1802
|
const saved = localStorage.getItem(storageKey);
|
|
1738
1803
|
if (saved) {
|
|
1739
1804
|
try {
|
|
@@ -1755,7 +1820,22 @@ var useChatUI = (options) => {
|
|
|
1755
1820
|
} catch {
|
|
1756
1821
|
}
|
|
1757
1822
|
}
|
|
1758
|
-
}, [storageKey, useExternalStorage,
|
|
1823
|
+
}, [storageKey, useExternalStorage, initialModel, models]);
|
|
1824
|
+
useEffect3(() => {
|
|
1825
|
+
if (!onLoadModelsRef.current) return;
|
|
1826
|
+
setIsModelsLoading(true);
|
|
1827
|
+
onLoadModelsRef.current().then((modelList) => {
|
|
1828
|
+
setLoadedModels(modelList);
|
|
1829
|
+
if (modelList.length > 0 && !modelList.find((m) => m.id === selectedModel)) {
|
|
1830
|
+
setSelectedModel(modelList[0].id);
|
|
1831
|
+
}
|
|
1832
|
+
}).catch((error) => {
|
|
1833
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to load models"));
|
|
1834
|
+
}).finally(() => {
|
|
1835
|
+
setIsModelsLoading(false);
|
|
1836
|
+
});
|
|
1837
|
+
}, []);
|
|
1838
|
+
const effectiveModels = loadedModels || models;
|
|
1759
1839
|
useEffect3(() => {
|
|
1760
1840
|
if (typeof window === "undefined") return;
|
|
1761
1841
|
if (useExternalStorage) return;
|
|
@@ -1768,8 +1848,8 @@ var useChatUI = (options) => {
|
|
|
1768
1848
|
localStorage.setItem(`${storageKey}_personalization`, JSON.stringify(personalization));
|
|
1769
1849
|
}, [personalization, storageKey]);
|
|
1770
1850
|
useEffect3(() => {
|
|
1771
|
-
|
|
1772
|
-
}, [currentSession
|
|
1851
|
+
onSessionChangeRef.current?.(currentSession);
|
|
1852
|
+
}, [currentSession]);
|
|
1773
1853
|
const buildSystemPrompt = useCallback5(() => {
|
|
1774
1854
|
const parts = [];
|
|
1775
1855
|
const { userProfile, responseStyle, language } = personalization;
|
|
@@ -1975,10 +2055,10 @@ ${newConversation}
|
|
|
1975
2055
|
}, []);
|
|
1976
2056
|
const newSession = useCallback5(async () => {
|
|
1977
2057
|
const projectId = enableProjects ? projectHook.currentProjectId || DEFAULT_PROJECT_ID : void 0;
|
|
1978
|
-
if (useExternalStorage &&
|
|
2058
|
+
if (useExternalStorage && onCreateSessionRef.current) {
|
|
1979
2059
|
setIsSessionLoading(true);
|
|
1980
2060
|
try {
|
|
1981
|
-
const created = await
|
|
2061
|
+
const created = await onCreateSessionRef.current();
|
|
1982
2062
|
const now2 = Date.now();
|
|
1983
2063
|
const newSess2 = {
|
|
1984
2064
|
id: created.id,
|
|
@@ -1992,7 +2072,7 @@ ${newConversation}
|
|
|
1992
2072
|
setSessions((prev) => [newSess2, ...prev]);
|
|
1993
2073
|
setCurrentSessionId(newSess2.id);
|
|
1994
2074
|
} catch (error) {
|
|
1995
|
-
|
|
2075
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to create session"));
|
|
1996
2076
|
} finally {
|
|
1997
2077
|
setIsSessionLoading(false);
|
|
1998
2078
|
}
|
|
@@ -2010,12 +2090,12 @@ ${newConversation}
|
|
|
2010
2090
|
};
|
|
2011
2091
|
setSessions((prev) => [newSess, ...prev]);
|
|
2012
2092
|
setCurrentSessionId(newSess.id);
|
|
2013
|
-
}, [selectedModel, useExternalStorage,
|
|
2093
|
+
}, [selectedModel, useExternalStorage, enableProjects, projectHook.currentProjectId]);
|
|
2014
2094
|
const selectSession = useCallback5(async (id) => {
|
|
2015
|
-
if (useExternalStorage &&
|
|
2095
|
+
if (useExternalStorage && onLoadSessionRef.current) {
|
|
2016
2096
|
setIsSessionLoading(true);
|
|
2017
2097
|
try {
|
|
2018
|
-
const sessionDetail = await
|
|
2098
|
+
const sessionDetail = await onLoadSessionRef.current(id);
|
|
2019
2099
|
let loadedMessages = sessionDetail.messages.map((m, idx) => ({
|
|
2020
2100
|
id: m.id || generateId3("msg"),
|
|
2021
2101
|
role: typeof m.role === "string" ? m.role.toLowerCase() : m.role,
|
|
@@ -2061,7 +2141,7 @@ ${newConversation}
|
|
|
2061
2141
|
setSelectedModel(existingSession.model);
|
|
2062
2142
|
}
|
|
2063
2143
|
} catch (error) {
|
|
2064
|
-
|
|
2144
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to load session"));
|
|
2065
2145
|
const cached = readSessionCache(storageKey, id);
|
|
2066
2146
|
if (cached && cached.messages.length > 0) {
|
|
2067
2147
|
console.warn("[useChatUI] onLoadSession failed, using localStorage cache");
|
|
@@ -2086,11 +2166,11 @@ ${newConversation}
|
|
|
2086
2166
|
setCurrentSessionId(id);
|
|
2087
2167
|
setSelectedModel(session.model);
|
|
2088
2168
|
}
|
|
2089
|
-
}, [sessions, useExternalStorage,
|
|
2169
|
+
}, [sessions, useExternalStorage, storageKey, initialModel, models]);
|
|
2090
2170
|
const deleteSession = useCallback5(async (id) => {
|
|
2091
|
-
if (useExternalStorage &&
|
|
2171
|
+
if (useExternalStorage && onDeleteSessionCallbackRef.current) {
|
|
2092
2172
|
try {
|
|
2093
|
-
await
|
|
2173
|
+
await onDeleteSessionCallbackRef.current(id);
|
|
2094
2174
|
removeSessionCache(storageKey, id);
|
|
2095
2175
|
setSessions((prev) => {
|
|
2096
2176
|
const filtered = prev.filter((s) => s.id !== id);
|
|
@@ -2100,7 +2180,7 @@ ${newConversation}
|
|
|
2100
2180
|
return filtered;
|
|
2101
2181
|
});
|
|
2102
2182
|
} catch (error) {
|
|
2103
|
-
|
|
2183
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to delete session"));
|
|
2104
2184
|
}
|
|
2105
2185
|
return;
|
|
2106
2186
|
}
|
|
@@ -2114,20 +2194,20 @@ ${newConversation}
|
|
|
2114
2194
|
}
|
|
2115
2195
|
return filtered;
|
|
2116
2196
|
});
|
|
2117
|
-
}, [currentSessionId, storageKey, useExternalStorage
|
|
2197
|
+
}, [currentSessionId, storageKey, useExternalStorage]);
|
|
2118
2198
|
const renameSession = useCallback5(async (id, newTitle) => {
|
|
2119
2199
|
if (!newTitle.trim()) return;
|
|
2120
|
-
if (useExternalStorage &&
|
|
2200
|
+
if (useExternalStorage && onUpdateSessionTitleRef.current) {
|
|
2121
2201
|
try {
|
|
2122
|
-
await
|
|
2202
|
+
await onUpdateSessionTitleRef.current(id, newTitle.trim());
|
|
2123
2203
|
setSessions(
|
|
2124
2204
|
(prev) => prev.map(
|
|
2125
2205
|
(s) => s.id === id ? { ...s, title: newTitle.trim(), updatedAt: Date.now() } : s
|
|
2126
2206
|
)
|
|
2127
2207
|
);
|
|
2128
|
-
|
|
2208
|
+
onTitleChangeRef.current?.(id, newTitle.trim());
|
|
2129
2209
|
} catch (error) {
|
|
2130
|
-
|
|
2210
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to update session title"));
|
|
2131
2211
|
}
|
|
2132
2212
|
return;
|
|
2133
2213
|
}
|
|
@@ -2136,8 +2216,8 @@ ${newConversation}
|
|
|
2136
2216
|
(s) => s.id === id ? { ...s, title: newTitle.trim(), updatedAt: Date.now() } : s
|
|
2137
2217
|
)
|
|
2138
2218
|
);
|
|
2139
|
-
|
|
2140
|
-
}, [
|
|
2219
|
+
onTitleChangeRef.current?.(id, newTitle.trim());
|
|
2220
|
+
}, [useExternalStorage]);
|
|
2141
2221
|
const setModel = useCallback5((model) => {
|
|
2142
2222
|
setSelectedModel(model);
|
|
2143
2223
|
if (currentSessionId) {
|
|
@@ -2171,13 +2251,13 @@ ${newConversation}
|
|
|
2171
2251
|
const updatePersonalization = useCallback5((config) => {
|
|
2172
2252
|
setPersonalization((prev) => {
|
|
2173
2253
|
const next = { ...prev, ...config };
|
|
2174
|
-
|
|
2254
|
+
onPersonalizationChangeRef.current?.(next);
|
|
2175
2255
|
return next;
|
|
2176
2256
|
});
|
|
2177
|
-
}, [
|
|
2257
|
+
}, []);
|
|
2178
2258
|
const savePersonalization = useCallback5(() => {
|
|
2179
|
-
|
|
2180
|
-
}, [
|
|
2259
|
+
onPersonalizationSaveRef.current?.(personalization);
|
|
2260
|
+
}, [personalization]);
|
|
2181
2261
|
const addAttachments = useCallback5((files) => {
|
|
2182
2262
|
const newAttachments = files.map((file) => {
|
|
2183
2263
|
const isImage = file.type.startsWith("image/");
|
|
@@ -2210,9 +2290,9 @@ ${newConversation}
|
|
|
2210
2290
|
if (!messageContent.trim() || isLoading) return;
|
|
2211
2291
|
let sessionId = currentSessionId;
|
|
2212
2292
|
if (!sessionId) {
|
|
2213
|
-
if (useExternalStorage &&
|
|
2293
|
+
if (useExternalStorage && onCreateSessionRef.current) {
|
|
2214
2294
|
try {
|
|
2215
|
-
const created = await
|
|
2295
|
+
const created = await onCreateSessionRef.current();
|
|
2216
2296
|
const now = Date.now();
|
|
2217
2297
|
const newSess = {
|
|
2218
2298
|
id: created.id,
|
|
@@ -2226,7 +2306,7 @@ ${newConversation}
|
|
|
2226
2306
|
sessionId = newSess.id;
|
|
2227
2307
|
setCurrentSessionId(sessionId);
|
|
2228
2308
|
} catch (error) {
|
|
2229
|
-
|
|
2309
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to create session"));
|
|
2230
2310
|
setIsLoading(false);
|
|
2231
2311
|
return;
|
|
2232
2312
|
}
|
|
@@ -2279,13 +2359,66 @@ ${finalContent}`;
|
|
|
2279
2359
|
...isHidden && { hidden: true },
|
|
2280
2360
|
...userContentParts && { contentParts: userContentParts }
|
|
2281
2361
|
};
|
|
2362
|
+
let attachmentResults = [];
|
|
2363
|
+
if (currentAttachments.length > 0) {
|
|
2364
|
+
const attachmentSkills = Object.entries(resolvedSkills).filter(
|
|
2365
|
+
([, config]) => config.trigger === "attachment"
|
|
2366
|
+
);
|
|
2367
|
+
for (const [skillName, skillConfig] of attachmentSkills) {
|
|
2368
|
+
const matchedFiles = currentAttachments.filter((att) => {
|
|
2369
|
+
if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
|
|
2370
|
+
return skillConfig.acceptedTypes.some((type) => {
|
|
2371
|
+
if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
|
|
2372
|
+
if (type.includes("*")) {
|
|
2373
|
+
const regex = new RegExp("^" + type.replace("*", ".*") + "$");
|
|
2374
|
+
return regex.test(att.mimeType);
|
|
2375
|
+
}
|
|
2376
|
+
return att.mimeType === type;
|
|
2377
|
+
});
|
|
2378
|
+
});
|
|
2379
|
+
if (matchedFiles.length === 0) continue;
|
|
2380
|
+
try {
|
|
2381
|
+
const filesToPass = skillConfig.autoConvertBase64 ? await convertAttachmentsToBase64(matchedFiles) : matchedFiles;
|
|
2382
|
+
const result = await skillConfig.execute({ files: filesToPass, userMessage: finalContent });
|
|
2383
|
+
attachmentResults.push({
|
|
2384
|
+
type: "tool_result",
|
|
2385
|
+
toolName: skillName,
|
|
2386
|
+
label: skillConfig.label,
|
|
2387
|
+
icon: skillConfig.icon,
|
|
2388
|
+
result: {
|
|
2389
|
+
type: "text",
|
|
2390
|
+
content: result.content,
|
|
2391
|
+
metadata: result.metadata,
|
|
2392
|
+
sources: result.sources
|
|
2393
|
+
}
|
|
2394
|
+
});
|
|
2395
|
+
} catch (error) {
|
|
2396
|
+
console.error(`[useChatUI] attachment skill ${skillName} failed:`, error);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
let shouldContinueAfterAttachment = continueAfterToolResult;
|
|
2401
|
+
if (attachmentResults.length > 0) {
|
|
2402
|
+
for (const part of attachmentResults) {
|
|
2403
|
+
if (part.type === "tool_result" && onSkillCompleteRef.current) {
|
|
2404
|
+
const decision = onSkillCompleteRef.current(part.toolName, {
|
|
2405
|
+
content: part.result.content,
|
|
2406
|
+
metadata: part.result.metadata,
|
|
2407
|
+
sources: part.result.sources
|
|
2408
|
+
});
|
|
2409
|
+
shouldContinueAfterAttachment = decision === "continue";
|
|
2410
|
+
if (!shouldContinueAfterAttachment) break;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2282
2414
|
const assistantMessageId = generateId3("msg");
|
|
2283
2415
|
const assistantMessage = {
|
|
2284
2416
|
id: assistantMessageId,
|
|
2285
2417
|
role: "assistant",
|
|
2286
2418
|
content: "",
|
|
2287
2419
|
model: selectedModel,
|
|
2288
|
-
timestamp: Date.now()
|
|
2420
|
+
timestamp: Date.now(),
|
|
2421
|
+
...attachmentResults.length > 0 && { contentParts: attachmentResults }
|
|
2289
2422
|
};
|
|
2290
2423
|
setInput("");
|
|
2291
2424
|
setQuotedText(null);
|
|
@@ -2312,19 +2445,23 @@ ${finalContent}`;
|
|
|
2312
2445
|
return s;
|
|
2313
2446
|
})
|
|
2314
2447
|
);
|
|
2315
|
-
if (isFirstMessage &&
|
|
2316
|
-
Promise.resolve(
|
|
2448
|
+
if (isFirstMessage && generateTitleRef.current) {
|
|
2449
|
+
Promise.resolve(generateTitleRef.current(finalContent)).then((generatedTitle) => {
|
|
2317
2450
|
if (generatedTitle && generatedTitle.trim()) {
|
|
2318
2451
|
setSessions(
|
|
2319
2452
|
(prev) => prev.map(
|
|
2320
2453
|
(s) => s.id === capturedSessionId ? { ...s, title: generatedTitle.trim(), updatedAt: Date.now() } : s
|
|
2321
2454
|
)
|
|
2322
2455
|
);
|
|
2323
|
-
|
|
2456
|
+
onTitleChangeRef.current?.(capturedSessionId, generatedTitle.trim());
|
|
2324
2457
|
}
|
|
2325
2458
|
}).catch(() => {
|
|
2326
2459
|
});
|
|
2327
2460
|
}
|
|
2461
|
+
if (attachmentResults.length > 0 && !shouldContinueAfterAttachment) {
|
|
2462
|
+
setIsLoading(false);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2328
2465
|
setIsLoading(true);
|
|
2329
2466
|
abortControllerRef.current = new AbortController();
|
|
2330
2467
|
try {
|
|
@@ -2384,6 +2521,20 @@ ${currentContextSummary}` },
|
|
|
2384
2521
|
} else {
|
|
2385
2522
|
chatMessages = messagesToSend.map((m) => ({ role: m.role, content: m.content }));
|
|
2386
2523
|
}
|
|
2524
|
+
if (attachmentResults.length > 0 && shouldContinueAfterAttachment) {
|
|
2525
|
+
const attachmentContext = attachmentResults.filter((part) => part.type === "tool_result").map((part) => `[${part.label || part.toolName} \uACB0\uACFC]
|
|
2526
|
+
${part.result.content}`).join("\n\n");
|
|
2527
|
+
if (attachmentContext) {
|
|
2528
|
+
chatMessages.push({
|
|
2529
|
+
role: "user",
|
|
2530
|
+
content: `\uD30C\uC77C \uBD84\uC11D \uACB0\uACFC:
|
|
2531
|
+
|
|
2532
|
+
${attachmentContext}
|
|
2533
|
+
|
|
2534
|
+
\uC704 \uACB0\uACFC\uB97C \uCC38\uACE0\uD558\uC5EC \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694.`
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2387
2538
|
console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content: m.content.slice(0, 50) })));
|
|
2388
2539
|
const baseSystemPrompt = buildSystemPrompt();
|
|
2389
2540
|
const combinedSystemPrompt = [baseSystemPrompt, actionPrompt].filter(Boolean).join("\n\n");
|
|
@@ -2648,6 +2799,16 @@ ${currentContextSummary}` },
|
|
|
2648
2799
|
abortControllerRef.current = null;
|
|
2649
2800
|
return;
|
|
2650
2801
|
}
|
|
2802
|
+
let shouldContinue = continueAfterToolResult;
|
|
2803
|
+
if (onSkillCompleteRef.current) {
|
|
2804
|
+
const decision = onSkillCompleteRef.current(toolName, result);
|
|
2805
|
+
shouldContinue = decision === "continue";
|
|
2806
|
+
}
|
|
2807
|
+
if (!shouldContinue) {
|
|
2808
|
+
setIsLoading(false);
|
|
2809
|
+
abortControllerRef.current = null;
|
|
2810
|
+
return;
|
|
2811
|
+
}
|
|
2651
2812
|
skipNextSkillParsingRef.current = true;
|
|
2652
2813
|
const feedbackPrompt = resultType === "error" ? `\uB3C4\uAD6C "${toolName}" \uC2E4\uD589 \uC911 \uC624\uB958 \uBC1C\uC0DD: ${result.content}
|
|
2653
2814
|
|
|
@@ -2688,6 +2849,16 @@ ${result.content}
|
|
|
2688
2849
|
abortControllerRef.current = null;
|
|
2689
2850
|
return;
|
|
2690
2851
|
}
|
|
2852
|
+
let shouldContinueSkill = continueAfterToolResult;
|
|
2853
|
+
if (onSkillCompleteRef.current) {
|
|
2854
|
+
const decision = onSkillCompleteRef.current(detectedSkill.name, result);
|
|
2855
|
+
shouldContinueSkill = decision === "continue";
|
|
2856
|
+
}
|
|
2857
|
+
if (!shouldContinueSkill) {
|
|
2858
|
+
setIsLoading(false);
|
|
2859
|
+
abortControllerRef.current = null;
|
|
2860
|
+
return;
|
|
2861
|
+
}
|
|
2691
2862
|
skipNextSkillParsingRef.current = true;
|
|
2692
2863
|
const resultPrompt = `\uC2A4\uD0AC "${detectedSkill.name}" \uC2E4\uD589 \uACB0\uACFC:
|
|
2693
2864
|
|
|
@@ -2727,7 +2898,7 @@ ${result.content}
|
|
|
2727
2898
|
);
|
|
2728
2899
|
if (useExternalStorage && capturedSessionId) {
|
|
2729
2900
|
const assistantContentForSave = accumulatedContent;
|
|
2730
|
-
if (assistantContentForSave &&
|
|
2901
|
+
if (assistantContentForSave && onSaveMessagesRef.current) {
|
|
2731
2902
|
const latestSession = sessionsRef.current.find((s) => s.id === capturedSessionId);
|
|
2732
2903
|
const latestMessages = latestSession?.messages || [];
|
|
2733
2904
|
const userMsg = latestMessages.find((m) => m.role === "user" && m.content === finalContent);
|
|
@@ -2736,7 +2907,7 @@ ${result.content}
|
|
|
2736
2907
|
{ role: "user", message: finalContent, ...userMsg?.contentParts && { contentParts: userMsg.contentParts } },
|
|
2737
2908
|
{ role: "assistant", message: assistantContentForSave, ...assistantMsg?.contentParts && { contentParts: assistantMsg.contentParts } }
|
|
2738
2909
|
];
|
|
2739
|
-
|
|
2910
|
+
onSaveMessagesRef.current(capturedSessionId, messagesToSave).catch((saveError) => {
|
|
2740
2911
|
console.error("[useChatUI] Failed to save messages:", saveError);
|
|
2741
2912
|
});
|
|
2742
2913
|
}
|
|
@@ -2764,7 +2935,7 @@ ${result.content}
|
|
|
2764
2935
|
return;
|
|
2765
2936
|
}
|
|
2766
2937
|
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
2767
|
-
|
|
2938
|
+
onErrorRef.current?.(err);
|
|
2768
2939
|
setSessions(
|
|
2769
2940
|
(prev) => prev.map((s) => {
|
|
2770
2941
|
if (s.id === capturedSessionId) {
|
|
@@ -3037,11 +3208,11 @@ ${formattedParts.join("\n")}
|
|
|
3037
3208
|
return;
|
|
3038
3209
|
}
|
|
3039
3210
|
console.error("[ChatUI] Regenerate error:", error);
|
|
3040
|
-
|
|
3211
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Unknown error"));
|
|
3041
3212
|
} finally {
|
|
3042
3213
|
setIsLoading(false);
|
|
3043
3214
|
}
|
|
3044
|
-
}, [currentSession, currentSessionId, isLoading, selectedModel, models, apiEndpoint, apiKey, buildSystemPrompt
|
|
3215
|
+
}, [currentSession, currentSessionId, isLoading, selectedModel, models, apiEndpoint, apiKey, buildSystemPrompt]);
|
|
3045
3216
|
const askOtherModel = useCallback5(async (messageId, targetModel) => {
|
|
3046
3217
|
if (!currentSession || !currentSessionId || isLoading) return;
|
|
3047
3218
|
const assistantIndex = currentSession.messages.findIndex((m) => m.id === messageId);
|
|
@@ -3193,7 +3364,7 @@ ${currentSession.contextSummary}` },
|
|
|
3193
3364
|
return;
|
|
3194
3365
|
}
|
|
3195
3366
|
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
3196
|
-
|
|
3367
|
+
onErrorRef.current?.(err);
|
|
3197
3368
|
} finally {
|
|
3198
3369
|
setIsLoading(false);
|
|
3199
3370
|
setLoadingAlternativeFor(null);
|
|
@@ -3262,7 +3433,8 @@ ${currentSession.contextSummary}` },
|
|
|
3262
3433
|
getActiveAlternative,
|
|
3263
3434
|
updatePersonalization,
|
|
3264
3435
|
savePersonalization,
|
|
3265
|
-
models,
|
|
3436
|
+
models: effectiveModels,
|
|
3437
|
+
isModelsLoading,
|
|
3266
3438
|
// Memory
|
|
3267
3439
|
globalMemory,
|
|
3268
3440
|
compressionState,
|
|
@@ -3350,7 +3522,25 @@ ${currentSession.contextSummary}` },
|
|
|
3350
3522
|
systemPrompt: `\uC0AC\uC6A9\uC790\uAC00 "${toolConfig.label || skillName}" \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uB824\uACE0 \uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC758 \uBA54\uC2DC\uC9C0\uB97C \uBC14\uD0D5\uC73C\uB85C \uBC18\uB4DC\uC2DC <skill_use name="${skillName}"> \uD0DC\uADF8\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC774 \uB3C4\uAD6C\uB97C \uD638\uCD9C\uD558\uC138\uC694. \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uACE0 \uD14D\uC2A4\uD2B8\uB85C\uB9CC \uB2F5\uBCC0\uD558\uC9C0 \uB9C8\uC138\uC694.`
|
|
3351
3523
|
});
|
|
3352
3524
|
} else {
|
|
3353
|
-
|
|
3525
|
+
const currentQuery = input;
|
|
3526
|
+
executeManualSkill(skillName, { query: currentQuery }).then((result) => {
|
|
3527
|
+
if (!result || !result.content) return;
|
|
3528
|
+
let shouldContinue = continueAfterToolResult;
|
|
3529
|
+
if (onSkillCompleteRef.current) {
|
|
3530
|
+
const decision = onSkillCompleteRef.current(skillName, result);
|
|
3531
|
+
shouldContinue = decision === "continue";
|
|
3532
|
+
}
|
|
3533
|
+
if (!shouldContinue) return;
|
|
3534
|
+
skipNextSkillParsingRef.current = true;
|
|
3535
|
+
const resultPrompt = `\uC2A4\uD0AC "${skillName}" \uC2E4\uD589 \uACB0\uACFC:
|
|
3536
|
+
|
|
3537
|
+
${result.content}
|
|
3538
|
+
|
|
3539
|
+
\uC704 \uACB0\uACFC\uB97C \uBC14\uD0D5\uC73C\uB85C \uC0AC\uC6A9\uC790\uC758 \uC6D0\uB798 \uC9C8\uBB38\uC5D0 \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
|
|
3540
|
+
setTimeout(() => {
|
|
3541
|
+
sendMessage(resultPrompt, { hiddenUserMessage: true });
|
|
3542
|
+
}, 100);
|
|
3543
|
+
});
|
|
3354
3544
|
}
|
|
3355
3545
|
},
|
|
3356
3546
|
// Project
|
|
@@ -3375,8 +3565,8 @@ ${currentSession.contextSummary}` },
|
|
|
3375
3565
|
if (!enableProjects) return;
|
|
3376
3566
|
const projectSessions = sessionsRef.current.filter((s) => s.projectId === projectId);
|
|
3377
3567
|
for (const sess of projectSessions) {
|
|
3378
|
-
if (useExternalStorage &&
|
|
3379
|
-
await
|
|
3568
|
+
if (useExternalStorage && onDeleteSessionCallbackRef.current) {
|
|
3569
|
+
await onDeleteSessionCallbackRef.current(sess.id).catch(() => {
|
|
3380
3570
|
});
|
|
3381
3571
|
}
|
|
3382
3572
|
removeSessionCache(storageKey, sess.id);
|
|
@@ -3736,7 +3926,8 @@ var ChatSidebar = ({
|
|
|
3736
3926
|
onNewProject,
|
|
3737
3927
|
onProjectSettings,
|
|
3738
3928
|
renderAfterHeader,
|
|
3739
|
-
renderFooter
|
|
3929
|
+
renderFooter,
|
|
3930
|
+
isLoading = false
|
|
3740
3931
|
}) => {
|
|
3741
3932
|
const sidebarWidth = typeof widthProp === "number" ? `${widthProp}px` : widthProp || "288px";
|
|
3742
3933
|
const [editingId, setEditingId] = useState7(null);
|
|
@@ -3780,6 +3971,7 @@ var ChatSidebar = ({
|
|
|
3780
3971
|
className: `chatllm-sidebar chatllm-sidebar-transition ${theme ? `chatllm-root ${themeClass}` : ""}`,
|
|
3781
3972
|
style: {
|
|
3782
3973
|
width: isOpen ? sidebarWidth : "0",
|
|
3974
|
+
height: "100%",
|
|
3783
3975
|
flexShrink: 0,
|
|
3784
3976
|
backgroundColor: "var(--chatllm-sidebar-bg)",
|
|
3785
3977
|
borderRight: isOpen ? "1px solid var(--chatllm-border)" : "none",
|
|
@@ -3884,7 +4076,22 @@ var ChatSidebar = ({
|
|
|
3884
4076
|
display: "flex",
|
|
3885
4077
|
flexDirection: "column"
|
|
3886
4078
|
},
|
|
3887
|
-
children:
|
|
4079
|
+
children: isLoading ? (
|
|
4080
|
+
/* Skeleton Loading State */
|
|
4081
|
+
/* @__PURE__ */ jsx3("div", { style: { display: "flex", flexDirection: "column", gap: "8px", padding: "0 4px" }, children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx3(
|
|
4082
|
+
"div",
|
|
4083
|
+
{
|
|
4084
|
+
className: "chatllm-skeleton-pulse",
|
|
4085
|
+
style: {
|
|
4086
|
+
height: "48px",
|
|
4087
|
+
borderRadius: "8px",
|
|
4088
|
+
backgroundColor: "var(--chatllm-bg-tertiary)",
|
|
4089
|
+
opacity: 1 - (i - 1) * 0.15
|
|
4090
|
+
}
|
|
4091
|
+
},
|
|
4092
|
+
i
|
|
4093
|
+
)) })
|
|
4094
|
+
) : sessions.length === 0 ? (
|
|
3888
4095
|
/* Empty State */
|
|
3889
4096
|
/* @__PURE__ */ jsxs2(
|
|
3890
4097
|
"div",
|
|
@@ -4827,6 +5034,16 @@ var ChatInput = ({
|
|
|
4827
5034
|
}
|
|
4828
5035
|
)
|
|
4829
5036
|
] }),
|
|
5037
|
+
/* @__PURE__ */ jsx5(
|
|
5038
|
+
"button",
|
|
5039
|
+
{
|
|
5040
|
+
onClick: () => fileInputRef.current?.click(),
|
|
5041
|
+
style: iconButtonStyle,
|
|
5042
|
+
title: "\uD30C\uC77C \uCCA8\uBD80",
|
|
5043
|
+
"aria-label": "\uD30C\uC77C \uCCA8\uBD80",
|
|
5044
|
+
children: /* @__PURE__ */ jsx5(IconSvg, { name: "attachment-line", size: 22, color: "var(--chatllm-text-muted)" })
|
|
5045
|
+
}
|
|
5046
|
+
),
|
|
4830
5047
|
/* @__PURE__ */ jsxs4("div", { ref: mainMenuRef, style: { position: "relative" }, children: [
|
|
4831
5048
|
/* @__PURE__ */ jsx5(
|
|
4832
5049
|
"button",
|
|
@@ -6812,6 +7029,7 @@ var PollCard = ({
|
|
|
6812
7029
|
onSkip?.();
|
|
6813
7030
|
}, [questions, onSubmit, onSkip]);
|
|
6814
7031
|
useEffect7(() => {
|
|
7032
|
+
if (typeof window === "undefined") return;
|
|
6815
7033
|
const handleKeyDown = (e) => {
|
|
6816
7034
|
if (e.key === "Escape") handleSkip();
|
|
6817
7035
|
};
|
|
@@ -7756,7 +7974,7 @@ var MessageBubble = ({
|
|
|
7756
7974
|
const displaySources = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.sources : message.sources;
|
|
7757
7975
|
const handleMouseUp = () => {
|
|
7758
7976
|
if (!onQuote) return;
|
|
7759
|
-
const selection = window.getSelection();
|
|
7977
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
7760
7978
|
const text = selection?.toString().trim();
|
|
7761
7979
|
if (text && text.length > 0) {
|
|
7762
7980
|
}
|
|
@@ -8371,7 +8589,7 @@ var MessageList = ({
|
|
|
8371
8589
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
8372
8590
|
}, [messages]);
|
|
8373
8591
|
const handleMouseUp = useCallback8(() => {
|
|
8374
|
-
const selection = window.getSelection();
|
|
8592
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
8375
8593
|
const text = selection?.toString().trim();
|
|
8376
8594
|
if (text && text.length > 0) {
|
|
8377
8595
|
const range = selection?.getRangeAt(0);
|
|
@@ -8387,7 +8605,7 @@ var MessageList = ({
|
|
|
8387
8605
|
}
|
|
8388
8606
|
} else {
|
|
8389
8607
|
setTimeout(() => {
|
|
8390
|
-
const currentSelection = window.getSelection()?.toString().trim();
|
|
8608
|
+
const currentSelection = typeof window !== "undefined" ? window.getSelection()?.toString().trim() : void 0;
|
|
8391
8609
|
if (!currentSelection) {
|
|
8392
8610
|
setSelectionPosition(null);
|
|
8393
8611
|
}
|
|
@@ -8399,7 +8617,9 @@ var MessageList = ({
|
|
|
8399
8617
|
onQuote(selectedText);
|
|
8400
8618
|
setSelectionPosition(null);
|
|
8401
8619
|
setSelectedText("");
|
|
8402
|
-
window
|
|
8620
|
+
if (typeof window !== "undefined") {
|
|
8621
|
+
window.getSelection()?.removeAllRanges();
|
|
8622
|
+
}
|
|
8403
8623
|
}
|
|
8404
8624
|
};
|
|
8405
8625
|
return /* @__PURE__ */ jsxs15(
|
|
@@ -9057,7 +9277,7 @@ var SettingsModal = ({
|
|
|
9057
9277
|
"button",
|
|
9058
9278
|
{
|
|
9059
9279
|
onClick: () => {
|
|
9060
|
-
if (window.confirm("\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9280
|
+
if (typeof window !== "undefined" && window.confirm("\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9061
9281
|
onClearAllData();
|
|
9062
9282
|
}
|
|
9063
9283
|
},
|
|
@@ -9328,7 +9548,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
|
|
|
9328
9548
|
"button",
|
|
9329
9549
|
{
|
|
9330
9550
|
onClick: () => {
|
|
9331
|
-
if (window.confirm("\uBAA8\uB4E0 AI \uBA54\uBAA8\uB9AC\uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9551
|
+
if (typeof window !== "undefined" && window.confirm("\uBAA8\uB4E0 AI \uBA54\uBAA8\uB9AC\uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9332
9552
|
onClearAll();
|
|
9333
9553
|
}
|
|
9334
9554
|
},
|
|
@@ -9575,7 +9795,7 @@ var ProjectSettingsModal = ({
|
|
|
9575
9795
|
"button",
|
|
9576
9796
|
{
|
|
9577
9797
|
onClick: () => {
|
|
9578
|
-
if (window.confirm(`"${project.title}" \uD504\uB85C\uC81D\uD2B8\uC640 \uC18C\uC18D \uB300\uD654\uAC00 \uBAA8\uB450 \uC0AD\uC81C\uB429\uB2C8\uB2E4. \uACC4\uC18D\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`)) {
|
|
9798
|
+
if (typeof window !== "undefined" && window.confirm(`"${project.title}" \uD504\uB85C\uC81D\uD2B8\uC640 \uC18C\uC18D \uB300\uD654\uAC00 \uBAA8\uB450 \uC0AD\uC81C\uB429\uB2C8\uB2E4. \uACC4\uC18D\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`)) {
|
|
9579
9799
|
onDeleteProject(project.id);
|
|
9580
9800
|
onClose();
|
|
9581
9801
|
}
|
|
@@ -10080,7 +10300,8 @@ var ChatUIView = ({
|
|
|
10080
10300
|
projectSettingsOpen,
|
|
10081
10301
|
openProjectSettings,
|
|
10082
10302
|
closeProjectSettings,
|
|
10083
|
-
projectMemory
|
|
10303
|
+
projectMemory,
|
|
10304
|
+
isSessionsLoading
|
|
10084
10305
|
} = state;
|
|
10085
10306
|
const greeting = currentPersonalization.userProfile.nickname ? `\uC548\uB155\uD558\uC138\uC694, ${currentPersonalization.userProfile.nickname}\uB2D8` : "\uC548\uB155\uD558\uC138\uC694";
|
|
10086
10307
|
const handleTemplateClick = (template) => {
|
|
@@ -10154,6 +10375,7 @@ var ChatUIView = ({
|
|
|
10154
10375
|
currentProjectId,
|
|
10155
10376
|
onSelectProject: projects.length > 0 ? selectProject : void 0,
|
|
10156
10377
|
onNewProject: projects.length > 0 ? () => {
|
|
10378
|
+
if (typeof window === "undefined") return;
|
|
10157
10379
|
const title = window.prompt("\uD504\uB85C\uC81D\uD2B8 \uC774\uB984\uC744 \uC785\uB825\uD558\uC138\uC694");
|
|
10158
10380
|
if (title?.trim()) {
|
|
10159
10381
|
createProject({ title: title.trim() });
|
|
@@ -10164,7 +10386,8 @@ var ChatUIView = ({
|
|
|
10164
10386
|
openProjectSettings();
|
|
10165
10387
|
} : void 0,
|
|
10166
10388
|
renderAfterHeader: sidebarRenderAfterHeader,
|
|
10167
|
-
renderFooter: sidebarRenderFooter
|
|
10389
|
+
renderFooter: sidebarRenderFooter,
|
|
10390
|
+
isLoading: isSessionsLoading
|
|
10168
10391
|
}
|
|
10169
10392
|
),
|
|
10170
10393
|
/* @__PURE__ */ jsxs19(
|
|
@@ -10336,6 +10559,9 @@ var ChatUIWithHook = ({
|
|
|
10336
10559
|
skills,
|
|
10337
10560
|
tools,
|
|
10338
10561
|
onToolCall,
|
|
10562
|
+
continueAfterToolResult,
|
|
10563
|
+
onSkillComplete,
|
|
10564
|
+
onLoadModels,
|
|
10339
10565
|
// Project options
|
|
10340
10566
|
enableProjects,
|
|
10341
10567
|
onLoadProjects,
|
|
@@ -10375,6 +10601,9 @@ var ChatUIWithHook = ({
|
|
|
10375
10601
|
skills,
|
|
10376
10602
|
tools,
|
|
10377
10603
|
onToolCall,
|
|
10604
|
+
continueAfterToolResult,
|
|
10605
|
+
onSkillComplete,
|
|
10606
|
+
onLoadModels,
|
|
10378
10607
|
enableProjects,
|
|
10379
10608
|
onLoadProjects,
|
|
10380
10609
|
onCreateProject,
|