@gendive/chatllm 0.17.19 → 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.js +95 -108
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +95 -108
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
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);
|