andy-stack_vaultkeeper-ai/Helpers/DocumentHelper.ts
Andrew Beal 72bf43a8ea refactor: clarify binary file attachment handling for AI agents
Add explicit instructions across all agent prompts explaining that binary
files (PDFs, images, documents) return content as attachments in the
message following the tool result, not as text in the result itself.

Update tool response messages to clearly state the attachment delivery
mechanism and prevent agents from re-reading the same file expecting
different output.

Improve build safety by neutralizing dynamic eval constructs and
hardening the officeparser plugin against bundle shape changes.
2026-05-31 17:58:23 +01:00

48 lines
No EOL
2 KiB
TypeScript

import { extractText, getDocumentProxy } from 'unpdf';
import type { IPageText } from '../Types/SearchTypes';
import { Exception } from './Exception';
import { parseOffice } from 'officeparser';
// Handles PDF format
export async function readPDF(arrayBuffer: ArrayBuffer): Promise<IPageText[]> {
try {
const pdf = await getDocumentProxy(new Uint8Array(arrayBuffer), { isEvalSupported: false });
const pages = (await extractText(pdf, { mergePages: false })).text;
const pageTexts: IPageText[] = pages.map((pageText, index) => ({
text: pageText,
pageNumber: index + 1
}));
return pageTexts;
} catch (error) {
/** PDF.js error types (from underlying pdfjs-dist library):
* - InvalidPDFException: Invalid or corrupted PDF structure
* - PasswordException: PDF requires a password
* - FormatError: PDF format error
* - UnexpectedResponseException: Unexpected server response
* - AbortException: Operation was aborted
* - UnknownErrorException: Unknown error occurred **/
if (error instanceof Error && error.name === 'PasswordException') {
return [{ text: "PDF is password protected!", pageNumber: 1 }] as 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 parseOffice(arrayBuffer, {
extractAttachments: true,
ocr: true,
ocrLanguage: "eng+esp"
});
// OfficeParser doesn't currently expose page data (page number etc)
return [{ text: (await ast.to('text')).value, pageNumber: 1 }] as IPageText[];
} catch (error) {
return [{ text: `Failed to read document: ${Exception.messageFrom(error)}`, pageNumber: 1 }] as IPageText[];
}
}