openfox 2.0.135 → 2.0.136
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/CHANGELOG.md +27 -0
- package/dist/CHANGELOG.md +27 -0
- package/dist/agent-defaults/builder.agent.md +1 -0
- package/dist/agent-defaults/planner.agent.md +1 -0
- package/dist/{ask-UBIRH3SO.js → ask-46J5WYRL.js} +2 -2
- package/dist/{auto-config-5VSNLVNI.js → auto-config-2A7Y2WOK.js} +25 -6
- package/dist/{backend-NDBY3DAQ.js → backend-24FTDSHF.js} +4 -2
- package/dist/{chat-handler-WGDFMOOD.js → chat-handler-SYU4HJMI.js} +30 -26
- package/dist/{chunk-QZOV4OVN.js → chunk-342BKOTE.js} +5 -5
- package/dist/{chunk-7QMWYNVF.js → chunk-4LLGI372.js} +2 -2
- package/dist/chunk-4SBVW4UH.js +24 -0
- package/dist/{chunk-NFEZATSN.js → chunk-5YPHN5NC.js} +8 -8
- package/dist/{chunk-ZMK4VX7V.js → chunk-64YDOCQR.js} +53 -21
- package/dist/{chunk-UV6IH6HK.js → chunk-AKWJMMEJ.js} +15 -1
- package/dist/{chunk-ORCQ3EXQ.js → chunk-BHVR2YS5.js} +2 -2
- package/dist/{chunk-5H5NRWHA.js → chunk-CPVEONNS.js} +12 -10
- package/dist/{chunk-S67WIWUG.js → chunk-DG2YSWMC.js} +40 -6
- package/dist/{chunk-ESZQTFQP.js → chunk-EXLCFEML.js} +86 -1010
- package/dist/chunk-FSSUPWYO.js +336 -0
- package/dist/{chunk-5UQ4CKOA.js → chunk-G5GUQKLS.js} +27 -6
- package/dist/{chunk-GP3CLMPQ.js → chunk-GP5BYQMF.js} +23 -23
- package/dist/{chunk-7ET46SNE.js → chunk-HEYU7FAY.js} +3 -3
- package/dist/{chunk-IAT2LBIX.js → chunk-MILEZY2J.js} +4 -4
- package/dist/{chunk-O3RCSKUH.js → chunk-MOYWDP73.js} +2 -2
- package/dist/{chunk-J3NMNYGM.js → chunk-N5JKVNLH.js} +2 -2
- package/dist/{chunk-I5ODJKYM.js → chunk-PQKLOLGC.js} +162 -6
- package/dist/{chunk-DWA4IE65.js → chunk-Q33DL67W.js} +2 -2
- package/dist/{chunk-OZWHRBDY.js → chunk-QBWJCO5K.js} +12 -29
- package/dist/{chunk-EUOWCVU6.js → chunk-QMU3ZY2C.js} +37 -341
- package/dist/{chunk-BIZFY3QP.js → chunk-QQQBNL7A.js} +212 -148
- package/dist/{chunk-CTWZPN7G.js → chunk-QUAEH3MP.js} +29 -1
- package/dist/{chunk-5UMXFLET.js → chunk-SAGDTQXD.js} +3 -3
- package/dist/chunk-U6FHHT2B.js +1155 -0
- package/dist/{chunk-4R5GV7RW.js → chunk-UL7776XB.js} +21 -21
- package/dist/{chunk-JURM3RPZ.js → chunk-V5AC2TV7.js} +8 -13
- package/dist/{chunk-UKIUQAQZ.js → chunk-VA2TYWQR.js} +4 -4
- package/dist/{chunk-JE7LW7Y6.js → chunk-VIJVLLPT.js} +12 -3
- package/dist/{chunk-2AI7VYPN.js → chunk-VKMPR25F.js} +9 -3
- package/dist/chunk-VWBPQZLO.js +7 -0
- package/dist/{chunk-F2MOHHXB.js → chunk-X4PVR6AW.js} +2 -2
- package/dist/chunk-XG3AUMPI.js +72 -0
- package/dist/{chunk-MEEUXRFL.js → chunk-XGG4XCKP.js} +2 -2
- package/dist/{chunk-VHLD6PCZ.js → chunk-YDPC4FLR.js} +17 -11
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/client-MVI3J7SN.js +18 -0
- package/dist/{client-pure-FLKP6PTI.js → client-pure-YZ4IGCU4.js} +4 -2
- package/dist/{compactor-454UEIEX.js → compactor-LBK53WAK.js} +14 -12
- package/dist/describe-image-4XDLSKAB.js +30 -0
- package/dist/{dynamic-context-LKC6JYLQ.js → dynamic-context-RDBNQPPA.js} +12 -10
- package/dist/{events-335XAKFK.js → events-YTYYT3PR.js} +6 -6
- package/dist/{export-import-3WMRLO4A.js → export-import-GHRCOQHF.js} +7 -7
- package/dist/{folding-H7JTX6KI.js → folding-3MMOPS4W.js} +4 -4
- package/dist/{http-client-A445WYZU.js → http-client-C6UYWVWZ.js} +3 -3
- package/dist/launch-YZ46OEFP.js +58 -0
- package/dist/{manager-ZACEUL5P.js → manager-FSPRJCYT.js} +4 -4
- package/dist/{model-catalog-2PCKTYGW.js → model-catalog-Y5MA5OZP.js} +2 -2
- package/dist/{orchestrator-JGJWTRO5.js → orchestrator-6QGQ55NT.js} +29 -25
- package/dist/package.json +1 -1
- package/dist/{path-security-4LROI7F4.js → path-security-EC4Z2ZZG.js} +8 -8
- package/dist/{platform-XPMZKAUB.js → platform-KPKYBU54.js} +3 -3
- package/dist/{processor-MSQP63ML.js → processor-B2RV7MVC.js} +29 -25
- package/dist/{provider-JWUNG2TD.js → provider-SOC6Z25R.js} +10 -8
- package/dist/{provider-manager-2KKZ37XJ.js → provider-manager-Y53SVVQ3.js} +10 -8
- package/dist/{registry-BEIR7Y5G.js → registry-FMDMGIUB.js} +3 -3
- package/dist/{serve-CW5C3CBZ.js → serve-EWA5HXC7.js} +41 -32
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +34 -30
- package/dist/server-ZAPAB3FS.js +61 -0
- package/dist/{service-XIUNS5XV.js → service-NKLQH647.js} +12 -9
- package/dist/{session-overrides-LYW5PJ3R.js → session-overrides-ANQBKV74.js} +11 -7
- package/dist/{sessions-AOK3AGHY.js → sessions-GLYACE5R.js} +4 -4
- package/dist/{settings-ZJPM6PQV.js → settings-WH6BVQCP.js} +4 -2
- package/dist/{tasks-3JJWJJ3X.js → tasks-GPM3JAE6.js} +14 -10
- package/dist/tool-adapter-ZY4FC4C4.js +9 -0
- package/dist/{tools-E63MOJBO.js → tools-EJOABHVO.js} +27 -23
- package/dist/{update-XVXNSSDK.js → update-IPHJMRQZ.js} +2 -2
- package/dist/web/assets/{index-wTFCxQAw.js → index-CfFwerN2.js} +84 -84
- package/dist/web/assets/{index-Bg_Z8i3F.css → index-ChJjYovg.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WY3PWHWY.js +0 -7
- package/dist/client-VVYOWXRR.js +0 -16
- package/dist/launch-GJ7EHQRI.js +0 -54
- package/dist/server-ZHEB7XS2.js +0 -57
- package/dist/tool-adapter-FJAFLDZA.js +0 -8
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cacheSet,
|
|
3
|
+
contentHash,
|
|
4
|
+
decodeDataUrl,
|
|
5
|
+
extractPdfContent,
|
|
6
|
+
extractPdfText
|
|
7
|
+
} from "./chunk-FSSUPWYO.js";
|
|
8
|
+
import {
|
|
9
|
+
sanitizeToolSchema
|
|
10
|
+
} from "./chunk-XG3AUMPI.js";
|
|
11
|
+
|
|
1
12
|
// src/shared/constants.ts
|
|
2
13
|
var TEXT_MIME_PREFIXES = ["text/"];
|
|
3
14
|
var TEXT_MIME_EXACT = [
|
|
@@ -11,330 +22,6 @@ var TEXT_MIME_EXACT = [
|
|
|
11
22
|
"image/svg+xml"
|
|
12
23
|
];
|
|
13
24
|
|
|
14
|
-
// src/server/tools/types.ts
|
|
15
|
-
var OUTPUT_LIMITS = {
|
|
16
|
-
read_file: {
|
|
17
|
-
maxLines: 2e3,
|
|
18
|
-
maxBytes: 1e5,
|
|
19
|
-
maxImageBytes: 2097152,
|
|
20
|
-
// 2MB for images
|
|
21
|
-
maxPdfPages: 50,
|
|
22
|
-
maxPdfImages: 20,
|
|
23
|
-
maxFileBytes: 20971520
|
|
24
|
-
// 20MB general file safety limit
|
|
25
|
-
},
|
|
26
|
-
run_command: {
|
|
27
|
-
maxLines: 2e3,
|
|
28
|
-
maxBytes: 5e4
|
|
29
|
-
},
|
|
30
|
-
glob: {
|
|
31
|
-
maxResults: 500
|
|
32
|
-
},
|
|
33
|
-
grep: {
|
|
34
|
-
maxMatches: 200
|
|
35
|
-
},
|
|
36
|
-
web_fetch: {
|
|
37
|
-
maxBytes: 1e5
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// src/server/tools/pdf-utils.ts
|
|
42
|
-
import { getDocument, OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
43
|
-
import { PNG } from "pngjs";
|
|
44
|
-
var PDF_HEADER = Buffer.from("%PDF");
|
|
45
|
-
function isPdfBuffer(buffer) {
|
|
46
|
-
return buffer.length > 4 && buffer.subarray(0, 4).equals(PDF_HEADER);
|
|
47
|
-
}
|
|
48
|
-
function isPasswordError(err) {
|
|
49
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
50
|
-
return message.toLowerCase().includes("password") || message.toLowerCase().includes("encrypt");
|
|
51
|
-
}
|
|
52
|
-
function formatPdfErrorMessage(err) {
|
|
53
|
-
if (isPasswordError(err)) {
|
|
54
|
-
return "This PDF is password-protected. Unlock it with an external tool first.";
|
|
55
|
-
}
|
|
56
|
-
return `Failed to read PDF: ${err instanceof Error ? err.message : String(err)}`;
|
|
57
|
-
}
|
|
58
|
-
function processPdfContent(text, maxBytes) {
|
|
59
|
-
let output = text;
|
|
60
|
-
let truncated = false;
|
|
61
|
-
if (output.length > maxBytes) {
|
|
62
|
-
output = output.slice(0, maxBytes) + "\n\n[Output truncated due to size limit]";
|
|
63
|
-
truncated = true;
|
|
64
|
-
}
|
|
65
|
-
const isScanned = output.replace(/\[Page \d+\/\d+\]\n/g, "").trim().length === 0;
|
|
66
|
-
return { output, truncated, isScanned };
|
|
67
|
-
}
|
|
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) {
|
|
257
|
-
const doc = await getDocument({ data: Uint8Array.from(buffer) }).promise;
|
|
258
|
-
const pageCount = doc.numPages;
|
|
259
|
-
const allBlocks = [];
|
|
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
|
-
}
|
|
272
|
-
try {
|
|
273
|
-
for (let i = 1; i <= limitedPageCount; i++) {
|
|
274
|
-
const page = await doc.getPage(i);
|
|
275
|
-
try {
|
|
276
|
-
const blocks = await extractPageBlocks(page, i, pageCount, imageCounter, maxImages);
|
|
277
|
-
allBlocks.push(...blocks);
|
|
278
|
-
} finally {
|
|
279
|
-
page.cleanup();
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
} catch {
|
|
283
|
-
} finally {
|
|
284
|
-
doc.cleanup();
|
|
285
|
-
}
|
|
286
|
-
if (pageCount > limitedPageCount) {
|
|
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
|
-
}
|
|
312
|
-
|
|
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);
|
|
323
|
-
}
|
|
324
|
-
cache.set(key, value);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// src/server/utils/data-url.ts
|
|
328
|
-
function decodeDataUrl(data) {
|
|
329
|
-
const match = data.match(/^data:.*?;base64,(.+)$/);
|
|
330
|
-
if (!match?.[1]) return null;
|
|
331
|
-
try {
|
|
332
|
-
return Buffer.from(match[1], "base64");
|
|
333
|
-
} catch {
|
|
334
|
-
return null;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
25
|
// src/server/llm/resolve-attachments.ts
|
|
339
26
|
function formatVisionFallbackDescription(filename, description) {
|
|
340
27
|
return [
|
|
@@ -499,7 +186,7 @@ function getThinking(msg, override) {
|
|
|
499
186
|
}
|
|
500
187
|
return msg["reasoning"] ?? msg["reasoning_content"] ?? msg["thinking"];
|
|
501
188
|
}
|
|
502
|
-
function buildAssistantMessage(msg, thinkingField, sendReasoningInMessages) {
|
|
189
|
+
function buildAssistantMessage(msg, thinkingField, sendReasoningInMessages, inlineThinking) {
|
|
503
190
|
const result = {
|
|
504
191
|
role: "assistant",
|
|
505
192
|
content: msg.content || " "
|
|
@@ -507,8 +194,19 @@ function buildAssistantMessage(msg, thinkingField, sendReasoningInMessages) {
|
|
|
507
194
|
if (msg.toolCalls?.length) {
|
|
508
195
|
result["tool_calls"] = convertToolCalls(msg.toolCalls);
|
|
509
196
|
}
|
|
510
|
-
if (
|
|
511
|
-
|
|
197
|
+
if (sendReasoningInMessages === false) return result;
|
|
198
|
+
const echoField = thinkingField ?? "reasoning";
|
|
199
|
+
const isReasoningContentProvider = thinkingField === "reasoning_content";
|
|
200
|
+
if (msg.thinkingContent) {
|
|
201
|
+
if (inlineThinking && isReasoningContentProvider && !msg.toolCalls?.length) {
|
|
202
|
+
result["content"] = `${msg.thinkingContent}
|
|
203
|
+
|
|
204
|
+
${msg.content || ""}`.trim() || " ";
|
|
205
|
+
} else {
|
|
206
|
+
result[echoField] = msg.thinkingContent;
|
|
207
|
+
}
|
|
208
|
+
} else if (isReasoningContentProvider && msg.toolCalls?.length) {
|
|
209
|
+
result[echoField] = "";
|
|
512
210
|
}
|
|
513
211
|
return result;
|
|
514
212
|
}
|
|
@@ -536,7 +234,7 @@ ${attachment.data}` }];
|
|
|
536
234
|
}
|
|
537
235
|
return [{ type: "text", text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)` }];
|
|
538
236
|
}
|
|
539
|
-
async function convertMessages(messages, modelSupportsVision, thinkingField, sendReasoningInMessages) {
|
|
237
|
+
async function convertMessages(messages, modelSupportsVision, thinkingField, sendReasoningInMessages, inlineThinking) {
|
|
540
238
|
const filtered = messages.filter((msg) => {
|
|
541
239
|
if (msg.role !== "assistant") return true;
|
|
542
240
|
const isEmpty = !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0);
|
|
@@ -562,7 +260,12 @@ async function convertMessages(messages, modelSupportsVision, thinkingField, sen
|
|
|
562
260
|
}
|
|
563
261
|
} else if (msg.role === "assistant") {
|
|
564
262
|
result.push(
|
|
565
|
-
buildAssistantMessage(
|
|
263
|
+
buildAssistantMessage(
|
|
264
|
+
msg,
|
|
265
|
+
thinkingField,
|
|
266
|
+
sendReasoningInMessages,
|
|
267
|
+
inlineThinking
|
|
268
|
+
)
|
|
566
269
|
);
|
|
567
270
|
} else if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
568
271
|
const content = await buildAttachmentContent(msg.content, msg.attachments, modelSupportsVision);
|
|
@@ -585,18 +288,20 @@ function convertTools(tools) {
|
|
|
585
288
|
function: {
|
|
586
289
|
name: tool.function.name,
|
|
587
290
|
description: tool.function.description,
|
|
588
|
-
parameters: tool.function.parameters
|
|
291
|
+
parameters: sanitizeToolSchema(tool.function.parameters)
|
|
589
292
|
}
|
|
590
293
|
}));
|
|
591
294
|
}
|
|
592
295
|
async function buildChatCompletionCreateParams(model, request, profile, capabilities, reasoningEffort, isStreaming, thinkingField, sendReasoningInMessages, apiProtocol) {
|
|
593
296
|
const userVisionOverride = request.modelSettings?.supportsVision;
|
|
594
297
|
const modelSupportsVision = userVisionOverride ?? profile.supportsVision ?? false;
|
|
298
|
+
const inlineThinking = thinkingField === "reasoning_content" && !request.tools?.length;
|
|
595
299
|
const convertedMessages = await convertMessages(
|
|
596
300
|
request.messages,
|
|
597
301
|
modelSupportsVision,
|
|
598
302
|
thinkingField,
|
|
599
|
-
sendReasoningInMessages
|
|
303
|
+
sendReasoningInMessages,
|
|
304
|
+
inlineThinking
|
|
600
305
|
);
|
|
601
306
|
const temperature = request.modelSettings?.temperature ?? request.temperature ?? profile.temperature;
|
|
602
307
|
const maxTokens = request.modelSettings?.maxTokens ?? request.maxTokens ?? profile.defaultMaxTokens;
|
|
@@ -729,15 +434,6 @@ function mapFinishReason(reason) {
|
|
|
729
434
|
}
|
|
730
435
|
|
|
731
436
|
export {
|
|
732
|
-
OUTPUT_LIMITS,
|
|
733
|
-
isPdfBuffer,
|
|
734
|
-
formatPdfErrorMessage,
|
|
735
|
-
processPdfContent,
|
|
736
|
-
extractPdfContent,
|
|
737
|
-
extractPdfText,
|
|
738
|
-
contentHash,
|
|
739
|
-
cacheSet,
|
|
740
|
-
decodeDataUrl,
|
|
741
437
|
resolveAttachmentsInMessages,
|
|
742
438
|
parseToolArguments,
|
|
743
439
|
buildModelParams,
|
|
@@ -748,4 +444,4 @@ export {
|
|
|
748
444
|
buildStreamingCreateParams,
|
|
749
445
|
mapFinishReason
|
|
750
446
|
};
|
|
751
|
-
//# sourceMappingURL=chunk-
|
|
447
|
+
//# sourceMappingURL=chunk-QMU3ZY2C.js.map
|