@gendive/chatllm 0.17.42 → 0.17.44

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.
@@ -1665,6 +1665,34 @@ var convertAttachmentsToBase64 = async (attachments) => Promise.all(
1665
1665
  size: att.size
1666
1666
  }))
1667
1667
  );
1668
+ var findPreviousResultImage = (messages) => {
1669
+ for (let i = messages.length - 1; i >= 0; i--) {
1670
+ const msg = messages[i];
1671
+ if (msg.role !== "assistant") continue;
1672
+ if (msg.contentParts) {
1673
+ for (let j = msg.contentParts.length - 1; j >= 0; j--) {
1674
+ const part = msg.contentParts[j];
1675
+ if (part.type === "tool_result" && part.result?.type === "image" && part.result?.content) {
1676
+ return { name: "\uC774\uC804 \uC0DD\uC131 \uC774\uBBF8\uC9C0", url: part.result.content };
1677
+ }
1678
+ if (part.type === "image" && part.url) {
1679
+ return { name: part.alt || "\uC774\uC804 \uC774\uBBF8\uC9C0", url: part.url };
1680
+ }
1681
+ }
1682
+ }
1683
+ if (msg.skillExecution?.result?.metadata?.type === "image" && msg.skillExecution.result.content) {
1684
+ return { name: "\uC774\uC804 \uC0DD\uC131 \uC774\uBBF8\uC9C0", url: msg.skillExecution.result.content };
1685
+ }
1686
+ if (msg.checklistBlock?.items) {
1687
+ for (let j = msg.checklistBlock.items.length - 1; j >= 0; j--) {
1688
+ if (msg.checklistBlock.items[j].imageUrl) {
1689
+ return { name: "\uC774\uC804 \uC0DD\uC131 \uC774\uBBF8\uC9C0", url: msg.checklistBlock.items[j].imageUrl };
1690
+ }
1691
+ }
1692
+ }
1693
+ }
1694
+ return null;
1695
+ };
1668
1696
  var generateTitle = (messages) => {
1669
1697
  const firstUserMessage = messages.find((m) => m.role === "user");
1670
1698
  if (!firstUserMessage) return "\uC0C8 \uB300\uD654";
@@ -2545,8 +2573,11 @@ ${finalContent}`;
2545
2573
  const attachmentSkills = Object.entries(resolvedSkills).filter(
2546
2574
  ([, config]) => config.trigger === "attachment"
2547
2575
  );
2576
+ const hasImageAtts = currentAttachments.some((a) => a.type === "image");
2577
+ const hasText = finalContent.trim().length > 0;
2578
+ const skipImageAttachmentSkill = hasImageAtts && hasText;
2548
2579
  for (const [skillName, skillConfig] of attachmentSkills) {
2549
- const matchedFiles = currentAttachments.filter((att) => {
2580
+ let matchedFiles = currentAttachments.filter((att) => {
2550
2581
  if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
2551
2582
  return skillConfig.acceptedTypes.some((type) => {
2552
2583
  if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
@@ -2557,6 +2588,9 @@ ${finalContent}`;
2557
2588
  return att.mimeType === type;
2558
2589
  });
2559
2590
  });
2591
+ if (skipImageAttachmentSkill) {
2592
+ matchedFiles = matchedFiles.filter((att) => att.type !== "image");
2593
+ }
2560
2594
  if (matchedFiles.length === 0) continue;
2561
2595
  setSessions(
2562
2596
  (prev) => prev.map((s) => {
@@ -2640,6 +2674,18 @@ ${finalContent}`;
2640
2674
  pendingAttachmentDataRef.current = null;
2641
2675
  }
2642
2676
  }
2677
+ if (currentAttachments.length === 0 && finalContent.trim().length > 0 && !pendingAttachmentDataRef.current) {
2678
+ const previousImage = findPreviousResultImage(existingMessages);
2679
+ if (previousImage) {
2680
+ pendingAttachmentDataRef.current = [{
2681
+ name: previousImage.name,
2682
+ mimeType: "image/png",
2683
+ base64: "",
2684
+ url: previousImage.url,
2685
+ size: 0
2686
+ }];
2687
+ }
2688
+ }
2643
2689
  let shouldContinueAfterAttachment = continueAfterToolResult;
2644
2690
  if (attachmentResults.length > 0) {
2645
2691
  for (const part of attachmentResults) {
@@ -2762,6 +2808,27 @@ ${attachmentContext}
2762
2808
  });
2763
2809
  }
2764
2810
  }
2811
+ } else if (attachmentResults.length === 0 && pendingAttachmentDataRef.current !== null) {
2812
+ const isReferenceImage = pendingAttachmentDataRef.current.some((d) => d.url && !d.base64);
2813
+ if (isReferenceImage) {
2814
+ chatMessages.push({
2815
+ role: "user",
2816
+ content: `\uC774\uC804 \uB300\uD654\uC5D0\uC11C \uC0DD\uC131/\uD3B8\uC9D1\uB41C \uC774\uBBF8\uC9C0\uAC00 \uC788\uC2B5\uB2C8\uB2E4. \uC774\uBBF8\uC9C0 \uB370\uC774\uD130\uB294 \uB3C4\uAD6C \uD638\uCD9C \uC2DC \uC790\uB3D9\uC73C\uB85C \uC804\uB2EC\uB429\uB2C8\uB2E4.
2817
+
2818
+ \uC0AC\uC6A9\uC790\uAC00 \uC774 \uC774\uBBF8\uC9C0\uB97C \uAE30\uBC18\uC73C\uB85C \uCD94\uAC00 \uC791\uC5C5\uC744 \uC694\uCCAD\uD558\uB294 \uACBD\uC6B0, \uC774\uBBF8\uC9C0\uB97C \uB2E4\uC2DC \uC694\uCCAD\uD558\uC9C0 \uB9D0\uACE0 \uBC14\uB85C \uC801\uC808\uD55C \uB3C4\uAD6C\uB97C \uD638\uCD9C\uD558\uC138\uC694.`
2819
+ });
2820
+ } else {
2821
+ chatMessages.push({
2822
+ role: "user",
2823
+ content: `\uC0AC\uC6A9\uC790\uAC00 \uC774\uBBF8\uC9C0\uB97C \uCCA8\uBD80\uD588\uC2B5\uB2C8\uB2E4. \uC774\uBBF8\uC9C0 \uB370\uC774\uD130\uB294 \uB3C4\uAD6C \uD638\uCD9C \uC2DC \uC790\uB3D9\uC73C\uB85C \uC804\uB2EC\uB429\uB2C8\uB2E4.
2824
+
2825
+ \uC0AC\uC6A9\uC790\uC758 \uC694\uCCAD \uC758\uB3C4\uB97C \uD30C\uC545\uD558\uC5EC \uC801\uC808\uD55C \uB3C4\uAD6C\uB97C \uC120\uD0DD\uD558\uC138\uC694:
2826
+ - \uC774\uBBF8\uC9C0 \uBD84\uC11D/\uC124\uBA85 \uC694\uCCAD \u2192 analyze_image \uB3C4\uAD6C
2827
+ - \uC774\uBBF8\uC9C0 \uD3B8\uC9D1/\uC218\uC815 \uC694\uCCAD \u2192 edit_image \uB3C4\uAD6C
2828
+ - \uC0C8 \uC774\uBBF8\uC9C0 \uC0DD\uC131 \uC694\uCCAD \u2192 generate_image \uB3C4\uAD6C
2829
+ - \uB3C4\uAD6C \uC5C6\uC774 \uB2F5\uBCC0 \uAC00\uB2A5 \u2192 \uBC14\uB85C \uB2F5\uBCC0`
2830
+ });
2831
+ }
2765
2832
  }
2766
2833
  console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content: m.content.slice(0, 50) })));
2767
2834
  const baseSystemPrompt = buildSystemPrompt();
@@ -2987,7 +3054,8 @@ ${attachmentContext}
2987
3054
  }, attachExtra);
2988
3055
  pendingAttachmentDataRef.current = null;
2989
3056
  if (skillResult?.content) {
2990
- if (skillResult.metadata?.type === "image") {
3057
+ const isImageSkillResult = skillResult.metadata?.type === "image" || skillResult.metadata?.resultType === "image";
3058
+ if (isImageSkillResult) {
2991
3059
  accumulatedContent = skillResult.metadata?.outputText || "\uC774\uBBF8\uC9C0 \uC0DD\uC131 \uC644\uB8CC";
2992
3060
  checklistStepImageUrl = skillResult.content;
2993
3061
  } else {
@@ -3132,7 +3200,7 @@ ${result.content}
3132
3200
  abortControllerRef.current = null;
3133
3201
  return;
3134
3202
  }
3135
- const skillResultType = result.metadata?.type;
3203
+ const skillResultType = result.metadata?.type || result.metadata?.resultType;
3136
3204
  if (skillResultType === "image" || skillResultType === "file") {
3137
3205
  const imgFileParts = [];
3138
3206
  if (skillCleanContent.trim()) {