@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.
@@ -2184,6 +2184,23 @@ var convertAttachmentsToBase64 = async (attachments) => Promise.all(
2184
2184
  size: att.size
2185
2185
  }))
2186
2186
  );
2187
+ var convertAttachmentsWithUploaderCached = async (attachments, uploader, cache) => Promise.all(
2188
+ attachments.map(async (att) => {
2189
+ let url = cache.get(att.id);
2190
+ if (!url) {
2191
+ url = await uploader(att.file);
2192
+ cache.set(att.id, url);
2193
+ }
2194
+ return {
2195
+ name: att.name,
2196
+ mimeType: att.mimeType,
2197
+ base64: "",
2198
+ url,
2199
+ size: att.size,
2200
+ source: "uploader"
2201
+ };
2202
+ })
2203
+ );
2187
2204
  var findPreviousResultImage = (messages) => {
2188
2205
  for (let i = messages.length - 1; i >= 0; i--) {
2189
2206
  const msg = messages[i];
@@ -2245,6 +2262,8 @@ var useChatUI = (options) => {
2245
2262
  // Image upload
2246
2263
  onUploadImage,
2247
2264
  onImageError,
2265
+ // File upload
2266
+ fileUploader,
2248
2267
  // External storage options
2249
2268
  useExternalStorage = false,
2250
2269
  startWithNewSession = false,
@@ -2352,6 +2371,7 @@ var useChatUI = (options) => {
2352
2371
  const onLoadModelsRef = useRef5(onLoadModels);
2353
2372
  const onUploadImageRef = useRef5(onUploadImage);
2354
2373
  const onImageErrorRef = useRef5(onImageError);
2374
+ const fileUploaderRef = useRef5(fileUploader);
2355
2375
  const globalMemoryRef = useRef5(null);
2356
2376
  useEffect4(() => {
2357
2377
  onSendMessageRef.current = onSendMessage;
@@ -2373,6 +2393,7 @@ var useChatUI = (options) => {
2373
2393
  onSessionContextChangeRef.current = onSessionContextChange;
2374
2394
  onUploadImageRef.current = onUploadImage;
2375
2395
  onImageErrorRef.current = onImageError;
2396
+ fileUploaderRef.current = fileUploader;
2376
2397
  onLoadModelsRef.current = onLoadModels;
2377
2398
  });
2378
2399
  const abortControllersRef = useRef5(/* @__PURE__ */ new Map());
@@ -3452,6 +3473,7 @@ ${finalContent}`;
3452
3473
  const actionPrompt = selectedAction?.systemPrompt;
3453
3474
  const isHidden = options2?.hiddenUserMessage ?? false;
3454
3475
  const currentAttachments = attachments;
3476
+ const uploadedUrlMap = /* @__PURE__ */ new Map();
3455
3477
  let userContentParts;
3456
3478
  if (currentAttachments.length > 0) {
3457
3479
  userContentParts = [];
@@ -3460,8 +3482,19 @@ ${finalContent}`;
3460
3482
  }
3461
3483
  for (const att of currentAttachments) {
3462
3484
  if (att.type === "image" && att.file) {
3463
- const dataUri = await fileToDataUri(att.file);
3464
- const imageUrl = onUploadImageRef.current ? await onUploadImageRef.current(dataUri, att.name) : dataUri;
3485
+ let imageUrl;
3486
+ try {
3487
+ if (fileUploaderRef.current) {
3488
+ imageUrl = await fileUploaderRef.current(att.file);
3489
+ } else {
3490
+ const dataUri = await fileToDataUri(att.file);
3491
+ imageUrl = onUploadImageRef.current ? await onUploadImageRef.current(dataUri, att.name) : dataUri;
3492
+ }
3493
+ } catch (err) {
3494
+ console.error("[chatllm] image upload failed, falling back to data URI:", err);
3495
+ imageUrl = await fileToDataUri(att.file);
3496
+ }
3497
+ uploadedUrlMap.set(att.id, imageUrl);
3465
3498
  userContentParts.push({ type: "image", url: imageUrl, alt: att.name, fileName: att.name });
3466
3499
  } else {
3467
3500
  userContentParts.push({ type: "file", name: att.name, url: att.previewUrl || "", mimeType: att.mimeType, size: att.size });
@@ -3560,7 +3593,7 @@ ${finalContent}`;
3560
3593
  })
3561
3594
  );
3562
3595
  try {
3563
- const filesToPass = skillConfig.autoConvertBase64 ? await convertAttachmentsToBase64(matchedFiles) : matchedFiles;
3596
+ const filesToPass = fileUploaderRef.current ? await convertAttachmentsWithUploaderCached(matchedFiles, fileUploaderRef.current, uploadedUrlMap) : skillConfig.autoConvertBase64 ? await convertAttachmentsToBase64(matchedFiles) : matchedFiles;
3564
3597
  const result = await skillConfig.execute({ files: filesToPass, userMessage: finalContent });
3565
3598
  const attachResultType = result.metadata?.type || result.metadata?.resultType || "text";
3566
3599
  const toolResultPart = {
@@ -3618,7 +3651,12 @@ ${finalContent}`;
3618
3651
  const hasUserText = finalContent.trim().length > 0;
3619
3652
  if (hasImageAttachments && hasUserText) {
3620
3653
  const imageAttachments = currentAttachments.filter((a) => a.type === "image");
3621
- pendingAttachmentDataRef.current = await convertAttachmentsToBase64(imageAttachments);
3654
+ try {
3655
+ pendingAttachmentDataRef.current = fileUploaderRef.current ? await convertAttachmentsWithUploaderCached(imageAttachments, fileUploaderRef.current, uploadedUrlMap) : await convertAttachmentsToBase64(imageAttachments);
3656
+ } catch (err) {
3657
+ console.error("[chatllm] pendingAttachment conversion failed:", err);
3658
+ pendingAttachmentDataRef.current = null;
3659
+ }
3622
3660
  } else {
3623
3661
  pendingAttachmentDataRef.current = null;
3624
3662
  }
@@ -3766,7 +3804,9 @@ ${attachmentContext}
3766
3804
  }
3767
3805
  }
3768
3806
  } else if (attachmentResults.length === 0 && pendingAttachmentDataRef.current !== null) {
3769
- const isReferenceImage = pendingAttachmentDataRef.current.some((d) => d.url && !d.base64);
3807
+ const isReferenceImage = pendingAttachmentDataRef.current.some(
3808
+ (d) => d.url && !d.base64 && d.source !== "uploader"
3809
+ );
3770
3810
  if (isReferenceImage) {
3771
3811
  chatMessages.push({
3772
3812
  role: "user",
@@ -15077,7 +15117,9 @@ var ChatUIWithHook = ({
15077
15117
  onAnalyzePatterns,
15078
15118
  // Image upload
15079
15119
  onUploadImage,
15080
- onImageError
15120
+ onImageError,
15121
+ // File upload
15122
+ fileUploader
15081
15123
  }) => {
15082
15124
  const hookOptions = {
15083
15125
  models,
@@ -15128,7 +15170,9 @@ var ChatUIWithHook = ({
15128
15170
  onAnalyzePatterns,
15129
15171
  // Image upload
15130
15172
  onUploadImage,
15131
- onImageError
15173
+ onImageError,
15174
+ // File upload
15175
+ fileUploader
15132
15176
  };
15133
15177
  const state = useChatUI(hookOptions);
15134
15178
  return /* @__PURE__ */ jsx23(ImageErrorContext.Provider, { value: onImageError || null, children: /* @__PURE__ */ jsx23(