@gendive/chatllm 0.17.25 → 0.17.27

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.
@@ -2567,6 +2567,7 @@ ${finalContent}`;
2567
2567
  try {
2568
2568
  const shouldSkipSkillParsing = skipNextSkillParsingRef.current;
2569
2569
  skipNextSkillParsingRef.current = false;
2570
+ let accumulatedContent = "";
2570
2571
  let messagesToSend = [...existingMessages, userMessage];
2571
2572
  const recompressionThreshold = DEFAULT_RECOMPRESSION_THRESHOLD;
2572
2573
  const tokenLimit = DEFAULT_TOKEN_LIMIT;
@@ -2655,6 +2656,7 @@ ${attachmentContext}
2655
2656
  systemPrompt: combinedSystemPrompt
2656
2657
  });
2657
2658
  if (typeof result === "string") {
2659
+ accumulatedContent = result;
2658
2660
  setSessions(
2659
2661
  (prev) => prev.map((s) => {
2660
2662
  if (s.id === capturedSessionId) {
@@ -2668,9 +2670,8 @@ ${attachmentContext}
2668
2670
  return s;
2669
2671
  })
2670
2672
  );
2671
- return;
2672
- }
2673
- if (typeof result === "object" && "content" in result) {
2673
+ } else if (typeof result === "object" && "content" in result) {
2674
+ accumulatedContent = result.content;
2674
2675
  setSessions(
2675
2676
  (prev) => prev.map((s) => {
2676
2677
  if (s.id === capturedSessionId) {
@@ -2684,9 +2685,9 @@ ${attachmentContext}
2684
2685
  return s;
2685
2686
  })
2686
2687
  );
2687
- return;
2688
+ } else {
2689
+ response = new Response(result);
2688
2690
  }
2689
- response = new Response(result);
2690
2691
  } else {
2691
2692
  const isOllama = provider === "ollama" || apiEndpoint.includes("ollama") || apiEndpoint.includes("11434");
2692
2693
  const requestBody = isOllama ? { model: selectedModel, messages: messagesForApi, stream: true } : {
@@ -2703,104 +2704,105 @@ ${attachmentContext}
2703
2704
  signal: abortControllerRef.current.signal
2704
2705
  });
2705
2706
  }
2706
- if (!response.ok) throw new Error("API error");
2707
- const reader = response.body?.getReader();
2708
- if (!reader) throw new Error("No reader");
2709
- const decoder = new TextDecoder();
2710
- let buffer = "";
2711
- let accumulatedContent = "";
2712
- let skillTagDetected = false;
2713
- let checklistTagDetected = false;
2714
- while (true) {
2715
- const { done, value } = await reader.read();
2716
- if (done) break;
2717
- buffer += decoder.decode(value, { stream: true });
2718
- const lines = buffer.split("\n");
2719
- buffer = lines.pop() || "";
2720
- for (const line of lines) {
2721
- if (!line.trim()) continue;
2722
- let data = line;
2723
- if (line.startsWith("data: ")) {
2724
- data = line.slice(6);
2725
- if (data === "[DONE]") continue;
2707
+ if (response) {
2708
+ if (!response.ok) throw new Error("API error");
2709
+ const reader = response.body?.getReader();
2710
+ if (!reader) throw new Error("No reader");
2711
+ const decoder = new TextDecoder();
2712
+ let buffer = "";
2713
+ let skillTagDetected = false;
2714
+ let checklistTagDetected = false;
2715
+ while (true) {
2716
+ const { done, value } = await reader.read();
2717
+ if (done) break;
2718
+ buffer += decoder.decode(value, { stream: true });
2719
+ const lines = buffer.split("\n");
2720
+ buffer = lines.pop() || "";
2721
+ for (const line of lines) {
2722
+ if (!line.trim()) continue;
2723
+ let data = line;
2724
+ if (line.startsWith("data: ")) {
2725
+ data = line.slice(6);
2726
+ if (data === "[DONE]") continue;
2727
+ }
2728
+ try {
2729
+ const parsed = JSON.parse(data);
2730
+ const content2 = parsed.message?.content || parsed.content || parsed.text || "";
2731
+ const thinking = parsed.message?.thinking || "";
2732
+ if (content2 || thinking) {
2733
+ if (content2) accumulatedContent += content2;
2734
+ if (!shouldSkipSkillParsing && accumulatedContent.includes("</skill_use>")) {
2735
+ const endIdx = accumulatedContent.indexOf("</skill_use>");
2736
+ accumulatedContent = accumulatedContent.substring(0, endIdx + "</skill_use>".length);
2737
+ skillTagDetected = true;
2738
+ }
2739
+ if (!skipNextChecklistParsingRef.current && accumulatedContent.includes("</checklist>")) {
2740
+ const endIdx = accumulatedContent.indexOf("</checklist>");
2741
+ accumulatedContent = accumulatedContent.substring(0, endIdx + "</checklist>".length);
2742
+ checklistTagDetected = true;
2743
+ }
2744
+ const displayContent = skillTagDetected ? accumulatedContent : null;
2745
+ setSessions(
2746
+ (prev) => prev.map((s) => {
2747
+ if (s.id === capturedSessionId) {
2748
+ return {
2749
+ ...s,
2750
+ messages: s.messages.map((m) => {
2751
+ if (m.id !== assistantMessageId) return m;
2752
+ if (displayContent) {
2753
+ return { ...m, content: displayContent };
2754
+ }
2755
+ let newContent = m.content;
2756
+ if (thinking) {
2757
+ if (!newContent.includes("<thinking>")) {
2758
+ newContent = "<thinking>" + thinking;
2759
+ } else if (!newContent.includes("</thinking>")) {
2760
+ newContent += thinking;
2761
+ }
2762
+ }
2763
+ if (content2) {
2764
+ if (newContent.includes("<thinking>") && !newContent.includes("</thinking>")) {
2765
+ newContent += "</thinking>\n\n";
2766
+ }
2767
+ newContent += content2;
2768
+ }
2769
+ return { ...m, content: newContent };
2770
+ })
2771
+ };
2772
+ }
2773
+ return s;
2774
+ })
2775
+ );
2776
+ if (skillTagDetected || checklistTagDetected) break;
2777
+ }
2778
+ } catch {
2779
+ }
2726
2780
  }
2781
+ if (skillTagDetected || checklistTagDetected) break;
2782
+ }
2783
+ if (buffer.trim()) {
2727
2784
  try {
2728
- const parsed = JSON.parse(data);
2729
- const content2 = parsed.message?.content || parsed.content || parsed.text || "";
2730
- const thinking = parsed.message?.thinking || "";
2731
- if (content2 || thinking) {
2732
- if (content2) accumulatedContent += content2;
2733
- if (!shouldSkipSkillParsing && accumulatedContent.includes("</skill_use>")) {
2734
- const endIdx = accumulatedContent.indexOf("</skill_use>");
2735
- accumulatedContent = accumulatedContent.substring(0, endIdx + "</skill_use>".length);
2736
- skillTagDetected = true;
2737
- }
2738
- if (!skipNextChecklistParsingRef.current && accumulatedContent.includes("</checklist>")) {
2739
- const endIdx = accumulatedContent.indexOf("</checklist>");
2740
- accumulatedContent = accumulatedContent.substring(0, endIdx + "</checklist>".length);
2741
- checklistTagDetected = true;
2742
- }
2743
- const displayContent = skillTagDetected ? accumulatedContent : null;
2785
+ const parsed = JSON.parse(buffer);
2786
+ const content2 = parsed.message?.content || parsed.content || parsed.text;
2787
+ if (content2) {
2788
+ accumulatedContent += content2;
2744
2789
  setSessions(
2745
2790
  (prev) => prev.map((s) => {
2746
2791
  if (s.id === capturedSessionId) {
2747
2792
  return {
2748
2793
  ...s,
2749
- messages: s.messages.map((m) => {
2750
- if (m.id !== assistantMessageId) return m;
2751
- if (displayContent) {
2752
- return { ...m, content: displayContent };
2753
- }
2754
- let newContent = m.content;
2755
- if (thinking) {
2756
- if (!newContent.includes("<thinking>")) {
2757
- newContent = "<thinking>" + thinking;
2758
- } else if (!newContent.includes("</thinking>")) {
2759
- newContent += thinking;
2760
- }
2761
- }
2762
- if (content2) {
2763
- if (newContent.includes("<thinking>") && !newContent.includes("</thinking>")) {
2764
- newContent += "</thinking>\n\n";
2765
- }
2766
- newContent += content2;
2767
- }
2768
- return { ...m, content: newContent };
2769
- })
2794
+ messages: s.messages.map(
2795
+ (m) => m.id === assistantMessageId ? { ...m, content: m.content + content2 } : m
2796
+ )
2770
2797
  };
2771
2798
  }
2772
2799
  return s;
2773
2800
  })
2774
2801
  );
2775
- if (skillTagDetected || checklistTagDetected) break;
2776
2802
  }
2777
2803
  } catch {
2778
2804
  }
2779
2805
  }
2780
- if (skillTagDetected || checklistTagDetected) break;
2781
- }
2782
- if (buffer.trim()) {
2783
- try {
2784
- const parsed = JSON.parse(buffer);
2785
- const content2 = parsed.message?.content || parsed.content || parsed.text;
2786
- if (content2) {
2787
- accumulatedContent += content2;
2788
- setSessions(
2789
- (prev) => prev.map((s) => {
2790
- if (s.id === capturedSessionId) {
2791
- return {
2792
- ...s,
2793
- messages: s.messages.map(
2794
- (m) => m.id === assistantMessageId ? { ...m, content: m.content + content2 } : m
2795
- )
2796
- };
2797
- }
2798
- return s;
2799
- })
2800
- );
2801
- }
2802
- } catch {
2803
- }
2804
2806
  }
2805
2807
  const saveMessagesOnEarlyReturn = () => {
2806
2808
  if (!useExternalStorage || !capturedSessionId) return;
@@ -2824,7 +2826,26 @@ ${attachmentContext}
2824
2826
  };
2825
2827
  if (!shouldSkipSkillParsing) {
2826
2828
  const assistantContent = accumulatedContent;
2829
+ console.log("[useChatUI] Post-processing \u2014 accumulatedContent \uAE38\uC774:", assistantContent.length, ", skill_use \uD3EC\uD568:", assistantContent.includes("<skill_use"));
2827
2830
  const { skillCall: detectedSkill, cleanContent: skillCleanContent } = parseSkillCallFromContent(assistantContent);
2831
+ if (detectedSkill) {
2832
+ console.log("[useChatUI] \uC2A4\uD0AC \uAC10\uC9C0:", detectedSkill.name, ", resolvedSkills \uD0A4:", Object.keys(resolvedSkills));
2833
+ }
2834
+ if (detectedSkill && !resolvedSkills[detectedSkill.name]) {
2835
+ console.warn(`[useChatUI] \uC2A4\uD0AC "${detectedSkill.name}" \uAC10\uC9C0\uB418\uC5C8\uC73C\uB098 \uBBF8\uB4F1\uB85D. \uB4F1\uB85D\uB41C \uC2A4\uD0AC:`, Object.keys(resolvedSkills));
2836
+ setSessions(
2837
+ (prev) => prev.map((s) => {
2838
+ if (s.id !== capturedSessionId) return s;
2839
+ return {
2840
+ ...s,
2841
+ messages: s.messages.map((m) => {
2842
+ if (m.id !== assistantMessageId) return m;
2843
+ return { ...m, content: skillCleanContent };
2844
+ })
2845
+ };
2846
+ })
2847
+ );
2848
+ }
2828
2849
  if (detectedSkill && resolvedSkills[detectedSkill.name]) {
2829
2850
  setSessions(
2830
2851
  (prev) => prev.map((s) => {