openfox 2.0.67 → 2.0.69
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-72DFHK5K.js → chat-handler-K3DWIGHG.js} +7 -6
- package/dist/{chunk-B6JUWVTK.js → chunk-46OR4W3L.js} +7 -7
- package/dist/{chunk-TMHWQYWE.js → chunk-64GN6OPR.js} +2 -2
- package/dist/{chunk-5EO6SEGV.js → chunk-7OW6X764.js} +2 -2
- package/dist/{chunk-B7WGOK7G.js → chunk-E4POUD2M.js} +2 -2
- package/dist/{chunk-BL5LOLVA.js → chunk-JHGKXQBO.js} +161 -28
- package/dist/{chunk-YU6DZAVA.js → chunk-PVWAE43V.js} +55 -100
- package/dist/{chunk-TJO4QFDQ.js → chunk-QFSDJIUS.js} +2 -2
- package/dist/chunk-UN26GIQG.js +54 -0
- package/dist/{chunk-PYRH4G2J.js → chunk-UTSSFPYA.js} +5 -5
- package/dist/{chunk-MQHMT5WF.js → chunk-VFYNKALW.js} +3 -3
- package/dist/{chunk-2GRUQN2B.js → chunk-WHVCGVQX.js} +384 -68
- package/dist/{chunk-ZLON3JTI.js → chunk-YQ3MEZJL.js} +2 -2
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{client-BUX62J2K.js → client-63U5CTPE.js} +3 -3
- package/dist/{client-pure-U6ZYUPJQ.js → client-pure-XHH4RRLB.js} +2 -2
- package/dist/{compactor-74CZVUWI.js → compactor-IPMMFFHM.js} +4 -4
- package/dist/{orchestrator-FEMPJOZD.js → orchestrator-PUV4WG77.js} +6 -5
- package/dist/package.json +3 -2
- package/dist/{processor-QB3NMRMO.js → processor-O2QW27BD.js} +7 -6
- package/dist/{protocol-42f_Png6.d.ts → protocol-DIhV-tAc.d.ts} +1 -1
- package/dist/provider/index.d.ts +4 -4
- package/dist/{provider-BDH6JGZB.js → provider-IBIWR4AI.js} +4 -4
- package/dist/{provider-manager-D3KIOD5E.js → provider-manager-7C3JVOLW.js} +4 -4
- package/dist/{serve-32FAA4FX.js → serve-Q34XBLR5.js} +11 -10
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +10 -9
- package/dist/{server-OYE7GERR.js → server-RLNPHLY2.js} +8 -7
- package/dist/shared/index.d.ts +3 -3
- package/dist/{tools-INWP6FGV.js → tools-CALGWIV2.js} +5 -4
- package/dist/{types-vezAEt_y.d.ts → types-BsfYpEai.d.ts} +2 -1
- package/dist/{types-apiMd7Df.d.ts → types-CBC6lLqc.d.ts} +1 -1
- package/dist/update-server-MYYQUNZX.js +10 -0
- package/dist/web/assets/{index-BELeAs12.css → index-BVTG7SRG.css} +1 -1
- package/dist/web/assets/{index-C3n65CNu.js → index-oKJVe9Cz.js} +75 -73
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +3 -2
- package/plugins-registry.json +14 -0
|
@@ -2,17 +2,18 @@ import {
|
|
|
2
2
|
buildRunChatTurnParams,
|
|
3
3
|
finalizeTurnCompletion,
|
|
4
4
|
generateSessionNameForSession
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-64GN6OPR.js";
|
|
6
6
|
import {
|
|
7
7
|
runChatTurn
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-UTSSFPYA.js";
|
|
9
|
+
import "./chunk-PVWAE43V.js";
|
|
10
|
+
import "./chunk-QFSDJIUS.js";
|
|
11
11
|
import "./chunk-4QBDV6LX.js";
|
|
12
12
|
import "./chunk-KXVFHMSM.js";
|
|
13
13
|
import "./chunk-TFCHWMOJ.js";
|
|
14
14
|
import "./chunk-PK2RMVMB.js";
|
|
15
15
|
import "./chunk-NWO6GRYE.js";
|
|
16
|
+
import "./chunk-UN26GIQG.js";
|
|
16
17
|
import "./chunk-VLV3XWZS.js";
|
|
17
18
|
import "./chunk-WGMJCFCE.js";
|
|
18
19
|
import {
|
|
@@ -31,7 +32,7 @@ import "./chunk-EU3WWTFH.js";
|
|
|
31
32
|
import "./chunk-J2GP3J3X.js";
|
|
32
33
|
import "./chunk-V4IE7HJY.js";
|
|
33
34
|
import "./chunk-YHEQTVFV.js";
|
|
34
|
-
import "./chunk-
|
|
35
|
+
import "./chunk-JHGKXQBO.js";
|
|
35
36
|
import "./chunk-K44MW7JJ.js";
|
|
36
37
|
import "./chunk-YD6NDTKF.js";
|
|
37
38
|
import "./chunk-WGAAQASA.js";
|
|
@@ -157,4 +158,4 @@ export {
|
|
|
157
158
|
startChatSession,
|
|
158
159
|
stopSessionExecution
|
|
159
160
|
};
|
|
160
|
-
//# sourceMappingURL=chat-handler-
|
|
161
|
+
//# sourceMappingURL=chat-handler-K3DWIGHG.js.map
|
|
@@ -3,10 +3,7 @@ import {
|
|
|
3
3
|
computeSessionHash,
|
|
4
4
|
runAgentTurn,
|
|
5
5
|
runChatTurn
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
appendCompactionPrompt
|
|
9
|
-
} from "./chunk-ZLON3JTI.js";
|
|
6
|
+
} from "./chunk-UTSSFPYA.js";
|
|
10
7
|
import {
|
|
11
8
|
deleteItemFromDir,
|
|
12
9
|
devServerManager,
|
|
@@ -16,11 +13,14 @@ import {
|
|
|
16
13
|
jsonSerializer,
|
|
17
14
|
loadAllAgentsDefault,
|
|
18
15
|
saveItemToDir
|
|
19
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-PVWAE43V.js";
|
|
17
|
+
import {
|
|
18
|
+
appendCompactionPrompt
|
|
19
|
+
} from "./chunk-YQ3MEZJL.js";
|
|
20
20
|
import {
|
|
21
21
|
TurnMetrics,
|
|
22
22
|
createMessageStartEvent
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-QFSDJIUS.js";
|
|
24
24
|
import {
|
|
25
25
|
checkAborted,
|
|
26
26
|
onProcessEvent,
|
|
@@ -2158,4 +2158,4 @@ export {
|
|
|
2158
2158
|
signalMcpReady,
|
|
2159
2159
|
createWebSocketServer
|
|
2160
2160
|
};
|
|
2161
|
-
//# sourceMappingURL=chunk-
|
|
2161
|
+
//# sourceMappingURL=chunk-46OR4W3L.js.map
|
|
@@ -135,7 +135,7 @@ async function generateSessionNameForSession(sessionId, userMessage, deps, signa
|
|
|
135
135
|
client = deps.getLLMClient();
|
|
136
136
|
client.setModel(providerConfig.model);
|
|
137
137
|
} else if (providerConfig) {
|
|
138
|
-
const { createLLMClient } = await import("./client-
|
|
138
|
+
const { createLLMClient } = await import("./client-63U5CTPE.js");
|
|
139
139
|
client = createLLMClient({
|
|
140
140
|
llm: {
|
|
141
141
|
baseUrl: providerConfig.baseUrl,
|
|
@@ -184,4 +184,4 @@ export {
|
|
|
184
184
|
buildRunChatTurnParams,
|
|
185
185
|
generateSessionNameForSession
|
|
186
186
|
};
|
|
187
|
-
//# sourceMappingURL=chunk-
|
|
187
|
+
//# sourceMappingURL=chunk-64GN6OPR.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createLLMClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E4POUD2M.js";
|
|
4
4
|
import {
|
|
5
5
|
getModelProfile
|
|
6
6
|
} from "./chunk-V4IE7HJY.js";
|
|
@@ -796,4 +796,4 @@ export {
|
|
|
796
796
|
parseDefaultModelSelection,
|
|
797
797
|
createProviderManager
|
|
798
798
|
};
|
|
799
|
-
//# sourceMappingURL=chunk-
|
|
799
|
+
//# sourceMappingURL=chunk-7OW6X764.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getThinking,
|
|
14
14
|
mapFinishReason,
|
|
15
15
|
parseToolArguments
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JHGKXQBO.js";
|
|
17
17
|
import {
|
|
18
18
|
LLMError,
|
|
19
19
|
OpenAIHttpClient
|
|
@@ -265,4 +265,4 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
265
265
|
export {
|
|
266
266
|
createLLMClient
|
|
267
267
|
};
|
|
268
|
-
//# sourceMappingURL=chunk-
|
|
268
|
+
//# sourceMappingURL=chunk-E4POUD2M.js.map
|
|
@@ -1,3 +1,101 @@
|
|
|
1
|
+
// src/server/tools/types.ts
|
|
2
|
+
var OUTPUT_LIMITS = {
|
|
3
|
+
read_file: {
|
|
4
|
+
maxLines: 2e3,
|
|
5
|
+
maxBytes: 1e5,
|
|
6
|
+
maxImageBytes: 2097152,
|
|
7
|
+
// 2MB for images
|
|
8
|
+
maxPdfPages: 50,
|
|
9
|
+
maxFileBytes: 20971520
|
|
10
|
+
// 20MB general file safety limit
|
|
11
|
+
},
|
|
12
|
+
run_command: {
|
|
13
|
+
maxLines: 2e3,
|
|
14
|
+
maxBytes: 5e4
|
|
15
|
+
},
|
|
16
|
+
glob: {
|
|
17
|
+
maxResults: 500
|
|
18
|
+
},
|
|
19
|
+
grep: {
|
|
20
|
+
maxMatches: 200
|
|
21
|
+
},
|
|
22
|
+
web_fetch: {
|
|
23
|
+
maxBytes: 1e5
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// src/server/tools/pdf-utils.ts
|
|
28
|
+
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
29
|
+
var PDF_HEADER = Buffer.from("%PDF");
|
|
30
|
+
function isPdfBuffer(buffer) {
|
|
31
|
+
return buffer.length > 4 && buffer.subarray(0, 4).equals(PDF_HEADER);
|
|
32
|
+
}
|
|
33
|
+
function isPasswordError(err) {
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
return message.toLowerCase().includes("password") || message.toLowerCase().includes("encrypt");
|
|
36
|
+
}
|
|
37
|
+
function formatPdfErrorMessage(err) {
|
|
38
|
+
if (isPasswordError(err)) {
|
|
39
|
+
return "This PDF is password-protected. Unlock it with an external tool first.";
|
|
40
|
+
}
|
|
41
|
+
return `Failed to read PDF: ${err instanceof Error ? err.message : String(err)}`;
|
|
42
|
+
}
|
|
43
|
+
function processPdfContent(text, maxBytes) {
|
|
44
|
+
let output = text;
|
|
45
|
+
let truncated = false;
|
|
46
|
+
if (output.length > maxBytes) {
|
|
47
|
+
output = output.slice(0, maxBytes) + "\n\n[Output truncated due to size limit]";
|
|
48
|
+
truncated = true;
|
|
49
|
+
}
|
|
50
|
+
const isScanned = output.replace(/\[Page \d+\/\d+\]\n/g, "").trim().length === 0;
|
|
51
|
+
return { output, truncated, isScanned };
|
|
52
|
+
}
|
|
53
|
+
async function extractPdfText(buffer) {
|
|
54
|
+
const doc = await getDocument({ data: Uint8Array.from(buffer) }).promise;
|
|
55
|
+
const pageCount = doc.numPages;
|
|
56
|
+
const rawMeta = await doc.getMetadata();
|
|
57
|
+
const info = rawMeta.info;
|
|
58
|
+
const title = info?.["Title"] || null;
|
|
59
|
+
const author = info?.["Author"] || null;
|
|
60
|
+
const pages = [];
|
|
61
|
+
const limitedPageCount = Math.min(pageCount, OUTPUT_LIMITS.read_file.maxPdfPages);
|
|
62
|
+
try {
|
|
63
|
+
for (let i = 1; i <= limitedPageCount; i++) {
|
|
64
|
+
const page = await doc.getPage(i);
|
|
65
|
+
try {
|
|
66
|
+
const content = await page.getTextContent();
|
|
67
|
+
const pageText = content.items.map((item) => "str" in item ? item.str : "").join(" ");
|
|
68
|
+
pages.push(`[Page ${i}/${pageCount}]
|
|
69
|
+
${pageText}`);
|
|
70
|
+
} finally {
|
|
71
|
+
page.cleanup();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} finally {
|
|
75
|
+
doc.cleanup();
|
|
76
|
+
}
|
|
77
|
+
let text = pages.join("\n\n");
|
|
78
|
+
if (pageCount > limitedPageCount) {
|
|
79
|
+
text += `
|
|
80
|
+
|
|
81
|
+
[PDF has ${pageCount} pages, showing first ${limitedPageCount}. Use a shell command to process more.]`;
|
|
82
|
+
}
|
|
83
|
+
return { text, pageCount, title, author };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/shared/constants.ts
|
|
87
|
+
var TEXT_MIME_PREFIXES = ["text/"];
|
|
88
|
+
var TEXT_MIME_EXACT = [
|
|
89
|
+
"application/json",
|
|
90
|
+
"application/xml",
|
|
91
|
+
"application/yaml",
|
|
92
|
+
"application/x-yaml",
|
|
93
|
+
"application/javascript",
|
|
94
|
+
"application/xhtml+xml",
|
|
95
|
+
"application/x-sh",
|
|
96
|
+
"image/svg+xml"
|
|
97
|
+
];
|
|
98
|
+
|
|
1
99
|
// src/server/llm/client-pure.ts
|
|
2
100
|
function parseToolArguments(raw, _meta) {
|
|
3
101
|
const input = raw?.trim() ? raw : "{}";
|
|
@@ -22,13 +120,14 @@ function buildModelParams(params) {
|
|
|
22
120
|
...params.maxTokens !== void 0 && { maxTokens: params.maxTokens }
|
|
23
121
|
};
|
|
24
122
|
}
|
|
25
|
-
function buildAttachmentContent(msgContent, attachments, modelSupportsVision) {
|
|
123
|
+
async function buildAttachmentContent(msgContent, attachments, modelSupportsVision) {
|
|
26
124
|
const content = [];
|
|
27
125
|
if (msgContent?.trim()) {
|
|
28
126
|
content.push({ type: "text", text: msgContent });
|
|
29
127
|
}
|
|
30
128
|
for (const attachment of attachments) {
|
|
31
|
-
|
|
129
|
+
const converted = await convertAttachment(attachment, modelSupportsVision);
|
|
130
|
+
content.push(converted);
|
|
32
131
|
}
|
|
33
132
|
return content;
|
|
34
133
|
}
|
|
@@ -62,7 +161,34 @@ function buildAssistantMessage(msg, thinkingField) {
|
|
|
62
161
|
}
|
|
63
162
|
return result;
|
|
64
163
|
}
|
|
65
|
-
function
|
|
164
|
+
async function convertAttachment(attachment, modelSupportsVision) {
|
|
165
|
+
const mimeType = attachment.mimeType;
|
|
166
|
+
if (TEXT_MIME_EXACT.includes(mimeType) || TEXT_MIME_PREFIXES.some((p) => mimeType.startsWith(p))) {
|
|
167
|
+
return {
|
|
168
|
+
type: "text",
|
|
169
|
+
text: `[File: ${attachment.filename || "file"}]
|
|
170
|
+
${attachment.data}`
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (mimeType === "application/pdf") {
|
|
174
|
+
try {
|
|
175
|
+
const base64Match = attachment.data.match(/^data:.*?;base64,(.+)$/);
|
|
176
|
+
if (base64Match?.[1]) {
|
|
177
|
+
const buffer = Buffer.from(base64Match[1], "base64");
|
|
178
|
+
const result = await extractPdfText(buffer);
|
|
179
|
+
return {
|
|
180
|
+
type: "text",
|
|
181
|
+
text: `[PDF: ${attachment.filename || "document.pdf"}]
|
|
182
|
+
${result.text}`
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
type: "text",
|
|
189
|
+
text: `[PDF: ${attachment.filename || "document.pdf"}] (could not extract text)`
|
|
190
|
+
};
|
|
191
|
+
}
|
|
66
192
|
if (modelSupportsVision) {
|
|
67
193
|
return {
|
|
68
194
|
type: "image_url",
|
|
@@ -80,41 +206,43 @@ function convertAttachmentSync(attachment, modelSupportsVision) {
|
|
|
80
206
|
text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`
|
|
81
207
|
};
|
|
82
208
|
}
|
|
83
|
-
function convertMessages(messages, modelSupportsVision, thinkingField) {
|
|
209
|
+
async function convertMessages(messages, modelSupportsVision, thinkingField) {
|
|
84
210
|
const filtered = messages.filter((msg) => {
|
|
85
211
|
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
86
212
|
});
|
|
87
|
-
|
|
213
|
+
const result = [];
|
|
214
|
+
for (const msg of filtered) {
|
|
88
215
|
if (msg.role === "tool") {
|
|
89
216
|
if (msg.attachments && msg.attachments.length > 0) {
|
|
90
|
-
const content = buildAttachmentContent(msg.content, msg.attachments, modelSupportsVision);
|
|
91
|
-
|
|
217
|
+
const content = await buildAttachmentContent(msg.content, msg.attachments, modelSupportsVision);
|
|
218
|
+
result.push({
|
|
92
219
|
role: "tool",
|
|
93
220
|
content,
|
|
94
221
|
tool_call_id: msg.toolCallId
|
|
95
|
-
};
|
|
222
|
+
});
|
|
223
|
+
} else {
|
|
224
|
+
result.push({
|
|
225
|
+
role: "tool",
|
|
226
|
+
content: msg.content,
|
|
227
|
+
tool_call_id: msg.toolCallId
|
|
228
|
+
});
|
|
96
229
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
if (msg.role === "assistant") {
|
|
104
|
-
return buildAssistantMessage(msg, thinkingField);
|
|
105
|
-
}
|
|
106
|
-
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
107
|
-
const content = buildAttachmentContent(msg.content, msg.attachments, modelSupportsVision);
|
|
108
|
-
return {
|
|
230
|
+
} else if (msg.role === "assistant") {
|
|
231
|
+
result.push(buildAssistantMessage(msg, thinkingField));
|
|
232
|
+
} else if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
233
|
+
const content = await buildAttachmentContent(msg.content, msg.attachments, modelSupportsVision);
|
|
234
|
+
result.push({
|
|
109
235
|
role: "user",
|
|
110
236
|
content
|
|
111
|
-
};
|
|
237
|
+
});
|
|
238
|
+
} else {
|
|
239
|
+
result.push({
|
|
240
|
+
role: msg.role,
|
|
241
|
+
content: msg.content
|
|
242
|
+
});
|
|
112
243
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
content: msg.content
|
|
116
|
-
};
|
|
117
|
-
});
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
118
246
|
}
|
|
119
247
|
function convertTools(tools) {
|
|
120
248
|
return tools.map((tool) => ({
|
|
@@ -129,7 +257,7 @@ function convertTools(tools) {
|
|
|
129
257
|
async function buildChatCompletionCreateParams(model, request, profile, capabilities, reasoningEffort, isStreaming, thinkingField) {
|
|
130
258
|
const userVisionOverride = request.modelSettings?.supportsVision;
|
|
131
259
|
const modelSupportsVision = userVisionOverride ?? profile.supportsVision ?? false;
|
|
132
|
-
const convertedMessages = convertMessages(request.messages, modelSupportsVision, thinkingField);
|
|
260
|
+
const convertedMessages = await convertMessages(request.messages, modelSupportsVision, thinkingField);
|
|
133
261
|
const temperature = request.modelSettings?.temperature ?? request.temperature ?? profile.temperature;
|
|
134
262
|
const maxTokens = request.modelSettings?.maxTokens ?? request.maxTokens ?? profile.defaultMaxTokens;
|
|
135
263
|
const topP = request.modelSettings?.topP ?? profile.topP;
|
|
@@ -210,6 +338,11 @@ function mapFinishReason(reason) {
|
|
|
210
338
|
}
|
|
211
339
|
|
|
212
340
|
export {
|
|
341
|
+
OUTPUT_LIMITS,
|
|
342
|
+
isPdfBuffer,
|
|
343
|
+
formatPdfErrorMessage,
|
|
344
|
+
processPdfContent,
|
|
345
|
+
extractPdfText,
|
|
213
346
|
parseToolArguments,
|
|
214
347
|
buildModelParams,
|
|
215
348
|
getThinking,
|
|
@@ -219,4 +352,4 @@ export {
|
|
|
219
352
|
buildStreamingCreateParams,
|
|
220
353
|
mapFinishReason
|
|
221
354
|
};
|
|
222
|
-
//# sourceMappingURL=chunk-
|
|
355
|
+
//# sourceMappingURL=chunk-JHGKXQBO.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
createToolCallEvent,
|
|
11
11
|
createToolResultEvent,
|
|
12
12
|
streamLLMPure
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QFSDJIUS.js";
|
|
14
14
|
import {
|
|
15
15
|
startInspectProxy
|
|
16
16
|
} from "./chunk-4QBDV6LX.js";
|
|
@@ -36,6 +36,9 @@ import {
|
|
|
36
36
|
import {
|
|
37
37
|
createMcpTools
|
|
38
38
|
} from "./chunk-NWO6GRYE.js";
|
|
39
|
+
import {
|
|
40
|
+
applyMcpServerUpdate
|
|
41
|
+
} from "./chunk-UN26GIQG.js";
|
|
39
42
|
import {
|
|
40
43
|
listBranches
|
|
41
44
|
} from "./chunk-VLV3XWZS.js";
|
|
@@ -75,6 +78,13 @@ import {
|
|
|
75
78
|
import {
|
|
76
79
|
modelSupportsVision
|
|
77
80
|
} from "./chunk-V4IE7HJY.js";
|
|
81
|
+
import {
|
|
82
|
+
OUTPUT_LIMITS,
|
|
83
|
+
extractPdfText,
|
|
84
|
+
formatPdfErrorMessage,
|
|
85
|
+
isPdfBuffer,
|
|
86
|
+
processPdfContent
|
|
87
|
+
} from "./chunk-JHGKXQBO.js";
|
|
78
88
|
import {
|
|
79
89
|
logger
|
|
80
90
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -90,32 +100,6 @@ import {
|
|
|
90
100
|
import { readFile as readFile2, stat, readdir } from "fs/promises";
|
|
91
101
|
import { extname, join as join2 } from "path";
|
|
92
102
|
|
|
93
|
-
// src/server/tools/types.ts
|
|
94
|
-
var OUTPUT_LIMITS = {
|
|
95
|
-
read_file: {
|
|
96
|
-
maxLines: 2e3,
|
|
97
|
-
maxBytes: 1e5,
|
|
98
|
-
maxImageBytes: 2097152,
|
|
99
|
-
// 2MB for images
|
|
100
|
-
maxPdfPages: 50,
|
|
101
|
-
maxFileBytes: 20971520
|
|
102
|
-
// 20MB general file safety limit
|
|
103
|
-
},
|
|
104
|
-
run_command: {
|
|
105
|
-
maxLines: 2e3,
|
|
106
|
-
maxBytes: 5e4
|
|
107
|
-
},
|
|
108
|
-
glob: {
|
|
109
|
-
maxResults: 500
|
|
110
|
-
},
|
|
111
|
-
grep: {
|
|
112
|
-
maxMatches: 200
|
|
113
|
-
},
|
|
114
|
-
web_fetch: {
|
|
115
|
-
maxBytes: 1e5
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
103
|
// src/server/tools/tool-helpers.ts
|
|
120
104
|
import { resolve as resolve2, isAbsolute } from "path";
|
|
121
105
|
|
|
@@ -244,9 +228,9 @@ function extractAbsolutePathsFromCommand(command) {
|
|
|
244
228
|
const paths = [];
|
|
245
229
|
const home = homedir();
|
|
246
230
|
let sanitized = command.replace(/https?:\/\/[^\s'"]+/g, " __URL__ ").replace(/ftp:\/\/[^\s'"]+/g, " __URL__ ");
|
|
247
|
-
sanitized = sanitized.replace(/s\/[^/]*\/[^/]*\/[gip]*/g, " __SED__ ");
|
|
248
|
-
sanitized = sanitized.replace(/s\|[^|]*\|[^|]*\|[gip]*/g, " __SED__ ");
|
|
249
|
-
sanitized = sanitized.replace(/s:[^:]*:[^:]*:[gip]*/g, " __SED__ ");
|
|
231
|
+
sanitized = sanitized.replace(/(?<!\w)s\/[^/]*\/[^/]*\/[gip]*/g, " __SED__ ");
|
|
232
|
+
sanitized = sanitized.replace(/(?<!\w)s\|[^|]*\|[^|]*\|[gip]*/g, " __SED__ ");
|
|
233
|
+
sanitized = sanitized.replace(/(?<!\w)s:[^:]*:[^:]*:[gip]*/g, " __SED__ ");
|
|
250
234
|
sanitized = sanitized.replace(
|
|
251
235
|
/git\s+commit\b.*?(?:-(?:[a-zA-Z]*m)(?=\s)|--message)\s+(["'])(?:(?!\1).)*\1/g,
|
|
252
236
|
(match2) => match2.replace(/\/[^\s"'|&;<>`()]+/g, " __COMMIT_MSG__ ")
|
|
@@ -863,67 +847,6 @@ function stringToUtf32(str, littleEndian) {
|
|
|
863
847
|
|
|
864
848
|
// src/server/tools/read.ts
|
|
865
849
|
import { fileTypeFromBuffer } from "file-type";
|
|
866
|
-
|
|
867
|
-
// src/server/tools/pdf-utils.ts
|
|
868
|
-
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
869
|
-
var PDF_HEADER = Buffer.from("%PDF");
|
|
870
|
-
function isPdfBuffer(buffer) {
|
|
871
|
-
return buffer.length > 4 && buffer.subarray(0, 4).equals(PDF_HEADER);
|
|
872
|
-
}
|
|
873
|
-
function isPasswordError(err) {
|
|
874
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
875
|
-
return message.toLowerCase().includes("password") || message.toLowerCase().includes("encrypt");
|
|
876
|
-
}
|
|
877
|
-
function formatPdfErrorMessage(err) {
|
|
878
|
-
if (isPasswordError(err)) {
|
|
879
|
-
return "This PDF is password-protected. Unlock it with an external tool first.";
|
|
880
|
-
}
|
|
881
|
-
return `Failed to read PDF: ${err instanceof Error ? err.message : String(err)}`;
|
|
882
|
-
}
|
|
883
|
-
function processPdfContent(text, maxBytes) {
|
|
884
|
-
let output = text;
|
|
885
|
-
let truncated = false;
|
|
886
|
-
if (output.length > maxBytes) {
|
|
887
|
-
output = output.slice(0, maxBytes) + "\n\n[Output truncated due to size limit]";
|
|
888
|
-
truncated = true;
|
|
889
|
-
}
|
|
890
|
-
const isScanned = output.replace(/\[Page \d+\/\d+\]\n/g, "").trim().length === 0;
|
|
891
|
-
return { output, truncated, isScanned };
|
|
892
|
-
}
|
|
893
|
-
async function extractPdfText(buffer) {
|
|
894
|
-
const doc = await getDocument({ data: Uint8Array.from(buffer) }).promise;
|
|
895
|
-
const pageCount = doc.numPages;
|
|
896
|
-
const rawMeta = await doc.getMetadata();
|
|
897
|
-
const info = rawMeta.info;
|
|
898
|
-
const title = info?.["Title"] || null;
|
|
899
|
-
const author = info?.["Author"] || null;
|
|
900
|
-
const pages = [];
|
|
901
|
-
const limitedPageCount = Math.min(pageCount, OUTPUT_LIMITS.read_file.maxPdfPages);
|
|
902
|
-
try {
|
|
903
|
-
for (let i = 1; i <= limitedPageCount; i++) {
|
|
904
|
-
const page = await doc.getPage(i);
|
|
905
|
-
try {
|
|
906
|
-
const content = await page.getTextContent();
|
|
907
|
-
const pageText = content.items.map((item) => "str" in item ? item.str : "").join(" ");
|
|
908
|
-
pages.push(`[Page ${i}/${pageCount}]
|
|
909
|
-
${pageText}`);
|
|
910
|
-
} finally {
|
|
911
|
-
page.cleanup();
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
} finally {
|
|
915
|
-
doc.cleanup();
|
|
916
|
-
}
|
|
917
|
-
let text = pages.join("\n\n");
|
|
918
|
-
if (pageCount > limitedPageCount) {
|
|
919
|
-
text += `
|
|
920
|
-
|
|
921
|
-
[PDF has ${pageCount} pages, showing first ${limitedPageCount}. Use a shell command to process more.]`;
|
|
922
|
-
}
|
|
923
|
-
return { text, pageCount, title, author };
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
// src/server/tools/read.ts
|
|
927
850
|
async function detectImageType(buffer, filePath) {
|
|
928
851
|
const fileType = await fileTypeFromBuffer(buffer);
|
|
929
852
|
const imageMimeTypes = ["image/png", "image/jpeg", "image/gif", "image/webp", "image/bmp", "image/svg+xml"];
|
|
@@ -2954,7 +2877,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
|
|
|
2954
2877
|
sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens);
|
|
2955
2878
|
if (!compacting) {
|
|
2956
2879
|
const contextState2 = sessionManager.getContextState(sessionId);
|
|
2957
|
-
const { shouldCompact, appendCompactionPrompt } = await import("./compactor-
|
|
2880
|
+
const { shouldCompact, appendCompactionPrompt } = await import("./compactor-IPMMFFHM.js");
|
|
2958
2881
|
if (shouldCompact(contextState2.currentTokens, contextState2.maxTokens, runtimeConfig.context.compactionThreshold)) {
|
|
2959
2882
|
appendCompactionPrompt(sessionId, append);
|
|
2960
2883
|
compacting = true;
|
|
@@ -3859,7 +3782,7 @@ var callSubAgentTool = {
|
|
|
3859
3782
|
};
|
|
3860
3783
|
}
|
|
3861
3784
|
try {
|
|
3862
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
3785
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-CALGWIV2.js");
|
|
3863
3786
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
3864
3787
|
const turnMetrics = new TurnMetrics();
|
|
3865
3788
|
const result = await executeSubAgent({
|
|
@@ -4781,18 +4704,18 @@ var mcpConfigTool = createTool(
|
|
|
4781
4704
|
type: "function",
|
|
4782
4705
|
function: {
|
|
4783
4706
|
name: "mcp_config",
|
|
4784
|
-
description: "Configure MCP servers (Model Context Protocol). Actions: list (show all servers and tools), add (add a server), remove (delete a server), toggle-tool (enable/disable a tool). Use this when the user asks to add, remove, or configure MCP servers or tools.",
|
|
4707
|
+
description: "Configure MCP servers (Model Context Protocol). Actions: list (show all servers and tools), add (add a server), update (modify an existing server \u2014 all fields are optional and merged with the current config, transport-incompatible fields are cleared on transport change), remove (delete a server), toggle-tool (enable/disable a tool). Use this when the user asks to add, remove, update, or configure MCP servers or tools.",
|
|
4785
4708
|
parameters: {
|
|
4786
4709
|
type: "object",
|
|
4787
4710
|
properties: {
|
|
4788
4711
|
action: {
|
|
4789
4712
|
type: "string",
|
|
4790
|
-
enum: ["list", "add", "remove", "toggle-tool"],
|
|
4791
|
-
description: "Action: list (show servers), add (add new server), remove (delete a server), toggle-tool (enable/disable a tool)"
|
|
4713
|
+
enum: ["list", "add", "update", "remove", "toggle-tool"],
|
|
4714
|
+
description: "Action: list (show servers), add (add new server), update (modify existing server), remove (delete a server), toggle-tool (enable/disable a tool)"
|
|
4792
4715
|
},
|
|
4793
4716
|
name: {
|
|
4794
4717
|
type: "string",
|
|
4795
|
-
description: "Server name (required for: add, remove, toggle-tool)"
|
|
4718
|
+
description: "Server name (required for: add, update, remove, toggle-tool)"
|
|
4796
4719
|
},
|
|
4797
4720
|
transport: {
|
|
4798
4721
|
type: "string",
|
|
@@ -4838,7 +4761,7 @@ var mcpConfigTool = createTool(
|
|
|
4838
4761
|
async (args, context, helpers) => {
|
|
4839
4762
|
const actionError = validateActionWithPermission(
|
|
4840
4763
|
args.action,
|
|
4841
|
-
["list", "add", "remove", "toggle-tool"],
|
|
4764
|
+
["list", "add", "update", "remove", "toggle-tool"],
|
|
4842
4765
|
"mcp_config",
|
|
4843
4766
|
context.permittedActions
|
|
4844
4767
|
);
|
|
@@ -4858,7 +4781,7 @@ var mcpConfigTool = createTool(
|
|
|
4858
4781
|
mcpNotifyChanged?.(sessionId);
|
|
4859
4782
|
}
|
|
4860
4783
|
async function rebuildTools() {
|
|
4861
|
-
const { setMcpTools: setMcpTools2 } = await import("./tools-
|
|
4784
|
+
const { setMcpTools: setMcpTools2 } = await import("./tools-CALGWIV2.js");
|
|
4862
4785
|
const mcpTools = createMcpTools(mcpManagerForTools);
|
|
4863
4786
|
setMcpTools2(mcpTools);
|
|
4864
4787
|
}
|
|
@@ -4914,6 +4837,38 @@ var mcpConfigTool = createTool(
|
|
|
4914
4837
|
const toolCount = server?.tools.length ?? 0;
|
|
4915
4838
|
return helpers.success(`Added MCP server "${args.name}" (${toolCount} tools discovered). ${APPLY_PROMPT_MESSAGE}`);
|
|
4916
4839
|
}
|
|
4840
|
+
if (args.action === "update") {
|
|
4841
|
+
if (!args.name) return helpers.error("Missing required field: name");
|
|
4842
|
+
const existing = mcpManagerForTools.getServer(args.name);
|
|
4843
|
+
if (!existing) return helpers.error(`MCP server "${args.name}" not found`);
|
|
4844
|
+
const globalConfig = await loadGlobalConfig(mcpConfigMode, mcpConfigPath);
|
|
4845
|
+
const mcpServers = { ...globalConfig.mcpServers ?? {} };
|
|
4846
|
+
const patch = {
|
|
4847
|
+
...args.transport !== void 0 ? { transport: args.transport } : {},
|
|
4848
|
+
...args.command !== void 0 ? { command: args.command } : {},
|
|
4849
|
+
...args.args !== void 0 ? { args: args.args } : {},
|
|
4850
|
+
...args.env !== void 0 ? { env: args.env } : {},
|
|
4851
|
+
...args.url !== void 0 ? { url: args.url } : {},
|
|
4852
|
+
...args.headers !== void 0 ? { headers: args.headers } : {}
|
|
4853
|
+
};
|
|
4854
|
+
const { error: updateError } = await applyMcpServerUpdate({
|
|
4855
|
+
name: args.name,
|
|
4856
|
+
patch,
|
|
4857
|
+
existing,
|
|
4858
|
+
persistedCfg: mcpServers[args.name],
|
|
4859
|
+
mcpManager: mcpManagerForTools,
|
|
4860
|
+
save: async (cfg) => {
|
|
4861
|
+
mcpServers[args.name] = cfg;
|
|
4862
|
+
await saveGlobalConfig(mcpConfigMode, { ...globalConfig, mcpServers }, mcpConfigPath);
|
|
4863
|
+
}
|
|
4864
|
+
});
|
|
4865
|
+
if (updateError) return helpers.error(updateError);
|
|
4866
|
+
await rebuildTools();
|
|
4867
|
+
notifyContextChanged(context.sessionId);
|
|
4868
|
+
const server = mcpManagerForTools.getServer(args.name);
|
|
4869
|
+
const toolCount = server?.tools.length ?? 0;
|
|
4870
|
+
return helpers.success(`Updated MCP server "${args.name}" (${toolCount} tools discovered). ${APPLY_PROMPT_MESSAGE}`);
|
|
4871
|
+
}
|
|
4917
4872
|
if (args.action === "remove") {
|
|
4918
4873
|
if (!args.name) return helpers.error("Missing required field: name");
|
|
4919
4874
|
await persistAndRebuild((mcpServers) => {
|
|
@@ -5521,4 +5476,4 @@ export {
|
|
|
5521
5476
|
getToolRegistryForAgent,
|
|
5522
5477
|
createToolRegistry
|
|
5523
5478
|
};
|
|
5524
|
-
//# sourceMappingURL=chunk-
|
|
5479
|
+
//# sourceMappingURL=chunk-PVWAE43V.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-JHGKXQBO.js";
|
|
16
16
|
import {
|
|
17
17
|
logger
|
|
18
18
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -678,4 +678,4 @@ export {
|
|
|
678
678
|
createChatDoneEvent,
|
|
679
679
|
consumeStreamGenerator
|
|
680
680
|
};
|
|
681
|
-
//# sourceMappingURL=chunk-
|
|
681
|
+
//# sourceMappingURL=chunk-QFSDJIUS.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/server/mcp/update-server.ts
|
|
2
|
+
function buildUpdatedServerConfig(patch, existing, persistedCfg) {
|
|
3
|
+
const existingTransport = existing.config.transport ?? "stdio";
|
|
4
|
+
const resolvedTransport = patch.transport ?? existingTransport;
|
|
5
|
+
const transportChanged = resolvedTransport !== existingTransport;
|
|
6
|
+
const mergedCommand = patch.command !== void 0 ? patch.command : transportChanged ? void 0 : existing.config.command;
|
|
7
|
+
const mergedArgs = patch.args !== void 0 ? patch.args : transportChanged ? void 0 : existing.config.args;
|
|
8
|
+
const mergedEnv = patch.env !== void 0 ? patch.env : transportChanged ? void 0 : existing.config.env;
|
|
9
|
+
const mergedUrl = patch.url !== void 0 ? patch.url : transportChanged ? void 0 : existing.config.url;
|
|
10
|
+
const mergedHeaders = patch.headers !== void 0 ? patch.headers : transportChanged ? void 0 : existing.config.headers;
|
|
11
|
+
if (resolvedTransport === "http" && !mergedUrl) {
|
|
12
|
+
return { serverCfg: {}, error: "url is required for http transport" };
|
|
13
|
+
}
|
|
14
|
+
if (resolvedTransport !== "http" && !mergedCommand) {
|
|
15
|
+
return { serverCfg: {}, error: "command is required for stdio transport" };
|
|
16
|
+
}
|
|
17
|
+
const serverCfg = {
|
|
18
|
+
transport: resolvedTransport,
|
|
19
|
+
...mergedCommand ? { command: mergedCommand } : {},
|
|
20
|
+
...mergedArgs && mergedArgs.length > 0 ? { args: mergedArgs } : {},
|
|
21
|
+
...mergedEnv && Object.keys(mergedEnv).length > 0 ? { env: mergedEnv } : {},
|
|
22
|
+
...mergedUrl ? { url: mergedUrl } : {},
|
|
23
|
+
...mergedHeaders && Object.keys(mergedHeaders).length > 0 ? { headers: mergedHeaders } : {},
|
|
24
|
+
...persistedCfg?.disabledTools && persistedCfg.disabledTools.length > 0 ? { disabledTools: persistedCfg.disabledTools } : {},
|
|
25
|
+
...persistedCfg?.cachedTools && persistedCfg.cachedTools.length > 0 ? { cachedTools: persistedCfg.cachedTools } : {}
|
|
26
|
+
};
|
|
27
|
+
return { serverCfg };
|
|
28
|
+
}
|
|
29
|
+
async function applyMcpServerUpdate(options) {
|
|
30
|
+
const { name, patch, existing, persistedCfg, mcpManager, save } = options;
|
|
31
|
+
const { serverCfg, error } = buildUpdatedServerConfig(patch, existing, persistedCfg);
|
|
32
|
+
if (error) return { serverCfg: {}, error };
|
|
33
|
+
mcpManager.removeServer(name);
|
|
34
|
+
try {
|
|
35
|
+
await mcpManager.addServer(name, serverCfg);
|
|
36
|
+
} catch (addError) {
|
|
37
|
+
await mcpManager.addServer(name, existing.config);
|
|
38
|
+
throw addError;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
await save(serverCfg);
|
|
42
|
+
} catch (saveError) {
|
|
43
|
+
mcpManager.removeServer(name);
|
|
44
|
+
await mcpManager.addServer(name, existing.config);
|
|
45
|
+
throw saveError;
|
|
46
|
+
}
|
|
47
|
+
return { serverCfg };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
buildUpdatedServerConfig,
|
|
52
|
+
applyMcpServerUpdate
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=chunk-UN26GIQG.js.map
|