@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.
@@ -417,7 +417,7 @@ var parseExtractionResult = (text) => {
417
417
  function useInfoExtraction(options) {
418
418
  const [isExtracting, setIsExtracting] = useState2(false);
419
419
  const [lastExtraction, setLastExtraction] = useState2(null);
420
- const { apiEndpoint, model, minConfidence = 0.8, globalMemory } = options;
420
+ const { apiEndpoint, model, minConfidence = 0.8, globalMemory, onCallLLM } = options;
421
421
  const extractInfo = useCallback2(
422
422
  async (messages) => {
423
423
  if (messages.length === 0) {
@@ -426,41 +426,44 @@ function useInfoExtraction(options) {
426
426
  setIsExtracting(true);
427
427
  try {
428
428
  const prompt = buildExtractionPrompt(messages);
429
- const response = await fetch(apiEndpoint, {
430
- method: "POST",
431
- headers: { "Content-Type": "application/json" },
432
- body: JSON.stringify({
433
- messages: [{ role: "user", content: prompt }],
434
- model: model || "default"
435
- })
436
- });
437
- if (!response.ok) {
438
- throw new Error(`API error: ${response.status}`);
439
- }
440
- const reader = response.body?.getReader();
441
- if (!reader) {
442
- return [];
443
- }
444
- const decoder = new TextDecoder();
445
- let buffer = "";
446
- let fullResponse = "";
447
- while (true) {
448
- const { done, value } = await reader.read();
449
- if (done) break;
450
- buffer += decoder.decode(value, { stream: true });
451
- const lines = buffer.split("\n");
452
- buffer = lines.pop() || "";
453
- for (const line of lines) {
454
- if (line.startsWith("data: ")) {
455
- const data = line.slice(6);
456
- if (data === "[DONE]") continue;
457
- try {
458
- const parsed = JSON.parse(data);
459
- {
429
+ let fullResponse;
430
+ if (onCallLLM) {
431
+ fullResponse = await onCallLLM(prompt, model || "default");
432
+ } else {
433
+ const response = await fetch(apiEndpoint, {
434
+ method: "POST",
435
+ headers: { "Content-Type": "application/json" },
436
+ body: JSON.stringify({
437
+ messages: [{ role: "user", content: prompt }],
438
+ model: model || "default"
439
+ })
440
+ });
441
+ if (!response.ok) {
442
+ throw new Error(`API error: ${response.status}`);
443
+ }
444
+ const reader = response.body?.getReader();
445
+ if (!reader) {
446
+ return [];
447
+ }
448
+ const decoder = new TextDecoder();
449
+ let buffer = "";
450
+ fullResponse = "";
451
+ while (true) {
452
+ const { done, value } = await reader.read();
453
+ if (done) break;
454
+ buffer += decoder.decode(value, { stream: true });
455
+ const lines = buffer.split("\n");
456
+ buffer = lines.pop() || "";
457
+ for (const line of lines) {
458
+ if (line.startsWith("data: ")) {
459
+ const data = line.slice(6);
460
+ if (data === "[DONE]") continue;
461
+ try {
462
+ const parsed = JSON.parse(data);
460
463
  const chunk = parsed.content ?? parsed.text ?? "";
461
464
  if (chunk) fullResponse += chunk;
465
+ } catch {
462
466
  }
463
- } catch {
464
467
  }
465
468
  }
466
469
  }
@@ -487,7 +490,7 @@ function useInfoExtraction(options) {
487
490
  setIsExtracting(false);
488
491
  }
489
492
  },
490
- [apiEndpoint, model, minConfidence, globalMemory]
493
+ [apiEndpoint, model, minConfidence, globalMemory, onCallLLM]
491
494
  );
492
495
  return {
493
496
  extractInfo,
@@ -1543,6 +1546,33 @@ var removeSessionCache = (storageKey, sessionId) => {
1543
1546
  };
1544
1547
 
1545
1548
  // src/react/hooks/useChatUI.ts
1549
+ var parseSSEResponse = async (response) => {
1550
+ const reader = response.body?.getReader();
1551
+ if (!reader) return "";
1552
+ const decoder = new TextDecoder();
1553
+ let buffer = "";
1554
+ let result = "";
1555
+ while (true) {
1556
+ const { done, value } = await reader.read();
1557
+ if (done) break;
1558
+ buffer += decoder.decode(value, { stream: true });
1559
+ const lines = buffer.split("\n");
1560
+ buffer = lines.pop() || "";
1561
+ for (const line of lines) {
1562
+ if (line.startsWith("data: ")) {
1563
+ const data = line.slice(6);
1564
+ if (data === "[DONE]") continue;
1565
+ try {
1566
+ const parsed = JSON.parse(data);
1567
+ const chunk = parsed.content ?? parsed.text ?? "";
1568
+ if (chunk) result += chunk;
1569
+ } catch {
1570
+ }
1571
+ }
1572
+ }
1573
+ }
1574
+ return result;
1575
+ };
1546
1576
  var DEFAULT_STORAGE_KEY = "chatllm_sessions";
1547
1577
  var DEFAULT_COMPRESSION_THRESHOLD = 20;
1548
1578
  var DEFAULT_KEEP_RECENT = 6;
@@ -1748,11 +1778,37 @@ var useChatUI = (options) => {
1748
1778
  );
1749
1779
  const projectMemoryRaw = useGlobalMemory(projectMemoryOptions);
1750
1780
  const projectMemory = enableProjects ? projectMemoryRaw : null;
1781
+ const callInternalLLM = useCallback5(async (prompt, model) => {
1782
+ if (onSendMessageRef.current) {
1783
+ const modelConfig = models.find((m) => m.id === model);
1784
+ const provider = modelConfig?.provider || "ollama";
1785
+ const result = await onSendMessageRef.current({
1786
+ messages: [{ role: "user", content: prompt }],
1787
+ model,
1788
+ provider,
1789
+ apiKey
1790
+ });
1791
+ if (typeof result === "string") return result;
1792
+ if (typeof result === "object" && "content" in result) return result.content;
1793
+ return parseSSEResponse(new Response(result));
1794
+ }
1795
+ const response = await fetch(apiEndpoint, {
1796
+ method: "POST",
1797
+ headers: { "Content-Type": "application/json" },
1798
+ body: JSON.stringify({
1799
+ messages: [{ role: "user", content: prompt }],
1800
+ model
1801
+ })
1802
+ });
1803
+ if (!response.ok) return "";
1804
+ return parseSSEResponse(response);
1805
+ }, [apiEndpoint, apiKey, models]);
1751
1806
  const infoExtraction = useInfoExtraction({
1752
1807
  apiEndpoint,
1753
1808
  model: selectedModel,
1754
1809
  minConfidence: 0.8,
1755
- globalMemory
1810
+ globalMemory,
1811
+ onCallLLM: callInternalLLM
1756
1812
  });
1757
1813
  const currentSession = sessions.find((s) => s.id === currentSessionId) || null;
1758
1814
  const messages = currentSession?.messages.filter((m) => !m.hidden) || [];
@@ -1950,46 +2006,11 @@ ${conversationText}
1950
2006
 
1951
2007
  \uC694\uC57D:`;
1952
2008
  try {
1953
- const response = await fetch(apiEndpoint, {
1954
- method: "POST",
1955
- headers: { "Content-Type": "application/json" },
1956
- body: JSON.stringify({
1957
- messages: [{ role: "user", content: summaryPrompt }],
1958
- model
1959
- })
1960
- });
1961
- if (!response.ok) return "";
1962
- const reader = response.body?.getReader();
1963
- if (!reader) return "";
1964
- const decoder = new TextDecoder();
1965
- let buffer = "";
1966
- let summary = "";
1967
- while (true) {
1968
- const { done, value } = await reader.read();
1969
- if (done) break;
1970
- buffer += decoder.decode(value, { stream: true });
1971
- const lines = buffer.split("\n");
1972
- buffer = lines.pop() || "";
1973
- for (const line of lines) {
1974
- if (line.startsWith("data: ")) {
1975
- const data = line.slice(6);
1976
- if (data === "[DONE]") continue;
1977
- try {
1978
- const parsed = JSON.parse(data);
1979
- {
1980
- const chunk = parsed.content ?? parsed.text ?? "";
1981
- if (chunk) summary += chunk;
1982
- }
1983
- } catch {
1984
- }
1985
- }
1986
- }
1987
- }
1988
- return summary;
2009
+ return await callInternalLLM(summaryPrompt, model);
1989
2010
  } catch {
1990
2011
  return "";
1991
2012
  }
1992
- }, [apiEndpoint]);
2013
+ }, [callInternalLLM]);
1993
2014
  const incrementalCompressContext = useCallback5(
1994
2015
  async (existingSummary, newMessages, model) => {
1995
2016
  const newConversation = newMessages.map((m) => `${m.role === "user" ? "\uC0AC\uC6A9\uC790" : "AI"}: ${m.content}`).join("\n\n");
@@ -2009,47 +2030,13 @@ ${newConversation}
2009
2030
 
2010
2031
  \uD1B5\uD569 \uC694\uC57D:`;
2011
2032
  try {
2012
- const response = await fetch(apiEndpoint, {
2013
- method: "POST",
2014
- headers: { "Content-Type": "application/json" },
2015
- body: JSON.stringify({
2016
- messages: [{ role: "user", content: mergePrompt }],
2017
- model
2018
- })
2019
- });
2020
- if (!response.ok) return existingSummary;
2021
- const reader = response.body?.getReader();
2022
- if (!reader) return existingSummary;
2023
- const decoder = new TextDecoder();
2024
- let buffer = "";
2025
- let summary = "";
2026
- while (true) {
2027
- const { done, value } = await reader.read();
2028
- if (done) break;
2029
- buffer += decoder.decode(value, { stream: true });
2030
- const lines = buffer.split("\n");
2031
- buffer = lines.pop() || "";
2032
- for (const line of lines) {
2033
- if (line.startsWith("data: ")) {
2034
- const data = line.slice(6);
2035
- if (data === "[DONE]") continue;
2036
- try {
2037
- const parsed = JSON.parse(data);
2038
- {
2039
- const chunk = parsed.content ?? parsed.text ?? "";
2040
- if (chunk) summary += chunk;
2041
- }
2042
- } catch {
2043
- }
2044
- }
2045
- }
2046
- }
2033
+ const summary = await callInternalLLM(mergePrompt, model);
2047
2034
  return summary || existingSummary;
2048
2035
  } catch {
2049
2036
  return existingSummary;
2050
2037
  }
2051
2038
  },
2052
- [apiEndpoint]
2039
+ [callInternalLLM]
2053
2040
  );
2054
2041
  const estimateTokens = useCallback5((messages2) => {
2055
2042
  return messages2.reduce((sum, m) => sum + Math.ceil(m.content.length / 4), 0);
@@ -9168,7 +9155,8 @@ var SettingsModal = ({
9168
9155
  onDeleteProjectMemory,
9169
9156
  onClearProjectMemory,
9170
9157
  enableProjects = false,
9171
- currentProjectTitle
9158
+ currentProjectTitle,
9159
+ showMemoryTab = true
9172
9160
  }) => {
9173
9161
  const [activeTab, setActiveTab] = useState16("general");
9174
9162
  const [localApiKey, setLocalApiKey] = useState16(apiKey);
@@ -9274,7 +9262,7 @@ var SettingsModal = ({
9274
9262
  label: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815"
9275
9263
  }
9276
9264
  ),
9277
- /* @__PURE__ */ jsx18(
9265
+ showMemoryTab && /* @__PURE__ */ jsx18(
9278
9266
  TabButton,
9279
9267
  {
9280
9268
  active: activeTab === "memory",
@@ -9283,7 +9271,7 @@ var SettingsModal = ({
9283
9271
  label: "AI \uBA54\uBAA8\uB9AC"
9284
9272
  }
9285
9273
  ),
9286
- enableProjects && /* @__PURE__ */ jsx18(
9274
+ showMemoryTab && enableProjects && /* @__PURE__ */ jsx18(
9287
9275
  TabButton,
9288
9276
  {
9289
9277
  active: activeTab === "project-memory",
@@ -9470,7 +9458,7 @@ var SettingsModal = ({
9470
9458
  }
9471
9459
  ) })
9472
9460
  ] }),
9473
- activeTab === "memory" && /* @__PURE__ */ jsx18(
9461
+ activeTab === "memory" && showMemoryTab && /* @__PURE__ */ jsx18(
9474
9462
  MemoryTabContent,
9475
9463
  {
9476
9464
  items: memoryItems,
@@ -9479,7 +9467,7 @@ var SettingsModal = ({
9479
9467
  onClearAll: onClearMemory
9480
9468
  }
9481
9469
  ),
9482
- activeTab === "project-memory" && enableProjects && /* @__PURE__ */ jsx18(
9470
+ activeTab === "project-memory" && showMemoryTab && enableProjects && /* @__PURE__ */ jsx18(
9483
9471
  MemoryTabContent,
9484
9472
  {
9485
9473
  items: projectMemoryItems,
@@ -10665,6 +10653,7 @@ var ChatUIView = ({
10665
10653
  sidebarRenderAfterHeader,
10666
10654
  sidebarRenderFooter,
10667
10655
  showSettings,
10656
+ showMemoryTab,
10668
10657
  showModelSelector,
10669
10658
  showThinking,
10670
10659
  thinkingDefaultOpen,
@@ -10933,6 +10922,7 @@ var ChatUIView = ({
10933
10922
  onDeleteMemory: globalMemory ? (key) => globalMemory.remove(key) : void 0,
10934
10923
  onClearMemory: globalMemory ? () => globalMemory.clear() : void 0,
10935
10924
  onSave: savePersonalization,
10925
+ showMemoryTab,
10936
10926
  enableProjects: projects.length > 0,
10937
10927
  projectMemoryItems,
10938
10928
  onDeleteProjectMemory: projectMemory ? (key) => projectMemory.remove(key) : void 0,
@@ -10973,6 +10963,7 @@ var ChatUIWithHook = ({
10973
10963
  sidebarRenderAfterHeader,
10974
10964
  sidebarRenderFooter,
10975
10965
  showSettings = true,
10966
+ showMemoryTab = true,
10976
10967
  showModelSelector = true,
10977
10968
  systemPrompt,
10978
10969
  contextCompressionThreshold = 20,
@@ -11065,6 +11056,7 @@ var ChatUIWithHook = ({
11065
11056
  sidebarRenderAfterHeader,
11066
11057
  sidebarRenderFooter,
11067
11058
  showSettings,
11059
+ showMemoryTab,
11068
11060
  showModelSelector,
11069
11061
  showThinking,
11070
11062
  thinkingDefaultOpen,
@@ -11088,6 +11080,7 @@ var ChatUI = (props) => {
11088
11080
  sidebarRenderAfterHeader,
11089
11081
  sidebarRenderFooter,
11090
11082
  showSettings = true,
11083
+ showMemoryTab: chatStateShowMemoryTab = true,
11091
11084
  showModelSelector = true,
11092
11085
  showThinking = true,
11093
11086
  thinkingDefaultOpen = false,
@@ -11109,6 +11102,7 @@ var ChatUI = (props) => {
11109
11102
  sidebarRenderAfterHeader,
11110
11103
  sidebarRenderFooter,
11111
11104
  showSettings,
11105
+ showMemoryTab: chatStateShowMemoryTab,
11112
11106
  showModelSelector,
11113
11107
  showThinking,
11114
11108
  thinkingDefaultOpen,