@gendive/chatllm 0.17.0 → 0.17.1
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 +18 -0
- package/dist/react/index.d.ts +18 -0
- package/dist/react/index.js +80 -9
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +80 -9
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.mts
CHANGED
|
@@ -396,6 +396,11 @@ interface ChatToolDefinition {
|
|
|
396
396
|
* @Todo vibecode - MIME 와일드카드 ('image/*'), 확장자 ('.pdf') 지원
|
|
397
397
|
*/
|
|
398
398
|
acceptedTypes?: string[];
|
|
399
|
+
/**
|
|
400
|
+
* @description 파일 첨부 시 File 객체를 base64 문자열로 자동 변환
|
|
401
|
+
* @Todo vibecode - true 시 execute()에 { name, mimeType, base64, size } 형태로 전달
|
|
402
|
+
*/
|
|
403
|
+
autoConvertBase64?: boolean;
|
|
399
404
|
}
|
|
400
405
|
interface ChatMessage {
|
|
401
406
|
id: string;
|
|
@@ -541,6 +546,11 @@ interface SkillConfig<TParams = Record<string, unknown>> {
|
|
|
541
546
|
* @example ['image/*', 'application/pdf', '.docx']
|
|
542
547
|
*/
|
|
543
548
|
acceptedTypes?: string[];
|
|
549
|
+
/**
|
|
550
|
+
* @description 파일 첨부 시 File 객체를 base64 문자열로 자동 변환
|
|
551
|
+
* @Todo vibecode - true 시 execute()에 { name, mimeType, base64, size } 형태로 전달
|
|
552
|
+
*/
|
|
553
|
+
autoConvertBase64?: boolean;
|
|
544
554
|
}
|
|
545
555
|
/**
|
|
546
556
|
* @description 스킬 실행 상태 (메시지에 첨부)
|
|
@@ -576,6 +586,14 @@ interface ModelConfig {
|
|
|
576
586
|
name: string;
|
|
577
587
|
provider: ProviderType;
|
|
578
588
|
description?: string;
|
|
589
|
+
/** @Todo vibecode - UI 표시용 아이콘 (URL 또는 아이콘 이름) */
|
|
590
|
+
icon?: string;
|
|
591
|
+
/** @Todo vibecode - 최대 출력 토큰 수 */
|
|
592
|
+
maxTokens?: number;
|
|
593
|
+
/** @Todo vibecode - 컨텍스트 윈도우 크기 (토큰) */
|
|
594
|
+
contextWindow?: number;
|
|
595
|
+
/** @Todo vibecode - 호스트 커스텀 필드 허용 */
|
|
596
|
+
[key: string]: unknown;
|
|
579
597
|
}
|
|
580
598
|
interface PromptTemplate {
|
|
581
599
|
id: string;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -396,6 +396,11 @@ interface ChatToolDefinition {
|
|
|
396
396
|
* @Todo vibecode - MIME 와일드카드 ('image/*'), 확장자 ('.pdf') 지원
|
|
397
397
|
*/
|
|
398
398
|
acceptedTypes?: string[];
|
|
399
|
+
/**
|
|
400
|
+
* @description 파일 첨부 시 File 객체를 base64 문자열로 자동 변환
|
|
401
|
+
* @Todo vibecode - true 시 execute()에 { name, mimeType, base64, size } 형태로 전달
|
|
402
|
+
*/
|
|
403
|
+
autoConvertBase64?: boolean;
|
|
399
404
|
}
|
|
400
405
|
interface ChatMessage {
|
|
401
406
|
id: string;
|
|
@@ -541,6 +546,11 @@ interface SkillConfig<TParams = Record<string, unknown>> {
|
|
|
541
546
|
* @example ['image/*', 'application/pdf', '.docx']
|
|
542
547
|
*/
|
|
543
548
|
acceptedTypes?: string[];
|
|
549
|
+
/**
|
|
550
|
+
* @description 파일 첨부 시 File 객체를 base64 문자열로 자동 변환
|
|
551
|
+
* @Todo vibecode - true 시 execute()에 { name, mimeType, base64, size } 형태로 전달
|
|
552
|
+
*/
|
|
553
|
+
autoConvertBase64?: boolean;
|
|
544
554
|
}
|
|
545
555
|
/**
|
|
546
556
|
* @description 스킬 실행 상태 (메시지에 첨부)
|
|
@@ -576,6 +586,14 @@ interface ModelConfig {
|
|
|
576
586
|
name: string;
|
|
577
587
|
provider: ProviderType;
|
|
578
588
|
description?: string;
|
|
589
|
+
/** @Todo vibecode - UI 표시용 아이콘 (URL 또는 아이콘 이름) */
|
|
590
|
+
icon?: string;
|
|
591
|
+
/** @Todo vibecode - 최대 출력 토큰 수 */
|
|
592
|
+
maxTokens?: number;
|
|
593
|
+
/** @Todo vibecode - 컨텍스트 윈도우 크기 (토큰) */
|
|
594
|
+
contextWindow?: number;
|
|
595
|
+
/** @Todo vibecode - 호스트 커스텀 필드 허용 */
|
|
596
|
+
[key: string]: unknown;
|
|
579
597
|
}
|
|
580
598
|
interface PromptTemplate {
|
|
581
599
|
id: string;
|
package/dist/react/index.js
CHANGED
|
@@ -1199,7 +1199,7 @@ var useProject = (options) => {
|
|
|
1199
1199
|
const currentProject = projects.find((p) => p.id === currentProjectId) || null;
|
|
1200
1200
|
(0, import_react4.useEffect)(() => {
|
|
1201
1201
|
if (!enabled || useExternalStorage || !initializedRef.current) return;
|
|
1202
|
-
if (projects.length > 0) {
|
|
1202
|
+
if (projects.length > 0 && typeof window !== "undefined") {
|
|
1203
1203
|
localStorage.setItem(storageKey, JSON.stringify(projects));
|
|
1204
1204
|
}
|
|
1205
1205
|
}, [enabled, projects, storageKey, useExternalStorage]);
|
|
@@ -1233,7 +1233,7 @@ var useProject = (options) => {
|
|
|
1233
1233
|
}
|
|
1234
1234
|
} else {
|
|
1235
1235
|
try {
|
|
1236
|
-
const saved = localStorage.getItem(storageKey);
|
|
1236
|
+
const saved = typeof window !== "undefined" ? localStorage.getItem(storageKey) : null;
|
|
1237
1237
|
if (saved) {
|
|
1238
1238
|
const parsed = JSON.parse(saved);
|
|
1239
1239
|
if (!parsed.find((p) => p.id === DEFAULT_PROJECT_ID)) {
|
|
@@ -1540,6 +1540,7 @@ var convertToolsToSkills = (tools, onToolCall) => {
|
|
|
1540
1540
|
label: tool.label || tool.name,
|
|
1541
1541
|
icon: tool.icon,
|
|
1542
1542
|
acceptedTypes: tool.acceptedTypes,
|
|
1543
|
+
autoConvertBase64: tool.autoConvertBase64,
|
|
1543
1544
|
parameters: {
|
|
1544
1545
|
type: "object",
|
|
1545
1546
|
properties: Object.fromEntries(
|
|
@@ -1613,6 +1614,20 @@ var DEFAULT_KEEP_RECENT = 6;
|
|
|
1613
1614
|
var DEFAULT_RECOMPRESSION_THRESHOLD = 10;
|
|
1614
1615
|
var DEFAULT_TOKEN_LIMIT = 8e3;
|
|
1615
1616
|
var generateId3 = (prefix) => `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
1617
|
+
var fileToBase64 = (file) => new Promise((resolve, reject) => {
|
|
1618
|
+
const reader = new FileReader();
|
|
1619
|
+
reader.onload = () => resolve(reader.result.split(",")[1] || "");
|
|
1620
|
+
reader.onerror = reject;
|
|
1621
|
+
reader.readAsDataURL(file);
|
|
1622
|
+
});
|
|
1623
|
+
var convertAttachmentsToBase64 = async (attachments) => Promise.all(
|
|
1624
|
+
attachments.map(async (att) => ({
|
|
1625
|
+
name: att.name,
|
|
1626
|
+
mimeType: att.mimeType,
|
|
1627
|
+
base64: await fileToBase64(att.file),
|
|
1628
|
+
size: att.size
|
|
1629
|
+
}))
|
|
1630
|
+
);
|
|
1616
1631
|
var generateTitle = (messages) => {
|
|
1617
1632
|
const firstUserMessage = messages.find((m) => m.role === "user");
|
|
1618
1633
|
if (!firstUserMessage) return "\uC0C8 \uB300\uD654";
|
|
@@ -1835,11 +1850,13 @@ var useChatUI = (options) => {
|
|
|
1835
1850
|
}).finally(() => {
|
|
1836
1851
|
setIsSessionsLoading(false);
|
|
1837
1852
|
});
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1853
|
+
if (typeof window !== "undefined") {
|
|
1854
|
+
const savedPersonalization2 = localStorage.getItem(`${storageKey}_personalization`);
|
|
1855
|
+
if (savedPersonalization2) {
|
|
1856
|
+
try {
|
|
1857
|
+
setPersonalization(JSON.parse(savedPersonalization2));
|
|
1858
|
+
} catch {
|
|
1859
|
+
}
|
|
1843
1860
|
}
|
|
1844
1861
|
}
|
|
1845
1862
|
return;
|
|
@@ -1847,6 +1864,7 @@ var useChatUI = (options) => {
|
|
|
1847
1864
|
if (enableProjects) {
|
|
1848
1865
|
migrateSessionsToProjects(storageKey);
|
|
1849
1866
|
}
|
|
1867
|
+
if (typeof window === "undefined") return;
|
|
1850
1868
|
const saved = localStorage.getItem(storageKey);
|
|
1851
1869
|
if (saved) {
|
|
1852
1870
|
try {
|
|
@@ -2426,7 +2444,8 @@ ${finalContent}`;
|
|
|
2426
2444
|
});
|
|
2427
2445
|
if (matchedFiles.length === 0) continue;
|
|
2428
2446
|
try {
|
|
2429
|
-
const
|
|
2447
|
+
const filesToPass = skillConfig.autoConvertBase64 ? await convertAttachmentsToBase64(matchedFiles) : matchedFiles;
|
|
2448
|
+
const result = await skillConfig.execute({ files: filesToPass, userMessage: finalContent });
|
|
2430
2449
|
attachmentResults.push({
|
|
2431
2450
|
type: "tool_result",
|
|
2432
2451
|
toolName: skillName,
|
|
@@ -2444,6 +2463,20 @@ ${finalContent}`;
|
|
|
2444
2463
|
}
|
|
2445
2464
|
}
|
|
2446
2465
|
}
|
|
2466
|
+
let shouldContinueAfterAttachment = continueAfterToolResult;
|
|
2467
|
+
if (attachmentResults.length > 0) {
|
|
2468
|
+
for (const part of attachmentResults) {
|
|
2469
|
+
if (part.type === "tool_result" && onSkillCompleteRef.current) {
|
|
2470
|
+
const decision = onSkillCompleteRef.current(part.toolName, {
|
|
2471
|
+
content: part.result.content,
|
|
2472
|
+
metadata: part.result.metadata,
|
|
2473
|
+
sources: part.result.sources
|
|
2474
|
+
});
|
|
2475
|
+
shouldContinueAfterAttachment = decision === "continue";
|
|
2476
|
+
if (!shouldContinueAfterAttachment) break;
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2447
2480
|
const assistantMessageId = generateId3("msg");
|
|
2448
2481
|
const assistantMessage = {
|
|
2449
2482
|
id: assistantMessageId,
|
|
@@ -2491,6 +2524,10 @@ ${finalContent}`;
|
|
|
2491
2524
|
}).catch(() => {
|
|
2492
2525
|
});
|
|
2493
2526
|
}
|
|
2527
|
+
if (attachmentResults.length > 0 && !shouldContinueAfterAttachment) {
|
|
2528
|
+
setIsLoading(false);
|
|
2529
|
+
return;
|
|
2530
|
+
}
|
|
2494
2531
|
setIsLoading(true);
|
|
2495
2532
|
abortControllerRef.current = new AbortController();
|
|
2496
2533
|
try {
|
|
@@ -2550,6 +2587,20 @@ ${currentContextSummary}` },
|
|
|
2550
2587
|
} else {
|
|
2551
2588
|
chatMessages = messagesToSend.map((m) => ({ role: m.role, content: m.content }));
|
|
2552
2589
|
}
|
|
2590
|
+
if (attachmentResults.length > 0 && shouldContinueAfterAttachment) {
|
|
2591
|
+
const attachmentContext = attachmentResults.filter((part) => part.type === "tool_result").map((part) => `[${part.label || part.toolName} \uACB0\uACFC]
|
|
2592
|
+
${part.result.content}`).join("\n\n");
|
|
2593
|
+
if (attachmentContext) {
|
|
2594
|
+
chatMessages.push({
|
|
2595
|
+
role: "user",
|
|
2596
|
+
content: `\uD30C\uC77C \uBD84\uC11D \uACB0\uACFC:
|
|
2597
|
+
|
|
2598
|
+
${attachmentContext}
|
|
2599
|
+
|
|
2600
|
+
\uC704 \uACB0\uACFC\uB97C \uCC38\uACE0\uD558\uC5EC \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694.`
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2553
2604
|
console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content: m.content.slice(0, 50) })));
|
|
2554
2605
|
const baseSystemPrompt = buildSystemPrompt();
|
|
2555
2606
|
const combinedSystemPrompt = [baseSystemPrompt, actionPrompt].filter(Boolean).join("\n\n");
|
|
@@ -3537,7 +3588,25 @@ ${currentSession.contextSummary}` },
|
|
|
3537
3588
|
systemPrompt: `\uC0AC\uC6A9\uC790\uAC00 "${toolConfig.label || skillName}" \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uB824\uACE0 \uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC758 \uBA54\uC2DC\uC9C0\uB97C \uBC14\uD0D5\uC73C\uB85C \uBC18\uB4DC\uC2DC <skill_use name="${skillName}"> \uD0DC\uADF8\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC774 \uB3C4\uAD6C\uB97C \uD638\uCD9C\uD558\uC138\uC694. \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uACE0 \uD14D\uC2A4\uD2B8\uB85C\uB9CC \uB2F5\uBCC0\uD558\uC9C0 \uB9C8\uC138\uC694.`
|
|
3538
3589
|
});
|
|
3539
3590
|
} else {
|
|
3540
|
-
|
|
3591
|
+
const currentQuery = input;
|
|
3592
|
+
executeManualSkill(skillName, { query: currentQuery }).then((result) => {
|
|
3593
|
+
if (!result || !result.content) return;
|
|
3594
|
+
let shouldContinue = continueAfterToolResult;
|
|
3595
|
+
if (onSkillCompleteRef.current) {
|
|
3596
|
+
const decision = onSkillCompleteRef.current(skillName, result);
|
|
3597
|
+
shouldContinue = decision === "continue";
|
|
3598
|
+
}
|
|
3599
|
+
if (!shouldContinue) return;
|
|
3600
|
+
skipNextSkillParsingRef.current = true;
|
|
3601
|
+
const resultPrompt = `\uC2A4\uD0AC "${skillName}" \uC2E4\uD589 \uACB0\uACFC:
|
|
3602
|
+
|
|
3603
|
+
${result.content}
|
|
3604
|
+
|
|
3605
|
+
\uC704 \uACB0\uACFC\uB97C \uBC14\uD0D5\uC73C\uB85C \uC0AC\uC6A9\uC790\uC758 \uC6D0\uB798 \uC9C8\uBB38\uC5D0 \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
|
|
3606
|
+
setTimeout(() => {
|
|
3607
|
+
sendMessage(resultPrompt, { hiddenUserMessage: true });
|
|
3608
|
+
}, 100);
|
|
3609
|
+
});
|
|
3541
3610
|
}
|
|
3542
3611
|
},
|
|
3543
3612
|
// Project
|
|
@@ -3968,6 +4037,7 @@ var ChatSidebar = ({
|
|
|
3968
4037
|
className: `chatllm-sidebar chatllm-sidebar-transition ${theme ? `chatllm-root ${themeClass}` : ""}`,
|
|
3969
4038
|
style: {
|
|
3970
4039
|
width: isOpen ? sidebarWidth : "0",
|
|
4040
|
+
height: "100%",
|
|
3971
4041
|
flexShrink: 0,
|
|
3972
4042
|
backgroundColor: "var(--chatllm-sidebar-bg)",
|
|
3973
4043
|
borderRight: isOpen ? "1px solid var(--chatllm-border)" : "none",
|
|
@@ -10371,6 +10441,7 @@ var ChatUIView = ({
|
|
|
10371
10441
|
currentProjectId,
|
|
10372
10442
|
onSelectProject: projects.length > 0 ? selectProject : void 0,
|
|
10373
10443
|
onNewProject: projects.length > 0 ? () => {
|
|
10444
|
+
if (typeof window === "undefined") return;
|
|
10374
10445
|
const title = window.prompt("\uD504\uB85C\uC81D\uD2B8 \uC774\uB984\uC744 \uC785\uB825\uD558\uC138\uC694");
|
|
10375
10446
|
if (title?.trim()) {
|
|
10376
10447
|
createProject({ title: title.trim() });
|