openfox 2.0.76 → 2.0.77
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/{chat-handler-3BZ4PDL2.js → chat-handler-FNRKORKP.js} +8 -8
- package/dist/{chunk-XTK6E2QR.js → chunk-3TQN25OM.js} +2 -2
- package/dist/{chunk-J7VCI5EX.js → chunk-BX3VJP2D.js} +96 -44
- package/dist/{chunk-OMWVB2XC.js → chunk-CI5BWHW7.js} +5 -5
- package/dist/{chunk-OCVRIPQP.js → chunk-CJDYSUU5.js} +3 -3
- package/dist/{chunk-HAQV6AJP.js → chunk-CPTC2MD5.js} +2 -2
- package/dist/chunk-NUXS5OQB.js +7 -0
- package/dist/{chunk-EZK7CGJ7.js → chunk-RMXPVQP4.js} +315 -45
- package/dist/{chunk-HLHGNHMV.js → chunk-VMYDUZWI.js} +5 -5
- package/dist/{chunk-KVRSAC4Z.js → chunk-VPFUXGMM.js} +6 -1
- package/dist/{chunk-W4ZEG3LX.js → chunk-WL2WEJAK.js} +2 -2
- package/dist/{chunk-7772ENZN.js → chunk-XNCHOD2X.js} +2 -2
- package/dist/{chunk-D6CI2B7B.js → chunk-YDV7RIQ6.js} +115 -72
- package/dist/{chunk-WGAAQASA.js → chunk-YFVSSMA3.js} +3 -2
- package/dist/{chunk-HHUIXHHX.js → chunk-YPHLCRFP.js} +7 -7
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{client-TDPQVBQ7.js → client-V5DZRO2D.js} +3 -3
- package/dist/{client-pure-NMLDKRDN.js → client-pure-5YE5WFJP.js} +2 -2
- package/dist/{compactor-BB3YYVRP.js → compactor-BJXFE5PL.js} +4 -4
- package/dist/{config-EUMVEFHU.js → config-MD74ETY5.js} +2 -2
- package/dist/{orchestrator-5IMCWX5P.js → orchestrator-67BZJEOO.js} +7 -7
- package/dist/package.json +3 -1
- package/dist/{processor-3R4GS6VB.js → processor-BCOSEMZK.js} +8 -8
- package/dist/{protocol-Sr6Jr4ZS.d.ts → protocol-Ceapo3jt.d.ts} +1 -1
- package/dist/provider/index.d.ts +4 -4
- package/dist/{provider-G2YC2IC4.js → provider-PI3RDDE4.js} +6 -6
- package/dist/{provider-manager-SQIELYLK.js → provider-manager-PD3BXUHY.js} +4 -4
- package/dist/{serve-MXKMKZYY.js → serve-BD44GN7N.js} +13 -13
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +12 -12
- package/dist/{server-SPYFMFQE.js → server-OLRW27DH.js} +9 -9
- package/dist/shared/index.d.ts +3 -3
- package/dist/{tools-JRCUWPJO.js → tools-T7S45DOQ.js} +6 -6
- package/dist/{types-C4cG9CtC.d.ts → types-DABVUbUu.d.ts} +1 -0
- package/dist/{types-DSZhFA8O.d.ts → types-pssMT-oY.d.ts} +1 -1
- package/dist/{update-OXDQ75M7.js → update-56VZOLQJ.js} +2 -2
- package/dist/{update-server-4MTM7M5P.js → update-server-V6GJ43WH.js} +2 -2
- package/dist/web/assets/index-BuUd6IgK.js +305 -0
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +3 -1
- package/dist/chunk-KQEVAO2Q.js +0 -7
- package/dist/web/assets/index-ghDkIdlf.js +0 -305
|
@@ -19,6 +19,7 @@ var OUTPUT_LIMITS = {
|
|
|
19
19
|
maxImageBytes: 2097152,
|
|
20
20
|
// 2MB for images
|
|
21
21
|
maxPdfPages: 50,
|
|
22
|
+
maxPdfImages: 20,
|
|
22
23
|
maxFileBytes: 20971520
|
|
23
24
|
// 20MB general file safety limit
|
|
24
25
|
},
|
|
@@ -38,7 +39,8 @@ var OUTPUT_LIMITS = {
|
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
// src/server/tools/pdf-utils.ts
|
|
41
|
-
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
42
|
+
import { getDocument, OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
43
|
+
import { PNG } from "pngjs";
|
|
42
44
|
var PDF_HEADER = Buffer.from("%PDF");
|
|
43
45
|
function isPdfBuffer(buffer) {
|
|
44
46
|
return buffer.length > 4 && buffer.subarray(0, 4).equals(PDF_HEADER);
|
|
@@ -63,47 +65,278 @@ function processPdfContent(text, maxBytes) {
|
|
|
63
65
|
const isScanned = output.replace(/\[Page \d+\/\d+\]\n/g, "").trim().length === 0;
|
|
64
66
|
return { output, truncated, isScanned };
|
|
65
67
|
}
|
|
66
|
-
|
|
68
|
+
var IMAGE_KIND_GRAYSCALE_1BPP = 1;
|
|
69
|
+
var IMAGE_KIND_RGB_24BPP = 2;
|
|
70
|
+
var IMAGE_KIND_RGBA_32BPP = 3;
|
|
71
|
+
function getRgbaPixel(data, width, x, y, kind) {
|
|
72
|
+
if (kind === IMAGE_KIND_RGBA_32BPP) {
|
|
73
|
+
const i = (y * width + x) * 4;
|
|
74
|
+
return [data[i] ?? 0, data[i + 1] ?? 0, data[i + 2] ?? 0, data[i + 3] ?? 255];
|
|
75
|
+
}
|
|
76
|
+
if (kind === IMAGE_KIND_RGB_24BPP) {
|
|
77
|
+
const i = (y * width + x) * 3;
|
|
78
|
+
return [data[i] ?? 0, data[i + 1] ?? 0, data[i + 2] ?? 0, 255];
|
|
79
|
+
}
|
|
80
|
+
if (kind === IMAGE_KIND_GRAYSCALE_1BPP) {
|
|
81
|
+
const bytesPerRow = Math.ceil(width / 8);
|
|
82
|
+
const byteIdx = y * bytesPerRow + Math.floor(x / 8);
|
|
83
|
+
const bitIdx = 7 - x % 8;
|
|
84
|
+
const val = (data[byteIdx] ?? 0) >> bitIdx & 1 ? 255 : 0;
|
|
85
|
+
return [val, val, val, 255];
|
|
86
|
+
}
|
|
87
|
+
return [0, 0, 0, 255];
|
|
88
|
+
}
|
|
89
|
+
function toRgbaBuffer(data, width, height, kind) {
|
|
90
|
+
const rgba = new Uint8Array(width * height * 4);
|
|
91
|
+
for (let y = 0; y < height; y++) {
|
|
92
|
+
for (let x = 0; x < width; x++) {
|
|
93
|
+
const [r, g, b, a] = getRgbaPixel(data, width, x, y, kind);
|
|
94
|
+
const i = (y * width + x) * 4;
|
|
95
|
+
rgba[i] = r;
|
|
96
|
+
rgba[i + 1] = g;
|
|
97
|
+
rgba[i + 2] = b;
|
|
98
|
+
rgba[i + 3] = a;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return rgba;
|
|
102
|
+
}
|
|
103
|
+
function extractBitmapToRawImageData(bitmap) {
|
|
104
|
+
const canvas = new globalThis.OffscreenCanvas(bitmap.width, bitmap.height);
|
|
105
|
+
const ctx = canvas.getContext("2d");
|
|
106
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
107
|
+
const imageData = ctx.getImageData(0, 0, bitmap.width, bitmap.height);
|
|
108
|
+
return {
|
|
109
|
+
width: bitmap.width,
|
|
110
|
+
height: bitmap.height,
|
|
111
|
+
data: new Uint8Array(imageData.data.buffer),
|
|
112
|
+
kind: IMAGE_KIND_RGBA_32BPP
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function encodeImageToDataUrl(imgData, maxDimension = 1024) {
|
|
116
|
+
try {
|
|
117
|
+
let { width, height } = imgData;
|
|
118
|
+
let { data, kind } = imgData;
|
|
119
|
+
if (imgData.bitmap && !data) {
|
|
120
|
+
const converted = extractBitmapToRawImageData(imgData.bitmap);
|
|
121
|
+
data = converted.data;
|
|
122
|
+
kind = converted.kind;
|
|
123
|
+
}
|
|
124
|
+
if (!data) return null;
|
|
125
|
+
if (width * height * 4 > 20971520) return null;
|
|
126
|
+
if (maxDimension > 0 && (width > maxDimension || height > maxDimension)) {
|
|
127
|
+
const scale = maxDimension / Math.max(width, height);
|
|
128
|
+
const newWidth = Math.round(width * scale);
|
|
129
|
+
const newHeight = Math.round(height * scale);
|
|
130
|
+
const scaled = new Uint8Array(newWidth * newHeight * 4);
|
|
131
|
+
for (let y = 0; y < newHeight; y++) {
|
|
132
|
+
for (let x = 0; x < newWidth; x++) {
|
|
133
|
+
const srcX = Math.floor(x / scale);
|
|
134
|
+
const srcY = Math.floor(y / scale);
|
|
135
|
+
const dstI = (y * newWidth + x) * 4;
|
|
136
|
+
const [r, g, b, a] = getRgbaPixel(data, width, srcX, srcY, kind);
|
|
137
|
+
scaled[dstI] = r;
|
|
138
|
+
scaled[dstI + 1] = g;
|
|
139
|
+
scaled[dstI + 2] = b;
|
|
140
|
+
scaled[dstI + 3] = a;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
width = newWidth;
|
|
144
|
+
height = newHeight;
|
|
145
|
+
const png2 = new PNG({ width, height });
|
|
146
|
+
Buffer.from(scaled.buffer, scaled.byteOffset, scaled.byteLength).copy(png2.data);
|
|
147
|
+
const pngBuffer2 = PNG.sync.write(png2);
|
|
148
|
+
return `data:image/png;base64,${pngBuffer2.toString("base64")}`;
|
|
149
|
+
}
|
|
150
|
+
let rgba;
|
|
151
|
+
if (kind === IMAGE_KIND_RGBA_32BPP) {
|
|
152
|
+
rgba = Uint8Array.from(
|
|
153
|
+
data instanceof Uint8ClampedArray ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : data
|
|
154
|
+
);
|
|
155
|
+
} else {
|
|
156
|
+
rgba = toRgbaBuffer(data, width, height, kind);
|
|
157
|
+
}
|
|
158
|
+
const png = new PNG({ width, height });
|
|
159
|
+
Buffer.from(rgba.buffer, rgba.byteOffset, rgba.byteLength).copy(png.data);
|
|
160
|
+
const pngBuffer = PNG.sync.write(png);
|
|
161
|
+
return `data:image/png;base64,${pngBuffer.toString("base64")}`;
|
|
162
|
+
} catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function extractPageBlocks(page, pageIndex, pageCount, imageCounter, maxImages) {
|
|
167
|
+
const [textContent, opList] = await Promise.all([page.getTextContent(), page.getOperatorList()]);
|
|
168
|
+
const textItems = textContent.items.filter(
|
|
169
|
+
(item) => "str" in item
|
|
170
|
+
);
|
|
171
|
+
const textStr = textItems.map((t) => t.str).join(" ").trim();
|
|
172
|
+
const imageOpIndices = [];
|
|
173
|
+
for (let i = 0; i < opList.fnArray.length; i++) {
|
|
174
|
+
const op = opList.fnArray[i];
|
|
175
|
+
if (op === OPS.paintImageXObject || op === OPS.paintInlineImageXObject || op === OPS.paintImageMaskXObject || op === OPS.paintImageMaskXObjectGroup || op === OPS.paintImageXObjectRepeat || op === OPS.paintImageMaskXObjectRepeat || op === OPS.paintInlineImageXObjectGroup || op === OPS.paintSolidColorImageMask) {
|
|
176
|
+
imageOpIndices.push(i);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const blocks = [];
|
|
180
|
+
if (textStr) {
|
|
181
|
+
blocks.push({ type: "text", content: `[Page ${pageIndex}/${pageCount}]
|
|
182
|
+
${textStr}` });
|
|
183
|
+
}
|
|
184
|
+
for (let imageOpIdx = 0; imageOpIdx < imageOpIndices.length; imageOpIdx++) {
|
|
185
|
+
if (imageCounter.count >= maxImages) {
|
|
186
|
+
imageCounter.limitReached = true;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
const opIdx = imageOpIndices[imageOpIdx];
|
|
190
|
+
if (opIdx === void 0) break;
|
|
191
|
+
const imgBlock = await extractImageBlock(page, opList, opIdx);
|
|
192
|
+
if (imgBlock) {
|
|
193
|
+
blocks.push(imgBlock);
|
|
194
|
+
imageCounter.count++;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return blocks;
|
|
198
|
+
}
|
|
199
|
+
function isValidPixelData(data) {
|
|
200
|
+
return data instanceof Uint8Array || data instanceof Uint8ClampedArray;
|
|
201
|
+
}
|
|
202
|
+
var IMAGE_RESOLVE_TIMEOUT_MS = 5e3;
|
|
203
|
+
async function getObjectWithFallback(objs, objId) {
|
|
204
|
+
try {
|
|
205
|
+
return objs.get(objId);
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
return new Promise((resolve, reject) => {
|
|
209
|
+
const timeoutId = setTimeout(() => reject(new Error("timeout")), IMAGE_RESOLVE_TIMEOUT_MS);
|
|
210
|
+
try {
|
|
211
|
+
;
|
|
212
|
+
objs.get(objId, (data) => {
|
|
213
|
+
clearTimeout(timeoutId);
|
|
214
|
+
resolve(data);
|
|
215
|
+
});
|
|
216
|
+
} catch (e) {
|
|
217
|
+
clearTimeout(timeoutId);
|
|
218
|
+
reject(e);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
async function extractImageBlock(page, opList, opIdx) {
|
|
223
|
+
const args = opList.argsArray[opIdx];
|
|
224
|
+
const objId = Array.isArray(args) ? args[0] : void 0;
|
|
225
|
+
let imgData = null;
|
|
226
|
+
if (objId && typeof objId === "string") {
|
|
227
|
+
try {
|
|
228
|
+
const store = objId.startsWith("g_") ? page.commonObjs : page.objs;
|
|
229
|
+
const raw = await getObjectWithFallback(store, objId);
|
|
230
|
+
if (raw && typeof raw === "object" && "width" in raw && "height" in raw) {
|
|
231
|
+
const r = raw;
|
|
232
|
+
if (isValidPixelData(r["data"])) {
|
|
233
|
+
imgData = raw;
|
|
234
|
+
} else if (r["bitmap"] && !r["data"]) {
|
|
235
|
+
imgData = raw;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
} catch {
|
|
239
|
+
}
|
|
240
|
+
} else if (Array.isArray(args) && args[0] && typeof args[0] === "object" && "width" in args[0]) {
|
|
241
|
+
const inline = args[0];
|
|
242
|
+
if (isValidPixelData(inline["data"])) {
|
|
243
|
+
imgData = args[0];
|
|
244
|
+
} else if (inline["bitmap"] && !inline["data"]) {
|
|
245
|
+
imgData = args[0];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (imgData) {
|
|
249
|
+
const dataUrl = encodeImageToDataUrl(imgData);
|
|
250
|
+
if (dataUrl) {
|
|
251
|
+
return { type: "image", dataUrl };
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
async function extractPdfContent(buffer) {
|
|
67
257
|
const doc = await getDocument({ data: Uint8Array.from(buffer) }).promise;
|
|
68
258
|
const pageCount = doc.numPages;
|
|
69
|
-
const
|
|
70
|
-
const info = rawMeta.info;
|
|
71
|
-
const title = info?.["Title"] || null;
|
|
72
|
-
const author = info?.["Author"] || null;
|
|
73
|
-
const pages = [];
|
|
259
|
+
const allBlocks = [];
|
|
74
260
|
const limitedPageCount = Math.min(pageCount, OUTPUT_LIMITS.read_file.maxPdfPages);
|
|
261
|
+
const maxImages = OUTPUT_LIMITS.read_file.maxPdfImages;
|
|
262
|
+
const imageCounter = { count: 0, limitReached: false };
|
|
263
|
+
let title = null;
|
|
264
|
+
let author = null;
|
|
265
|
+
try {
|
|
266
|
+
const rawMeta = await doc.getMetadata();
|
|
267
|
+
const info = rawMeta.info;
|
|
268
|
+
title = info?.["Title"] || null;
|
|
269
|
+
author = info?.["Author"] || null;
|
|
270
|
+
} catch {
|
|
271
|
+
}
|
|
75
272
|
try {
|
|
76
273
|
for (let i = 1; i <= limitedPageCount; i++) {
|
|
77
274
|
const page = await doc.getPage(i);
|
|
78
275
|
try {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
pages.push(`[Page ${i}/${pageCount}]
|
|
82
|
-
${pageText}`);
|
|
276
|
+
const blocks = await extractPageBlocks(page, i, pageCount, imageCounter, maxImages);
|
|
277
|
+
allBlocks.push(...blocks);
|
|
83
278
|
} finally {
|
|
84
279
|
page.cleanup();
|
|
85
280
|
}
|
|
86
281
|
}
|
|
282
|
+
} catch {
|
|
87
283
|
} finally {
|
|
88
284
|
doc.cleanup();
|
|
89
285
|
}
|
|
90
|
-
let text = pages.join("\n\n");
|
|
91
286
|
if (pageCount > limitedPageCount) {
|
|
92
|
-
|
|
287
|
+
allBlocks.push({
|
|
288
|
+
type: "text",
|
|
289
|
+
content: `[PDF has ${pageCount} pages, showing first ${limitedPageCount}. Use a shell command to process more.]`
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (imageCounter.limitReached) {
|
|
293
|
+
allBlocks.push({
|
|
294
|
+
type: "text",
|
|
295
|
+
content: `[Image limit reached: showing first ${maxImages} images out of more in this document.]`
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
blocks: allBlocks,
|
|
300
|
+
pageCount,
|
|
301
|
+
title,
|
|
302
|
+
author,
|
|
303
|
+
imageCount: imageCounter.count,
|
|
304
|
+
imageLimitReached: imageCounter.limitReached
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
async function extractPdfText(buffer) {
|
|
308
|
+
const result = await extractPdfContent(buffer);
|
|
309
|
+
const text = result.blocks.filter((b) => b.type === "text").map((b) => b.content ?? "").join("\n\n");
|
|
310
|
+
return { text, pageCount: result.pageCount, title: result.title, author: result.author };
|
|
311
|
+
}
|
|
93
312
|
|
|
94
|
-
|
|
313
|
+
// src/server/utils/cache.ts
|
|
314
|
+
import { createHash } from "crypto";
|
|
315
|
+
function contentHash(data) {
|
|
316
|
+
return createHash("sha256").update(data).digest("hex").slice(0, 16);
|
|
317
|
+
}
|
|
318
|
+
function cacheSet(cache, key, value) {
|
|
319
|
+
const max = 50;
|
|
320
|
+
if (cache.size >= max) {
|
|
321
|
+
const first = cache.keys().next().value;
|
|
322
|
+
if (first !== void 0) cache.delete(first);
|
|
95
323
|
}
|
|
96
|
-
|
|
324
|
+
cache.set(key, value);
|
|
97
325
|
}
|
|
98
326
|
|
|
99
|
-
// src/server/
|
|
100
|
-
function
|
|
327
|
+
// src/server/utils/data-url.ts
|
|
328
|
+
function decodeDataUrl(data) {
|
|
101
329
|
const match = data.match(/^data:.*?;base64,(.+)$/);
|
|
102
|
-
if (match?.[1])
|
|
103
|
-
|
|
330
|
+
if (!match?.[1]) return null;
|
|
331
|
+
try {
|
|
332
|
+
return Buffer.from(match[1], "base64");
|
|
333
|
+
} catch {
|
|
334
|
+
return null;
|
|
104
335
|
}
|
|
105
|
-
return data;
|
|
106
336
|
}
|
|
337
|
+
|
|
338
|
+
// src/server/llm/resolve-attachments.ts
|
|
339
|
+
var pdfBlockCache = /* @__PURE__ */ new Map();
|
|
107
340
|
async function extractPdfFromDataUrl(data, filename) {
|
|
108
341
|
const base64Match = data.match(/^data:.*?;base64,(.+)$/);
|
|
109
342
|
if (base64Match?.[1]) {
|
|
@@ -118,14 +351,50 @@ ${result.text}`;
|
|
|
118
351
|
}
|
|
119
352
|
return `[PDF: ${filename}] (could not extract text)`;
|
|
120
353
|
}
|
|
354
|
+
async function extractPdfBlocksFromDataUrl(data, filename) {
|
|
355
|
+
const cacheKey = contentHash(data);
|
|
356
|
+
const cached = pdfBlockCache.get(cacheKey);
|
|
357
|
+
if (cached) {
|
|
358
|
+
const result = [{ type: "text", text: `[PDF: ${filename}]` }];
|
|
359
|
+
result.push(...cached);
|
|
360
|
+
return result;
|
|
361
|
+
}
|
|
362
|
+
const base64Match = data.match(/^data:.*?;base64,(.+)$/);
|
|
363
|
+
if (!base64Match?.[1]) {
|
|
364
|
+
cacheSet(pdfBlockCache, cacheKey, []);
|
|
365
|
+
return [{ type: "text", text: `[PDF: ${filename}] (could not extract content)` }];
|
|
366
|
+
}
|
|
367
|
+
try {
|
|
368
|
+
const buffer = Buffer.from(base64Match[1], "base64");
|
|
369
|
+
const result = await extractPdfContent(buffer);
|
|
370
|
+
const body = [];
|
|
371
|
+
for (const block of result.blocks) {
|
|
372
|
+
if (block.type === "text" && block.content) {
|
|
373
|
+
body.push({ type: "text", text: block.content });
|
|
374
|
+
} else if (block.type === "image" && block.dataUrl) {
|
|
375
|
+
body.push({ type: "image_url", image_url: { url: block.dataUrl } });
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
cacheSet(pdfBlockCache, cacheKey, body);
|
|
379
|
+
const parts = [{ type: "text", text: `[PDF: ${filename}]` }];
|
|
380
|
+
parts.push(...body);
|
|
381
|
+
return parts;
|
|
382
|
+
} catch {
|
|
383
|
+
cacheSet(pdfBlockCache, cacheKey, []);
|
|
384
|
+
return [{ type: "text", text: `[PDF: ${filename}] (could not extract content)` }];
|
|
385
|
+
}
|
|
386
|
+
}
|
|
121
387
|
async function resolveAttachmentToText(attachment, supportsVision) {
|
|
122
388
|
const mimeType = attachment.mimeType;
|
|
123
389
|
if (TEXT_MIME_EXACT.includes(mimeType) || TEXT_MIME_PREFIXES.some((p) => mimeType.startsWith(p))) {
|
|
124
|
-
const text =
|
|
390
|
+
const text = decodeDataUrl(attachment.data)?.toString("utf8") ?? attachment.data;
|
|
125
391
|
return `[File: ${attachment.filename || "file"}]
|
|
126
392
|
${text}`;
|
|
127
393
|
}
|
|
128
394
|
if (mimeType === "application/pdf") {
|
|
395
|
+
if (attachment.pdfContent) {
|
|
396
|
+
return attachment.pdfContent;
|
|
397
|
+
}
|
|
129
398
|
return extractPdfFromDataUrl(attachment.data, attachment.filename || "document.pdf");
|
|
130
399
|
}
|
|
131
400
|
if (supportsVision) {
|
|
@@ -136,6 +405,7 @@ ${text}`;
|
|
|
136
405
|
}
|
|
137
406
|
return `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`;
|
|
138
407
|
}
|
|
408
|
+
var isVisionAttachment = (attachment) => attachment.mimeType.startsWith("image/") || attachment.mimeType === "application/pdf";
|
|
139
409
|
async function resolveAttachmentsInMessages(messages, supportsVision) {
|
|
140
410
|
const result = [];
|
|
141
411
|
for (const msg of messages) {
|
|
@@ -143,7 +413,7 @@ async function resolveAttachmentsInMessages(messages, supportsVision) {
|
|
|
143
413
|
result.push(msg);
|
|
144
414
|
continue;
|
|
145
415
|
}
|
|
146
|
-
if (supportsVision && msg.attachments.every(
|
|
416
|
+
if (supportsVision && msg.attachments.every(isVisionAttachment)) {
|
|
147
417
|
result.push(msg);
|
|
148
418
|
continue;
|
|
149
419
|
}
|
|
@@ -151,7 +421,7 @@ async function resolveAttachmentsInMessages(messages, supportsVision) {
|
|
|
151
421
|
if (msg.content?.trim()) parts.push(msg.content);
|
|
152
422
|
const remainingImageAttachments = [];
|
|
153
423
|
for (const attachment of msg.attachments) {
|
|
154
|
-
if (supportsVision && attachment
|
|
424
|
+
if (supportsVision && isVisionAttachment(attachment)) {
|
|
155
425
|
remainingImageAttachments.push(attachment);
|
|
156
426
|
continue;
|
|
157
427
|
}
|
|
@@ -197,8 +467,8 @@ async function buildAttachmentContent(msgContent, attachments, modelSupportsVisi
|
|
|
197
467
|
content.push({ type: "text", text: msgContent });
|
|
198
468
|
}
|
|
199
469
|
for (const attachment of attachments) {
|
|
200
|
-
const
|
|
201
|
-
content.push(
|
|
470
|
+
const parts = await convertAttachment(attachment, modelSupportsVision);
|
|
471
|
+
content.push(...parts);
|
|
202
472
|
}
|
|
203
473
|
return content;
|
|
204
474
|
}
|
|
@@ -222,7 +492,7 @@ function getThinking(msg, override) {
|
|
|
222
492
|
function buildAssistantMessage(msg, thinkingField) {
|
|
223
493
|
const result = {
|
|
224
494
|
role: "assistant",
|
|
225
|
-
content: msg.content || null
|
|
495
|
+
content: msg.toolCalls?.length ? msg.content || "" : msg.content || null
|
|
226
496
|
};
|
|
227
497
|
if (msg.toolCalls?.length) {
|
|
228
498
|
result["tool_calls"] = convertToolCalls(msg.toolCalls);
|
|
@@ -235,32 +505,28 @@ function buildAssistantMessage(msg, thinkingField) {
|
|
|
235
505
|
async function convertAttachment(attachment, modelSupportsVision) {
|
|
236
506
|
const mimeType = attachment.mimeType;
|
|
237
507
|
if (TEXT_MIME_EXACT.includes(mimeType) || TEXT_MIME_PREFIXES.some((p) => mimeType.startsWith(p))) {
|
|
238
|
-
return {
|
|
239
|
-
|
|
240
|
-
text: `[File: ${attachment.filename || "file"}]
|
|
241
|
-
${attachment.data}`
|
|
242
|
-
};
|
|
508
|
+
return [{ type: "text", text: `[File: ${attachment.filename || "file"}]
|
|
509
|
+
${attachment.data}` }];
|
|
243
510
|
}
|
|
244
511
|
if (mimeType === "application/pdf") {
|
|
512
|
+
if (modelSupportsVision) {
|
|
513
|
+
return extractPdfBlocksFromDataUrl(attachment.data, attachment.filename || "document.pdf");
|
|
514
|
+
}
|
|
515
|
+
if (attachment.pdfContent) {
|
|
516
|
+
return [{ type: "text", text: attachment.pdfContent }];
|
|
517
|
+
}
|
|
245
518
|
const text = await extractPdfFromDataUrl(attachment.data, attachment.filename || "document.pdf");
|
|
246
|
-
return { type: "text", text };
|
|
519
|
+
return [{ type: "text", text }];
|
|
247
520
|
}
|
|
248
521
|
if (modelSupportsVision) {
|
|
249
|
-
return {
|
|
250
|
-
type: "image_url",
|
|
251
|
-
image_url: { url: attachment.data }
|
|
252
|
-
};
|
|
522
|
+
return [{ type: "image_url", image_url: { url: attachment.data } }];
|
|
253
523
|
}
|
|
254
524
|
if (attachment.description) {
|
|
255
|
-
return
|
|
256
|
-
type: "text",
|
|
257
|
-
|
|
258
|
-
};
|
|
525
|
+
return [
|
|
526
|
+
{ type: "text", text: `[Image: ${attachment.filename || "image"} - description: ${attachment.description}]` }
|
|
527
|
+
];
|
|
259
528
|
}
|
|
260
|
-
return {
|
|
261
|
-
type: "text",
|
|
262
|
-
text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`
|
|
263
|
-
};
|
|
529
|
+
return [{ type: "text", text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)` }];
|
|
264
530
|
}
|
|
265
531
|
async function convertMessages(messages, modelSupportsVision, thinkingField) {
|
|
266
532
|
const filtered = messages.filter((msg) => {
|
|
@@ -398,7 +664,11 @@ export {
|
|
|
398
664
|
isPdfBuffer,
|
|
399
665
|
formatPdfErrorMessage,
|
|
400
666
|
processPdfContent,
|
|
667
|
+
extractPdfContent,
|
|
401
668
|
extractPdfText,
|
|
669
|
+
contentHash,
|
|
670
|
+
cacheSet,
|
|
671
|
+
decodeDataUrl,
|
|
402
672
|
resolveAttachmentsInMessages,
|
|
403
673
|
parseToolArguments,
|
|
404
674
|
buildModelParams,
|
|
@@ -409,4 +679,4 @@ export {
|
|
|
409
679
|
buildStreamingCreateParams,
|
|
410
680
|
mapFinishReason
|
|
411
681
|
};
|
|
412
|
-
//# sourceMappingURL=chunk-
|
|
682
|
+
//# sourceMappingURL=chunk-RMXPVQP4.js.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadAllAgentsDefault,
|
|
10
10
|
processEventsForConversation,
|
|
11
11
|
runTopLevelAgentLoop
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YDV7RIQ6.js";
|
|
13
13
|
import {
|
|
14
14
|
TurnMetrics,
|
|
15
15
|
buildAgentReminder,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
buildTopLevelSystemPrompt,
|
|
18
18
|
createChatDoneEvent,
|
|
19
19
|
createMessageStartEvent
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-XNCHOD2X.js";
|
|
21
21
|
import {
|
|
22
22
|
PathAccessDeniedError
|
|
23
23
|
} from "./chunk-46RORSKU.js";
|
|
@@ -66,7 +66,7 @@ function resolveAgentDef(sessionManager, sessionId) {
|
|
|
66
66
|
}
|
|
67
67
|
async function buildCachedPrompt(sessionManager, sessionId, agentDef) {
|
|
68
68
|
const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
|
|
69
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
69
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-T7S45DOQ.js");
|
|
70
70
|
const tools = getToolRegistryForAgent2(agentDef).definitions;
|
|
71
71
|
const toolFingerprint = getToolFingerprint(tools);
|
|
72
72
|
const allAgents = await loadAllAgentsDefault();
|
|
@@ -79,7 +79,7 @@ async function buildCachedPrompt(sessionManager, sessionId, agentDef) {
|
|
|
79
79
|
async function computeSessionHash(sessionManager, sessionId) {
|
|
80
80
|
const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
|
|
81
81
|
const agentDef = await resolveAgentDef(sessionManager, sessionId);
|
|
82
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
82
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-T7S45DOQ.js");
|
|
83
83
|
const tools = getToolRegistryForAgent2(agentDef).definitions;
|
|
84
84
|
const toolFingerprint = getToolFingerprint(tools);
|
|
85
85
|
return computeDynamicContextHash(instructionContent, skills, toolFingerprint);
|
|
@@ -359,4 +359,4 @@ export {
|
|
|
359
359
|
runChatTurn,
|
|
360
360
|
runAgentTurn
|
|
361
361
|
};
|
|
362
|
-
//# sourceMappingURL=chunk-
|
|
362
|
+
//# sourceMappingURL=chunk-VMYDUZWI.js.map
|
|
@@ -8,6 +8,10 @@ function buildUpdatedServerConfig(patch, existing, persistedCfg) {
|
|
|
8
8
|
const mergedEnv = patch.env !== void 0 ? patch.env : transportChanged ? void 0 : existing.config.env;
|
|
9
9
|
const mergedUrl = patch.url !== void 0 ? patch.url : transportChanged ? void 0 : existing.config.url;
|
|
10
10
|
const mergedHeaders = patch.headers !== void 0 ? patch.headers : transportChanged ? void 0 : existing.config.headers;
|
|
11
|
+
const mergedTimeout = patch.timeout !== void 0 ? patch.timeout : existing.config.timeout;
|
|
12
|
+
if (patch.timeout !== void 0 && (typeof patch.timeout !== "number" || patch.timeout <= 0)) {
|
|
13
|
+
return { serverCfg: {}, error: "timeout must be a positive number" };
|
|
14
|
+
}
|
|
11
15
|
if (resolvedTransport === "http" && !mergedUrl) {
|
|
12
16
|
return { serverCfg: {}, error: "url is required for http transport" };
|
|
13
17
|
}
|
|
@@ -21,6 +25,7 @@ function buildUpdatedServerConfig(patch, existing, persistedCfg) {
|
|
|
21
25
|
...mergedEnv && Object.keys(mergedEnv).length > 0 ? { env: mergedEnv } : {},
|
|
22
26
|
...mergedUrl ? { url: mergedUrl } : {},
|
|
23
27
|
...mergedHeaders && Object.keys(mergedHeaders).length > 0 ? { headers: mergedHeaders } : {},
|
|
28
|
+
...mergedTimeout !== void 0 ? { timeout: mergedTimeout } : {},
|
|
24
29
|
...persistedCfg?.disabledTools && persistedCfg.disabledTools.length > 0 ? { disabledTools: persistedCfg.disabledTools } : {},
|
|
25
30
|
...persistedCfg?.cachedTools && persistedCfg.cachedTools.length > 0 ? { cachedTools: persistedCfg.cachedTools } : {}
|
|
26
31
|
};
|
|
@@ -51,4 +56,4 @@ export {
|
|
|
51
56
|
buildUpdatedServerConfig,
|
|
52
57
|
applyMcpServerUpdate
|
|
53
58
|
};
|
|
54
|
-
//# sourceMappingURL=chunk-
|
|
59
|
+
//# sourceMappingURL=chunk-VPFUXGMM.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getThinking,
|
|
14
14
|
mapFinishReason,
|
|
15
15
|
parseToolArguments
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RMXPVQP4.js";
|
|
17
17
|
import {
|
|
18
18
|
LLMError,
|
|
19
19
|
OpenAIHttpClient
|
|
@@ -268,4 +268,4 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
268
268
|
export {
|
|
269
269
|
createLLMClient
|
|
270
270
|
};
|
|
271
|
-
//# sourceMappingURL=chunk-
|
|
271
|
+
//# sourceMappingURL=chunk-WL2WEJAK.js.map
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-YHEQTVFV.js";
|
|
13
13
|
import {
|
|
14
14
|
buildModelParams
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-RMXPVQP4.js";
|
|
16
16
|
import {
|
|
17
17
|
logger
|
|
18
18
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -679,4 +679,4 @@ export {
|
|
|
679
679
|
createChatDoneEvent,
|
|
680
680
|
consumeStreamGenerator
|
|
681
681
|
};
|
|
682
|
-
//# sourceMappingURL=chunk-
|
|
682
|
+
//# sourceMappingURL=chunk-XNCHOD2X.js.map
|