@gendive/chatllm 0.17.37 → 0.17.39
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 +5 -32
- package/dist/react/index.d.ts +5 -32
- package/dist/react/index.js +41 -50
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +41 -50
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -983,7 +983,7 @@ ${skillDescriptions}
|
|
|
983
983
|
**\uBC18\uBCF5: \uD574\uB2F9 \uB3C4\uAD6C\uAC00 \uC788\uB2E4\uBA74, <skill_use> \uD0DC\uADF8 \uC5C6\uC774 \uC808\uB300 \uC751\uB2F5\uD558\uC9C0 \uB9C8\uC138\uC694.**`;
|
|
984
984
|
}, [resolvedSkills]);
|
|
985
985
|
const handleSkillCall = useCallback3(
|
|
986
|
-
async (content, callbacks) => {
|
|
986
|
+
async (content, callbacks, extraParams) => {
|
|
987
987
|
const { skillCall, cleanContent } = parseSkillCallFromContent(content);
|
|
988
988
|
if (!skillCall) {
|
|
989
989
|
return { skillCall: null, cleanContent: content, result: null };
|
|
@@ -993,9 +993,10 @@ ${skillDescriptions}
|
|
|
993
993
|
console.warn(`[useSkills] \uB4F1\uB85D\uB418\uC9C0 \uC54A\uC740 \uC2A4\uD0AC: ${skillCall.name}`);
|
|
994
994
|
return { skillCall, cleanContent, result: null };
|
|
995
995
|
}
|
|
996
|
+
const mergedParams = extraParams ? { ...skillCall.params, ...extraParams } : skillCall.params;
|
|
996
997
|
setActiveSkillExecution({
|
|
997
998
|
skillName: skillCall.name,
|
|
998
|
-
params:
|
|
999
|
+
params: mergedParams,
|
|
999
1000
|
status: "executing"
|
|
1000
1001
|
});
|
|
1001
1002
|
const abortController = new AbortController();
|
|
@@ -1011,7 +1012,7 @@ ${skillDescriptions}
|
|
|
1011
1012
|
onStream: callbacks?.onStream,
|
|
1012
1013
|
signal: callbacks?.signal || abortController.signal
|
|
1013
1014
|
};
|
|
1014
|
-
const result = await skill.execute(
|
|
1015
|
+
const result = await skill.execute(mergedParams, mergedCallbacks);
|
|
1015
1016
|
setActiveSkillExecution(
|
|
1016
1017
|
(prev) => prev ? { ...prev, status: "done", result } : null
|
|
1017
1018
|
);
|
|
@@ -1712,8 +1713,6 @@ var useChatUI = (options) => {
|
|
|
1712
1713
|
onDeleteProject,
|
|
1713
1714
|
onAddProjectFile,
|
|
1714
1715
|
onDeleteProjectFile,
|
|
1715
|
-
// Image attachment mode
|
|
1716
|
-
imageAttachmentMode = "auto-execute",
|
|
1717
1716
|
// Stream control
|
|
1718
1717
|
continueAfterToolResult = true,
|
|
1719
1718
|
onSkillComplete,
|
|
@@ -1790,6 +1789,7 @@ var useChatUI = (options) => {
|
|
|
1790
1789
|
const skipNextSkillParsingRef = useRef4(false);
|
|
1791
1790
|
const skipNextChecklistParsingRef = useRef4(false);
|
|
1792
1791
|
const activeChecklistRef = useRef4(null);
|
|
1792
|
+
const pendingAttachmentDataRef = useRef4(null);
|
|
1793
1793
|
const lastExtractionMsgCountRef = useRef4(0);
|
|
1794
1794
|
const memoryOptions = useMemo2(
|
|
1795
1795
|
() => ({
|
|
@@ -2534,20 +2534,12 @@ ${finalContent}`;
|
|
|
2534
2534
|
})
|
|
2535
2535
|
);
|
|
2536
2536
|
let attachmentResults = [];
|
|
2537
|
-
const aiDecideImageAttachments = [];
|
|
2538
2537
|
if (currentAttachments.length > 0) {
|
|
2539
|
-
const autoExecAttachments = imageAttachmentMode === "ai-decide" ? currentAttachments.filter((att) => {
|
|
2540
|
-
if (att.type === "image") {
|
|
2541
|
-
aiDecideImageAttachments.push(att);
|
|
2542
|
-
return false;
|
|
2543
|
-
}
|
|
2544
|
-
return true;
|
|
2545
|
-
}) : currentAttachments;
|
|
2546
2538
|
const attachmentSkills = Object.entries(resolvedSkills).filter(
|
|
2547
2539
|
([, config]) => config.trigger === "attachment"
|
|
2548
2540
|
);
|
|
2549
2541
|
for (const [skillName, skillConfig] of attachmentSkills) {
|
|
2550
|
-
const matchedFiles =
|
|
2542
|
+
const matchedFiles = currentAttachments.filter((att) => {
|
|
2551
2543
|
if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
|
|
2552
2544
|
return skillConfig.acceptedTypes.some((type) => {
|
|
2553
2545
|
if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
|
|
@@ -2632,6 +2624,14 @@ ${finalContent}`;
|
|
|
2632
2624
|
);
|
|
2633
2625
|
}
|
|
2634
2626
|
}
|
|
2627
|
+
const hasImageAttachments = currentAttachments.some((a) => a.type === "image");
|
|
2628
|
+
const hasUserText = finalContent.trim().length > 0;
|
|
2629
|
+
if (hasImageAttachments && hasUserText) {
|
|
2630
|
+
const imageAttachments = currentAttachments.filter((a) => a.type === "image");
|
|
2631
|
+
pendingAttachmentDataRef.current = await convertAttachmentsToBase64(imageAttachments);
|
|
2632
|
+
} else {
|
|
2633
|
+
pendingAttachmentDataRef.current = null;
|
|
2634
|
+
}
|
|
2635
2635
|
}
|
|
2636
2636
|
let shouldContinueAfterAttachment = continueAfterToolResult;
|
|
2637
2637
|
if (attachmentResults.length > 0) {
|
|
@@ -2725,48 +2725,37 @@ ${currentContextSummary}` },
|
|
|
2725
2725
|
} else {
|
|
2726
2726
|
chatMessages = messagesToSend.map((m) => ({ role: m.role, content: m.content }));
|
|
2727
2727
|
}
|
|
2728
|
-
if (aiDecideImageAttachments.length > 0) {
|
|
2729
|
-
const imageBase64s = await Promise.all(
|
|
2730
|
-
aiDecideImageAttachments.map(async (att) => ({
|
|
2731
|
-
mimeType: att.mimeType,
|
|
2732
|
-
base64: await fileToBase64(att.file)
|
|
2733
|
-
}))
|
|
2734
|
-
);
|
|
2735
|
-
for (let i = chatMessages.length - 1; i >= 0; i--) {
|
|
2736
|
-
if (chatMessages[i].role === "user") {
|
|
2737
|
-
const textContent = typeof chatMessages[i].content === "string" ? chatMessages[i].content : "";
|
|
2738
|
-
const multimodalParts = [];
|
|
2739
|
-
if (textContent.trim()) {
|
|
2740
|
-
multimodalParts.push({ type: "text", text: textContent });
|
|
2741
|
-
}
|
|
2742
|
-
for (const img of imageBase64s) {
|
|
2743
|
-
multimodalParts.push({
|
|
2744
|
-
type: "image_url",
|
|
2745
|
-
image_url: { url: `data:${img.mimeType};base64,${img.base64}` }
|
|
2746
|
-
});
|
|
2747
|
-
}
|
|
2748
|
-
chatMessages[i] = { ...chatMessages[i], content: multimodalParts };
|
|
2749
|
-
break;
|
|
2750
|
-
}
|
|
2751
|
-
}
|
|
2752
|
-
}
|
|
2753
2728
|
if (attachmentResults.length > 0 && shouldContinueAfterAttachment) {
|
|
2754
|
-
skipNextSkillParsingRef.current = true;
|
|
2755
2729
|
const attachmentContext = attachmentResults.filter((part) => part.type === "tool_result").map((part) => `[${part.label || part.toolName} \uACB0\uACFC]
|
|
2756
2730
|
${part.result.content}`).join("\n\n");
|
|
2757
2731
|
if (attachmentContext) {
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2732
|
+
const hasImageWithText = pendingAttachmentDataRef.current !== null;
|
|
2733
|
+
if (hasImageWithText) {
|
|
2734
|
+
chatMessages.push({
|
|
2735
|
+
role: "user",
|
|
2736
|
+
/** @Todo vibecode - 분석 결과 제공 + 도구 선택 허용 (편집/생성 등) */
|
|
2737
|
+
content: `\uC0AC\uC6A9\uC790\uAC00 \uC774\uBBF8\uC9C0\uB97C \uCCA8\uBD80\uD588\uC2B5\uB2C8\uB2E4. \uC544\uB798\uB294 \uC774\uBBF8\uC9C0 \uC790\uB3D9 \uBD84\uC11D \uACB0\uACFC\uC785\uB2C8\uB2E4.
|
|
2738
|
+
|
|
2739
|
+
${attachmentContext}
|
|
2740
|
+
|
|
2741
|
+
\uC0AC\uC6A9\uC790\uC758 \uC694\uCCAD: "${finalContent}"
|
|
2742
|
+
|
|
2743
|
+
\uC704 \uBD84\uC11D \uACB0\uACFC\uB97C \uCC38\uACE0\uD558\uB418, \uC0AC\uC6A9\uC790\uC758 \uC694\uCCAD \uC758\uB3C4\uC5D0 \uB530\uB77C \uC801\uC808\uD55C \uB3C4\uAD6C\uB97C \uC120\uD0DD\uD558\uC138\uC694. \uC774\uBBF8\uC9C0 \uD3B8\uC9D1\uC774\uB098 \uC0DD\uC131\uC774 \uD544\uC694\uD558\uBA74 \uD574\uB2F9 \uB3C4\uAD6C\uB97C \uD638\uCD9C\uD558\uACE0, \uBD84\uC11D \uACB0\uACFC\uB9CC\uC73C\uB85C \uCDA9\uBD84\uD558\uBA74 \uBC14\uB85C \uB2F5\uBCC0\uD558\uC138\uC694.`
|
|
2744
|
+
});
|
|
2745
|
+
} else {
|
|
2746
|
+
skipNextSkillParsingRef.current = true;
|
|
2747
|
+
chatMessages.push({
|
|
2748
|
+
role: "user",
|
|
2749
|
+
content: `\uC0AC\uC6A9\uC790\uAC00 \uCCA8\uBD80\uD55C \uD30C\uC77C\uC758 \uBD84\uC11D \uACB0\uACFC\uC785\uB2C8\uB2E4. \uC6D0\uBCF8 \uD30C\uC77C \uB0B4\uC6A9\uC774 \uC774\uBBF8 \uC544\uB798\uC5D0 \uD3EC\uD568\uB418\uC5B4 \uC788\uC73C\uBBC0\uB85C \uC6D0\uBCF8 \uD30C\uC77C\uC744 \uB2E4\uC2DC \uC694\uCCAD\uD558\uC9C0 \uB9C8\uC138\uC694.
|
|
2762
2750
|
|
|
2763
2751
|
${attachmentContext}
|
|
2764
2752
|
|
|
2765
2753
|
\uC704 \uBD84\uC11D \uACB0\uACFC\uB9CC\uC73C\uB85C \uC0AC\uC6A9\uC790\uC758 \uC9C8\uBB38\uC5D0 \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`
|
|
2766
|
-
|
|
2754
|
+
});
|
|
2755
|
+
}
|
|
2767
2756
|
}
|
|
2768
2757
|
}
|
|
2769
|
-
console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content:
|
|
2758
|
+
console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content: m.content.slice(0, 50) })));
|
|
2770
2759
|
const baseSystemPrompt = buildSystemPrompt();
|
|
2771
2760
|
const combinedSystemPrompt = [baseSystemPrompt, actionPrompt].filter(Boolean).join("\n\n");
|
|
2772
2761
|
const messagesForApi = combinedSystemPrompt ? [{ role: "system", content: combinedSystemPrompt }, ...chatMessages] : chatMessages;
|
|
@@ -2984,9 +2973,11 @@ ${attachmentContext}
|
|
|
2984
2973
|
})
|
|
2985
2974
|
);
|
|
2986
2975
|
try {
|
|
2976
|
+
const attachExtra = pendingAttachmentDataRef.current ? { __attachedImages__: pendingAttachmentDataRef.current } : void 0;
|
|
2987
2977
|
const { result: skillResult } = await handleSkillCall(assistantContent, {
|
|
2988
2978
|
signal: abortControllerRef.current?.signal
|
|
2989
|
-
});
|
|
2979
|
+
}, attachExtra);
|
|
2980
|
+
pendingAttachmentDataRef.current = null;
|
|
2990
2981
|
if (skillResult?.content) {
|
|
2991
2982
|
accumulatedContent = skillResult.content;
|
|
2992
2983
|
}
|
|
@@ -3015,6 +3006,8 @@ ${attachmentContext}
|
|
|
3015
3006
|
})
|
|
3016
3007
|
);
|
|
3017
3008
|
let streamedReport = "";
|
|
3009
|
+
const attachExtraParams = pendingAttachmentDataRef.current ? { __attachedImages__: pendingAttachmentDataRef.current } : void 0;
|
|
3010
|
+
pendingAttachmentDataRef.current = null;
|
|
3018
3011
|
const { result } = await handleSkillCall(assistantContent, {
|
|
3019
3012
|
onProgress: (progress) => {
|
|
3020
3013
|
setSessions(
|
|
@@ -3049,7 +3042,7 @@ ${attachmentContext}
|
|
|
3049
3042
|
);
|
|
3050
3043
|
},
|
|
3051
3044
|
signal: abortControllerRef.current?.signal
|
|
3052
|
-
});
|
|
3045
|
+
}, attachExtraParams);
|
|
3053
3046
|
if (result) {
|
|
3054
3047
|
if (result.metadata?.__toolResult__) {
|
|
3055
3048
|
const resultType = result.metadata.resultType;
|
|
@@ -12340,7 +12333,6 @@ var ChatUIWithHook = ({
|
|
|
12340
12333
|
skills,
|
|
12341
12334
|
tools,
|
|
12342
12335
|
onToolCall,
|
|
12343
|
-
imageAttachmentMode,
|
|
12344
12336
|
continueAfterToolResult,
|
|
12345
12337
|
onSkillComplete,
|
|
12346
12338
|
onLoadModels,
|
|
@@ -12383,7 +12375,6 @@ var ChatUIWithHook = ({
|
|
|
12383
12375
|
skills,
|
|
12384
12376
|
tools,
|
|
12385
12377
|
onToolCall,
|
|
12386
|
-
imageAttachmentMode,
|
|
12387
12378
|
continueAfterToolResult,
|
|
12388
12379
|
onSkillComplete,
|
|
12389
12380
|
onLoadModels,
|