@anuma/sdk 6.26.0 → 6.26.2
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/expo/index.cjs +72 -2
- package/dist/expo/index.d.mts +93 -1
- package/dist/expo/index.d.ts +93 -1
- package/dist/expo/index.mjs +68 -2
- package/dist/index.cjs +68 -0
- package/dist/index.d.mts +80 -1
- package/dist/index.d.ts +80 -1
- package/dist/index.mjs +64 -0
- package/dist/react/index.cjs +523 -127
- package/dist/react/index.d.mts +333 -206
- package/dist/react/index.d.ts +333 -206
- package/dist/react/index.mjs +519 -127
- package/dist/server/index.cjs +440 -121
- package/dist/server/index.d.mts +85 -7
- package/dist/server/index.d.ts +85 -7
- package/dist/server/index.mjs +439 -121
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -16461,6 +16461,7 @@ __export(index_exports, {
|
|
|
16461
16461
|
extractEntitiesForMemories: () => extractEntitiesForMemories,
|
|
16462
16462
|
extractFacts: () => extractFacts,
|
|
16463
16463
|
findMatchingTools: () => findMatchingTools,
|
|
16464
|
+
formatFileProcessingNotes: () => formatFileProcessingNotes,
|
|
16464
16465
|
generateConversationId: () => generateConversationId,
|
|
16465
16466
|
generateEmbedding: () => generateEmbedding,
|
|
16466
16467
|
generateEmbeddings: () => generateEmbeddings,
|
|
@@ -20216,6 +20217,15 @@ async function assembleDecryptedMessage(message, address) {
|
|
|
20216
20217
|
// src/lib/db/chat/types.ts
|
|
20217
20218
|
var import_uuid = require("uuid");
|
|
20218
20219
|
|
|
20220
|
+
// src/lib/chat/fileContext.ts
|
|
20221
|
+
var ATTACHED_FILES_OPEN_TAG = "<attached_files>";
|
|
20222
|
+
var ATTACHED_FILES_CLOSE_TAG = "</attached_files>";
|
|
20223
|
+
var ATTACHED_FILES_PREFIX = `${ATTACHED_FILES_OPEN_TAG}
|
|
20224
|
+
The user attached the following file(s) to this message. Their extracted contents are below; when the user refers to "the attached file", "this file" or "the document", they mean these.`;
|
|
20225
|
+
function isAttachedFilesText(text12) {
|
|
20226
|
+
return typeof text12 === "string" && text12.startsWith(ATTACHED_FILES_PREFIX) && text12.endsWith(ATTACHED_FILES_CLOSE_TAG);
|
|
20227
|
+
}
|
|
20228
|
+
|
|
20219
20229
|
// src/lib/chat/useChat/strategies/types.ts
|
|
20220
20230
|
function isChatCompletionResponse(r) {
|
|
20221
20231
|
if (r.object === "response") return false;
|
|
@@ -33902,14 +33912,37 @@ init_logger();
|
|
|
33902
33912
|
if (typeof process !== "undefined" && typeof process.umask !== "function") {
|
|
33903
33913
|
process.umask = (_mask) => 18;
|
|
33904
33914
|
}
|
|
33915
|
+
var MAX_ROWS_PER_SHEET = 2e3;
|
|
33916
|
+
function csvField(value) {
|
|
33917
|
+
return /[",\r\n]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value;
|
|
33918
|
+
}
|
|
33919
|
+
function uniqueHeaders(raw, columnCount) {
|
|
33920
|
+
const bases = [];
|
|
33921
|
+
for (let col = 1; col <= columnCount; col++) bases.push(raw[col]?.trim() || `Column${col}`);
|
|
33922
|
+
const taken = new Set(bases);
|
|
33923
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
33924
|
+
return bases.map((base) => {
|
|
33925
|
+
if (!emitted.has(base)) {
|
|
33926
|
+
emitted.add(base);
|
|
33927
|
+
return base;
|
|
33928
|
+
}
|
|
33929
|
+
let n = 2;
|
|
33930
|
+
while (taken.has(`${base}_${n}`)) n++;
|
|
33931
|
+
const name = `${base}_${n}`;
|
|
33932
|
+
taken.add(name);
|
|
33933
|
+
emitted.add(name);
|
|
33934
|
+
return name;
|
|
33935
|
+
});
|
|
33936
|
+
}
|
|
33905
33937
|
var ExcelProcessor = class {
|
|
33906
|
-
constructor() {
|
|
33938
|
+
constructor(options = {}) {
|
|
33907
33939
|
this.name = "excel";
|
|
33908
33940
|
this.supportedMimeTypes = [
|
|
33909
33941
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
33910
33942
|
// .xlsx
|
|
33911
33943
|
];
|
|
33912
33944
|
this.supportedExtensions = [".xlsx"];
|
|
33945
|
+
this.maxRowsPerSheet = options.maxRowsPerSheet ?? MAX_ROWS_PER_SHEET;
|
|
33913
33946
|
}
|
|
33914
33947
|
async loadExcelJS() {
|
|
33915
33948
|
const mod = await import("exceljs");
|
|
@@ -33924,31 +33957,51 @@ var ExcelProcessor = class {
|
|
|
33924
33957
|
if (workbook.worksheets.length === 0) {
|
|
33925
33958
|
return null;
|
|
33926
33959
|
}
|
|
33927
|
-
|
|
33960
|
+
let truncated = false;
|
|
33961
|
+
const sections = [];
|
|
33928
33962
|
for (const worksheet of workbook.worksheets) {
|
|
33929
|
-
const
|
|
33930
|
-
|
|
33931
|
-
|
|
33932
|
-
|
|
33933
|
-
|
|
33963
|
+
const rawHeaders = [];
|
|
33964
|
+
let columnCount = 0;
|
|
33965
|
+
worksheet.getRow(1).eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
33966
|
+
rawHeaders[colNumber] = cell.text;
|
|
33967
|
+
columnCount = Math.max(columnCount, colNumber);
|
|
33934
33968
|
});
|
|
33969
|
+
const rows = [];
|
|
33970
|
+
let totalRows = 0;
|
|
33935
33971
|
worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
|
|
33936
33972
|
if (rowNumber === 1) return;
|
|
33937
|
-
|
|
33973
|
+
totalRows++;
|
|
33974
|
+
if (rows.length >= this.maxRowsPerSheet) return;
|
|
33975
|
+
const values = [];
|
|
33938
33976
|
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
33939
|
-
|
|
33940
|
-
|
|
33977
|
+
values[colNumber - 1] = String(this.resolveCellValue(cell.value));
|
|
33978
|
+
columnCount = Math.max(columnCount, colNumber);
|
|
33941
33979
|
});
|
|
33942
|
-
rows.push(
|
|
33980
|
+
rows.push(values);
|
|
33943
33981
|
});
|
|
33944
|
-
|
|
33982
|
+
const headers = uniqueHeaders(rawHeaders, columnCount);
|
|
33983
|
+
const lines = [headers, ...rows].map(
|
|
33984
|
+
(values) => headers.map((_, i) => csvField(values[i] ?? "")).join(",")
|
|
33985
|
+
);
|
|
33986
|
+
let section = `## Sheet: ${worksheet.name}
|
|
33987
|
+
|
|
33988
|
+
\`\`\`csv
|
|
33989
|
+
${lines.join("\n")}
|
|
33990
|
+
\`\`\``;
|
|
33991
|
+
if (totalRows > rows.length) {
|
|
33992
|
+
truncated = true;
|
|
33993
|
+
section += `
|
|
33994
|
+
[truncated: showing the first ${rows.length} of ${totalRows} data rows of sheet "${worksheet.name}"]`;
|
|
33995
|
+
}
|
|
33996
|
+
sections.push(section);
|
|
33945
33997
|
}
|
|
33946
33998
|
return {
|
|
33947
|
-
extractedText:
|
|
33948
|
-
format: "
|
|
33999
|
+
extractedText: sections.join("\n\n"),
|
|
34000
|
+
format: "markdown",
|
|
33949
34001
|
metadata: {
|
|
33950
34002
|
sheetCount: workbook.worksheets.length,
|
|
33951
|
-
sheetNames: workbook.worksheets.map((ws) => ws.name)
|
|
34003
|
+
sheetNames: workbook.worksheets.map((ws) => ws.name),
|
|
34004
|
+
truncated
|
|
33952
34005
|
}
|
|
33953
34006
|
};
|
|
33954
34007
|
} catch (error) {
|
|
@@ -33977,6 +34030,9 @@ init_logger();
|
|
|
33977
34030
|
// src/lib/pdf.ts
|
|
33978
34031
|
var pdfjsModule = null;
|
|
33979
34032
|
var workerConfigured = false;
|
|
34033
|
+
var RENDER_SCALE = 1.5;
|
|
34034
|
+
var MAX_RENDER_SIDE_PX = 1600;
|
|
34035
|
+
var JPEG_QUALITY = 0.8;
|
|
33980
34036
|
async function getPdfjs() {
|
|
33981
34037
|
if (!pdfjsModule) {
|
|
33982
34038
|
pdfjsModule = await import("pdfjs-dist");
|
|
@@ -33987,46 +34043,126 @@ async function getPdfjs() {
|
|
|
33987
34043
|
}
|
|
33988
34044
|
return pdfjsModule;
|
|
33989
34045
|
}
|
|
33990
|
-
async function
|
|
34046
|
+
async function withPdfDocument(pdfDataUrl, fn) {
|
|
33991
34047
|
const pdfjs = await getPdfjs();
|
|
33992
34048
|
const loadingTask = pdfjs.getDocument(pdfDataUrl);
|
|
33993
|
-
|
|
33994
|
-
|
|
33995
|
-
|
|
33996
|
-
|
|
33997
|
-
|
|
33998
|
-
|
|
33999
|
-
|
|
34000
|
-
|
|
34001
|
-
|
|
34049
|
+
let pdf;
|
|
34050
|
+
try {
|
|
34051
|
+
pdf = await loadingTask.promise;
|
|
34052
|
+
} catch (error) {
|
|
34053
|
+
await loadingTask.destroy().catch(() => void 0);
|
|
34054
|
+
throw error;
|
|
34055
|
+
}
|
|
34056
|
+
try {
|
|
34057
|
+
return await fn(pdf);
|
|
34058
|
+
} finally {
|
|
34059
|
+
await pdf.destroy().catch(() => void 0);
|
|
34002
34060
|
}
|
|
34003
|
-
return textParts.join("\n\n");
|
|
34004
34061
|
}
|
|
34005
|
-
|
|
34006
|
-
|
|
34007
|
-
const
|
|
34008
|
-
|
|
34009
|
-
|
|
34010
|
-
|
|
34011
|
-
|
|
34012
|
-
|
|
34013
|
-
|
|
34014
|
-
|
|
34015
|
-
|
|
34016
|
-
|
|
34017
|
-
|
|
34018
|
-
|
|
34019
|
-
|
|
34020
|
-
|
|
34021
|
-
|
|
34022
|
-
|
|
34023
|
-
|
|
34024
|
-
|
|
34025
|
-
|
|
34062
|
+
function joinPdfTextItems(items) {
|
|
34063
|
+
let text12 = "";
|
|
34064
|
+
for (const item of items) {
|
|
34065
|
+
if (!("str" in item)) continue;
|
|
34066
|
+
const { str, hasEOL } = item;
|
|
34067
|
+
text12 += str + (hasEOL ? "\n" : " ");
|
|
34068
|
+
}
|
|
34069
|
+
return text12.replace(/[ \t]+\n/g, "\n").trim();
|
|
34070
|
+
}
|
|
34071
|
+
function computeRenderScale(width, height) {
|
|
34072
|
+
const longest = Math.max(width, height);
|
|
34073
|
+
if (!(longest > 0)) return RENDER_SCALE;
|
|
34074
|
+
return Math.min(RENDER_SCALE, MAX_RENDER_SIDE_PX / longest);
|
|
34075
|
+
}
|
|
34076
|
+
async function extractPdfPageTexts(pdfDataUrl) {
|
|
34077
|
+
return withPdfDocument(pdfDataUrl, async (pdf) => {
|
|
34078
|
+
const pageTexts = [];
|
|
34079
|
+
for (let i = 1; i <= pdf.numPages; i++) {
|
|
34080
|
+
const page = await pdf.getPage(i);
|
|
34081
|
+
const textContent = await page.getTextContent();
|
|
34082
|
+
pageTexts.push(joinPdfTextItems(textContent.items));
|
|
34083
|
+
}
|
|
34084
|
+
return pageTexts;
|
|
34085
|
+
});
|
|
34086
|
+
}
|
|
34087
|
+
async function renderPdfPages(pdfDataUrl, maxPages, pageNumbers) {
|
|
34088
|
+
return withPdfDocument(pdfDataUrl, async (pdf) => {
|
|
34089
|
+
const requested = pageNumbers?.filter((n) => n >= 1 && n <= pdf.numPages) ?? Array.from(
|
|
34090
|
+
{ length: maxPages !== void 0 ? Math.min(maxPages, pdf.numPages) : pdf.numPages },
|
|
34091
|
+
(_, i) => i + 1
|
|
34092
|
+
);
|
|
34093
|
+
const pages = [];
|
|
34094
|
+
for (const pageNumber of requested) {
|
|
34095
|
+
const page = await pdf.getPage(pageNumber);
|
|
34096
|
+
const base = page.getViewport({ scale: 1 });
|
|
34097
|
+
const viewport = page.getViewport({ scale: computeRenderScale(base.width, base.height) });
|
|
34098
|
+
const canvas = document.createElement("canvas");
|
|
34099
|
+
const context = canvas.getContext("2d");
|
|
34100
|
+
if (!context) continue;
|
|
34101
|
+
canvas.height = Math.floor(viewport.height);
|
|
34102
|
+
canvas.width = Math.floor(viewport.width);
|
|
34103
|
+
context.fillStyle = "#ffffff";
|
|
34104
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
34105
|
+
await page.render({
|
|
34106
|
+
canvasContext: context,
|
|
34107
|
+
viewport,
|
|
34108
|
+
background: "#ffffff"
|
|
34109
|
+
}).promise;
|
|
34110
|
+
pages.push({ pageNumber, dataUrl: canvas.toDataURL("image/jpeg", JPEG_QUALITY) });
|
|
34111
|
+
canvas.width = 0;
|
|
34112
|
+
canvas.height = 0;
|
|
34113
|
+
}
|
|
34114
|
+
return { pages, pageCount: pdf.numPages };
|
|
34115
|
+
});
|
|
34026
34116
|
}
|
|
34027
34117
|
|
|
34028
34118
|
// src/lib/processors/PdfProcessor.ts
|
|
34029
34119
|
var MAX_IMAGE_PAGES = 20;
|
|
34120
|
+
var MIN_PAGE_TEXT_CHARS = 20;
|
|
34121
|
+
function selectPdfImagePages(pageTexts, maxImagePages = MAX_IMAGE_PAGES) {
|
|
34122
|
+
const needImage = [];
|
|
34123
|
+
pageTexts.forEach((text12, index) => {
|
|
34124
|
+
if (text12.trim().length < MIN_PAGE_TEXT_CHARS) needImage.push(index + 1);
|
|
34125
|
+
});
|
|
34126
|
+
const limit = Math.max(0, maxImagePages);
|
|
34127
|
+
return { rendered: needImage.slice(0, limit), omitted: needImage.slice(limit) };
|
|
34128
|
+
}
|
|
34129
|
+
function formatPageList(pages) {
|
|
34130
|
+
const ranges = [];
|
|
34131
|
+
for (let i = 0; i < pages.length; i++) {
|
|
34132
|
+
const start = pages[i];
|
|
34133
|
+
let end = start;
|
|
34134
|
+
while (i + 1 < pages.length && pages[i + 1] === end + 1) end = pages[++i];
|
|
34135
|
+
ranges.push(start === end ? `${start}` : `${start}-${end}`);
|
|
34136
|
+
}
|
|
34137
|
+
return `${pages.length === 1 ? "page" : "pages"} ${ranges.join(", ")}`;
|
|
34138
|
+
}
|
|
34139
|
+
function buildPdfImageNote(fileName, includedPages, omittedPages, pageCount) {
|
|
34140
|
+
const imageOnlyCount = includedPages.length + omittedPages.length;
|
|
34141
|
+
const allPages = [...includedPages, ...omittedPages].sort((a, b) => a - b);
|
|
34142
|
+
const subject = pageCount === void 0 || imageOnlyCount >= pageCount ? `${fileName}: scanned/image-based PDF (no extractable text)` : `${fileName}: ${imageOnlyCount} of ${pageCount} pages have no extractable text (${formatPageList(allPages)})`;
|
|
34143
|
+
if (includedPages.length === 0) {
|
|
34144
|
+
return `[${subject} \u2014 ${formatPageList(omittedPages)} could not be included as images because of the image limit, so their content is not available]`;
|
|
34145
|
+
}
|
|
34146
|
+
const included = `${formatPageList(includedPages)} rendered as images and included in this message for visual analysis`;
|
|
34147
|
+
if (omittedPages.length === 0) return `[${subject} \u2014 ${included}]`;
|
|
34148
|
+
return `[${subject} \u2014 ${included}; ${formatPageList(omittedPages)} not included because of the image limit, so their content is not available]`;
|
|
34149
|
+
}
|
|
34150
|
+
function rewriteImageNote(result, fileName, keptImages) {
|
|
34151
|
+
const images = result.imageDataUrls ?? [];
|
|
34152
|
+
const note = result.metadata?.imageNote;
|
|
34153
|
+
if (!note || keptImages >= images.length) return result.extractedText;
|
|
34154
|
+
const imagePages = result.metadata?.imagePages ?? [];
|
|
34155
|
+
const omittedPages = result.metadata?.omittedImagePages ?? [];
|
|
34156
|
+
const pageCount = result.metadata?.pageCount;
|
|
34157
|
+
const kept = Math.max(0, keptImages);
|
|
34158
|
+
const newNote = buildPdfImageNote(
|
|
34159
|
+
fileName,
|
|
34160
|
+
imagePages.slice(0, kept),
|
|
34161
|
+
[...imagePages.slice(kept), ...omittedPages].sort((a, b) => a - b),
|
|
34162
|
+
pageCount
|
|
34163
|
+
);
|
|
34164
|
+
return result.extractedText.replace(note, () => newNote);
|
|
34165
|
+
}
|
|
34030
34166
|
var PdfProcessor = class {
|
|
34031
34167
|
constructor() {
|
|
34032
34168
|
this.name = "pdf";
|
|
@@ -34035,43 +34171,65 @@ var PdfProcessor = class {
|
|
|
34035
34171
|
}
|
|
34036
34172
|
async process(file) {
|
|
34037
34173
|
const logger = getLogger();
|
|
34174
|
+
let pageTexts = null;
|
|
34038
34175
|
try {
|
|
34039
|
-
|
|
34040
|
-
if (text12 && text12.trim().length > 0) {
|
|
34041
|
-
return {
|
|
34042
|
-
extractedText: text12,
|
|
34043
|
-
format: "plain"
|
|
34044
|
-
};
|
|
34045
|
-
}
|
|
34046
|
-
logger.info(
|
|
34047
|
-
`[PdfProcessor] Text extraction returned empty for "${file.name}" \u2014 falling back to image conversion`
|
|
34048
|
-
);
|
|
34176
|
+
pageTexts = await extractPdfPageTexts(file.dataUrl);
|
|
34049
34177
|
} catch (textError) {
|
|
34050
34178
|
logger.warn(
|
|
34051
|
-
|
|
34179
|
+
"[PdfProcessor] Text extraction failed \u2014 falling back to image conversion:",
|
|
34052
34180
|
textError
|
|
34053
34181
|
);
|
|
34054
34182
|
}
|
|
34183
|
+
const text12 = (pageTexts ?? []).filter((t) => t.trim()).join("\n\n");
|
|
34184
|
+
const { rendered, omitted } = pageTexts ? selectPdfImagePages(pageTexts) : { rendered: [], omitted: [] };
|
|
34185
|
+
if (pageTexts && rendered.length === 0 && omitted.length === 0) {
|
|
34186
|
+
return text12.trim() ? { extractedText: text12, format: "plain" } : null;
|
|
34187
|
+
}
|
|
34188
|
+
let renderedPages;
|
|
34189
|
+
let pageCount = pageTexts?.length;
|
|
34055
34190
|
try {
|
|
34056
|
-
|
|
34057
|
-
|
|
34058
|
-
|
|
34059
|
-
|
|
34191
|
+
if (pageTexts) {
|
|
34192
|
+
renderedPages = (await renderPdfPages(file.dataUrl, void 0, rendered)).pages;
|
|
34193
|
+
} else {
|
|
34194
|
+
const result = await renderPdfPages(file.dataUrl, MAX_IMAGE_PAGES);
|
|
34195
|
+
renderedPages = result.pages;
|
|
34196
|
+
pageCount = result.pageCount;
|
|
34060
34197
|
}
|
|
34061
|
-
logger.info(`[PdfProcessor] Converted ${images.length} page(s) of "${file.name}" to images`);
|
|
34062
|
-
return {
|
|
34063
|
-
// Contextual note for the LLM — keep it self-contained since the
|
|
34064
|
-
// images are only injected in the current request and not persisted
|
|
34065
|
-
// for follow-up turns.
|
|
34066
|
-
extractedText: `[${file.name}: scanned/image-based PDF \u2014 ${images.length} page(s) rendered as images and included in this message for visual analysis]`,
|
|
34067
|
-
format: "plain",
|
|
34068
|
-
imageDataUrls: images,
|
|
34069
|
-
metadata: { pageCount: images.length }
|
|
34070
|
-
};
|
|
34071
34198
|
} catch (imageError) {
|
|
34072
|
-
|
|
34073
|
-
|
|
34199
|
+
if (!text12.trim()) {
|
|
34200
|
+
logger.error("[PdfProcessor] Image conversion also failed:", imageError);
|
|
34201
|
+
throw imageError;
|
|
34202
|
+
}
|
|
34203
|
+
logger.warn("[PdfProcessor] Image conversion failed \u2014 keeping text only:", imageError);
|
|
34204
|
+
renderedPages = [];
|
|
34205
|
+
}
|
|
34206
|
+
const images = renderedPages.map((p) => p.dataUrl);
|
|
34207
|
+
const imagePages = renderedPages.map((p) => p.pageNumber);
|
|
34208
|
+
const included = new Set(imagePages);
|
|
34209
|
+
const needImage = pageTexts ? [...rendered, ...omitted] : Array.from({ length: pageCount ?? 0 }, (_, i) => i + 1);
|
|
34210
|
+
const omittedPages = needImage.filter((n) => !included.has(n)).sort((a, b) => a - b);
|
|
34211
|
+
if (images.length === 0 && !text12.trim()) {
|
|
34212
|
+
logger.warn("[PdfProcessor] Image conversion also returned empty");
|
|
34213
|
+
return null;
|
|
34074
34214
|
}
|
|
34215
|
+
logger.info(
|
|
34216
|
+
`[PdfProcessor] Rendered ${images.length} page(s) as images, ${omittedPages.length} image-only page(s) omitted`
|
|
34217
|
+
);
|
|
34218
|
+
const imageNote = buildPdfImageNote(file.name, imagePages, omittedPages, pageCount);
|
|
34219
|
+
return {
|
|
34220
|
+
extractedText: text12.trim() ? `${imageNote}
|
|
34221
|
+
|
|
34222
|
+
${text12}` : imageNote,
|
|
34223
|
+
format: "plain",
|
|
34224
|
+
imageDataUrls: images.length > 0 ? images : void 0,
|
|
34225
|
+
metadata: {
|
|
34226
|
+
pageCount,
|
|
34227
|
+
imageNote,
|
|
34228
|
+
imagePages,
|
|
34229
|
+
omittedImagePages: omittedPages,
|
|
34230
|
+
truncated: omittedPages.length > 0
|
|
34231
|
+
}
|
|
34232
|
+
};
|
|
34075
34233
|
}
|
|
34076
34234
|
};
|
|
34077
34235
|
|
|
@@ -34113,6 +34271,21 @@ var EXT = {
|
|
|
34113
34271
|
CFG: ".cfg",
|
|
34114
34272
|
CONF: ".conf"
|
|
34115
34273
|
};
|
|
34274
|
+
function decodeText(bytes) {
|
|
34275
|
+
if (bytes[0] === 255 && bytes[1] === 254) {
|
|
34276
|
+
return new TextDecoder("utf-16le", { fatal: false }).decode(bytes.subarray(2));
|
|
34277
|
+
}
|
|
34278
|
+
if (bytes[0] === 254 && bytes[1] === 255) {
|
|
34279
|
+
const swapped = new Uint8Array(bytes.length - 2);
|
|
34280
|
+
for (let i = 2; i + 1 < bytes.length; i += 2) {
|
|
34281
|
+
swapped[i - 2] = bytes[i + 1];
|
|
34282
|
+
swapped[i - 1] = bytes[i];
|
|
34283
|
+
}
|
|
34284
|
+
return new TextDecoder("utf-16le", { fatal: false }).decode(swapped);
|
|
34285
|
+
}
|
|
34286
|
+
const hasUtf8Bom = bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191;
|
|
34287
|
+
return new TextDecoder("utf-8", { fatal: false }).decode(hasUtf8Bom ? bytes.subarray(3) : bytes);
|
|
34288
|
+
}
|
|
34116
34289
|
var TextProcessor = class {
|
|
34117
34290
|
constructor() {
|
|
34118
34291
|
this.name = "text";
|
|
@@ -34122,7 +34295,7 @@ var TextProcessor = class {
|
|
|
34122
34295
|
async process(file) {
|
|
34123
34296
|
try {
|
|
34124
34297
|
const arrayBuffer = await dataUrlToArrayBuffer(file.dataUrl);
|
|
34125
|
-
const text12 = new
|
|
34298
|
+
const text12 = decodeText(new Uint8Array(arrayBuffer));
|
|
34126
34299
|
if (!text12.trim()) {
|
|
34127
34300
|
return null;
|
|
34128
34301
|
}
|
|
@@ -34145,7 +34318,7 @@ var TextProcessor = class {
|
|
|
34145
34318
|
* rather than prose).
|
|
34146
34319
|
*/
|
|
34147
34320
|
resolveFormat(file) {
|
|
34148
|
-
const type = file.type?.toLowerCase() ?? "";
|
|
34321
|
+
const type = file.type?.split(";")[0].trim().toLowerCase() ?? "";
|
|
34149
34322
|
const name = file.name?.toLowerCase() ?? "";
|
|
34150
34323
|
if (type === MIME.MARKDOWN || type === MIME.X_MARKDOWN || name.endsWith(EXT.MD) || name.endsWith(EXT.MARKDOWN)) {
|
|
34151
34324
|
return "markdown";
|
|
@@ -34203,6 +34376,12 @@ var WordProcessor = class {
|
|
|
34203
34376
|
// src/lib/processors/ZipProcessor.ts
|
|
34204
34377
|
var import_jszip = __toESM(require("jszip"));
|
|
34205
34378
|
init_logger();
|
|
34379
|
+
var MAX_ZIP_ENTRIES = 1e3;
|
|
34380
|
+
var MAX_TOTAL_UNCOMPRESSED_BYTES = 50 * 1024 * 1024;
|
|
34381
|
+
function declaredUncompressedSize(zipObject) {
|
|
34382
|
+
const size = zipObject._data?.uncompressedSize;
|
|
34383
|
+
return typeof size === "number" ? size : void 0;
|
|
34384
|
+
}
|
|
34206
34385
|
var ZipProcessor = class {
|
|
34207
34386
|
constructor(options = {}) {
|
|
34208
34387
|
this.name = "zip";
|
|
@@ -34237,14 +34416,35 @@ var ZipProcessor = class {
|
|
|
34237
34416
|
zipObject: zipEntry
|
|
34238
34417
|
});
|
|
34239
34418
|
});
|
|
34240
|
-
const
|
|
34241
|
-
|
|
34419
|
+
const visibleEntries = this.includeHidden ? entries : entries.filter((entry) => !this.isHidden(entry.path));
|
|
34420
|
+
visibleEntries.sort((a, b) => {
|
|
34242
34421
|
if (a.isDirectory !== b.isDirectory) {
|
|
34243
34422
|
return a.isDirectory ? -1 : 1;
|
|
34244
34423
|
}
|
|
34245
34424
|
return a.path.localeCompare(b.path);
|
|
34246
34425
|
});
|
|
34247
|
-
|
|
34426
|
+
const visibleDirs = visibleEntries.filter((e) => e.isDirectory);
|
|
34427
|
+
const visibleFiles = visibleEntries.filter((e) => !e.isDirectory);
|
|
34428
|
+
const listedDirs = visibleDirs.slice(0, MAX_ZIP_ENTRIES);
|
|
34429
|
+
const listedFiles = visibleFiles.slice(0, MAX_ZIP_ENTRIES);
|
|
34430
|
+
const filteredEntries = [...listedDirs, ...listedFiles];
|
|
34431
|
+
const notes = [];
|
|
34432
|
+
if (visibleFiles.length > listedFiles.length) {
|
|
34433
|
+
notes.push(
|
|
34434
|
+
`[truncated: the archive has ${visibleFiles.length} files; only the first ${listedFiles.length} were listed and considered for extraction, the other ${visibleFiles.length - listedFiles.length} files were dropped]`
|
|
34435
|
+
);
|
|
34436
|
+
}
|
|
34437
|
+
if (visibleDirs.length > listedDirs.length) {
|
|
34438
|
+
notes.push(
|
|
34439
|
+
`[truncated: listing the first ${listedDirs.length} of ${visibleDirs.length} directories]`
|
|
34440
|
+
);
|
|
34441
|
+
}
|
|
34442
|
+
let totalBytes = 0;
|
|
34443
|
+
let byteBudgetHit = false;
|
|
34444
|
+
let truncated = notes.length > 0;
|
|
34445
|
+
const logger = getLogger();
|
|
34446
|
+
for (let index = 0; index < filteredEntries.length; index++) {
|
|
34447
|
+
const entry = filteredEntries[index];
|
|
34248
34448
|
if (entry.isDirectory) continue;
|
|
34249
34449
|
const fileName = entry.path.split("/").pop() || entry.path;
|
|
34250
34450
|
const extension = this.getFileExtension(fileName);
|
|
@@ -34258,9 +34458,20 @@ var ZipProcessor = class {
|
|
|
34258
34458
|
};
|
|
34259
34459
|
const processor = this.registry?.findProcessor(fileMetadata);
|
|
34260
34460
|
if (!processor || processor.name === "zip") continue;
|
|
34461
|
+
const declared = declaredUncompressedSize(entry.zipObject);
|
|
34462
|
+
if (declared !== void 0 && declared > this.maxFileSize) continue;
|
|
34463
|
+
if (totalBytes + (declared ?? 0) > MAX_TOTAL_UNCOMPRESSED_BYTES) {
|
|
34464
|
+
byteBudgetHit = true;
|
|
34465
|
+
break;
|
|
34466
|
+
}
|
|
34261
34467
|
try {
|
|
34262
34468
|
const data = await entry.zipObject.async("uint8array");
|
|
34469
|
+
totalBytes += data.length;
|
|
34263
34470
|
if (data.length > this.maxFileSize) continue;
|
|
34471
|
+
if (totalBytes > MAX_TOTAL_UNCOMPRESSED_BYTES) {
|
|
34472
|
+
byteBudgetHit = true;
|
|
34473
|
+
break;
|
|
34474
|
+
}
|
|
34264
34475
|
const base64 = uint8ArrayToBase64(data);
|
|
34265
34476
|
const dataUrl = `data:${mimeType};base64,${base64}`;
|
|
34266
34477
|
const fileWithData = {
|
|
@@ -34270,23 +34481,36 @@ var ZipProcessor = class {
|
|
|
34270
34481
|
};
|
|
34271
34482
|
const result = await processor.process(fileWithData);
|
|
34272
34483
|
if (result && result.extractedText.trim()) {
|
|
34484
|
+
if (result.metadata?.truncated || result.imageDataUrls?.length) truncated = true;
|
|
34273
34485
|
processedContents.push({
|
|
34274
34486
|
path: entry.path,
|
|
34275
34487
|
processorName: processor.name,
|
|
34276
|
-
|
|
34488
|
+
// Page images of nested files are not forwarded, so their note must not claim them.
|
|
34489
|
+
result: { ...result, extractedText: rewriteImageNote(result, fileName, 0) }
|
|
34277
34490
|
});
|
|
34278
34491
|
}
|
|
34279
|
-
} catch {
|
|
34492
|
+
} catch (error) {
|
|
34493
|
+
logger.warn(
|
|
34494
|
+
`[ZipProcessor] Failed to process archive entry #${index + 1} (${processor.name}, ${mimeType})`,
|
|
34495
|
+
error
|
|
34496
|
+
);
|
|
34280
34497
|
}
|
|
34281
34498
|
}
|
|
34282
|
-
|
|
34499
|
+
if (byteBudgetHit) {
|
|
34500
|
+
truncated = true;
|
|
34501
|
+
notes.push(
|
|
34502
|
+
`[truncated: stopped reading the archive after ${Math.round(MAX_TOTAL_UNCOMPRESSED_BYTES / 1024 / 1024)} MB of decompressed content; later files were not extracted]`
|
|
34503
|
+
);
|
|
34504
|
+
}
|
|
34505
|
+
const output = [this.formatOutput(filteredEntries, processedContents), ...notes].join("\n");
|
|
34283
34506
|
return {
|
|
34284
34507
|
extractedText: output,
|
|
34285
34508
|
format: "markdown",
|
|
34286
34509
|
metadata: {
|
|
34287
34510
|
fileCount: filteredEntries.filter((e) => !e.isDirectory).length,
|
|
34288
34511
|
directoryCount: filteredEntries.filter((e) => e.isDirectory).length,
|
|
34289
|
-
processedFiles: processedContents.length
|
|
34512
|
+
processedFiles: processedContents.length,
|
|
34513
|
+
truncated
|
|
34290
34514
|
}
|
|
34291
34515
|
};
|
|
34292
34516
|
} catch (error) {
|
|
@@ -34388,9 +34612,10 @@ var ProcessorRegistry = class {
|
|
|
34388
34612
|
* @returns The matching processor, or null if none found
|
|
34389
34613
|
*/
|
|
34390
34614
|
findProcessor(file) {
|
|
34391
|
-
|
|
34615
|
+
const mimeType = file.type?.split(";")[0].trim().toLowerCase();
|
|
34616
|
+
if (mimeType) {
|
|
34392
34617
|
for (const processor of this.processors.values()) {
|
|
34393
|
-
if (processor.supportedMimeTypes.includes(
|
|
34618
|
+
if (processor.supportedMimeTypes.includes(mimeType)) {
|
|
34394
34619
|
return processor;
|
|
34395
34620
|
}
|
|
34396
34621
|
}
|
|
@@ -34457,9 +34682,55 @@ var ProcessorRegistry = class {
|
|
|
34457
34682
|
}
|
|
34458
34683
|
};
|
|
34459
34684
|
|
|
34685
|
+
// src/lib/processors/fileStatusNotes.ts
|
|
34686
|
+
var DEFAULT_MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
34687
|
+
function formatMegabytes(bytes) {
|
|
34688
|
+
const mb = bytes / (1024 * 1024);
|
|
34689
|
+
return `${Number.isInteger(mb) ? mb : mb.toFixed(1)} MB`;
|
|
34690
|
+
}
|
|
34691
|
+
function formatFileProcessingNotes(statuses, options = {}) {
|
|
34692
|
+
const maxFileSizeBytes = options.maxFileSizeBytes ?? DEFAULT_MAX_FILE_SIZE_BYTES;
|
|
34693
|
+
const why = {
|
|
34694
|
+
too_large: `the file is larger than ${formatMegabytes(maxFileSizeBytes)}`,
|
|
34695
|
+
unsupported_type: "its file type is not supported for reading",
|
|
34696
|
+
no_data: "its contents were not available to the app",
|
|
34697
|
+
empty: "no text or images could be extracted from it (it may be blank)",
|
|
34698
|
+
timeout: "reading it took too long and was stopped",
|
|
34699
|
+
error: "its text could not be extracted (it may be password-protected or damaged)"
|
|
34700
|
+
};
|
|
34701
|
+
const lines = statuses.filter((s) => s.status === "skipped" || s.status === "failed").map((s) => `[${s.fileName} could not be read: ${why[s.reason ?? "error"]}]`);
|
|
34702
|
+
return lines.length > 0 ? lines.join("\n") : null;
|
|
34703
|
+
}
|
|
34704
|
+
|
|
34460
34705
|
// src/lib/processors/preprocessor.ts
|
|
34461
34706
|
init_logger();
|
|
34462
34707
|
var MAX_TOTAL_IMAGES = 20;
|
|
34708
|
+
var DEFAULT_MAX_EXTRACTED_CHARS_PER_FILE = 1e5;
|
|
34709
|
+
var DEFAULT_MAX_EXTRACTED_CHARS_TOTAL = 2e5;
|
|
34710
|
+
var ProcessingTimeoutError = class extends Error {
|
|
34711
|
+
constructor(timeoutMs) {
|
|
34712
|
+
super(`Timed out processing file after ${timeoutMs}ms`);
|
|
34713
|
+
this.name = "ProcessingTimeoutError";
|
|
34714
|
+
}
|
|
34715
|
+
};
|
|
34716
|
+
function truncationMarker(kept, total, fileName) {
|
|
34717
|
+
return `
|
|
34718
|
+
[truncated: showing the first ${kept} of ${total} characters of ${fileName}]`;
|
|
34719
|
+
}
|
|
34720
|
+
function truncateText(text12, limit, fileName) {
|
|
34721
|
+
if (text12.length <= limit) return { text: text12, truncated: false };
|
|
34722
|
+
let end = Math.max(0, limit);
|
|
34723
|
+
const code = text12.charCodeAt(end - 1);
|
|
34724
|
+
if (end > 0 && code >= 55296 && code <= 56319) end--;
|
|
34725
|
+
return {
|
|
34726
|
+
text: `${text12.slice(0, end)}${truncationMarker(end, text12.length, fileName)}`,
|
|
34727
|
+
truncated: true
|
|
34728
|
+
};
|
|
34729
|
+
}
|
|
34730
|
+
var FILE_SEPARATOR = "\n\n---\n\n";
|
|
34731
|
+
function isImageFile(file) {
|
|
34732
|
+
return (file.type ?? "").trim().toLowerCase().startsWith("image/");
|
|
34733
|
+
}
|
|
34463
34734
|
function createDefaultRegistry() {
|
|
34464
34735
|
const registry = new ProcessorRegistry();
|
|
34465
34736
|
registry.register(new PdfProcessor());
|
|
@@ -34509,10 +34780,11 @@ async function preprocessFiles(files, options = {}) {
|
|
|
34509
34780
|
processors = void 0,
|
|
34510
34781
|
// undefined means use defaults
|
|
34511
34782
|
keepOriginalFiles = true,
|
|
34512
|
-
maxFileSizeBytes =
|
|
34513
|
-
// 10MB
|
|
34783
|
+
maxFileSizeBytes = DEFAULT_MAX_FILE_SIZE_BYTES,
|
|
34514
34784
|
timeoutMs = 3e4,
|
|
34515
34785
|
// 30s per file
|
|
34786
|
+
maxExtractedCharsPerFile = DEFAULT_MAX_EXTRACTED_CHARS_PER_FILE,
|
|
34787
|
+
maxExtractedCharsTotal = DEFAULT_MAX_EXTRACTED_CHARS_TOTAL,
|
|
34516
34788
|
onProgress,
|
|
34517
34789
|
onError
|
|
34518
34790
|
} = options;
|
|
@@ -34522,23 +34794,23 @@ async function preprocessFiles(files, options = {}) {
|
|
|
34522
34794
|
extractedContent: null,
|
|
34523
34795
|
originalFiles: files,
|
|
34524
34796
|
preprocessedFileIds: [],
|
|
34797
|
+
fileStatuses: [],
|
|
34525
34798
|
metadata: { processedCount: 0, skippedCount: 0, errorCount: 0 }
|
|
34526
34799
|
};
|
|
34527
34800
|
}
|
|
34528
|
-
if (processors
|
|
34529
|
-
|
|
34530
|
-
|
|
34531
|
-
|
|
34532
|
-
|
|
34533
|
-
|
|
34534
|
-
};
|
|
34535
|
-
}
|
|
34536
|
-
if (processors === null) {
|
|
34801
|
+
if (processors === null || processors?.length === 0) {
|
|
34802
|
+
const fileStatuses2 = files.filter((file) => !isImageFile(file)).map((file) => ({
|
|
34803
|
+
fileId: file.id,
|
|
34804
|
+
fileName: file.name,
|
|
34805
|
+
status: "skipped",
|
|
34806
|
+
reason: "unsupported_type"
|
|
34807
|
+
}));
|
|
34537
34808
|
return {
|
|
34538
34809
|
extractedContent: null,
|
|
34539
34810
|
originalFiles: files,
|
|
34540
34811
|
preprocessedFileIds: [],
|
|
34541
|
-
|
|
34812
|
+
fileStatuses: fileStatuses2,
|
|
34813
|
+
metadata: { processedCount: 0, skippedCount: fileStatuses2.length, errorCount: 0 }
|
|
34542
34814
|
};
|
|
34543
34815
|
}
|
|
34544
34816
|
let registry;
|
|
@@ -34556,28 +34828,38 @@ async function preprocessFiles(files, options = {}) {
|
|
|
34556
34828
|
const extractedTexts = [];
|
|
34557
34829
|
const allImageUrls = [];
|
|
34558
34830
|
const preprocessedFileIds = [];
|
|
34831
|
+
const fileStatuses = [];
|
|
34559
34832
|
let processedCount = 0;
|
|
34560
34833
|
let skippedCount = 0;
|
|
34561
34834
|
let errorCount = 0;
|
|
34835
|
+
let totalChars = 0;
|
|
34836
|
+
const overBudgetFiles = [];
|
|
34562
34837
|
for (let i = 0; i < files.length; i++) {
|
|
34563
34838
|
const file = files[i];
|
|
34839
|
+
const label = `#${i + 1} (${file.type || "unknown type"}, ${file.size} bytes)`;
|
|
34840
|
+
const skip = (reason) => {
|
|
34841
|
+
skippedCount++;
|
|
34842
|
+
fileStatuses.push({ fileId: file.id, fileName: file.name, status: "skipped", reason });
|
|
34843
|
+
};
|
|
34564
34844
|
onProgress?.(i + 1, files.length, file.name);
|
|
34845
|
+
const processor = registry.findProcessor(file);
|
|
34846
|
+
if (!processor && isImageFile(file)) continue;
|
|
34565
34847
|
if (file.size > maxFileSizeBytes) {
|
|
34566
34848
|
logger.info(
|
|
34567
|
-
`[preprocessFiles] Skipping
|
|
34849
|
+
`[preprocessFiles] Skipping file ${label} \u2014 exceeds ${maxFileSizeBytes} byte limit`
|
|
34568
34850
|
);
|
|
34569
|
-
|
|
34851
|
+
skip("too_large");
|
|
34570
34852
|
continue;
|
|
34571
34853
|
}
|
|
34572
|
-
const processor = registry.findProcessor(file);
|
|
34573
34854
|
if (!processor) {
|
|
34574
|
-
|
|
34855
|
+
skip("unsupported_type");
|
|
34575
34856
|
continue;
|
|
34576
34857
|
}
|
|
34858
|
+
let timer;
|
|
34577
34859
|
try {
|
|
34578
34860
|
if (!file.url) {
|
|
34579
|
-
logger.info(`[preprocessFiles] Skipping
|
|
34580
|
-
|
|
34861
|
+
logger.info(`[preprocessFiles] Skipping file ${label} \u2014 no data URL available`);
|
|
34862
|
+
skip("no_data");
|
|
34581
34863
|
continue;
|
|
34582
34864
|
}
|
|
34583
34865
|
const fileWithData = {
|
|
@@ -34586,40 +34868,76 @@ async function preprocessFiles(files, options = {}) {
|
|
|
34586
34868
|
};
|
|
34587
34869
|
const result = await Promise.race([
|
|
34588
34870
|
processor.process(fileWithData),
|
|
34589
|
-
new Promise(
|
|
34590
|
-
|
|
34591
|
-
)
|
|
34871
|
+
new Promise((_, reject) => {
|
|
34872
|
+
timer = setTimeout(() => reject(new ProcessingTimeoutError(timeoutMs)), timeoutMs);
|
|
34873
|
+
})
|
|
34592
34874
|
]);
|
|
34593
34875
|
if (result && result.extractedText.trim()) {
|
|
34594
|
-
const
|
|
34595
|
-
|
|
34596
|
-
result.extractedText,
|
|
34597
|
-
result.format
|
|
34598
|
-
);
|
|
34599
|
-
extractedTexts.push(formattedContent);
|
|
34876
|
+
const separatorLength = extractedTexts.length > 0 ? FILE_SEPARATOR.length : 0;
|
|
34877
|
+
const remaining = maxExtractedCharsTotal - totalChars - separatorLength - formatExtractedContent(file.name, "", result.format).length;
|
|
34600
34878
|
preprocessedFileIds.push(file.id);
|
|
34601
34879
|
processedCount++;
|
|
34602
|
-
|
|
34603
|
-
|
|
34604
|
-
|
|
34605
|
-
|
|
34606
|
-
|
|
34880
|
+
const fullLength = result.extractedText.length;
|
|
34881
|
+
if (fullLength > remaining && remaining - truncationMarker(fullLength, fullLength, file.name).length <= 0) {
|
|
34882
|
+
overBudgetFiles.push(file.name);
|
|
34883
|
+
fileStatuses.push({ fileId: file.id, fileName: file.name, status: "truncated" });
|
|
34884
|
+
continue;
|
|
34607
34885
|
}
|
|
34886
|
+
const images = result.imageDataUrls ?? [];
|
|
34887
|
+
const keptImages = Math.min(
|
|
34888
|
+
images.length,
|
|
34889
|
+
Math.max(0, MAX_TOTAL_IMAGES - allImageUrls.length)
|
|
34890
|
+
);
|
|
34891
|
+
allImageUrls.push(...images.slice(0, keptImages));
|
|
34892
|
+
const text12 = rewriteImageNote(result, file.name, keptImages);
|
|
34893
|
+
const fitsWhole = text12.length <= Math.min(maxExtractedCharsPerFile, remaining);
|
|
34894
|
+
const limit = fitsWhole ? text12.length : Math.min(
|
|
34895
|
+
maxExtractedCharsPerFile,
|
|
34896
|
+
remaining - truncationMarker(text12.length, text12.length, file.name).length
|
|
34897
|
+
);
|
|
34898
|
+
const capped = truncateText(text12, Math.max(0, limit), file.name);
|
|
34899
|
+
const formattedContent = formatExtractedContent(file.name, capped.text, result.format);
|
|
34900
|
+
totalChars += separatorLength + formattedContent.length;
|
|
34901
|
+
extractedTexts.push(formattedContent);
|
|
34902
|
+
const truncated = capped.truncated || keptImages < images.length || result.metadata?.truncated === true;
|
|
34903
|
+
fileStatuses.push({
|
|
34904
|
+
fileId: file.id,
|
|
34905
|
+
fileName: file.name,
|
|
34906
|
+
status: truncated ? "truncated" : keptImages > 0 ? "rendered_as_images" : "extracted"
|
|
34907
|
+
});
|
|
34608
34908
|
} else {
|
|
34609
|
-
|
|
34909
|
+
skip("empty");
|
|
34610
34910
|
}
|
|
34611
34911
|
} catch (error) {
|
|
34612
34912
|
errorCount++;
|
|
34613
|
-
|
|
34913
|
+
const timedOut = error instanceof ProcessingTimeoutError;
|
|
34914
|
+
fileStatuses.push({
|
|
34915
|
+
fileId: file.id,
|
|
34916
|
+
fileName: file.name,
|
|
34917
|
+
status: "failed",
|
|
34918
|
+
reason: timedOut ? "timeout" : "error"
|
|
34919
|
+
});
|
|
34920
|
+
logger.error(
|
|
34921
|
+
`[preprocessFiles] Error processing file ${label} with ${processor.name}:`,
|
|
34922
|
+
error
|
|
34923
|
+
);
|
|
34614
34924
|
onError?.(file.name, error instanceof Error ? error : new Error(String(error)));
|
|
34925
|
+
} finally {
|
|
34926
|
+
clearTimeout(timer);
|
|
34615
34927
|
}
|
|
34616
34928
|
}
|
|
34617
|
-
|
|
34929
|
+
if (overBudgetFiles.length > 0) {
|
|
34930
|
+
extractedTexts.push(
|
|
34931
|
+
`[truncated: the attachment text limit (${maxExtractedCharsTotal} characters) was reached; the contents of ${overBudgetFiles.join(", ")} were not included]`
|
|
34932
|
+
);
|
|
34933
|
+
}
|
|
34934
|
+
const extractedContent = extractedTexts.length > 0 ? extractedTexts.join(FILE_SEPARATOR) : null;
|
|
34618
34935
|
return {
|
|
34619
34936
|
extractedContent,
|
|
34620
34937
|
imageContentUrls: allImageUrls.length > 0 ? allImageUrls : void 0,
|
|
34621
34938
|
originalFiles: keepOriginalFiles ? files : void 0,
|
|
34622
34939
|
preprocessedFileIds,
|
|
34940
|
+
fileStatuses,
|
|
34623
34941
|
metadata: { processedCount, skippedCount, errorCount }
|
|
34624
34942
|
};
|
|
34625
34943
|
}
|
|
@@ -36777,7 +37095,7 @@ function extractLastUserText(messages) {
|
|
|
36777
37095
|
const content = lastUserMsg.content;
|
|
36778
37096
|
if (typeof content === "string") return content;
|
|
36779
37097
|
if (Array.isArray(content)) {
|
|
36780
|
-
return content.filter((c) => c?.type === "text").map((c) => c.text ?? "").join(" ");
|
|
37098
|
+
return content.filter((c) => c?.type === "text" && !isAttachedFilesText(c.text)).map((c) => c.text ?? "").join(" ");
|
|
36781
37099
|
}
|
|
36782
37100
|
return "";
|
|
36783
37101
|
}
|
|
@@ -38452,6 +38770,7 @@ function buildSystemPrompt(ctx, options) {
|
|
|
38452
38770
|
extractEntitiesForMemories,
|
|
38453
38771
|
extractFacts,
|
|
38454
38772
|
findMatchingTools,
|
|
38773
|
+
formatFileProcessingNotes,
|
|
38455
38774
|
generateConversationId,
|
|
38456
38775
|
generateEmbedding,
|
|
38457
38776
|
generateEmbeddings,
|