diff --git a/src/LLMProviders/brevilabsClient.ts b/src/LLMProviders/brevilabsClient.ts index 14ebb74c..acc22937 100644 --- a/src/LLMProviders/brevilabsClient.ts +++ b/src/LLMProviders/brevilabsClient.ts @@ -3,7 +3,7 @@ import { getDecryptedKey } from "@/encryptionService"; import { logInfo } from "@/logger"; import { turnOffPlus, turnOnPlus } from "@/plusUtils"; import { getSettings } from "@/settings/model"; -import { Buffer } from "buffer"; +import { arrayBufferToBase64 } from "@/utils/base64"; import { Notice } from "obsidian"; export interface BrocaResponse { @@ -307,7 +307,7 @@ export class BrevilabsClient { async pdf4llm(binaryContent: ArrayBuffer): Promise { // Convert ArrayBuffer to base64 string - const base64Content = Buffer.from(binaryContent).toString("base64"); + const base64Content = arrayBufferToBase64(binaryContent); const { data, error } = await this.makeRequest("/pdf4llm", { pdf: base64Content, diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx index 7ec012c2..f256ee09 100644 --- a/src/components/Chat.tsx +++ b/src/components/Chat.tsx @@ -22,8 +22,8 @@ import { ABORT_REASON, EVENT_NAMES, LOADING_MESSAGES, - USER_SENDER, RESTRICTION_MESSAGES, + USER_SENDER, } from "@/constants"; import { AppContext, EventTargetContext } from "@/context"; import { useChatManager } from "@/hooks/useChatManager"; @@ -36,7 +36,7 @@ import { updateSetting, useSettingsValue } from "@/settings/model"; import { ChatUIState } from "@/state/ChatUIState"; import { FileParserManager } from "@/tools/FileParserManager"; import { err2String, isPlusChain } from "@/utils"; -import { Buffer } from "buffer"; +import { arrayBufferToBase64 } from "@/utils/base64"; import { Notice, TFile } from "obsidian"; import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; @@ -182,7 +182,7 @@ const Chat: React.FC = ({ // Add images if present for (const image of selectedImages) { const imageData = await image.arrayBuffer(); - const base64Image = Buffer.from(imageData).toString("base64"); + const base64Image = arrayBufferToBase64(imageData); content.push({ type: "image_url", image_url: { diff --git a/src/imageProcessing/imageProcessor.ts b/src/imageProcessing/imageProcessor.ts index e480c43d..d47bf2b8 100644 --- a/src/imageProcessing/imageProcessor.ts +++ b/src/imageProcessing/imageProcessor.ts @@ -1,5 +1,6 @@ import { logError } from "@/logger"; import { safeFetch } from "@/utils"; +import { arrayBufferToBase64 } from "@/utils/base64"; import { Notice, TFile, Vault } from "obsidian"; export interface ImageContent { @@ -196,8 +197,7 @@ export class ImageProcessor { return null; } - const buffer = Buffer.from(arrayBuffer); - const base64 = buffer.toString("base64"); + const base64 = arrayBufferToBase64(arrayBuffer); const result = `data:${mimeType};base64,${base64}`; return result; @@ -234,8 +234,7 @@ export class ImageProcessor { return null; } - const buffer = Buffer.from(arrayBuffer); - const base64 = buffer.toString("base64"); + const base64 = arrayBufferToBase64(arrayBuffer); return `data:${contentType};base64,${base64}`; } catch (error) { logError("Error converting web image to base64:", error); @@ -268,8 +267,7 @@ export class ImageProcessor { return null; } - const buffer = Buffer.from(arrayBuffer); - const base64 = buffer.toString("base64"); + const base64 = arrayBufferToBase64(arrayBuffer); const result = `data:${mimeType};base64,${base64}`; return result; diff --git a/src/utils/base64.ts b/src/utils/base64.ts new file mode 100644 index 00000000..43199459 --- /dev/null +++ b/src/utils/base64.ts @@ -0,0 +1,17 @@ +export function arrayBufferToBase64(buffer: ArrayBuffer): string { + const bytes = new Uint8Array(buffer); + let binary = ""; + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + return (globalThis as any)["btoa"](binary); +} + +export function base64ToArrayBuffer(base64: string): ArrayBuffer { + const binaryString = (globalThis as any)["atob"](base64); + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + return bytes.buffer; +}