@gendive/chatllm 0.17.18 → 0.17.20
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 +4 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +107 -113
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +107 -113
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.mts
CHANGED
|
@@ -647,6 +647,8 @@ interface ChatUIProps {
|
|
|
647
647
|
sidebarRenderFooter?: () => React.ReactNode;
|
|
648
648
|
/** 설정 버튼 표시 여부 */
|
|
649
649
|
showSettings?: boolean;
|
|
650
|
+
/** @description 설정 모달에서 메모리 탭 표시 여부 (기본: true) @Todo vibecode */
|
|
651
|
+
showMemoryTab?: boolean;
|
|
650
652
|
/** 모델 선택기 표시 여부 */
|
|
651
653
|
showModelSelector?: boolean;
|
|
652
654
|
/** 초기 시스템 프롬프트 */
|
|
@@ -1790,6 +1792,8 @@ interface SettingsModalProps {
|
|
|
1790
1792
|
enableProjects?: boolean;
|
|
1791
1793
|
/** @description 현재 프로젝트 이름 @Todo vibecode */
|
|
1792
1794
|
currentProjectTitle?: string;
|
|
1795
|
+
/** @description 메모리 탭 표시 여부 (기본: true) @Todo vibecode */
|
|
1796
|
+
showMemoryTab?: boolean;
|
|
1793
1797
|
}
|
|
1794
1798
|
declare const SettingsModal: React$1.FC<SettingsModalProps>;
|
|
1795
1799
|
|
package/dist/react/index.d.ts
CHANGED
|
@@ -647,6 +647,8 @@ interface ChatUIProps {
|
|
|
647
647
|
sidebarRenderFooter?: () => React.ReactNode;
|
|
648
648
|
/** 설정 버튼 표시 여부 */
|
|
649
649
|
showSettings?: boolean;
|
|
650
|
+
/** @description 설정 모달에서 메모리 탭 표시 여부 (기본: true) @Todo vibecode */
|
|
651
|
+
showMemoryTab?: boolean;
|
|
650
652
|
/** 모델 선택기 표시 여부 */
|
|
651
653
|
showModelSelector?: boolean;
|
|
652
654
|
/** 초기 시스템 프롬프트 */
|
|
@@ -1790,6 +1792,8 @@ interface SettingsModalProps {
|
|
|
1790
1792
|
enableProjects?: boolean;
|
|
1791
1793
|
/** @description 현재 프로젝트 이름 @Todo vibecode */
|
|
1792
1794
|
currentProjectTitle?: string;
|
|
1795
|
+
/** @description 메모리 탭 표시 여부 (기본: true) @Todo vibecode */
|
|
1796
|
+
showMemoryTab?: boolean;
|
|
1793
1797
|
}
|
|
1794
1798
|
declare const SettingsModal: React$1.FC<SettingsModalProps>;
|
|
1795
1799
|
|
package/dist/react/index.js
CHANGED
|
@@ -483,7 +483,7 @@ var parseExtractionResult = (text) => {
|
|
|
483
483
|
function useInfoExtraction(options) {
|
|
484
484
|
const [isExtracting, setIsExtracting] = (0, import_react2.useState)(false);
|
|
485
485
|
const [lastExtraction, setLastExtraction] = (0, import_react2.useState)(null);
|
|
486
|
-
const { apiEndpoint, model, minConfidence = 0.8, globalMemory } = options;
|
|
486
|
+
const { apiEndpoint, model, minConfidence = 0.8, globalMemory, onCallLLM } = options;
|
|
487
487
|
const extractInfo = (0, import_react2.useCallback)(
|
|
488
488
|
async (messages) => {
|
|
489
489
|
if (messages.length === 0) {
|
|
@@ -492,41 +492,44 @@ function useInfoExtraction(options) {
|
|
|
492
492
|
setIsExtracting(true);
|
|
493
493
|
try {
|
|
494
494
|
const prompt = buildExtractionPrompt(messages);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
495
|
+
let fullResponse;
|
|
496
|
+
if (onCallLLM) {
|
|
497
|
+
fullResponse = await onCallLLM(prompt, model || "default");
|
|
498
|
+
} else {
|
|
499
|
+
const response = await fetch(apiEndpoint, {
|
|
500
|
+
method: "POST",
|
|
501
|
+
headers: { "Content-Type": "application/json" },
|
|
502
|
+
body: JSON.stringify({
|
|
503
|
+
messages: [{ role: "user", content: prompt }],
|
|
504
|
+
model: model || "default"
|
|
505
|
+
})
|
|
506
|
+
});
|
|
507
|
+
if (!response.ok) {
|
|
508
|
+
throw new Error(`API error: ${response.status}`);
|
|
509
|
+
}
|
|
510
|
+
const reader = response.body?.getReader();
|
|
511
|
+
if (!reader) {
|
|
512
|
+
return [];
|
|
513
|
+
}
|
|
514
|
+
const decoder = new TextDecoder();
|
|
515
|
+
let buffer = "";
|
|
516
|
+
fullResponse = "";
|
|
517
|
+
while (true) {
|
|
518
|
+
const { done, value } = await reader.read();
|
|
519
|
+
if (done) break;
|
|
520
|
+
buffer += decoder.decode(value, { stream: true });
|
|
521
|
+
const lines = buffer.split("\n");
|
|
522
|
+
buffer = lines.pop() || "";
|
|
523
|
+
for (const line of lines) {
|
|
524
|
+
if (line.startsWith("data: ")) {
|
|
525
|
+
const data = line.slice(6);
|
|
526
|
+
if (data === "[DONE]") continue;
|
|
527
|
+
try {
|
|
528
|
+
const parsed = JSON.parse(data);
|
|
526
529
|
const chunk = parsed.content ?? parsed.text ?? "";
|
|
527
530
|
if (chunk) fullResponse += chunk;
|
|
531
|
+
} catch {
|
|
528
532
|
}
|
|
529
|
-
} catch {
|
|
530
533
|
}
|
|
531
534
|
}
|
|
532
535
|
}
|
|
@@ -553,7 +556,7 @@ function useInfoExtraction(options) {
|
|
|
553
556
|
setIsExtracting(false);
|
|
554
557
|
}
|
|
555
558
|
},
|
|
556
|
-
[apiEndpoint, model, minConfidence, globalMemory]
|
|
559
|
+
[apiEndpoint, model, minConfidence, globalMemory, onCallLLM]
|
|
557
560
|
);
|
|
558
561
|
return {
|
|
559
562
|
extractInfo,
|
|
@@ -1609,6 +1612,33 @@ var removeSessionCache = (storageKey, sessionId) => {
|
|
|
1609
1612
|
};
|
|
1610
1613
|
|
|
1611
1614
|
// src/react/hooks/useChatUI.ts
|
|
1615
|
+
var parseSSEResponse = async (response) => {
|
|
1616
|
+
const reader = response.body?.getReader();
|
|
1617
|
+
if (!reader) return "";
|
|
1618
|
+
const decoder = new TextDecoder();
|
|
1619
|
+
let buffer = "";
|
|
1620
|
+
let result = "";
|
|
1621
|
+
while (true) {
|
|
1622
|
+
const { done, value } = await reader.read();
|
|
1623
|
+
if (done) break;
|
|
1624
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1625
|
+
const lines = buffer.split("\n");
|
|
1626
|
+
buffer = lines.pop() || "";
|
|
1627
|
+
for (const line of lines) {
|
|
1628
|
+
if (line.startsWith("data: ")) {
|
|
1629
|
+
const data = line.slice(6);
|
|
1630
|
+
if (data === "[DONE]") continue;
|
|
1631
|
+
try {
|
|
1632
|
+
const parsed = JSON.parse(data);
|
|
1633
|
+
const chunk = parsed.content ?? parsed.text ?? "";
|
|
1634
|
+
if (chunk) result += chunk;
|
|
1635
|
+
} catch {
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
return result;
|
|
1641
|
+
};
|
|
1612
1642
|
var DEFAULT_STORAGE_KEY = "chatllm_sessions";
|
|
1613
1643
|
var DEFAULT_COMPRESSION_THRESHOLD = 20;
|
|
1614
1644
|
var DEFAULT_KEEP_RECENT = 6;
|
|
@@ -1814,11 +1844,37 @@ var useChatUI = (options) => {
|
|
|
1814
1844
|
);
|
|
1815
1845
|
const projectMemoryRaw = useGlobalMemory(projectMemoryOptions);
|
|
1816
1846
|
const projectMemory = enableProjects ? projectMemoryRaw : null;
|
|
1847
|
+
const callInternalLLM = (0, import_react5.useCallback)(async (prompt, model) => {
|
|
1848
|
+
if (onSendMessageRef.current) {
|
|
1849
|
+
const modelConfig = models.find((m) => m.id === model);
|
|
1850
|
+
const provider = modelConfig?.provider || "ollama";
|
|
1851
|
+
const result = await onSendMessageRef.current({
|
|
1852
|
+
messages: [{ role: "user", content: prompt }],
|
|
1853
|
+
model,
|
|
1854
|
+
provider,
|
|
1855
|
+
apiKey
|
|
1856
|
+
});
|
|
1857
|
+
if (typeof result === "string") return result;
|
|
1858
|
+
if (typeof result === "object" && "content" in result) return result.content;
|
|
1859
|
+
return parseSSEResponse(new Response(result));
|
|
1860
|
+
}
|
|
1861
|
+
const response = await fetch(apiEndpoint, {
|
|
1862
|
+
method: "POST",
|
|
1863
|
+
headers: { "Content-Type": "application/json" },
|
|
1864
|
+
body: JSON.stringify({
|
|
1865
|
+
messages: [{ role: "user", content: prompt }],
|
|
1866
|
+
model
|
|
1867
|
+
})
|
|
1868
|
+
});
|
|
1869
|
+
if (!response.ok) return "";
|
|
1870
|
+
return parseSSEResponse(response);
|
|
1871
|
+
}, [apiEndpoint, apiKey, models]);
|
|
1817
1872
|
const infoExtraction = useInfoExtraction({
|
|
1818
1873
|
apiEndpoint,
|
|
1819
1874
|
model: selectedModel,
|
|
1820
1875
|
minConfidence: 0.8,
|
|
1821
|
-
globalMemory
|
|
1876
|
+
globalMemory,
|
|
1877
|
+
onCallLLM: callInternalLLM
|
|
1822
1878
|
});
|
|
1823
1879
|
const currentSession = sessions.find((s) => s.id === currentSessionId) || null;
|
|
1824
1880
|
const messages = currentSession?.messages.filter((m) => !m.hidden) || [];
|
|
@@ -2016,46 +2072,11 @@ ${conversationText}
|
|
|
2016
2072
|
|
|
2017
2073
|
\uC694\uC57D:`;
|
|
2018
2074
|
try {
|
|
2019
|
-
|
|
2020
|
-
method: "POST",
|
|
2021
|
-
headers: { "Content-Type": "application/json" },
|
|
2022
|
-
body: JSON.stringify({
|
|
2023
|
-
messages: [{ role: "user", content: summaryPrompt }],
|
|
2024
|
-
model
|
|
2025
|
-
})
|
|
2026
|
-
});
|
|
2027
|
-
if (!response.ok) return "";
|
|
2028
|
-
const reader = response.body?.getReader();
|
|
2029
|
-
if (!reader) return "";
|
|
2030
|
-
const decoder = new TextDecoder();
|
|
2031
|
-
let buffer = "";
|
|
2032
|
-
let summary = "";
|
|
2033
|
-
while (true) {
|
|
2034
|
-
const { done, value } = await reader.read();
|
|
2035
|
-
if (done) break;
|
|
2036
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2037
|
-
const lines = buffer.split("\n");
|
|
2038
|
-
buffer = lines.pop() || "";
|
|
2039
|
-
for (const line of lines) {
|
|
2040
|
-
if (line.startsWith("data: ")) {
|
|
2041
|
-
const data = line.slice(6);
|
|
2042
|
-
if (data === "[DONE]") continue;
|
|
2043
|
-
try {
|
|
2044
|
-
const parsed = JSON.parse(data);
|
|
2045
|
-
{
|
|
2046
|
-
const chunk = parsed.content ?? parsed.text ?? "";
|
|
2047
|
-
if (chunk) summary += chunk;
|
|
2048
|
-
}
|
|
2049
|
-
} catch {
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
return summary;
|
|
2075
|
+
return await callInternalLLM(summaryPrompt, model);
|
|
2055
2076
|
} catch {
|
|
2056
2077
|
return "";
|
|
2057
2078
|
}
|
|
2058
|
-
}, [
|
|
2079
|
+
}, [callInternalLLM]);
|
|
2059
2080
|
const incrementalCompressContext = (0, import_react5.useCallback)(
|
|
2060
2081
|
async (existingSummary, newMessages, model) => {
|
|
2061
2082
|
const newConversation = newMessages.map((m) => `${m.role === "user" ? "\uC0AC\uC6A9\uC790" : "AI"}: ${m.content}`).join("\n\n");
|
|
@@ -2075,47 +2096,13 @@ ${newConversation}
|
|
|
2075
2096
|
|
|
2076
2097
|
\uD1B5\uD569 \uC694\uC57D:`;
|
|
2077
2098
|
try {
|
|
2078
|
-
const
|
|
2079
|
-
method: "POST",
|
|
2080
|
-
headers: { "Content-Type": "application/json" },
|
|
2081
|
-
body: JSON.stringify({
|
|
2082
|
-
messages: [{ role: "user", content: mergePrompt }],
|
|
2083
|
-
model
|
|
2084
|
-
})
|
|
2085
|
-
});
|
|
2086
|
-
if (!response.ok) return existingSummary;
|
|
2087
|
-
const reader = response.body?.getReader();
|
|
2088
|
-
if (!reader) return existingSummary;
|
|
2089
|
-
const decoder = new TextDecoder();
|
|
2090
|
-
let buffer = "";
|
|
2091
|
-
let summary = "";
|
|
2092
|
-
while (true) {
|
|
2093
|
-
const { done, value } = await reader.read();
|
|
2094
|
-
if (done) break;
|
|
2095
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2096
|
-
const lines = buffer.split("\n");
|
|
2097
|
-
buffer = lines.pop() || "";
|
|
2098
|
-
for (const line of lines) {
|
|
2099
|
-
if (line.startsWith("data: ")) {
|
|
2100
|
-
const data = line.slice(6);
|
|
2101
|
-
if (data === "[DONE]") continue;
|
|
2102
|
-
try {
|
|
2103
|
-
const parsed = JSON.parse(data);
|
|
2104
|
-
{
|
|
2105
|
-
const chunk = parsed.content ?? parsed.text ?? "";
|
|
2106
|
-
if (chunk) summary += chunk;
|
|
2107
|
-
}
|
|
2108
|
-
} catch {
|
|
2109
|
-
}
|
|
2110
|
-
}
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2099
|
+
const summary = await callInternalLLM(mergePrompt, model);
|
|
2113
2100
|
return summary || existingSummary;
|
|
2114
2101
|
} catch {
|
|
2115
2102
|
return existingSummary;
|
|
2116
2103
|
}
|
|
2117
2104
|
},
|
|
2118
|
-
[
|
|
2105
|
+
[callInternalLLM]
|
|
2119
2106
|
);
|
|
2120
2107
|
const estimateTokens = (0, import_react5.useCallback)((messages2) => {
|
|
2121
2108
|
return messages2.reduce((sum, m) => sum + Math.ceil(m.content.length / 4), 0);
|
|
@@ -9234,7 +9221,8 @@ var SettingsModal = ({
|
|
|
9234
9221
|
onDeleteProjectMemory,
|
|
9235
9222
|
onClearProjectMemory,
|
|
9236
9223
|
enableProjects = false,
|
|
9237
|
-
currentProjectTitle
|
|
9224
|
+
currentProjectTitle,
|
|
9225
|
+
showMemoryTab = true
|
|
9238
9226
|
}) => {
|
|
9239
9227
|
const [activeTab, setActiveTab] = (0, import_react18.useState)("general");
|
|
9240
9228
|
const [localApiKey, setLocalApiKey] = (0, import_react18.useState)(apiKey);
|
|
@@ -9340,7 +9328,7 @@ var SettingsModal = ({
|
|
|
9340
9328
|
label: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815"
|
|
9341
9329
|
}
|
|
9342
9330
|
),
|
|
9343
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9331
|
+
showMemoryTab && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9344
9332
|
TabButton,
|
|
9345
9333
|
{
|
|
9346
9334
|
active: activeTab === "memory",
|
|
@@ -9349,7 +9337,7 @@ var SettingsModal = ({
|
|
|
9349
9337
|
label: "AI \uBA54\uBAA8\uB9AC"
|
|
9350
9338
|
}
|
|
9351
9339
|
),
|
|
9352
|
-
enableProjects && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9340
|
+
showMemoryTab && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9353
9341
|
TabButton,
|
|
9354
9342
|
{
|
|
9355
9343
|
active: activeTab === "project-memory",
|
|
@@ -9536,7 +9524,7 @@ var SettingsModal = ({
|
|
|
9536
9524
|
}
|
|
9537
9525
|
) })
|
|
9538
9526
|
] }),
|
|
9539
|
-
activeTab === "memory" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9527
|
+
activeTab === "memory" && showMemoryTab && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9540
9528
|
MemoryTabContent,
|
|
9541
9529
|
{
|
|
9542
9530
|
items: memoryItems,
|
|
@@ -9545,7 +9533,7 @@ var SettingsModal = ({
|
|
|
9545
9533
|
onClearAll: onClearMemory
|
|
9546
9534
|
}
|
|
9547
9535
|
),
|
|
9548
|
-
activeTab === "project-memory" && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9536
|
+
activeTab === "project-memory" && showMemoryTab && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
9549
9537
|
MemoryTabContent,
|
|
9550
9538
|
{
|
|
9551
9539
|
items: projectMemoryItems,
|
|
@@ -10731,6 +10719,7 @@ var ChatUIView = ({
|
|
|
10731
10719
|
sidebarRenderAfterHeader,
|
|
10732
10720
|
sidebarRenderFooter,
|
|
10733
10721
|
showSettings,
|
|
10722
|
+
showMemoryTab,
|
|
10734
10723
|
showModelSelector,
|
|
10735
10724
|
showThinking,
|
|
10736
10725
|
thinkingDefaultOpen,
|
|
@@ -10999,6 +10988,7 @@ var ChatUIView = ({
|
|
|
10999
10988
|
onDeleteMemory: globalMemory ? (key) => globalMemory.remove(key) : void 0,
|
|
11000
10989
|
onClearMemory: globalMemory ? () => globalMemory.clear() : void 0,
|
|
11001
10990
|
onSave: savePersonalization,
|
|
10991
|
+
showMemoryTab,
|
|
11002
10992
|
enableProjects: projects.length > 0,
|
|
11003
10993
|
projectMemoryItems,
|
|
11004
10994
|
onDeleteProjectMemory: projectMemory ? (key) => projectMemory.remove(key) : void 0,
|
|
@@ -11039,6 +11029,7 @@ var ChatUIWithHook = ({
|
|
|
11039
11029
|
sidebarRenderAfterHeader,
|
|
11040
11030
|
sidebarRenderFooter,
|
|
11041
11031
|
showSettings = true,
|
|
11032
|
+
showMemoryTab = true,
|
|
11042
11033
|
showModelSelector = true,
|
|
11043
11034
|
systemPrompt,
|
|
11044
11035
|
contextCompressionThreshold = 20,
|
|
@@ -11131,6 +11122,7 @@ var ChatUIWithHook = ({
|
|
|
11131
11122
|
sidebarRenderAfterHeader,
|
|
11132
11123
|
sidebarRenderFooter,
|
|
11133
11124
|
showSettings,
|
|
11125
|
+
showMemoryTab,
|
|
11134
11126
|
showModelSelector,
|
|
11135
11127
|
showThinking,
|
|
11136
11128
|
thinkingDefaultOpen,
|
|
@@ -11154,6 +11146,7 @@ var ChatUI = (props) => {
|
|
|
11154
11146
|
sidebarRenderAfterHeader,
|
|
11155
11147
|
sidebarRenderFooter,
|
|
11156
11148
|
showSettings = true,
|
|
11149
|
+
showMemoryTab: chatStateShowMemoryTab = true,
|
|
11157
11150
|
showModelSelector = true,
|
|
11158
11151
|
showThinking = true,
|
|
11159
11152
|
thinkingDefaultOpen = false,
|
|
@@ -11175,6 +11168,7 @@ var ChatUI = (props) => {
|
|
|
11175
11168
|
sidebarRenderAfterHeader,
|
|
11176
11169
|
sidebarRenderFooter,
|
|
11177
11170
|
showSettings,
|
|
11171
|
+
showMemoryTab: chatStateShowMemoryTab,
|
|
11178
11172
|
showModelSelector,
|
|
11179
11173
|
showThinking,
|
|
11180
11174
|
thinkingDefaultOpen,
|