mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
Update file attachment messaging and add document file support
Add support for DOCX, PPTX, XLSX, ODT, ODP, and ODS document formats by converting them to plain text. Standardize attachment introduction messages across all AI providers from "Binary data for X follows" to "The contents of the file 'X' are provided below."
This commit is contained in:
parent
562ab8d036
commit
a4c65f16c2
21 changed files with 919 additions and 61 deletions
|
|
@ -308,7 +308,7 @@ export class Claude extends BaseAIClass {
|
|||
}
|
||||
|
||||
return [
|
||||
{type: "text", text: `Binary data for ${attachment.fileName} follows in next message` },
|
||||
{type: "text", text: `The contents of the file '${attachment.fileName}' are provided below.` },
|
||||
{
|
||||
type: isPlainText || mimeType === MimeType.APPLICATION_PDF ? "document" : "image",
|
||||
source: {
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ export class Gemini extends BaseAIClass {
|
|||
continue;
|
||||
}
|
||||
|
||||
parts.push({ text: `Binary data for ${attachment.fileName} follows in next message` });
|
||||
parts.push({ text: `The contents of the file '${attachment.fileName}' are provided below.` });
|
||||
parts.push({
|
||||
fileData: {
|
||||
mimeType: mimeType,
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ export class Mistral extends BaseAIClass {
|
|||
const signedUrl = fileService.getSignedUrl(fileID);
|
||||
if (signedUrl) {
|
||||
contentParts.push(
|
||||
{ type: "text", text: `Document: ${attachment.fileName}` },
|
||||
{ type: "text", text: `The contents of the file '${attachment.fileName}' are provided below.` },
|
||||
{ type: "document_url", document_url: signedUrl }
|
||||
);
|
||||
} else {
|
||||
|
|
@ -371,7 +371,7 @@ export class Mistral extends BaseAIClass {
|
|||
const signedUrl = fileService.getSignedUrl(fileID);
|
||||
if (signedUrl) {
|
||||
contentParts.push(
|
||||
{ type: "text", text: `Image: ${attachment.fileName}` },
|
||||
{ type: "text", text: `The contents of the file '${attachment.fileName}' are provided below.` },
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: signedUrl
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ export class OpenAI extends BaseAIClass {
|
|||
}
|
||||
|
||||
contentBlocks.push(
|
||||
{ type: "input_text", text: `Binary data for ${attachment.fileName} follows in next message` },
|
||||
{ type: "input_text", text: `The contents of the file '${attachment.fileName}' are provided below.` },
|
||||
{
|
||||
type: isPlainText || mimeType === MimeType.APPLICATION_PDF ? "input_file" : "input_image",
|
||||
file_id: fileID
|
||||
|
|
|
|||
|
|
@ -250,8 +250,10 @@
|
|||
{#if message.role === Role.User}
|
||||
<div class="message-container {Role.User}" use:trackingAction={index}>
|
||||
<div class="message-bubble {Role.User}">
|
||||
<div class="message-text-user content-fade-in" contenteditable="false">
|
||||
{@html content}
|
||||
<div class="message-text-user-container content-fade-in" contenteditable="false">
|
||||
<div class="message-text-user">
|
||||
{@html content}
|
||||
</div>
|
||||
</div>
|
||||
{#if message.references.length > 0}
|
||||
<hr class="message-attachment-break"/>
|
||||
|
|
@ -383,16 +385,20 @@
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
.message-text-user {
|
||||
.message-text-user-container {
|
||||
max-height: 15vh;
|
||||
overflow: scroll;
|
||||
padding-top: var(--size-4-2);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.message-text-user::-webkit-scrollbar {
|
||||
.message-text-user-container::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.message-text-user-container {
|
||||
padding-bottom: var(--size-4-2);
|
||||
}
|
||||
|
||||
.conversation-empty-state {
|
||||
margin: auto;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Role } from "Enums/Role";
|
|||
import { AITool } from "Enums/AITool";
|
||||
import { isTextFile, toFileType } from "Enums/FileType";
|
||||
import { FileTypeToMimeType } from "Enums/FileTypeMimeTypeMapping";
|
||||
import { isDocumentMimeType, MimeType } from "Enums/MimeType";
|
||||
|
||||
export class Conversation {
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ export class Conversation {
|
|||
name: functionResponse.name,
|
||||
response: {
|
||||
results: responseResults,
|
||||
...(binaryResults.length > 0 && {message: "Binary files follow in next message"})
|
||||
...(binaryResults.length > 0 && {message: "The contents of the files are provided below."})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -84,7 +85,7 @@ export class Conversation {
|
|||
functionResponse: {
|
||||
name: functionResponse.name,
|
||||
response: {
|
||||
message: "Files retrieved successfully. Binary content follows in next message.",
|
||||
message: "Files retrieved successfully. The contents of the files are provided below.",
|
||||
count: binaryResults.length
|
||||
}
|
||||
}
|
||||
|
|
@ -104,7 +105,12 @@ export class Conversation {
|
|||
.filter(file => file.type && file.contents !== undefined)
|
||||
.map(file => {
|
||||
const fileName = file.path.split('/').pop() || file.path;
|
||||
const mimeType = FileTypeToMimeType[toFileType(file.type as string)];
|
||||
let mimeType = FileTypeToMimeType[toFileType(file.type as string)];
|
||||
|
||||
if (isDocumentMimeType(mimeType)) {
|
||||
mimeType = MimeType.TEXT_PLAIN;
|
||||
return new Attachment(fileName, mimeType, StringTools.toBase64(file.contents as string));
|
||||
}
|
||||
|
||||
return new Attachment(fileName, mimeType, file.contents as string);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -136,6 +136,14 @@ export enum FileType {
|
|||
DIFF = "diff",
|
||||
PATCH = "patch",
|
||||
|
||||
// Document formats
|
||||
DOCX = "docx",
|
||||
PPTX = "pptx",
|
||||
XLSX = "xlsx",
|
||||
ODT = "odt",
|
||||
ODP = "odp",
|
||||
ODS = "ods",
|
||||
|
||||
// Logs
|
||||
LOG = "log",
|
||||
|
||||
|
|
@ -158,7 +166,16 @@ export function isFileType(value: unknown, fileType: FileType): value is FileTyp
|
|||
}
|
||||
|
||||
export function isBinaryFile(extension: string) {
|
||||
return isKnownFileType(extension) && !isTextFile(extension);
|
||||
return isKnownFileType(extension) && !isTextFile(extension) && !isDocumentFile(extension);
|
||||
}
|
||||
|
||||
export function isDocumentFile(extension: string) {
|
||||
return isFileType(extension, FileType.DOCX)
|
||||
|| isFileType(extension, FileType.PPTX)
|
||||
|| isFileType(extension, FileType.XLSX)
|
||||
|| isFileType(extension, FileType.ODT)
|
||||
|| isFileType(extension, FileType.ODP)
|
||||
|| isFileType(extension, FileType.ODS);
|
||||
}
|
||||
|
||||
export function isTextFile(extension: string) {
|
||||
|
|
|
|||
|
|
@ -143,6 +143,14 @@ export const FileTypeToMimeType: Record<FileType, MimeType> = {
|
|||
[FileType.DIFF]: MimeType.TEXT_PLAIN,
|
||||
[FileType.PATCH]: MimeType.TEXT_PLAIN,
|
||||
|
||||
// Document formats
|
||||
[FileType.DOCX]: MimeType.APPLICATION_DOCX,
|
||||
[FileType.PPTX]: MimeType.APPLICATION_PPTX,
|
||||
[FileType.XLSX]: MimeType.APPLICATION_XLSX,
|
||||
[FileType.ODT]: MimeType.APPLICATION_ODT,
|
||||
[FileType.ODP]: MimeType.APPLICATION_ODP,
|
||||
[FileType.ODS]: MimeType.APPLICATION_ODS,
|
||||
|
||||
// Logs
|
||||
[FileType.LOG]: MimeType.TEXT_PLAIN,
|
||||
|
||||
|
|
@ -245,5 +253,13 @@ export const MimeTypeToFileTypes: Record<MimeType, FileType[]> = {
|
|||
[MimeType.VIDEO_OGG]: [FileType.OGV],
|
||||
[MimeType.VIDEO_WEBM]: [FileType.WEBM, FileType.WEBM_VIDEO],
|
||||
|
||||
// Office document formats
|
||||
[MimeType.APPLICATION_DOCX]: [FileType.DOCX],
|
||||
[MimeType.APPLICATION_PPTX]: [FileType.PPTX],
|
||||
[MimeType.APPLICATION_XLSX]: [FileType.XLSX],
|
||||
[MimeType.APPLICATION_ODT]: [FileType.ODT],
|
||||
[MimeType.APPLICATION_ODP]: [FileType.ODP],
|
||||
[MimeType.APPLICATION_ODS]: [FileType.ODS],
|
||||
|
||||
[MimeType.UNKNOWN]: [FileType.UNKNOWN]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,6 +63,14 @@ export enum MimeType {
|
|||
APPLICATION_TYPESCRIPT = "application/x-typescript",
|
||||
APPLICATION_SH = "application/x-sh",
|
||||
|
||||
// Office document formats
|
||||
APPLICATION_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
APPLICATION_PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
APPLICATION_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
APPLICATION_ODT = "application/vnd.oasis.opendocument.text",
|
||||
APPLICATION_ODP = "application/vnd.oasis.opendocument.presentation",
|
||||
APPLICATION_ODS = "application/vnd.oasis.opendocument.spreadsheet",
|
||||
|
||||
// Markup formats
|
||||
TEXT_RST = "text/x-rst",
|
||||
TEXT_ASCIIDOC = "text/x-asciidoc",
|
||||
|
|
@ -108,6 +116,15 @@ export function isKnownMimeType(value: string): value is MimeType {
|
|||
return Object.values(MimeType).includes(value as MimeType) && value !== MimeType.UNKNOWN.toString();
|
||||
}
|
||||
|
||||
export function isDocumentMimeType(mimeType: MimeType) {
|
||||
return mimeType === MimeType.APPLICATION_DOCX ||
|
||||
mimeType === MimeType.APPLICATION_PPTX ||
|
||||
mimeType === MimeType.APPLICATION_XLSX ||
|
||||
mimeType === MimeType.APPLICATION_ODT ||
|
||||
mimeType === MimeType.APPLICATION_ODP ||
|
||||
mimeType === MimeType.APPLICATION_ODS;
|
||||
}
|
||||
|
||||
export function isImageMimeType(mimeType: MimeType) {
|
||||
return mimeType === MimeType.IMAGE_AVIF ||
|
||||
mimeType === MimeType.IMAGE_BMP ||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { extractText, getDocumentProxy } from 'unpdf';
|
||||
import type { IPageText } from '../Types/SearchTypes';
|
||||
import { Exception } from './Exception';
|
||||
import OfficeParser from 'officeparser';
|
||||
|
||||
// Handles PDF format
|
||||
export async function readPDF(arrayBuffer: ArrayBuffer): Promise<IPageText[]> {
|
||||
try {
|
||||
const pdf = await getDocumentProxy(new Uint8Array(arrayBuffer));
|
||||
|
|
@ -27,4 +29,20 @@ export async function readPDF(arrayBuffer: ArrayBuffer): Promise<IPageText[]> {
|
|||
}
|
||||
return [{ text: `Failed to read PDF: ${Exception.messageFrom(error)}`, pageNumber: 1 }] as IPageText[];
|
||||
}
|
||||
}
|
||||
|
||||
// Handles document formats: DOCX, PPTX, XLSX, ODT, ODP, ODS
|
||||
export async function readDocument(arrayBuffer: ArrayBuffer): Promise<IPageText[]> {
|
||||
try {
|
||||
const ast = await OfficeParser.parseOffice(arrayBuffer, {
|
||||
extractAttachments: true,
|
||||
ocr: true,
|
||||
ocrLanguage: "eng+esp"
|
||||
});
|
||||
|
||||
// OfficeParser doesn't currently expose page data (page number etc)
|
||||
return [{ text: ast.toText(), pageNumber: 1 }] as IPageText[];
|
||||
} catch (error) {
|
||||
return [{ text: `Failed to read document: ${Exception.messageFrom(error)}`, pageNumber: 1 }] as IPageText[];
|
||||
}
|
||||
}
|
||||
|
|
@ -68,6 +68,15 @@ export abstract class StringTools {
|
|||
return regex;
|
||||
}
|
||||
|
||||
public static toBase64(text: string): string {
|
||||
const bytes = new TextEncoder().encode(text);
|
||||
let binary = "";
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
return btoa(binary);
|
||||
}
|
||||
|
||||
public static toBytes(input: string): Uint8Array<ArrayBuffer> {
|
||||
const binaryString = atob(input);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ import { arrayBufferToBase64, Notice } from "obsidian";
|
|||
import { FileTypeToMimeType } from "Enums/FileTypeMimeTypeMapping";
|
||||
import * as path from "path-browserify";
|
||||
import { pathExtname } from "Helpers/Helpers";
|
||||
import { FileType, toFileType } from "Enums/FileType";
|
||||
import { FileType, isDocumentFile, toFileType } from "Enums/FileType";
|
||||
import type { FileSystemService } from "./FileSystemService";
|
||||
import { Resolve } from "./DependencyService";
|
||||
import { Services } from "./Services";
|
||||
import { readDocument } from "Helpers/DocumentHelper";
|
||||
import { MimeType } from "Enums/MimeType";
|
||||
import { StringTools } from "Helpers/StringTools";
|
||||
|
||||
export class InputService {
|
||||
|
||||
|
|
@ -43,12 +46,21 @@ export class InputService {
|
|||
new Notice(`Unsupported file '${file.name}'`);
|
||||
continue;
|
||||
}
|
||||
|
||||
attachments.push(new Attachment(
|
||||
file.name,
|
||||
FileTypeToMimeType[fileType],
|
||||
arrayBufferToBase64(await file.arrayBuffer())
|
||||
));
|
||||
|
||||
if (isDocumentFile(fileType)) {
|
||||
const content = await readDocument(await file.arrayBuffer());
|
||||
attachments.push(new Attachment(
|
||||
file.name,
|
||||
MimeType.TEXT_PLAIN,
|
||||
StringTools.toBase64(content[0].text)
|
||||
));
|
||||
} else {
|
||||
attachments.push(new Attachment(
|
||||
file.name,
|
||||
FileTypeToMimeType[fileType],
|
||||
arrayBufferToBase64(await file.arrayBuffer())
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import * as path from "path-browserify";
|
|||
import { Event } from "Enums/Event";
|
||||
import { AbortService } from "./AbortService";
|
||||
import { AIToolResponse } from "AIClasses/ToolDefinitions/AIToolResponse";
|
||||
import { FileType, isBinaryFile, isFileType } from "Enums/FileType";
|
||||
import { readPDF } from "Helpers/PDFHelper";
|
||||
import { FileType, isBinaryFile, isDocumentFile, isFileType } from "Enums/FileType";
|
||||
import { readDocument, readPDF } from "Helpers/DocumentHelper";
|
||||
|
||||
interface IFileEventArgs {
|
||||
oldPath: string;
|
||||
|
|
@ -86,13 +86,22 @@ export class VaultService {
|
|||
return Exception.new(`File does not exist: ${filePath}`);
|
||||
}
|
||||
|
||||
if (isBinaryFile(file.extension.toLowerCase())) {
|
||||
const fileExtension = file.extension.toLowerCase();
|
||||
|
||||
if (isBinaryFile(fileExtension)) {
|
||||
const arrayBuffer = await this.readBinaryData(file, allowAccessToPluginRoot);
|
||||
if (arrayBuffer) {
|
||||
return arrayBufferToBase64(arrayBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDocumentFile(fileExtension)) {
|
||||
const arrayBuffer = await this.readBinaryData(file, allowAccessToPluginRoot);
|
||||
if (arrayBuffer) {
|
||||
return (await readDocument(arrayBuffer))[0].text;
|
||||
}
|
||||
}
|
||||
|
||||
return await this.vault.read(file);
|
||||
}
|
||||
|
||||
|
|
@ -380,9 +389,14 @@ export class VaultService {
|
|||
const batchPromises = batch.map(async (file) => {
|
||||
try {
|
||||
let content;
|
||||
if (isFileType(file.extension.toLocaleLowerCase(), FileType.PDF)) {
|
||||
const fileExtension = file.extension.toLocaleLowerCase();
|
||||
|
||||
if (isFileType(fileExtension, FileType.PDF)) {
|
||||
const arrayBuffer = await this.vault.readBinary(file);
|
||||
content = await readPDF(arrayBuffer);
|
||||
} else if (isDocumentFile(fileExtension)) {
|
||||
const arrayBuffer = await this.vault.readBinary(file);
|
||||
content = await readDocument(arrayBuffer);
|
||||
} else {
|
||||
content = [{ text: await this.vault.cachedRead(file), pageNumber: 1 }] as IPageText[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -795,7 +795,7 @@ describe('Claude', () => {
|
|||
expect(result[0].content.length).toBeGreaterThan(1);
|
||||
|
||||
// Should have filename text block from formatBinaryFiles
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === 'Binary data for test-image.png follows in next message');
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === `The contents of the file 'test-image.png' are provided below.`);
|
||||
expect(filenameBlock).toBeDefined();
|
||||
|
||||
// Should have image content blocks from formatBinaryFiles
|
||||
|
|
@ -828,7 +828,7 @@ describe('Claude', () => {
|
|||
expect(result[0].content.length).toBeGreaterThan(1);
|
||||
|
||||
// Should have filename text block from formatBinaryFiles
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === 'Binary data for document.pdf follows in next message');
|
||||
const filenameBlock = result[0].content.find((block: any) => block.type === 'text' && block.text === `The contents of the file 'document.pdf' are provided below.`);
|
||||
expect(filenameBlock).toBeDefined();
|
||||
|
||||
// Should have document content blocks from formatBinaryFiles
|
||||
|
|
@ -1241,7 +1241,7 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
type: 'text',
|
||||
text: 'Binary data for report.pdf follows in next message'
|
||||
text: `The contents of the file 'report.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'document',
|
||||
|
|
@ -1269,7 +1269,7 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
type: 'text',
|
||||
text: 'Binary data for photo.jpg follows in next message'
|
||||
text: `The contents of the file 'photo.jpg' are provided below.`
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'image',
|
||||
|
|
@ -1410,7 +1410,7 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(6);
|
||||
|
||||
// PDF file
|
||||
expect(parsed[0]).toEqual({ type: 'text', text: 'Binary data for doc.pdf follows in next message' });
|
||||
expect(parsed[0]).toEqual({ type: 'text', text: `The contents of the file 'doc.pdf' are provided below.` });
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'document',
|
||||
source: {
|
||||
|
|
@ -1420,7 +1420,7 @@ describe('Claude', () => {
|
|||
});
|
||||
|
||||
// JPEG image
|
||||
expect(parsed[2]).toEqual({ type: 'text', text: 'Binary data for image.jpg follows in next message' });
|
||||
expect(parsed[2]).toEqual({ type: 'text', text: `The contents of the file 'image.jpg' are provided below.` });
|
||||
expect(parsed[3]).toEqual({
|
||||
type: 'image',
|
||||
source: {
|
||||
|
|
@ -1430,7 +1430,7 @@ describe('Claude', () => {
|
|||
});
|
||||
|
||||
// PNG image
|
||||
expect(parsed[4]).toEqual({ type: 'text', text: 'Binary data for screenshot.png follows in next message' });
|
||||
expect(parsed[4]).toEqual({ type: 'text', text: `The contents of the file 'screenshot.png' are provided below.` });
|
||||
expect(parsed[5]).toEqual({
|
||||
type: 'image',
|
||||
source: {
|
||||
|
|
@ -1477,14 +1477,14 @@ describe('Claude', () => {
|
|||
expect(parsed).toHaveLength(5);
|
||||
|
||||
expect(parsed[0].type).toBe('text');
|
||||
expect(parsed[0].text).toBe('Binary data for good.jpg follows in next message');
|
||||
expect(parsed[0].text).toBe(`The contents of the file 'good.jpg' are provided below.`);
|
||||
expect(parsed[1].type).toBe('image');
|
||||
expect(parsed[2]).toEqual({
|
||||
type: 'text',
|
||||
text: 'Unsupported mime type \'image/bmp\': bad.bmp'
|
||||
});
|
||||
expect(parsed[3].type).toBe('text');
|
||||
expect(parsed[3].text).toBe('Binary data for doc.pdf follows in next message');
|
||||
expect(parsed[3].text).toBe(`The contents of the file 'doc.pdf' are provided below.`);
|
||||
expect(parsed[4].type).toBe('document');
|
||||
});
|
||||
|
||||
|
|
@ -1532,9 +1532,9 @@ describe('Claude', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(4);
|
||||
expect(parsed[0].text).toBe('Binary data for document.PDF follows in next message');
|
||||
expect(parsed[0].text).toBe(`The contents of the file 'document.PDF' are provided below.`);
|
||||
expect(parsed[1].type).toBe('document');
|
||||
expect(parsed[2].text).toBe('Binary data for photo.JPG follows in next message');
|
||||
expect(parsed[2].text).toBe(`The contents of the file 'photo.JPG' are provided below.`);
|
||||
expect(parsed[3].type).toBe('image');
|
||||
});
|
||||
|
||||
|
|
@ -1561,7 +1561,7 @@ describe('Claude', () => {
|
|||
const result = claude.formatBinaryFiles([attachment as any]);
|
||||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed[0].text).toBe('Binary data for report (final) v2.pdf follows in next message');
|
||||
expect(parsed[0].text).toBe(`The contents of the file 'report (final) v2.pdf' are provided below.`);
|
||||
});
|
||||
|
||||
it('should handle JPEG files with .jpeg extension', () => {
|
||||
|
|
|
|||
|
|
@ -1135,7 +1135,7 @@ describe('Gemini', () => {
|
|||
|
||||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
text: 'Binary data for report.pdf follows in next message'
|
||||
text: `The contents of the file 'report.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
|
|
@ -1161,7 +1161,7 @@ describe('Gemini', () => {
|
|||
|
||||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
text: 'Binary data for photo.jpg follows in next message'
|
||||
text: `The contents of the file 'photo.jpg' are provided below.`
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
|
|
@ -1271,7 +1271,7 @@ describe('Gemini', () => {
|
|||
expect(parsed).toHaveLength(6);
|
||||
|
||||
// PDF file
|
||||
expect(parsed[0]).toEqual({ text: 'Binary data for doc.pdf follows in next message' });
|
||||
expect(parsed[0]).toEqual({ text: `The contents of the file 'doc.pdf' are provided below.` });
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'application/pdf',
|
||||
|
|
@ -1280,7 +1280,7 @@ describe('Gemini', () => {
|
|||
});
|
||||
|
||||
// JPEG image
|
||||
expect(parsed[2]).toEqual({ text: 'Binary data for image.jpg follows in next message' });
|
||||
expect(parsed[2]).toEqual({ text: `The contents of the file 'image.jpg' are provided below.` });
|
||||
expect(parsed[3]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'image/jpeg',
|
||||
|
|
@ -1289,7 +1289,7 @@ describe('Gemini', () => {
|
|||
});
|
||||
|
||||
// PNG image
|
||||
expect(parsed[4]).toEqual({ text: 'Binary data for screenshot.png follows in next message' });
|
||||
expect(parsed[4]).toEqual({ text: `The contents of the file 'screenshot.png' are provided below.` });
|
||||
expect(parsed[5]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'image/png',
|
||||
|
|
@ -1334,12 +1334,12 @@ describe('Gemini', () => {
|
|||
|
||||
expect(parsed).toHaveLength(5);
|
||||
|
||||
expect(parsed[0]).toEqual({ text: 'Binary data for good.jpg follows in next message' });
|
||||
expect(parsed[0]).toEqual({ text: `The contents of the file 'good.jpg' are provided below.` });
|
||||
expect(parsed[1]).toHaveProperty('fileData');
|
||||
expect(parsed[2]).toEqual({
|
||||
text: 'Unsupported mime type \'image/bmp\': bad.bmp'
|
||||
});
|
||||
expect(parsed[3]).toEqual({ text: 'Binary data for doc.pdf follows in next message' });
|
||||
expect(parsed[3]).toEqual({ text: `The contents of the file 'doc.pdf' are provided below.` });
|
||||
expect(parsed[4]).toHaveProperty('fileData');
|
||||
});
|
||||
|
||||
|
|
@ -1369,7 +1369,7 @@ describe('Gemini', () => {
|
|||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed).toHaveLength(2); // Only successful upload
|
||||
expect(parsed[0]).toEqual({ text: 'Binary data for success.pdf follows in next message' });
|
||||
expect(parsed[0]).toEqual({ text: `The contents of the file 'success.pdf' are provided below.` });
|
||||
expect(parsed[1]).toEqual({
|
||||
fileData: {
|
||||
mimeType: 'application/pdf',
|
||||
|
|
@ -1399,7 +1399,7 @@ describe('Gemini', () => {
|
|||
const result = gemini.formatBinaryFiles([attachment as any]);
|
||||
const parsed = JSON.parse(result);
|
||||
|
||||
expect(parsed[0].text).toBe('Binary data for report (final) v2.pdf follows in next message');
|
||||
expect(parsed[0].text).toBe(`The contents of the file 'report (final) v2.pdf' are provided below.`);
|
||||
});
|
||||
|
||||
it('should handle JPEG files with .jpeg extension', () => {
|
||||
|
|
|
|||
|
|
@ -705,7 +705,7 @@ describe('Mistral', () => {
|
|||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
type: 'text',
|
||||
text: 'Document: report.pdf'
|
||||
text: `The contents of the file 'report.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'document_url',
|
||||
|
|
@ -730,7 +730,7 @@ describe('Mistral', () => {
|
|||
expect(parsed).toHaveLength(2);
|
||||
expect(parsed[0]).toEqual({
|
||||
type: 'text',
|
||||
text: 'Image: photo.jpg'
|
||||
text: `The contents of the file 'photo.jpg' are provided below.`
|
||||
});
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'image_url',
|
||||
|
|
@ -808,14 +808,14 @@ describe('Mistral', () => {
|
|||
expect(parsed).toHaveLength(4);
|
||||
|
||||
// PDF file
|
||||
expect(parsed[0]).toEqual({ type: 'text', text: 'Document: doc.pdf' });
|
||||
expect(parsed[0]).toEqual({ type: 'text', text: `The contents of the file 'doc.pdf' are provided below.` });
|
||||
expect(parsed[1]).toEqual({
|
||||
type: 'document_url',
|
||||
document_url: 'https://signed-url.com/file_1'
|
||||
});
|
||||
|
||||
// JPEG image
|
||||
expect(parsed[2]).toEqual({ type: 'text', text: 'Image: image.jpg' });
|
||||
expect(parsed[2]).toEqual({ type: 'text', text: `The contents of the file 'image.jpg' are provided below.` });
|
||||
expect(parsed[3]).toEqual({
|
||||
type: 'image_url',
|
||||
image_url: 'https://signed-url.com/file_2'
|
||||
|
|
|
|||
|
|
@ -1016,7 +1016,7 @@ describe('OpenAI', () => {
|
|||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for report.pdf follows in next message'
|
||||
text: `The contents of the file 'report.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_file',
|
||||
|
|
@ -1043,7 +1043,7 @@ describe('OpenAI', () => {
|
|||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for photo.jpg follows in next message'
|
||||
text: `The contents of the file 'photo.jpg' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_image',
|
||||
|
|
@ -1069,7 +1069,7 @@ describe('OpenAI', () => {
|
|||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for diagram.png follows in next message'
|
||||
text: `The contents of the file 'diagram.png' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_image',
|
||||
|
|
@ -1095,7 +1095,7 @@ describe('OpenAI', () => {
|
|||
expect(parsed[0].content).toHaveLength(2);
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for modern.webp follows in next message'
|
||||
text: `The contents of the file 'modern.webp' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_image',
|
||||
|
|
@ -1184,7 +1184,7 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for doc.pdf follows in next message'
|
||||
text: `The contents of the file 'doc.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_file',
|
||||
|
|
@ -1193,7 +1193,7 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed[0].content[2]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for image.jpg follows in next message'
|
||||
text: `The contents of the file 'image.jpg' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[3]).toEqual({
|
||||
type: 'input_image',
|
||||
|
|
@ -1202,7 +1202,7 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed[0].content[4]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for screenshot.png follows in next message'
|
||||
text: `The contents of the file 'screenshot.png' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[5]).toEqual({
|
||||
type: 'input_image',
|
||||
|
|
@ -1249,7 +1249,7 @@ describe('OpenAI', () => {
|
|||
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for good.jpg follows in next message'
|
||||
text: `The contents of the file 'good.jpg' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1].type).toBe('input_image');
|
||||
expect(parsed[0].content[2]).toEqual({
|
||||
|
|
@ -1258,7 +1258,7 @@ describe('OpenAI', () => {
|
|||
});
|
||||
expect(parsed[0].content[3]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for doc.pdf follows in next message'
|
||||
text: `The contents of the file 'doc.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[4].type).toBe('input_file');
|
||||
});
|
||||
|
|
@ -1292,7 +1292,7 @@ describe('OpenAI', () => {
|
|||
expect(parsed[0].content).toHaveLength(2); // Text + file reference
|
||||
expect(parsed[0].content[0]).toEqual({
|
||||
type: 'input_text',
|
||||
text: 'Binary data for success.pdf follows in next message'
|
||||
text: `The contents of the file 'success.pdf' are provided below.`
|
||||
});
|
||||
expect(parsed[0].content[1]).toEqual({
|
||||
type: 'input_file',
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { ConversationContent } from '../../Conversations/ConversationContent';
|
|||
import { Role } from '../../Enums/Role';
|
||||
import { AIToolResponse } from '../../AIClasses/ToolDefinitions/AIToolResponse';
|
||||
import { AITool } from '../../Enums/AITool';
|
||||
import { MimeType } from '../../Enums/MimeType';
|
||||
import { StringTools } from '../../Helpers/StringTools';
|
||||
|
||||
describe('Conversation', () => {
|
||||
describe('constructor', () => {
|
||||
|
|
@ -544,7 +546,72 @@ describe('Conversation', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('non-read_vault_files functions', () => {
|
||||
describe('read_vault_files with document files', () => {
|
||||
it('should base64-encode document file contents and set mime type to text/plain', () => {
|
||||
const conversation = new Conversation();
|
||||
const documentText = 'This is the extracted text from a document file.';
|
||||
const functionResponse = new AIToolResponse(
|
||||
AITool.ReadVaultFiles,
|
||||
{
|
||||
results: [
|
||||
{ path: 'report.odt', type: 'odt', contents: documentText }
|
||||
]
|
||||
},
|
||||
'tool-123'
|
||||
);
|
||||
|
||||
conversation.addFunctionResponse(functionResponse);
|
||||
|
||||
// Should have 2 items: function response + attachments
|
||||
expect(conversation.contents).toHaveLength(2);
|
||||
expect(conversation.contents[1].attachments).toHaveLength(1);
|
||||
|
||||
const attachment = conversation.contents[1].attachments[0];
|
||||
expect(attachment.fileName).toBe('report.odt');
|
||||
expect(attachment.mimeType).toBe(MimeType.TEXT_PLAIN);
|
||||
// Content should be base64-encoded, not plain text
|
||||
expect(attachment.base64).toBe(StringTools.toBase64(documentText));
|
||||
expect(attachment.base64).not.toBe(documentText);
|
||||
});
|
||||
|
||||
it('should handle document files alongside text and binary files', () => {
|
||||
const conversation = new Conversation();
|
||||
const functionResponse = new AIToolResponse(
|
||||
AITool.ReadVaultFiles,
|
||||
{
|
||||
results: [
|
||||
{ path: 'notes.md', type: 'md', contents: '# Notes' },
|
||||
{ path: 'spreadsheet.xlsx', type: 'xlsx', contents: 'Extracted spreadsheet text' },
|
||||
{ path: 'photo.png', type: 'png', contents: 'base64imagedata...' }
|
||||
]
|
||||
},
|
||||
'tool-123'
|
||||
);
|
||||
|
||||
conversation.addFunctionResponse(functionResponse);
|
||||
|
||||
// Should have 2 items: function response (text) + attachments (document + binary)
|
||||
expect(conversation.contents).toHaveLength(2);
|
||||
|
||||
// Text file in function response
|
||||
const parsedResponse = JSON.parse(conversation.contents[0].functionResponse!);
|
||||
expect(parsedResponse.functionResponse.response.results).toHaveLength(1);
|
||||
expect(parsedResponse.functionResponse.response.results[0].path).toBe('notes.md');
|
||||
|
||||
// Document and binary as attachments
|
||||
const attachments = conversation.contents[1].attachments;
|
||||
expect(attachments).toHaveLength(2);
|
||||
|
||||
const docAttachment = attachments.find(a => a.fileName === 'spreadsheet.xlsx')!;
|
||||
expect(docAttachment.mimeType).toBe(MimeType.TEXT_PLAIN);
|
||||
expect(docAttachment.base64).toBe(StringTools.toBase64('Extracted spreadsheet text'));
|
||||
|
||||
const imgAttachment = attachments.find(a => a.fileName === 'photo.png')!;
|
||||
expect(imgAttachment.base64).toBe('base64imagedata...');
|
||||
});
|
||||
});
|
||||
|
||||
describe('non-read_vault_files functions', () => {
|
||||
it('should handle other functions normally', () => {
|
||||
const conversation = new Conversation();
|
||||
const functionResponse = new AIToolResponse(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { SanitiserService } from '../../Services/SanitiserService';
|
|||
import { SettingsService, type IVaultkeeperAISettings } from '../../Services/SettingsService';
|
||||
import { AIProviderModel } from '../../Enums/ApiProvider';
|
||||
import { Exception } from '../../Helpers/Exception';
|
||||
import * as PDFHelper from '../../Helpers/PDFHelper';
|
||||
import * as PDFHelper from '../../Helpers/DocumentHelper';
|
||||
import type { IPageText } from '../../Types/SearchTypes';
|
||||
|
||||
/**
|
||||
|
|
|
|||
675
package-lock.json
generated
675
package-lock.json
generated
|
|
@ -20,6 +20,7 @@
|
|||
"highlight.js": "^11.11.1",
|
||||
"katex": "^0.16.33",
|
||||
"lowlight": "^3.3.0",
|
||||
"officeparser": "^6.0.4",
|
||||
"openai": "^6.25.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"regex-parser": "^2.3.1",
|
||||
|
|
@ -1002,6 +1003,256 @@
|
|||
"ret": "~0.1.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.96.tgz",
|
||||
"integrity": "sha512-6NNmNxvoJKeucVjxaaRUt3La2i5jShgiAbaY3G/72s1Vp3U06XPrAIxkAjBxpDcamEn/t+WJ4OOlGmvILo4/Ew==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"workspaces": [
|
||||
"e2e/*"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas-android-arm64": "0.1.96",
|
||||
"@napi-rs/canvas-darwin-arm64": "0.1.96",
|
||||
"@napi-rs/canvas-darwin-x64": "0.1.96",
|
||||
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.96",
|
||||
"@napi-rs/canvas-linux-arm64-gnu": "0.1.96",
|
||||
"@napi-rs/canvas-linux-arm64-musl": "0.1.96",
|
||||
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.96",
|
||||
"@napi-rs/canvas-linux-x64-gnu": "0.1.96",
|
||||
"@napi-rs/canvas-linux-x64-musl": "0.1.96",
|
||||
"@napi-rs/canvas-win32-arm64-msvc": "0.1.96",
|
||||
"@napi-rs/canvas-win32-x64-msvc": "0.1.96"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-android-arm64": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.96.tgz",
|
||||
"integrity": "sha512-ew1sPrN3dGdZ3L4FoohPfnjq0f9/Jk7o+wP7HkQZokcXgIUD6FIyICEWGhMYzv53j63wUcPvZeAwgewX58/egg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-darwin-arm64": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.96.tgz",
|
||||
"integrity": "sha512-Q/wOXZ5PzTqpdmA5eUOcegCf4Go/zz3aZ5DlzSeDpOjFmfwMKh8EzLAoweQ+mJVagcHQyzoJhaTEnrO68TNyNg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-darwin-x64": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.96.tgz",
|
||||
"integrity": "sha512-UrXiQz28tQEvGM1qvyptewOAfmUrrd5+wvi6Rzjj2VprZI8iZ2KIvBD2lTTG1bVF95AbeDeG7PJA0D9sLKaOFA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm-gnueabihf": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.96.tgz",
|
||||
"integrity": "sha512-I90ODxweD8aEP6XKU/NU+biso95MwCtQ2F46dUvhec1HesFi0tq/tAJkYic/1aBSiO/1kGKmSeD1B0duOHhEHQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm64-gnu": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.96.tgz",
|
||||
"integrity": "sha512-Dx/0+RFV++w3PcRy+4xNXkghhXjA5d0Mw1bs95emn5Llinp1vihMaA6WJt3oYv2LAHc36+gnrhIBsPhUyI2SGw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm64-musl": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.96.tgz",
|
||||
"integrity": "sha512-UvOi7fii3IE2KDfEfhh8m+LpzSRvhGK7o1eho99M2M0HTik11k3GX+2qgVx9EtujN3/bhFFS1kSO3+vPMaJ0Mg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-riscv64-gnu": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.96.tgz",
|
||||
"integrity": "sha512-MBSukhGCQ5nRtf9NbFYWOU080yqkZU1PbuH4o1ROvB4CbPl12fchDR35tU83Wz8gWIM9JTn99lBn9DenPIv7Ig==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-x64-gnu": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.96.tgz",
|
||||
"integrity": "sha512-I/ccu2SstyKiV3HIeVzyBIWfrJo8cN7+MSQZPnabewWV6hfJ2nY7Df2WqOHmobBRUw84uGR6zfQHsUEio/m5Vg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-x64-musl": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.96.tgz",
|
||||
"integrity": "sha512-H3uov7qnTl73GDT4h52lAqpJPsl1tIUyNPWJyhQ6gHakohNqqRq3uf80+NEpzcytKGEOENP1wX3yGwZxhjiWEQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-win32-arm64-msvc": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.96.tgz",
|
||||
"integrity": "sha512-ATp6Y+djOjYtkfV/VRH7CZ8I1MEtkUQBmKUbuWw5zWEHHqfL0cEcInE4Cxgx7zkNAhEdBbnH8HMVrqNp+/gwxA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-win32-x64-msvc": {
|
||||
"version": "0.1.96",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.96.tgz",
|
||||
"integrity": "sha512-UYGdTltVd+Z8mcIuoqGmAXXUvwH5CLf2M6mIB5B0/JmX5J041jETjqtSYl7gN+aj3k1by/SG6sS0hAwCqyK7zw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
|
|
@ -1671,6 +1922,12 @@
|
|||
"svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tokenizer/token": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
||||
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/aria-query": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||
|
|
@ -2299,12 +2556,33 @@
|
|||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.8.11",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
|
||||
"integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.5"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||
|
|
@ -2663,6 +2941,12 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bmp-js": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
|
||||
"integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
|
||||
|
|
@ -2700,12 +2984,51 @@
|
|||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz",
|
||||
|
|
@ -2942,6 +3265,21 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||
"engines": [
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
|
||||
|
|
@ -4433,6 +4771,24 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/events": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.x"
|
||||
}
|
||||
},
|
||||
"node_modules/expect-type": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
|
||||
|
|
@ -4591,6 +4947,23 @@
|
|||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/file-type": {
|
||||
"version": "16.5.4",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
|
||||
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readable-web-to-node-stream": "^3.0.0",
|
||||
"strtok3": "^6.2.4",
|
||||
"token-types": "^4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
|
||||
|
|
@ -5374,6 +5747,32 @@
|
|||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/idb-keyval": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.2.tgz",
|
||||
"integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
|
||||
|
|
@ -5858,6 +6257,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-url": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-weakmap": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
||||
|
|
@ -7593,6 +7998,26 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/officeparser": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/officeparser/-/officeparser-6.0.4.tgz",
|
||||
"integrity": "sha512-zmxst4xbrUxCCY6w5BLmmtewJY5eHkLKNJ+2Z5OKY0JPh5qmtUSslFkg0fC3xc+0RG4DFdfQ36107B99yLMfuQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.10",
|
||||
"concat-stream": "^2.0.0",
|
||||
"file-type": "^16.5.4",
|
||||
"pdfjs-dist": "5.4.530",
|
||||
"tesseract.js": "^6.0.0",
|
||||
"yauzl": "^3.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"officeparser": "dist/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||
|
|
@ -7652,6 +8077,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/opencollective-postinstall": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
||||
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"opencollective-postinstall": "index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
|
|
@ -7888,6 +8322,37 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pdfjs-dist": {
|
||||
"version": "5.4.530",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.4.530.tgz",
|
||||
"integrity": "sha512-r1hWsSIGGmyYUAHR26zSXkxYWLXLMd6AwqcaFYG9YUZ0GBf5GvcjJSeo512tabM4GYFhxhl5pMCmPr7Q72Rq2Q==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=20.16.0 || >=22.3.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas": "^0.1.84"
|
||||
}
|
||||
},
|
||||
"node_modules/peek-readable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
|
||||
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
|
|
@ -7985,6 +8450,15 @@
|
|||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
|
|
@ -8107,6 +8581,52 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-web-to-node-stream": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz",
|
||||
"integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readable-stream": "^4.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-web-to-node-stream/node_modules/readable-stream": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"events": "^3.3.0",
|
||||
"process": "^0.11.10",
|
||||
"string_decoder": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
|
|
@ -8144,6 +8664,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/regex": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz",
|
||||
|
|
@ -8952,6 +9478,15 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
|
|
@ -9177,6 +9712,23 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strtok3": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
|
||||
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"peek-readable": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/style-mod": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz",
|
||||
|
|
@ -9360,6 +9912,50 @@
|
|||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/tesseract.js": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz",
|
||||
"integrity": "sha512-/sPvMvrCtgxnNRCjbTYbr7BRu0yfWDsMZQ2a/T5aN/L1t8wUQN6tTWv6p6FwzpoEBA0jrN2UD2SX4QQFRdoDbA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"bmp-js": "^0.1.0",
|
||||
"idb-keyval": "^6.2.0",
|
||||
"is-url": "^1.2.4",
|
||||
"node-fetch": "^2.6.9",
|
||||
"opencollective-postinstall": "^2.0.3",
|
||||
"regenerator-runtime": "^0.13.3",
|
||||
"tesseract.js-core": "^6.0.0",
|
||||
"wasm-feature-detect": "^1.2.11",
|
||||
"zlibjs": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tesseract.js-core": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.1.2.tgz",
|
||||
"integrity": "sha512-pv4GjmramjdObhDyR1q85Td8X60Puu/lGQn7Kw2id05LLgHhAcWgnz6xSdMCSxBMWjQDmMyDXPTC2aqADdpiow==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/tesseract.js/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tinybench": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
||||
|
|
@ -9413,6 +10009,23 @@
|
|||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/token-types": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
|
||||
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"ieee754": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/toml-eslint-parser": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz",
|
||||
|
|
@ -9439,6 +10052,12 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/trim-lines": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
|
||||
|
|
@ -9616,6 +10235,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
|
|
@ -9837,6 +10462,12 @@
|
|||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
|
||||
|
|
@ -10062,6 +10693,12 @@
|
|||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/wasm-feature-detect": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz",
|
||||
"integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/web-namespaces": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
|
||||
|
|
@ -10081,6 +10718,12 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/whatwg-mimetype": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
|
||||
|
|
@ -10091,6 +10734,16 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
|
@ -10361,6 +11014,19 @@
|
|||
"url": "https://github.com/sponsors/ota-meshi"
|
||||
}
|
||||
},
|
||||
"node_modules/yauzl": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.1.tgz",
|
||||
"integrity": "sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"pend": "~1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
|
@ -10381,6 +11047,15 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/zlibjs": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
|
||||
"integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
"highlight.js": "^11.11.1",
|
||||
"katex": "^0.16.33",
|
||||
"lowlight": "^3.3.0",
|
||||
"officeparser": "^6.0.4",
|
||||
"openai": "^6.25.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"regex-parser": "^2.3.1",
|
||||
|
|
|
|||
Loading…
Reference in a new issue