@gendive/chatllm 0.16.0 → 0.17.0
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 +58 -1
- package/dist/react/index.d.ts +58 -1
- package/dist/react/index.js +301 -90
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +301 -90
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -1469,9 +1469,11 @@ 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,
|
|
1475
1477
|
parameters: {
|
|
1476
1478
|
type: "object",
|
|
1477
1479
|
properties: Object.fromEntries(
|
|
@@ -1596,7 +1598,12 @@ var useChatUI = (options) => {
|
|
|
1596
1598
|
onUpdateProject,
|
|
1597
1599
|
onDeleteProject,
|
|
1598
1600
|
onAddProjectFile,
|
|
1599
|
-
onDeleteProjectFile
|
|
1601
|
+
onDeleteProjectFile,
|
|
1602
|
+
// Stream control
|
|
1603
|
+
continueAfterToolResult = true,
|
|
1604
|
+
onSkillComplete,
|
|
1605
|
+
// Dynamic model loading
|
|
1606
|
+
onLoadModels
|
|
1600
1607
|
} = options;
|
|
1601
1608
|
const enableAutoExtraction = enableAutoExtractionProp ?? !useExternalStorage;
|
|
1602
1609
|
const [sessions, setSessions] = useState5([]);
|
|
@@ -1620,6 +1627,8 @@ var useChatUI = (options) => {
|
|
|
1620
1627
|
const [isSessionLoading, setIsSessionLoading] = useState5(false);
|
|
1621
1628
|
const [isDeepResearchMode, setIsDeepResearchMode] = useState5(false);
|
|
1622
1629
|
const [attachments, setAttachments] = useState5([]);
|
|
1630
|
+
const [isModelsLoading, setIsModelsLoading] = useState5(false);
|
|
1631
|
+
const [loadedModels, setLoadedModels] = useState5(null);
|
|
1623
1632
|
const [deepResearchProgress, setDeepResearchProgress] = useState5(
|
|
1624
1633
|
null
|
|
1625
1634
|
);
|
|
@@ -1627,6 +1636,40 @@ var useChatUI = (options) => {
|
|
|
1627
1636
|
useEffect3(() => {
|
|
1628
1637
|
sessionsRef.current = sessions;
|
|
1629
1638
|
}, [sessions]);
|
|
1639
|
+
const onSendMessageRef = useRef4(onSendMessage);
|
|
1640
|
+
const onSessionChangeRef = useRef4(onSessionChange);
|
|
1641
|
+
const onErrorRef = useRef4(onError);
|
|
1642
|
+
const onTitleChangeRef = useRef4(onTitleChange);
|
|
1643
|
+
const generateTitleRef = useRef4(generateTitleCallback);
|
|
1644
|
+
const onPersonalizationChangeRef = useRef4(options.onPersonalizationChange);
|
|
1645
|
+
const onPersonalizationSaveRef = useRef4(options.onPersonalizationSave);
|
|
1646
|
+
const onLoadSessionsRef = useRef4(onLoadSessions);
|
|
1647
|
+
const onCreateSessionRef = useRef4(onCreateSession);
|
|
1648
|
+
const onLoadSessionRef = useRef4(onLoadSession);
|
|
1649
|
+
const onDeleteSessionCallbackRef = useRef4(onDeleteSessionCallback);
|
|
1650
|
+
const onUpdateSessionTitleRef = useRef4(onUpdateSessionTitle);
|
|
1651
|
+
const onSaveMessagesRef = useRef4(onSaveMessages);
|
|
1652
|
+
const onToolCallRef = useRef4(onToolCall);
|
|
1653
|
+
const onSkillCompleteRef = useRef4(onSkillComplete);
|
|
1654
|
+
const onLoadModelsRef = useRef4(onLoadModels);
|
|
1655
|
+
useEffect3(() => {
|
|
1656
|
+
onSendMessageRef.current = onSendMessage;
|
|
1657
|
+
onSessionChangeRef.current = onSessionChange;
|
|
1658
|
+
onErrorRef.current = onError;
|
|
1659
|
+
onTitleChangeRef.current = onTitleChange;
|
|
1660
|
+
generateTitleRef.current = generateTitleCallback;
|
|
1661
|
+
onPersonalizationChangeRef.current = options.onPersonalizationChange;
|
|
1662
|
+
onPersonalizationSaveRef.current = options.onPersonalizationSave;
|
|
1663
|
+
onLoadSessionsRef.current = onLoadSessions;
|
|
1664
|
+
onCreateSessionRef.current = onCreateSession;
|
|
1665
|
+
onLoadSessionRef.current = onLoadSession;
|
|
1666
|
+
onDeleteSessionCallbackRef.current = onDeleteSessionCallback;
|
|
1667
|
+
onUpdateSessionTitleRef.current = onUpdateSessionTitle;
|
|
1668
|
+
onSaveMessagesRef.current = onSaveMessages;
|
|
1669
|
+
onToolCallRef.current = onToolCall;
|
|
1670
|
+
onSkillCompleteRef.current = onSkillComplete;
|
|
1671
|
+
onLoadModelsRef.current = onLoadModels;
|
|
1672
|
+
});
|
|
1630
1673
|
const abortControllerRef = useRef4(null);
|
|
1631
1674
|
const skipNextPollParsingRef = useRef4(false);
|
|
1632
1675
|
const skipNextSkillParsingRef = useRef4(false);
|
|
@@ -1642,11 +1685,15 @@ var useChatUI = (options) => {
|
|
|
1642
1685
|
[globalMemoryConfig, storageKey]
|
|
1643
1686
|
);
|
|
1644
1687
|
const globalMemory = useGlobalMemoryEnabled ? useGlobalMemory(memoryOptions) : null;
|
|
1688
|
+
const stableToolCall = useCallback5(
|
|
1689
|
+
(name, params) => onToolCallRef.current(name, params),
|
|
1690
|
+
[]
|
|
1691
|
+
);
|
|
1645
1692
|
const mergedSkills = useMemo2(() => {
|
|
1646
1693
|
if (!tools || !onToolCall) return skills || {};
|
|
1647
|
-
const toolSkills = convertToolsToSkills(tools,
|
|
1694
|
+
const toolSkills = convertToolsToSkills(tools, stableToolCall);
|
|
1648
1695
|
return { ...skills || {}, ...toolSkills };
|
|
1649
|
-
}, [skills, tools, onToolCall]);
|
|
1696
|
+
}, [skills, tools, !!onToolCall, stableToolCall]);
|
|
1650
1697
|
const {
|
|
1651
1698
|
buildSkillsPrompt,
|
|
1652
1699
|
handleSkillCall,
|
|
@@ -1700,9 +1747,9 @@ var useChatUI = (options) => {
|
|
|
1700
1747
|
}, [sessions, enableProjects, projectHook.currentProjectId]);
|
|
1701
1748
|
useEffect3(() => {
|
|
1702
1749
|
if (typeof window === "undefined") return;
|
|
1703
|
-
if (useExternalStorage &&
|
|
1750
|
+
if (useExternalStorage && onLoadSessionsRef.current) {
|
|
1704
1751
|
setIsSessionsLoading(true);
|
|
1705
|
-
|
|
1752
|
+
onLoadSessionsRef.current().then((sessionList) => {
|
|
1706
1753
|
const sessionsWithoutMessages = sessionList.map((s) => ({
|
|
1707
1754
|
id: s.id,
|
|
1708
1755
|
title: s.title,
|
|
@@ -1718,7 +1765,7 @@ var useChatUI = (options) => {
|
|
|
1718
1765
|
setCurrentSessionId(targetId);
|
|
1719
1766
|
}
|
|
1720
1767
|
}).catch((error) => {
|
|
1721
|
-
|
|
1768
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to load sessions"));
|
|
1722
1769
|
}).finally(() => {
|
|
1723
1770
|
setIsSessionsLoading(false);
|
|
1724
1771
|
});
|
|
@@ -1755,7 +1802,22 @@ var useChatUI = (options) => {
|
|
|
1755
1802
|
} catch {
|
|
1756
1803
|
}
|
|
1757
1804
|
}
|
|
1758
|
-
}, [storageKey, useExternalStorage,
|
|
1805
|
+
}, [storageKey, useExternalStorage, initialModel, models]);
|
|
1806
|
+
useEffect3(() => {
|
|
1807
|
+
if (!onLoadModelsRef.current) return;
|
|
1808
|
+
setIsModelsLoading(true);
|
|
1809
|
+
onLoadModelsRef.current().then((modelList) => {
|
|
1810
|
+
setLoadedModels(modelList);
|
|
1811
|
+
if (modelList.length > 0 && !modelList.find((m) => m.id === selectedModel)) {
|
|
1812
|
+
setSelectedModel(modelList[0].id);
|
|
1813
|
+
}
|
|
1814
|
+
}).catch((error) => {
|
|
1815
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to load models"));
|
|
1816
|
+
}).finally(() => {
|
|
1817
|
+
setIsModelsLoading(false);
|
|
1818
|
+
});
|
|
1819
|
+
}, []);
|
|
1820
|
+
const effectiveModels = loadedModels || models;
|
|
1759
1821
|
useEffect3(() => {
|
|
1760
1822
|
if (typeof window === "undefined") return;
|
|
1761
1823
|
if (useExternalStorage) return;
|
|
@@ -1768,8 +1830,8 @@ var useChatUI = (options) => {
|
|
|
1768
1830
|
localStorage.setItem(`${storageKey}_personalization`, JSON.stringify(personalization));
|
|
1769
1831
|
}, [personalization, storageKey]);
|
|
1770
1832
|
useEffect3(() => {
|
|
1771
|
-
|
|
1772
|
-
}, [currentSession
|
|
1833
|
+
onSessionChangeRef.current?.(currentSession);
|
|
1834
|
+
}, [currentSession]);
|
|
1773
1835
|
const buildSystemPrompt = useCallback5(() => {
|
|
1774
1836
|
const parts = [];
|
|
1775
1837
|
const { userProfile, responseStyle, language } = personalization;
|
|
@@ -1975,10 +2037,10 @@ ${newConversation}
|
|
|
1975
2037
|
}, []);
|
|
1976
2038
|
const newSession = useCallback5(async () => {
|
|
1977
2039
|
const projectId = enableProjects ? projectHook.currentProjectId || DEFAULT_PROJECT_ID : void 0;
|
|
1978
|
-
if (useExternalStorage &&
|
|
2040
|
+
if (useExternalStorage && onCreateSessionRef.current) {
|
|
1979
2041
|
setIsSessionLoading(true);
|
|
1980
2042
|
try {
|
|
1981
|
-
const created = await
|
|
2043
|
+
const created = await onCreateSessionRef.current();
|
|
1982
2044
|
const now2 = Date.now();
|
|
1983
2045
|
const newSess2 = {
|
|
1984
2046
|
id: created.id,
|
|
@@ -1992,7 +2054,7 @@ ${newConversation}
|
|
|
1992
2054
|
setSessions((prev) => [newSess2, ...prev]);
|
|
1993
2055
|
setCurrentSessionId(newSess2.id);
|
|
1994
2056
|
} catch (error) {
|
|
1995
|
-
|
|
2057
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to create session"));
|
|
1996
2058
|
} finally {
|
|
1997
2059
|
setIsSessionLoading(false);
|
|
1998
2060
|
}
|
|
@@ -2010,12 +2072,12 @@ ${newConversation}
|
|
|
2010
2072
|
};
|
|
2011
2073
|
setSessions((prev) => [newSess, ...prev]);
|
|
2012
2074
|
setCurrentSessionId(newSess.id);
|
|
2013
|
-
}, [selectedModel, useExternalStorage,
|
|
2075
|
+
}, [selectedModel, useExternalStorage, enableProjects, projectHook.currentProjectId]);
|
|
2014
2076
|
const selectSession = useCallback5(async (id) => {
|
|
2015
|
-
if (useExternalStorage &&
|
|
2077
|
+
if (useExternalStorage && onLoadSessionRef.current) {
|
|
2016
2078
|
setIsSessionLoading(true);
|
|
2017
2079
|
try {
|
|
2018
|
-
const sessionDetail = await
|
|
2080
|
+
const sessionDetail = await onLoadSessionRef.current(id);
|
|
2019
2081
|
let loadedMessages = sessionDetail.messages.map((m, idx) => ({
|
|
2020
2082
|
id: m.id || generateId3("msg"),
|
|
2021
2083
|
role: typeof m.role === "string" ? m.role.toLowerCase() : m.role,
|
|
@@ -2061,7 +2123,7 @@ ${newConversation}
|
|
|
2061
2123
|
setSelectedModel(existingSession.model);
|
|
2062
2124
|
}
|
|
2063
2125
|
} catch (error) {
|
|
2064
|
-
|
|
2126
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to load session"));
|
|
2065
2127
|
const cached = readSessionCache(storageKey, id);
|
|
2066
2128
|
if (cached && cached.messages.length > 0) {
|
|
2067
2129
|
console.warn("[useChatUI] onLoadSession failed, using localStorage cache");
|
|
@@ -2086,11 +2148,11 @@ ${newConversation}
|
|
|
2086
2148
|
setCurrentSessionId(id);
|
|
2087
2149
|
setSelectedModel(session.model);
|
|
2088
2150
|
}
|
|
2089
|
-
}, [sessions, useExternalStorage,
|
|
2151
|
+
}, [sessions, useExternalStorage, storageKey, initialModel, models]);
|
|
2090
2152
|
const deleteSession = useCallback5(async (id) => {
|
|
2091
|
-
if (useExternalStorage &&
|
|
2153
|
+
if (useExternalStorage && onDeleteSessionCallbackRef.current) {
|
|
2092
2154
|
try {
|
|
2093
|
-
await
|
|
2155
|
+
await onDeleteSessionCallbackRef.current(id);
|
|
2094
2156
|
removeSessionCache(storageKey, id);
|
|
2095
2157
|
setSessions((prev) => {
|
|
2096
2158
|
const filtered = prev.filter((s) => s.id !== id);
|
|
@@ -2100,7 +2162,7 @@ ${newConversation}
|
|
|
2100
2162
|
return filtered;
|
|
2101
2163
|
});
|
|
2102
2164
|
} catch (error) {
|
|
2103
|
-
|
|
2165
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to delete session"));
|
|
2104
2166
|
}
|
|
2105
2167
|
return;
|
|
2106
2168
|
}
|
|
@@ -2114,20 +2176,20 @@ ${newConversation}
|
|
|
2114
2176
|
}
|
|
2115
2177
|
return filtered;
|
|
2116
2178
|
});
|
|
2117
|
-
}, [currentSessionId, storageKey, useExternalStorage
|
|
2179
|
+
}, [currentSessionId, storageKey, useExternalStorage]);
|
|
2118
2180
|
const renameSession = useCallback5(async (id, newTitle) => {
|
|
2119
2181
|
if (!newTitle.trim()) return;
|
|
2120
|
-
if (useExternalStorage &&
|
|
2182
|
+
if (useExternalStorage && onUpdateSessionTitleRef.current) {
|
|
2121
2183
|
try {
|
|
2122
|
-
await
|
|
2184
|
+
await onUpdateSessionTitleRef.current(id, newTitle.trim());
|
|
2123
2185
|
setSessions(
|
|
2124
2186
|
(prev) => prev.map(
|
|
2125
2187
|
(s) => s.id === id ? { ...s, title: newTitle.trim(), updatedAt: Date.now() } : s
|
|
2126
2188
|
)
|
|
2127
2189
|
);
|
|
2128
|
-
|
|
2190
|
+
onTitleChangeRef.current?.(id, newTitle.trim());
|
|
2129
2191
|
} catch (error) {
|
|
2130
|
-
|
|
2192
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to update session title"));
|
|
2131
2193
|
}
|
|
2132
2194
|
return;
|
|
2133
2195
|
}
|
|
@@ -2136,8 +2198,8 @@ ${newConversation}
|
|
|
2136
2198
|
(s) => s.id === id ? { ...s, title: newTitle.trim(), updatedAt: Date.now() } : s
|
|
2137
2199
|
)
|
|
2138
2200
|
);
|
|
2139
|
-
|
|
2140
|
-
}, [
|
|
2201
|
+
onTitleChangeRef.current?.(id, newTitle.trim());
|
|
2202
|
+
}, [useExternalStorage]);
|
|
2141
2203
|
const setModel = useCallback5((model) => {
|
|
2142
2204
|
setSelectedModel(model);
|
|
2143
2205
|
if (currentSessionId) {
|
|
@@ -2171,13 +2233,13 @@ ${newConversation}
|
|
|
2171
2233
|
const updatePersonalization = useCallback5((config) => {
|
|
2172
2234
|
setPersonalization((prev) => {
|
|
2173
2235
|
const next = { ...prev, ...config };
|
|
2174
|
-
|
|
2236
|
+
onPersonalizationChangeRef.current?.(next);
|
|
2175
2237
|
return next;
|
|
2176
2238
|
});
|
|
2177
|
-
}, [
|
|
2239
|
+
}, []);
|
|
2178
2240
|
const savePersonalization = useCallback5(() => {
|
|
2179
|
-
|
|
2180
|
-
}, [
|
|
2241
|
+
onPersonalizationSaveRef.current?.(personalization);
|
|
2242
|
+
}, [personalization]);
|
|
2181
2243
|
const addAttachments = useCallback5((files) => {
|
|
2182
2244
|
const newAttachments = files.map((file) => {
|
|
2183
2245
|
const isImage = file.type.startsWith("image/");
|
|
@@ -2210,9 +2272,9 @@ ${newConversation}
|
|
|
2210
2272
|
if (!messageContent.trim() || isLoading) return;
|
|
2211
2273
|
let sessionId = currentSessionId;
|
|
2212
2274
|
if (!sessionId) {
|
|
2213
|
-
if (useExternalStorage &&
|
|
2275
|
+
if (useExternalStorage && onCreateSessionRef.current) {
|
|
2214
2276
|
try {
|
|
2215
|
-
const created = await
|
|
2277
|
+
const created = await onCreateSessionRef.current();
|
|
2216
2278
|
const now = Date.now();
|
|
2217
2279
|
const newSess = {
|
|
2218
2280
|
id: created.id,
|
|
@@ -2226,7 +2288,7 @@ ${newConversation}
|
|
|
2226
2288
|
sessionId = newSess.id;
|
|
2227
2289
|
setCurrentSessionId(sessionId);
|
|
2228
2290
|
} catch (error) {
|
|
2229
|
-
|
|
2291
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Failed to create session"));
|
|
2230
2292
|
setIsLoading(false);
|
|
2231
2293
|
return;
|
|
2232
2294
|
}
|
|
@@ -2279,13 +2341,51 @@ ${finalContent}`;
|
|
|
2279
2341
|
...isHidden && { hidden: true },
|
|
2280
2342
|
...userContentParts && { contentParts: userContentParts }
|
|
2281
2343
|
};
|
|
2344
|
+
let attachmentResults = [];
|
|
2345
|
+
if (currentAttachments.length > 0) {
|
|
2346
|
+
const attachmentSkills = Object.entries(resolvedSkills).filter(
|
|
2347
|
+
([, config]) => config.trigger === "attachment"
|
|
2348
|
+
);
|
|
2349
|
+
for (const [skillName, skillConfig] of attachmentSkills) {
|
|
2350
|
+
const matchedFiles = currentAttachments.filter((att) => {
|
|
2351
|
+
if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
|
|
2352
|
+
return skillConfig.acceptedTypes.some((type) => {
|
|
2353
|
+
if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
|
|
2354
|
+
if (type.includes("*")) {
|
|
2355
|
+
const regex = new RegExp("^" + type.replace("*", ".*") + "$");
|
|
2356
|
+
return regex.test(att.mimeType);
|
|
2357
|
+
}
|
|
2358
|
+
return att.mimeType === type;
|
|
2359
|
+
});
|
|
2360
|
+
});
|
|
2361
|
+
if (matchedFiles.length === 0) continue;
|
|
2362
|
+
try {
|
|
2363
|
+
const result = await skillConfig.execute({ files: matchedFiles, userMessage: finalContent });
|
|
2364
|
+
attachmentResults.push({
|
|
2365
|
+
type: "tool_result",
|
|
2366
|
+
toolName: skillName,
|
|
2367
|
+
label: skillConfig.label,
|
|
2368
|
+
icon: skillConfig.icon,
|
|
2369
|
+
result: {
|
|
2370
|
+
type: "text",
|
|
2371
|
+
content: result.content,
|
|
2372
|
+
metadata: result.metadata,
|
|
2373
|
+
sources: result.sources
|
|
2374
|
+
}
|
|
2375
|
+
});
|
|
2376
|
+
} catch (error) {
|
|
2377
|
+
console.error(`[useChatUI] attachment skill ${skillName} failed:`, error);
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2282
2381
|
const assistantMessageId = generateId3("msg");
|
|
2283
2382
|
const assistantMessage = {
|
|
2284
2383
|
id: assistantMessageId,
|
|
2285
2384
|
role: "assistant",
|
|
2286
2385
|
content: "",
|
|
2287
2386
|
model: selectedModel,
|
|
2288
|
-
timestamp: Date.now()
|
|
2387
|
+
timestamp: Date.now(),
|
|
2388
|
+
...attachmentResults.length > 0 && { contentParts: attachmentResults }
|
|
2289
2389
|
};
|
|
2290
2390
|
setInput("");
|
|
2291
2391
|
setQuotedText(null);
|
|
@@ -2312,15 +2412,15 @@ ${finalContent}`;
|
|
|
2312
2412
|
return s;
|
|
2313
2413
|
})
|
|
2314
2414
|
);
|
|
2315
|
-
if (isFirstMessage &&
|
|
2316
|
-
Promise.resolve(
|
|
2415
|
+
if (isFirstMessage && generateTitleRef.current) {
|
|
2416
|
+
Promise.resolve(generateTitleRef.current(finalContent)).then((generatedTitle) => {
|
|
2317
2417
|
if (generatedTitle && generatedTitle.trim()) {
|
|
2318
2418
|
setSessions(
|
|
2319
2419
|
(prev) => prev.map(
|
|
2320
2420
|
(s) => s.id === capturedSessionId ? { ...s, title: generatedTitle.trim(), updatedAt: Date.now() } : s
|
|
2321
2421
|
)
|
|
2322
2422
|
);
|
|
2323
|
-
|
|
2423
|
+
onTitleChangeRef.current?.(capturedSessionId, generatedTitle.trim());
|
|
2324
2424
|
}
|
|
2325
2425
|
}).catch(() => {
|
|
2326
2426
|
});
|
|
@@ -2648,6 +2748,16 @@ ${currentContextSummary}` },
|
|
|
2648
2748
|
abortControllerRef.current = null;
|
|
2649
2749
|
return;
|
|
2650
2750
|
}
|
|
2751
|
+
let shouldContinue = continueAfterToolResult;
|
|
2752
|
+
if (onSkillCompleteRef.current) {
|
|
2753
|
+
const decision = onSkillCompleteRef.current(toolName, result);
|
|
2754
|
+
shouldContinue = decision === "continue";
|
|
2755
|
+
}
|
|
2756
|
+
if (!shouldContinue) {
|
|
2757
|
+
setIsLoading(false);
|
|
2758
|
+
abortControllerRef.current = null;
|
|
2759
|
+
return;
|
|
2760
|
+
}
|
|
2651
2761
|
skipNextSkillParsingRef.current = true;
|
|
2652
2762
|
const feedbackPrompt = resultType === "error" ? `\uB3C4\uAD6C "${toolName}" \uC2E4\uD589 \uC911 \uC624\uB958 \uBC1C\uC0DD: ${result.content}
|
|
2653
2763
|
|
|
@@ -2688,6 +2798,16 @@ ${result.content}
|
|
|
2688
2798
|
abortControllerRef.current = null;
|
|
2689
2799
|
return;
|
|
2690
2800
|
}
|
|
2801
|
+
let shouldContinueSkill = continueAfterToolResult;
|
|
2802
|
+
if (onSkillCompleteRef.current) {
|
|
2803
|
+
const decision = onSkillCompleteRef.current(detectedSkill.name, result);
|
|
2804
|
+
shouldContinueSkill = decision === "continue";
|
|
2805
|
+
}
|
|
2806
|
+
if (!shouldContinueSkill) {
|
|
2807
|
+
setIsLoading(false);
|
|
2808
|
+
abortControllerRef.current = null;
|
|
2809
|
+
return;
|
|
2810
|
+
}
|
|
2691
2811
|
skipNextSkillParsingRef.current = true;
|
|
2692
2812
|
const resultPrompt = `\uC2A4\uD0AC "${detectedSkill.name}" \uC2E4\uD589 \uACB0\uACFC:
|
|
2693
2813
|
|
|
@@ -2727,7 +2847,7 @@ ${result.content}
|
|
|
2727
2847
|
);
|
|
2728
2848
|
if (useExternalStorage && capturedSessionId) {
|
|
2729
2849
|
const assistantContentForSave = accumulatedContent;
|
|
2730
|
-
if (assistantContentForSave &&
|
|
2850
|
+
if (assistantContentForSave && onSaveMessagesRef.current) {
|
|
2731
2851
|
const latestSession = sessionsRef.current.find((s) => s.id === capturedSessionId);
|
|
2732
2852
|
const latestMessages = latestSession?.messages || [];
|
|
2733
2853
|
const userMsg = latestMessages.find((m) => m.role === "user" && m.content === finalContent);
|
|
@@ -2736,7 +2856,7 @@ ${result.content}
|
|
|
2736
2856
|
{ role: "user", message: finalContent, ...userMsg?.contentParts && { contentParts: userMsg.contentParts } },
|
|
2737
2857
|
{ role: "assistant", message: assistantContentForSave, ...assistantMsg?.contentParts && { contentParts: assistantMsg.contentParts } }
|
|
2738
2858
|
];
|
|
2739
|
-
|
|
2859
|
+
onSaveMessagesRef.current(capturedSessionId, messagesToSave).catch((saveError) => {
|
|
2740
2860
|
console.error("[useChatUI] Failed to save messages:", saveError);
|
|
2741
2861
|
});
|
|
2742
2862
|
}
|
|
@@ -2764,7 +2884,7 @@ ${result.content}
|
|
|
2764
2884
|
return;
|
|
2765
2885
|
}
|
|
2766
2886
|
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
2767
|
-
|
|
2887
|
+
onErrorRef.current?.(err);
|
|
2768
2888
|
setSessions(
|
|
2769
2889
|
(prev) => prev.map((s) => {
|
|
2770
2890
|
if (s.id === capturedSessionId) {
|
|
@@ -3037,11 +3157,11 @@ ${formattedParts.join("\n")}
|
|
|
3037
3157
|
return;
|
|
3038
3158
|
}
|
|
3039
3159
|
console.error("[ChatUI] Regenerate error:", error);
|
|
3040
|
-
|
|
3160
|
+
onErrorRef.current?.(error instanceof Error ? error : new Error("Unknown error"));
|
|
3041
3161
|
} finally {
|
|
3042
3162
|
setIsLoading(false);
|
|
3043
3163
|
}
|
|
3044
|
-
}, [currentSession, currentSessionId, isLoading, selectedModel, models, apiEndpoint, apiKey, buildSystemPrompt
|
|
3164
|
+
}, [currentSession, currentSessionId, isLoading, selectedModel, models, apiEndpoint, apiKey, buildSystemPrompt]);
|
|
3045
3165
|
const askOtherModel = useCallback5(async (messageId, targetModel) => {
|
|
3046
3166
|
if (!currentSession || !currentSessionId || isLoading) return;
|
|
3047
3167
|
const assistantIndex = currentSession.messages.findIndex((m) => m.id === messageId);
|
|
@@ -3193,7 +3313,7 @@ ${currentSession.contextSummary}` },
|
|
|
3193
3313
|
return;
|
|
3194
3314
|
}
|
|
3195
3315
|
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
3196
|
-
|
|
3316
|
+
onErrorRef.current?.(err);
|
|
3197
3317
|
} finally {
|
|
3198
3318
|
setIsLoading(false);
|
|
3199
3319
|
setLoadingAlternativeFor(null);
|
|
@@ -3262,7 +3382,8 @@ ${currentSession.contextSummary}` },
|
|
|
3262
3382
|
getActiveAlternative,
|
|
3263
3383
|
updatePersonalization,
|
|
3264
3384
|
savePersonalization,
|
|
3265
|
-
models,
|
|
3385
|
+
models: effectiveModels,
|
|
3386
|
+
isModelsLoading,
|
|
3266
3387
|
// Memory
|
|
3267
3388
|
globalMemory,
|
|
3268
3389
|
compressionState,
|
|
@@ -3375,8 +3496,8 @@ ${currentSession.contextSummary}` },
|
|
|
3375
3496
|
if (!enableProjects) return;
|
|
3376
3497
|
const projectSessions = sessionsRef.current.filter((s) => s.projectId === projectId);
|
|
3377
3498
|
for (const sess of projectSessions) {
|
|
3378
|
-
if (useExternalStorage &&
|
|
3379
|
-
await
|
|
3499
|
+
if (useExternalStorage && onDeleteSessionCallbackRef.current) {
|
|
3500
|
+
await onDeleteSessionCallbackRef.current(sess.id).catch(() => {
|
|
3380
3501
|
});
|
|
3381
3502
|
}
|
|
3382
3503
|
removeSessionCache(storageKey, sess.id);
|
|
@@ -3736,7 +3857,8 @@ var ChatSidebar = ({
|
|
|
3736
3857
|
onNewProject,
|
|
3737
3858
|
onProjectSettings,
|
|
3738
3859
|
renderAfterHeader,
|
|
3739
|
-
renderFooter
|
|
3860
|
+
renderFooter,
|
|
3861
|
+
isLoading = false
|
|
3740
3862
|
}) => {
|
|
3741
3863
|
const sidebarWidth = typeof widthProp === "number" ? `${widthProp}px` : widthProp || "288px";
|
|
3742
3864
|
const [editingId, setEditingId] = useState7(null);
|
|
@@ -3831,11 +3953,10 @@ var ChatSidebar = ({
|
|
|
3831
3953
|
style: {
|
|
3832
3954
|
fontSize: "14px",
|
|
3833
3955
|
fontWeight: 700,
|
|
3834
|
-
textTransform: "uppercase",
|
|
3835
3956
|
letterSpacing: "-0.01em",
|
|
3836
3957
|
color: "var(--chatllm-text)"
|
|
3837
3958
|
},
|
|
3838
|
-
children: "
|
|
3959
|
+
children: "AI \uCC44\uD305"
|
|
3839
3960
|
}
|
|
3840
3961
|
)
|
|
3841
3962
|
] })
|
|
@@ -3885,7 +4006,22 @@ var ChatSidebar = ({
|
|
|
3885
4006
|
display: "flex",
|
|
3886
4007
|
flexDirection: "column"
|
|
3887
4008
|
},
|
|
3888
|
-
children:
|
|
4009
|
+
children: isLoading ? (
|
|
4010
|
+
/* Skeleton Loading State */
|
|
4011
|
+
/* @__PURE__ */ jsx3("div", { style: { display: "flex", flexDirection: "column", gap: "8px", padding: "0 4px" }, children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx3(
|
|
4012
|
+
"div",
|
|
4013
|
+
{
|
|
4014
|
+
className: "chatllm-skeleton-pulse",
|
|
4015
|
+
style: {
|
|
4016
|
+
height: "48px",
|
|
4017
|
+
borderRadius: "8px",
|
|
4018
|
+
backgroundColor: "var(--chatllm-bg-tertiary)",
|
|
4019
|
+
opacity: 1 - (i - 1) * 0.15
|
|
4020
|
+
}
|
|
4021
|
+
},
|
|
4022
|
+
i
|
|
4023
|
+
)) })
|
|
4024
|
+
) : sessions.length === 0 ? (
|
|
3889
4025
|
/* Empty State */
|
|
3890
4026
|
/* @__PURE__ */ jsxs2(
|
|
3891
4027
|
"div",
|
|
@@ -4828,6 +4964,16 @@ var ChatInput = ({
|
|
|
4828
4964
|
}
|
|
4829
4965
|
)
|
|
4830
4966
|
] }),
|
|
4967
|
+
/* @__PURE__ */ jsx5(
|
|
4968
|
+
"button",
|
|
4969
|
+
{
|
|
4970
|
+
onClick: () => fileInputRef.current?.click(),
|
|
4971
|
+
style: iconButtonStyle,
|
|
4972
|
+
title: "\uD30C\uC77C \uCCA8\uBD80",
|
|
4973
|
+
"aria-label": "\uD30C\uC77C \uCCA8\uBD80",
|
|
4974
|
+
children: /* @__PURE__ */ jsx5(IconSvg, { name: "attachment-line", size: 22, color: "var(--chatllm-text-muted)" })
|
|
4975
|
+
}
|
|
4976
|
+
),
|
|
4831
4977
|
/* @__PURE__ */ jsxs4("div", { ref: mainMenuRef, style: { position: "relative" }, children: [
|
|
4832
4978
|
/* @__PURE__ */ jsx5(
|
|
4833
4979
|
"button",
|
|
@@ -5507,45 +5653,99 @@ var parseTableRow = (row) => {
|
|
|
5507
5653
|
return row.split("|").slice(1, -1).map((cell) => cell.trim());
|
|
5508
5654
|
};
|
|
5509
5655
|
var MarkdownTable = ({ data }) => {
|
|
5656
|
+
const [copied, setCopied] = React6.useState(false);
|
|
5657
|
+
const [isHovered, setIsHovered] = React6.useState(false);
|
|
5658
|
+
const handleCopy = async () => {
|
|
5659
|
+
const headerLine = data.headers.join(" ");
|
|
5660
|
+
const bodyLines = data.rows.map((row) => row.join(" "));
|
|
5661
|
+
const text = [headerLine, ...bodyLines].join("\n");
|
|
5662
|
+
try {
|
|
5663
|
+
await navigator.clipboard.writeText(text);
|
|
5664
|
+
setCopied(true);
|
|
5665
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
5666
|
+
} catch {
|
|
5667
|
+
console.error("Failed to copy table");
|
|
5668
|
+
}
|
|
5669
|
+
};
|
|
5510
5670
|
return /* @__PURE__ */ jsxs6(
|
|
5511
|
-
"
|
|
5671
|
+
"div",
|
|
5512
5672
|
{
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
borderCollapse: "collapse",
|
|
5517
|
-
margin: "12px 0",
|
|
5518
|
-
fontSize: "14px"
|
|
5519
|
-
},
|
|
5673
|
+
style: { position: "relative", margin: "12px 0" },
|
|
5674
|
+
onMouseEnter: () => setIsHovered(true),
|
|
5675
|
+
onMouseLeave: () => setIsHovered(false),
|
|
5520
5676
|
children: [
|
|
5521
|
-
/* @__PURE__ */
|
|
5522
|
-
"
|
|
5677
|
+
/* @__PURE__ */ jsxs6(
|
|
5678
|
+
"table",
|
|
5523
5679
|
{
|
|
5680
|
+
className: "chatllm-table",
|
|
5524
5681
|
style: {
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
backgroundColor: "var(--chatllm-bg-secondary, #f9fafb)",
|
|
5529
|
-
fontWeight: 600,
|
|
5530
|
-
color: "var(--chatllm-text, #374151)"
|
|
5682
|
+
width: "100%",
|
|
5683
|
+
borderCollapse: "collapse",
|
|
5684
|
+
fontSize: "14px"
|
|
5531
5685
|
},
|
|
5532
|
-
children:
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5686
|
+
children: [
|
|
5687
|
+
/* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsx7("tr", { children: data.headers.map((header, i) => /* @__PURE__ */ jsx7(
|
|
5688
|
+
"th",
|
|
5689
|
+
{
|
|
5690
|
+
style: {
|
|
5691
|
+
border: "1px solid var(--chatllm-border, #e5e7eb)",
|
|
5692
|
+
padding: "10px 12px",
|
|
5693
|
+
textAlign: data.alignments[i] || "left",
|
|
5694
|
+
backgroundColor: "var(--chatllm-bg-secondary, #f9fafb)",
|
|
5695
|
+
fontWeight: 600,
|
|
5696
|
+
color: "var(--chatllm-text, #374151)"
|
|
5697
|
+
},
|
|
5698
|
+
children: parseInlineElements(header, `th-${i}`)
|
|
5699
|
+
},
|
|
5700
|
+
i
|
|
5701
|
+
)) }) }),
|
|
5702
|
+
/* @__PURE__ */ jsx7("tbody", { children: data.rows.map((row, rowIndex) => /* @__PURE__ */ jsx7("tr", { children: row.map((cell, cellIndex) => /* @__PURE__ */ jsx7(
|
|
5703
|
+
"td",
|
|
5704
|
+
{
|
|
5705
|
+
style: {
|
|
5706
|
+
border: "1px solid var(--chatllm-border, #e5e7eb)",
|
|
5707
|
+
padding: "10px 12px",
|
|
5708
|
+
textAlign: data.alignments[cellIndex] || "left",
|
|
5709
|
+
color: "var(--chatllm-text, #374151)"
|
|
5710
|
+
},
|
|
5711
|
+
children: parseInlineElements(cell, `td-${rowIndex}-${cellIndex}`)
|
|
5712
|
+
},
|
|
5713
|
+
cellIndex
|
|
5714
|
+
)) }, rowIndex)) })
|
|
5715
|
+
]
|
|
5716
|
+
}
|
|
5717
|
+
),
|
|
5718
|
+
/* @__PURE__ */ jsxs6(
|
|
5719
|
+
"button",
|
|
5538
5720
|
{
|
|
5721
|
+
onClick: handleCopy,
|
|
5539
5722
|
style: {
|
|
5723
|
+
position: "absolute",
|
|
5724
|
+
top: "4px",
|
|
5725
|
+
right: "4px",
|
|
5726
|
+
padding: "4px 8px",
|
|
5727
|
+
fontSize: "12px",
|
|
5728
|
+
backgroundColor: "var(--chatllm-bg, #ffffff)",
|
|
5540
5729
|
border: "1px solid var(--chatllm-border, #e5e7eb)",
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
color: "var(--chatllm-text, #
|
|
5730
|
+
borderRadius: "6px",
|
|
5731
|
+
cursor: "pointer",
|
|
5732
|
+
color: copied ? "var(--chatllm-success, #22c55e)" : "var(--chatllm-text-muted, #9ca3af)",
|
|
5733
|
+
opacity: isHovered || copied ? 1 : 0,
|
|
5734
|
+
transition: "opacity 0.15s",
|
|
5735
|
+
display: "flex",
|
|
5736
|
+
alignItems: "center",
|
|
5737
|
+
gap: "4px",
|
|
5738
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
|
|
5544
5739
|
},
|
|
5545
|
-
children:
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5740
|
+
children: [
|
|
5741
|
+
/* @__PURE__ */ jsx7("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: copied ? /* @__PURE__ */ jsx7("polyline", { points: "20 6 9 17 4 12" }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
5742
|
+
/* @__PURE__ */ jsx7("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
|
|
5743
|
+
/* @__PURE__ */ jsx7("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
5744
|
+
] }) }),
|
|
5745
|
+
copied ? "\uBCF5\uC0AC\uB428" : "\uBCF5\uC0AC"
|
|
5746
|
+
]
|
|
5747
|
+
}
|
|
5748
|
+
)
|
|
5549
5749
|
]
|
|
5550
5750
|
}
|
|
5551
5751
|
);
|
|
@@ -6759,6 +6959,7 @@ var PollCard = ({
|
|
|
6759
6959
|
onSkip?.();
|
|
6760
6960
|
}, [questions, onSubmit, onSkip]);
|
|
6761
6961
|
useEffect7(() => {
|
|
6962
|
+
if (typeof window === "undefined") return;
|
|
6762
6963
|
const handleKeyDown = (e) => {
|
|
6763
6964
|
if (e.key === "Escape") handleSkip();
|
|
6764
6965
|
};
|
|
@@ -7703,7 +7904,7 @@ var MessageBubble = ({
|
|
|
7703
7904
|
const displaySources = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.sources : message.sources;
|
|
7704
7905
|
const handleMouseUp = () => {
|
|
7705
7906
|
if (!onQuote) return;
|
|
7706
|
-
const selection = window.getSelection();
|
|
7907
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
7707
7908
|
const text = selection?.toString().trim();
|
|
7708
7909
|
if (text && text.length > 0) {
|
|
7709
7910
|
}
|
|
@@ -8318,7 +8519,7 @@ var MessageList = ({
|
|
|
8318
8519
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
8319
8520
|
}, [messages]);
|
|
8320
8521
|
const handleMouseUp = useCallback8(() => {
|
|
8321
|
-
const selection = window.getSelection();
|
|
8522
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
8322
8523
|
const text = selection?.toString().trim();
|
|
8323
8524
|
if (text && text.length > 0) {
|
|
8324
8525
|
const range = selection?.getRangeAt(0);
|
|
@@ -8334,7 +8535,7 @@ var MessageList = ({
|
|
|
8334
8535
|
}
|
|
8335
8536
|
} else {
|
|
8336
8537
|
setTimeout(() => {
|
|
8337
|
-
const currentSelection = window.getSelection()?.toString().trim();
|
|
8538
|
+
const currentSelection = typeof window !== "undefined" ? window.getSelection()?.toString().trim() : void 0;
|
|
8338
8539
|
if (!currentSelection) {
|
|
8339
8540
|
setSelectionPosition(null);
|
|
8340
8541
|
}
|
|
@@ -8346,7 +8547,9 @@ var MessageList = ({
|
|
|
8346
8547
|
onQuote(selectedText);
|
|
8347
8548
|
setSelectionPosition(null);
|
|
8348
8549
|
setSelectedText("");
|
|
8349
|
-
window
|
|
8550
|
+
if (typeof window !== "undefined") {
|
|
8551
|
+
window.getSelection()?.removeAllRanges();
|
|
8552
|
+
}
|
|
8350
8553
|
}
|
|
8351
8554
|
};
|
|
8352
8555
|
return /* @__PURE__ */ jsxs15(
|
|
@@ -9004,7 +9207,7 @@ var SettingsModal = ({
|
|
|
9004
9207
|
"button",
|
|
9005
9208
|
{
|
|
9006
9209
|
onClick: () => {
|
|
9007
|
-
if (window.confirm("\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9210
|
+
if (typeof window !== "undefined" && window.confirm("\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9008
9211
|
onClearAllData();
|
|
9009
9212
|
}
|
|
9010
9213
|
},
|
|
@@ -9275,7 +9478,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
|
|
|
9275
9478
|
"button",
|
|
9276
9479
|
{
|
|
9277
9480
|
onClick: () => {
|
|
9278
|
-
if (window.confirm("\uBAA8\uB4E0 AI \uBA54\uBAA8\uB9AC\uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9481
|
+
if (typeof window !== "undefined" && window.confirm("\uBAA8\uB4E0 AI \uBA54\uBAA8\uB9AC\uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?")) {
|
|
9279
9482
|
onClearAll();
|
|
9280
9483
|
}
|
|
9281
9484
|
},
|
|
@@ -9522,7 +9725,7 @@ var ProjectSettingsModal = ({
|
|
|
9522
9725
|
"button",
|
|
9523
9726
|
{
|
|
9524
9727
|
onClick: () => {
|
|
9525
|
-
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?`)) {
|
|
9728
|
+
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?`)) {
|
|
9526
9729
|
onDeleteProject(project.id);
|
|
9527
9730
|
onClose();
|
|
9528
9731
|
}
|
|
@@ -10027,7 +10230,8 @@ var ChatUIView = ({
|
|
|
10027
10230
|
projectSettingsOpen,
|
|
10028
10231
|
openProjectSettings,
|
|
10029
10232
|
closeProjectSettings,
|
|
10030
|
-
projectMemory
|
|
10233
|
+
projectMemory,
|
|
10234
|
+
isSessionsLoading
|
|
10031
10235
|
} = state;
|
|
10032
10236
|
const greeting = currentPersonalization.userProfile.nickname ? `\uC548\uB155\uD558\uC138\uC694, ${currentPersonalization.userProfile.nickname}\uB2D8` : "\uC548\uB155\uD558\uC138\uC694";
|
|
10033
10237
|
const handleTemplateClick = (template) => {
|
|
@@ -10111,7 +10315,8 @@ var ChatUIView = ({
|
|
|
10111
10315
|
openProjectSettings();
|
|
10112
10316
|
} : void 0,
|
|
10113
10317
|
renderAfterHeader: sidebarRenderAfterHeader,
|
|
10114
|
-
renderFooter: sidebarRenderFooter
|
|
10318
|
+
renderFooter: sidebarRenderFooter,
|
|
10319
|
+
isLoading: isSessionsLoading
|
|
10115
10320
|
}
|
|
10116
10321
|
),
|
|
10117
10322
|
/* @__PURE__ */ jsxs19(
|
|
@@ -10283,6 +10488,9 @@ var ChatUIWithHook = ({
|
|
|
10283
10488
|
skills,
|
|
10284
10489
|
tools,
|
|
10285
10490
|
onToolCall,
|
|
10491
|
+
continueAfterToolResult,
|
|
10492
|
+
onSkillComplete,
|
|
10493
|
+
onLoadModels,
|
|
10286
10494
|
// Project options
|
|
10287
10495
|
enableProjects,
|
|
10288
10496
|
onLoadProjects,
|
|
@@ -10322,6 +10530,9 @@ var ChatUIWithHook = ({
|
|
|
10322
10530
|
skills,
|
|
10323
10531
|
tools,
|
|
10324
10532
|
onToolCall,
|
|
10533
|
+
continueAfterToolResult,
|
|
10534
|
+
onSkillComplete,
|
|
10535
|
+
onLoadModels,
|
|
10325
10536
|
enableProjects,
|
|
10326
10537
|
onLoadProjects,
|
|
10327
10538
|
onCreateProject,
|