@gendive/chatllm 0.21.9 → 0.22.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 +11 -0
- package/dist/react/index.d.ts +11 -0
- package/dist/react/index.js +51 -7
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +51 -7
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.mts
CHANGED
|
@@ -1060,6 +1060,12 @@ interface ChatUIProps {
|
|
|
1060
1060
|
* @Todo vibecode - 새 URL 반환 시 img.src 갱신 + contentParts url 업데이트, null 반환 시 기본 에러 처리 (#13)
|
|
1061
1061
|
*/
|
|
1062
1062
|
onImageError?: (url: string, fileName?: string) => Promise<string | null>;
|
|
1063
|
+
/**
|
|
1064
|
+
* @description 첨부 파일 업로드 콜백 (File → URL 변환)
|
|
1065
|
+
* @Todo vibecode - autoConvertBase64 대신 File 객체를 직접 업로드하여 URL로 전달
|
|
1066
|
+
* base64 이중 변환(File→base64→File→업로드) 제거, 메모리 ~33% 절감
|
|
1067
|
+
*/
|
|
1068
|
+
fileUploader?: (file: File) => Promise<string>;
|
|
1063
1069
|
/**
|
|
1064
1070
|
* @description Thinking 블록 표시 여부
|
|
1065
1071
|
* @Todo vibecode - AI 추론 과정 표시 (기본: true)
|
|
@@ -1953,6 +1959,11 @@ interface UseChatUIOptions {
|
|
|
1953
1959
|
* @Todo vibecode - 새 URL 반환 시 img.src 갱신, null 반환 시 기본 에러 처리 (#13)
|
|
1954
1960
|
*/
|
|
1955
1961
|
onImageError?: (url: string, fileName?: string) => Promise<string | null>;
|
|
1962
|
+
/**
|
|
1963
|
+
* @description 첨부 파일 업로드 콜백 (File → URL 변환)
|
|
1964
|
+
* @Todo vibecode - autoConvertBase64 대신 File 객체를 직접 업로드하여 URL로 전달
|
|
1965
|
+
*/
|
|
1966
|
+
fileUploader?: (file: File) => Promise<string>;
|
|
1956
1967
|
/**
|
|
1957
1968
|
* @description 외부 스토리지 사용 여부
|
|
1958
1969
|
* @Todo vibecode - true 시 localStorage 대신 콜백 사용
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1060,6 +1060,12 @@ interface ChatUIProps {
|
|
|
1060
1060
|
* @Todo vibecode - 새 URL 반환 시 img.src 갱신 + contentParts url 업데이트, null 반환 시 기본 에러 처리 (#13)
|
|
1061
1061
|
*/
|
|
1062
1062
|
onImageError?: (url: string, fileName?: string) => Promise<string | null>;
|
|
1063
|
+
/**
|
|
1064
|
+
* @description 첨부 파일 업로드 콜백 (File → URL 변환)
|
|
1065
|
+
* @Todo vibecode - autoConvertBase64 대신 File 객체를 직접 업로드하여 URL로 전달
|
|
1066
|
+
* base64 이중 변환(File→base64→File→업로드) 제거, 메모리 ~33% 절감
|
|
1067
|
+
*/
|
|
1068
|
+
fileUploader?: (file: File) => Promise<string>;
|
|
1063
1069
|
/**
|
|
1064
1070
|
* @description Thinking 블록 표시 여부
|
|
1065
1071
|
* @Todo vibecode - AI 추론 과정 표시 (기본: true)
|
|
@@ -1953,6 +1959,11 @@ interface UseChatUIOptions {
|
|
|
1953
1959
|
* @Todo vibecode - 새 URL 반환 시 img.src 갱신, null 반환 시 기본 에러 처리 (#13)
|
|
1954
1960
|
*/
|
|
1955
1961
|
onImageError?: (url: string, fileName?: string) => Promise<string | null>;
|
|
1962
|
+
/**
|
|
1963
|
+
* @description 첨부 파일 업로드 콜백 (File → URL 변환)
|
|
1964
|
+
* @Todo vibecode - autoConvertBase64 대신 File 객체를 직접 업로드하여 URL로 전달
|
|
1965
|
+
*/
|
|
1966
|
+
fileUploader?: (file: File) => Promise<string>;
|
|
1956
1967
|
/**
|
|
1957
1968
|
* @description 외부 스토리지 사용 여부
|
|
1958
1969
|
* @Todo vibecode - true 시 localStorage 대신 콜백 사용
|
package/dist/react/index.js
CHANGED
|
@@ -2269,6 +2269,23 @@ var convertAttachmentsToBase64 = async (attachments) => Promise.all(
|
|
|
2269
2269
|
size: att.size
|
|
2270
2270
|
}))
|
|
2271
2271
|
);
|
|
2272
|
+
var convertAttachmentsWithUploaderCached = async (attachments, uploader, cache) => Promise.all(
|
|
2273
|
+
attachments.map(async (att) => {
|
|
2274
|
+
let url = cache.get(att.id);
|
|
2275
|
+
if (!url) {
|
|
2276
|
+
url = await uploader(att.file);
|
|
2277
|
+
cache.set(att.id, url);
|
|
2278
|
+
}
|
|
2279
|
+
return {
|
|
2280
|
+
name: att.name,
|
|
2281
|
+
mimeType: att.mimeType,
|
|
2282
|
+
base64: "",
|
|
2283
|
+
url,
|
|
2284
|
+
size: att.size,
|
|
2285
|
+
source: "uploader"
|
|
2286
|
+
};
|
|
2287
|
+
})
|
|
2288
|
+
);
|
|
2272
2289
|
var findPreviousResultImage = (messages) => {
|
|
2273
2290
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2274
2291
|
const msg = messages[i];
|
|
@@ -2330,6 +2347,8 @@ var useChatUI = (options) => {
|
|
|
2330
2347
|
// Image upload
|
|
2331
2348
|
onUploadImage,
|
|
2332
2349
|
onImageError,
|
|
2350
|
+
// File upload
|
|
2351
|
+
fileUploader,
|
|
2333
2352
|
// External storage options
|
|
2334
2353
|
useExternalStorage = false,
|
|
2335
2354
|
startWithNewSession = false,
|
|
@@ -2437,6 +2456,7 @@ var useChatUI = (options) => {
|
|
|
2437
2456
|
const onLoadModelsRef = (0, import_react6.useRef)(onLoadModels);
|
|
2438
2457
|
const onUploadImageRef = (0, import_react6.useRef)(onUploadImage);
|
|
2439
2458
|
const onImageErrorRef = (0, import_react6.useRef)(onImageError);
|
|
2459
|
+
const fileUploaderRef = (0, import_react6.useRef)(fileUploader);
|
|
2440
2460
|
const globalMemoryRef = (0, import_react6.useRef)(null);
|
|
2441
2461
|
(0, import_react6.useEffect)(() => {
|
|
2442
2462
|
onSendMessageRef.current = onSendMessage;
|
|
@@ -2458,6 +2478,7 @@ var useChatUI = (options) => {
|
|
|
2458
2478
|
onSessionContextChangeRef.current = onSessionContextChange;
|
|
2459
2479
|
onUploadImageRef.current = onUploadImage;
|
|
2460
2480
|
onImageErrorRef.current = onImageError;
|
|
2481
|
+
fileUploaderRef.current = fileUploader;
|
|
2461
2482
|
onLoadModelsRef.current = onLoadModels;
|
|
2462
2483
|
});
|
|
2463
2484
|
const abortControllersRef = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
@@ -3537,6 +3558,7 @@ ${finalContent}`;
|
|
|
3537
3558
|
const actionPrompt = selectedAction?.systemPrompt;
|
|
3538
3559
|
const isHidden = options2?.hiddenUserMessage ?? false;
|
|
3539
3560
|
const currentAttachments = attachments;
|
|
3561
|
+
const uploadedUrlMap = /* @__PURE__ */ new Map();
|
|
3540
3562
|
let userContentParts;
|
|
3541
3563
|
if (currentAttachments.length > 0) {
|
|
3542
3564
|
userContentParts = [];
|
|
@@ -3545,8 +3567,19 @@ ${finalContent}`;
|
|
|
3545
3567
|
}
|
|
3546
3568
|
for (const att of currentAttachments) {
|
|
3547
3569
|
if (att.type === "image" && att.file) {
|
|
3548
|
-
|
|
3549
|
-
|
|
3570
|
+
let imageUrl;
|
|
3571
|
+
try {
|
|
3572
|
+
if (fileUploaderRef.current) {
|
|
3573
|
+
imageUrl = await fileUploaderRef.current(att.file);
|
|
3574
|
+
} else {
|
|
3575
|
+
const dataUri = await fileToDataUri(att.file);
|
|
3576
|
+
imageUrl = onUploadImageRef.current ? await onUploadImageRef.current(dataUri, att.name) : dataUri;
|
|
3577
|
+
}
|
|
3578
|
+
} catch (err) {
|
|
3579
|
+
console.error("[chatllm] image upload failed, falling back to data URI:", err);
|
|
3580
|
+
imageUrl = await fileToDataUri(att.file);
|
|
3581
|
+
}
|
|
3582
|
+
uploadedUrlMap.set(att.id, imageUrl);
|
|
3550
3583
|
userContentParts.push({ type: "image", url: imageUrl, alt: att.name, fileName: att.name });
|
|
3551
3584
|
} else {
|
|
3552
3585
|
userContentParts.push({ type: "file", name: att.name, url: att.previewUrl || "", mimeType: att.mimeType, size: att.size });
|
|
@@ -3645,7 +3678,7 @@ ${finalContent}`;
|
|
|
3645
3678
|
})
|
|
3646
3679
|
);
|
|
3647
3680
|
try {
|
|
3648
|
-
const filesToPass = skillConfig.autoConvertBase64 ? await convertAttachmentsToBase64(matchedFiles) : matchedFiles;
|
|
3681
|
+
const filesToPass = fileUploaderRef.current ? await convertAttachmentsWithUploaderCached(matchedFiles, fileUploaderRef.current, uploadedUrlMap) : skillConfig.autoConvertBase64 ? await convertAttachmentsToBase64(matchedFiles) : matchedFiles;
|
|
3649
3682
|
const result = await skillConfig.execute({ files: filesToPass, userMessage: finalContent });
|
|
3650
3683
|
const attachResultType = result.metadata?.type || result.metadata?.resultType || "text";
|
|
3651
3684
|
const toolResultPart = {
|
|
@@ -3703,7 +3736,12 @@ ${finalContent}`;
|
|
|
3703
3736
|
const hasUserText = finalContent.trim().length > 0;
|
|
3704
3737
|
if (hasImageAttachments && hasUserText) {
|
|
3705
3738
|
const imageAttachments = currentAttachments.filter((a) => a.type === "image");
|
|
3706
|
-
|
|
3739
|
+
try {
|
|
3740
|
+
pendingAttachmentDataRef.current = fileUploaderRef.current ? await convertAttachmentsWithUploaderCached(imageAttachments, fileUploaderRef.current, uploadedUrlMap) : await convertAttachmentsToBase64(imageAttachments);
|
|
3741
|
+
} catch (err) {
|
|
3742
|
+
console.error("[chatllm] pendingAttachment conversion failed:", err);
|
|
3743
|
+
pendingAttachmentDataRef.current = null;
|
|
3744
|
+
}
|
|
3707
3745
|
} else {
|
|
3708
3746
|
pendingAttachmentDataRef.current = null;
|
|
3709
3747
|
}
|
|
@@ -3851,7 +3889,9 @@ ${attachmentContext}
|
|
|
3851
3889
|
}
|
|
3852
3890
|
}
|
|
3853
3891
|
} else if (attachmentResults.length === 0 && pendingAttachmentDataRef.current !== null) {
|
|
3854
|
-
const isReferenceImage = pendingAttachmentDataRef.current.some(
|
|
3892
|
+
const isReferenceImage = pendingAttachmentDataRef.current.some(
|
|
3893
|
+
(d) => d.url && !d.base64 && d.source !== "uploader"
|
|
3894
|
+
);
|
|
3855
3895
|
if (isReferenceImage) {
|
|
3856
3896
|
chatMessages.push({
|
|
3857
3897
|
role: "user",
|
|
@@ -15162,7 +15202,9 @@ var ChatUIWithHook = ({
|
|
|
15162
15202
|
onAnalyzePatterns,
|
|
15163
15203
|
// Image upload
|
|
15164
15204
|
onUploadImage,
|
|
15165
|
-
onImageError
|
|
15205
|
+
onImageError,
|
|
15206
|
+
// File upload
|
|
15207
|
+
fileUploader
|
|
15166
15208
|
}) => {
|
|
15167
15209
|
const hookOptions = {
|
|
15168
15210
|
models,
|
|
@@ -15213,7 +15255,9 @@ var ChatUIWithHook = ({
|
|
|
15213
15255
|
onAnalyzePatterns,
|
|
15214
15256
|
// Image upload
|
|
15215
15257
|
onUploadImage,
|
|
15216
|
-
onImageError
|
|
15258
|
+
onImageError,
|
|
15259
|
+
// File upload
|
|
15260
|
+
fileUploader
|
|
15217
15261
|
};
|
|
15218
15262
|
const state = useChatUI(hookOptions);
|
|
15219
15263
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ImageErrorContext.Provider, { value: onImageError || null, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|