@byteplus-iga-pages/agent 0.0.0-stage → 1.0.3
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/LICENSE +20 -0
- package/README.md +84 -2
- package/dist/cjs/261.js +77 -0
- package/dist/cjs/341.js +43 -0
- package/dist/cjs/401.js +3632 -0
- package/dist/cjs/419.js +854 -0
- package/dist/cjs/504.js +760 -0
- package/dist/cjs/521.js +242 -0
- package/dist/cjs/594.js +79 -0
- package/dist/cjs/647.js +1367 -0
- package/dist/cjs/808.js +322 -0
- package/dist/cjs/82.js +10089 -0
- package/dist/cjs/893.js +17720 -0
- package/dist/cjs/893.js.LICENSE.txt +13 -0
- package/dist/cjs/951.js +59 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/runtime.js +79 -0
- package/dist/cjs/sandbox/host.js +125 -0
- package/dist/cjs/sandbox/index.js +286 -0
- package/dist/cjs/store/claude.js +209 -0
- package/dist/cjs/store/host.js +92 -0
- package/dist/cjs/store/index.js +43 -0
- package/dist/cjs/store/langgraph.js +581 -0
- package/dist/cjs/store/openai.js +118 -0
- package/dist/cjs/tools/claude.js +59 -0
- package/dist/cjs/tools/index.js +37 -0
- package/dist/cjs/tools/langchain.js +52 -0
- package/dist/cjs/tools/openai-agents.js +43 -0
- package/dist/cjs/tools/openai.js +43 -0
- package/dist/esm/128.js +10381 -0
- package/dist/esm/261.js +67 -0
- package/dist/esm/341.js +30 -0
- package/dist/esm/392.js +4453 -0
- package/dist/esm/417.js +704 -0
- package/dist/esm/521.js +230 -0
- package/dist/esm/594.js +67 -0
- package/dist/esm/613.js +19042 -0
- package/dist/esm/613.js.LICENSE.txt +13 -0
- package/dist/esm/951.js +44 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/runtime.js +39 -0
- package/dist/esm/sandbox/host.js +1 -0
- package/dist/esm/sandbox/index.js +183 -0
- package/dist/esm/store/claude.js +172 -0
- package/dist/esm/store/host.js +46 -0
- package/dist/esm/store/index.js +2 -0
- package/dist/esm/store/langgraph.js +542 -0
- package/dist/esm/store/openai.js +81 -0
- package/dist/esm/tools/claude.js +22 -0
- package/dist/esm/tools/index.js +1 -0
- package/dist/esm/tools/langchain.js +16 -0
- package/dist/esm/tools/openai-agents.js +6 -0
- package/dist/esm/tools/openai.js +6 -0
- package/dist/types/_internal/data-plane/control-plane-request.d.ts +12 -0
- package/dist/types/_internal/data-plane/control-plane.d.ts +3 -0
- package/dist/types/_internal/data-plane/credential-provider.d.ts +25 -0
- package/dist/types/_internal/data-plane/errors.d.ts +19 -0
- package/dist/types/_internal/data-plane/index.d.ts +11 -0
- package/dist/types/_internal/data-plane/supabase-client.d.ts +12 -0
- package/dist/types/_internal/data-plane/token-client.d.ts +23 -0
- package/dist/types/sandbox/api-client.d.ts +37 -0
- package/dist/types/sandbox/api-types.d.ts +81 -0
- package/dist/types/sandbox/binding-repository.d.ts +62 -0
- package/dist/types/sandbox/error.d.ts +22 -0
- package/dist/types/sandbox/expiry.d.ts +11 -0
- package/dist/types/sandbox/host.d.ts +6 -0
- package/dist/types/sandbox/iga-sandbox.d.ts +208 -0
- package/dist/types/sandbox/index.d.ts +8 -0
- package/dist/types/sandbox/public-surface.d.ts +19 -0
- package/dist/types/sandbox/runtime-sandbox.d.ts +32 -0
- package/dist/types/sandbox/types.d.ts +238 -0
- package/dist/types/store/append.d.ts +41 -0
- package/dist/types/store/claude-repository.d.ts +36 -0
- package/dist/types/store/claude.d.ts +3 -0
- package/dist/types/store/control-plane-request.d.ts +2 -0
- package/dist/types/store/credential-error.d.ts +2 -0
- package/dist/types/store/credential-provider.d.ts +29 -0
- package/dist/types/store/errors.d.ts +29 -0
- package/dist/types/store/factory.d.ts +31 -0
- package/dist/types/store/host.d.ts +5 -0
- package/dist/types/store/index.d.ts +6 -0
- package/dist/types/store/json.d.ts +7 -0
- package/dist/types/store/langgraph-repository.d.ts +98 -0
- package/dist/types/store/langgraph.d.ts +43 -0
- package/dist/types/store/openai.d.ts +12 -0
- package/dist/types/store/pagination.d.ts +27 -0
- package/dist/types/store/runtime-data-plane.d.ts +8 -0
- package/dist/types/store/runtime-provider.d.ts +1 -0
- package/dist/types/store/runtime-store.d.ts +20 -0
- package/dist/types/store/store.d.ts +240 -0
- package/dist/types/store/supabase-transport.d.ts +43 -0
- package/dist/types/store/token-client.d.ts +7 -0
- package/dist/types/tools/adapters.d.ts +5 -0
- package/dist/types/tools/claude.d.ts +4 -0
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/langchain.d.ts +16 -0
- package/dist/types/tools/model-output.d.ts +8 -0
- package/dist/types/tools/openai-agents.d.ts +4 -0
- package/dist/types/tools/openai.d.ts +5 -0
- package/dist/types/tools/registry.d.ts +16 -0
- package/dist/types/tools/result.d.ts +17 -0
- package/dist/types/tools/sandbox-result-mappers.d.ts +10 -0
- package/dist/types/tools/sandbox-tools.d.ts +17 -0
- package/dist/types/tools/types.d.ts +307 -0
- package/package.json +136 -4
package/dist/cjs/419.js
ADDED
|
@@ -0,0 +1,854 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.ids = [
|
|
3
|
+
"419"
|
|
4
|
+
];
|
|
5
|
+
exports.modules = {
|
|
6
|
+
"../tools/src/registry.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
7
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
8
|
+
uU: ()=>createToolRegistry,
|
|
9
|
+
Y: ()=>getTools,
|
|
10
|
+
nn: ()=>selectSources
|
|
11
|
+
});
|
|
12
|
+
var types = __webpack_require__("../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js");
|
|
13
|
+
var src_error = __webpack_require__("../sandbox/src/error.ts");
|
|
14
|
+
const REDACTED = "[redacted]";
|
|
15
|
+
const MAX_ERROR_MESSAGE_LENGTH = 1000;
|
|
16
|
+
const SENSITIVE_KEY = /token|auth|password|secret|api[_-]?key|credential/i;
|
|
17
|
+
const BASE64_KEY = /base64|image/i;
|
|
18
|
+
const INLINE_SECRET = /\b(token|authorization|password|secret|api[_-]?key|credential|signature)\b["']?\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi;
|
|
19
|
+
const BEARER_TOKEN = /\bBearer\s+[A-Za-z0-9._~+\/-]+=*/gi;
|
|
20
|
+
const JWT = /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
|
|
21
|
+
const SIGNED_QUERY = /([?&](?:access[_-]?token|api[_-]?key|key|token|signature|credential|auth|password|secret)\s*=)[^&#\s]*/gi;
|
|
22
|
+
const URL_CREDENTIALS = /([a-z][a-z0-9+.-]*:\/\/)[^@\s/]+@/gi;
|
|
23
|
+
function success(data, preserveScreenshot = false) {
|
|
24
|
+
return {
|
|
25
|
+
status: "success",
|
|
26
|
+
data: sanitize(data, preserveScreenshot)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function failure(tool, error) {
|
|
30
|
+
return {
|
|
31
|
+
status: "error",
|
|
32
|
+
error: normalizeError(tool, error)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function normalizeError(tool, error) {
|
|
36
|
+
if (error instanceof ToolExecutionError) return {
|
|
37
|
+
tool,
|
|
38
|
+
...error.info
|
|
39
|
+
};
|
|
40
|
+
if (error instanceof src_error.ES) return {
|
|
41
|
+
tool,
|
|
42
|
+
...error.toJSON(),
|
|
43
|
+
message: sanitizeMessage(error.message)
|
|
44
|
+
};
|
|
45
|
+
if ((0, src_error.zf)(error)) return {
|
|
46
|
+
tool,
|
|
47
|
+
code: "UnknownError",
|
|
48
|
+
message: "Tool execution was cancelled."
|
|
49
|
+
};
|
|
50
|
+
if (error instanceof Error) return {
|
|
51
|
+
tool,
|
|
52
|
+
code: "UnknownError",
|
|
53
|
+
message: sanitizeMessage(error.message) || "Tool execution failed."
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
tool,
|
|
57
|
+
code: "UnknownError",
|
|
58
|
+
message: "Tool execution failed."
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function sandboxResponseError(error) {
|
|
62
|
+
const response = error && "object" == typeof error ? error : {};
|
|
63
|
+
const raw = response.rawResponse;
|
|
64
|
+
return upstreamError(response.error, raw?.status ?? responseStatus(response.error), responseMessage(error) ?? "The sandbox operation failed.");
|
|
65
|
+
}
|
|
66
|
+
class ToolExecutionError extends Error {
|
|
67
|
+
constructor(info){
|
|
68
|
+
super(info.message), this.info = info;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function checkSandboxBusinessResult(body, operation, status) {
|
|
72
|
+
if (!body || "object" != typeof body) return;
|
|
73
|
+
const response = body;
|
|
74
|
+
const data = response.data && "object" == typeof response.data ? response.data : void 0;
|
|
75
|
+
let message;
|
|
76
|
+
if (false === response.success) message = responseMessage(response) ?? "The sandbox operation failed.";
|
|
77
|
+
else if (operation.startsWith("sandbox.file.") && "string" == typeof data?.error_type) message = responseMessage(data) ?? "The file operation failed.";
|
|
78
|
+
else if ("sandbox.shell.execCommand" === operation || "sandbox.code.executeCode" === operation) {
|
|
79
|
+
if ("number" == typeof data?.exit_code && 0 !== data.exit_code) message = `Execution exited with code ${data.exit_code}.`;
|
|
80
|
+
else if ("string" == typeof data?.status && [
|
|
81
|
+
"error",
|
|
82
|
+
"failed",
|
|
83
|
+
"no_change_timeout",
|
|
84
|
+
"hard_timeout",
|
|
85
|
+
"terminated"
|
|
86
|
+
].includes(data.status)) message = `Execution ended with status ${data.status}.`;
|
|
87
|
+
}
|
|
88
|
+
if (void 0 !== message) throw upstreamError(body, status, message);
|
|
89
|
+
}
|
|
90
|
+
function upstreamError(upstream, status, message) {
|
|
91
|
+
const summary = new src_error.ES(sanitizeMessage(message), {
|
|
92
|
+
status
|
|
93
|
+
}).toJSON();
|
|
94
|
+
return new ToolExecutionError({
|
|
95
|
+
...summary,
|
|
96
|
+
...0 === status ? {
|
|
97
|
+
status: 0
|
|
98
|
+
} : {},
|
|
99
|
+
...void 0 !== upstream ? {
|
|
100
|
+
upstream: redactErrorDetails(upstream)
|
|
101
|
+
} : {}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function responseStatus(value, depth = 0) {
|
|
105
|
+
if (!value || "object" != typeof value || depth > 3) return;
|
|
106
|
+
const record = value;
|
|
107
|
+
if ("number" == typeof record.statusCode) return record.statusCode;
|
|
108
|
+
return responseStatus(record.content, depth + 1);
|
|
109
|
+
}
|
|
110
|
+
function sanitize(value, preserveScreenshot = false) {
|
|
111
|
+
if (Array.isArray(value)) return value.map((item)=>sanitize(item));
|
|
112
|
+
if (null !== value && "object" == typeof value) return Object.fromEntries(Object.entries(value).map(([key, item])=>{
|
|
113
|
+
if (SENSITIVE_KEY.test(key)) return [
|
|
114
|
+
key,
|
|
115
|
+
REDACTED
|
|
116
|
+
];
|
|
117
|
+
if (preserveScreenshot && "base64Image" === key) return [
|
|
118
|
+
key,
|
|
119
|
+
item
|
|
120
|
+
];
|
|
121
|
+
if (BASE64_KEY.test(key) && "string" == typeof item) return [
|
|
122
|
+
`${key}Length`,
|
|
123
|
+
item.length
|
|
124
|
+
];
|
|
125
|
+
return [
|
|
126
|
+
key,
|
|
127
|
+
sanitize(item)
|
|
128
|
+
];
|
|
129
|
+
}));
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
function redactText(message) {
|
|
133
|
+
return message.replace(BEARER_TOKEN, "Bearer [redacted]").replace(JWT, "[redacted]").replace(SIGNED_QUERY, "$1[redacted]").replace(URL_CREDENTIALS, "$1[redacted]@").replace(INLINE_SECRET, "$1=[redacted]");
|
|
134
|
+
}
|
|
135
|
+
function sanitizeMessage(message) {
|
|
136
|
+
const redacted = redactText(message);
|
|
137
|
+
return redacted.length > MAX_ERROR_MESSAGE_LENGTH ? `${redacted.slice(0, MAX_ERROR_MESSAGE_LENGTH)}…` : redacted;
|
|
138
|
+
}
|
|
139
|
+
function redactErrorDetails(value, ancestors = new WeakSet()) {
|
|
140
|
+
if ("string" == typeof value) return redactText(value);
|
|
141
|
+
if (null === value || "object" != typeof value) return value;
|
|
142
|
+
if (ancestors.has(value)) return "[Circular]";
|
|
143
|
+
ancestors.add(value);
|
|
144
|
+
try {
|
|
145
|
+
if (Array.isArray(value)) return value.map((item)=>redactErrorDetails(item, ancestors));
|
|
146
|
+
return Object.fromEntries(Object.entries(value).filter(([, item])=>"function" != typeof item).map(([key, item])=>[
|
|
147
|
+
key,
|
|
148
|
+
/token|auth|password|secret|api[_-]?key|credential|signature|cookie/i.test(key) ? REDACTED : redactErrorDetails(item, ancestors)
|
|
149
|
+
]));
|
|
150
|
+
} finally{
|
|
151
|
+
ancestors.delete(value);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function responseMessage(value, depth = 0) {
|
|
155
|
+
if (!value || "object" != typeof value || depth > 3) return;
|
|
156
|
+
const record = value;
|
|
157
|
+
for (const key of [
|
|
158
|
+
"message",
|
|
159
|
+
"errorMessage"
|
|
160
|
+
])if ("string" == typeof record[key] && record[key].trim()) return record[key];
|
|
161
|
+
for (const key of [
|
|
162
|
+
"error",
|
|
163
|
+
"content",
|
|
164
|
+
"body"
|
|
165
|
+
]){
|
|
166
|
+
const message = responseMessage(record[key], depth + 1);
|
|
167
|
+
if (message) return message;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const shellConsoleEntrySchema = types.Ik({
|
|
171
|
+
ps1: types.Yj(),
|
|
172
|
+
command: types.Yj(),
|
|
173
|
+
output: types.Yj().nullish()
|
|
174
|
+
});
|
|
175
|
+
const shellExecSchema = types.Ik({
|
|
176
|
+
session_id: types.Yj(),
|
|
177
|
+
command: types.Yj(),
|
|
178
|
+
status: types.k5([
|
|
179
|
+
"running",
|
|
180
|
+
"completed",
|
|
181
|
+
"no_change_timeout",
|
|
182
|
+
"hard_timeout",
|
|
183
|
+
"terminated"
|
|
184
|
+
]),
|
|
185
|
+
output: types.Yj().nullish(),
|
|
186
|
+
console: types.YO(shellConsoleEntrySchema).nullish(),
|
|
187
|
+
exit_code: types.ai().nullish()
|
|
188
|
+
});
|
|
189
|
+
const filesReadSchema = types.Ik({
|
|
190
|
+
content: types.Yj(),
|
|
191
|
+
file: types.Yj()
|
|
192
|
+
});
|
|
193
|
+
const filesWriteSchema = types.Ik({
|
|
194
|
+
file: types.Yj(),
|
|
195
|
+
bytes_written: types.ai().optional()
|
|
196
|
+
});
|
|
197
|
+
const fileListEntrySchema = types.Ik({
|
|
198
|
+
name: types.Yj(),
|
|
199
|
+
path: types.Yj(),
|
|
200
|
+
is_directory: types.zM(),
|
|
201
|
+
size: types.ai().nullish(),
|
|
202
|
+
modified_time: types.Yj().nullish(),
|
|
203
|
+
permissions: types.Yj().nullish(),
|
|
204
|
+
extension: types.Yj().nullish()
|
|
205
|
+
});
|
|
206
|
+
const filesListSchema = types.Ik({
|
|
207
|
+
path: types.Yj(),
|
|
208
|
+
files: types.YO(fileListEntrySchema).optional(),
|
|
209
|
+
total_count: types.ai().optional(),
|
|
210
|
+
directory_count: types.ai().optional(),
|
|
211
|
+
file_count: types.ai().optional()
|
|
212
|
+
});
|
|
213
|
+
const fileSearchMatchSchema = types.Ik({
|
|
214
|
+
file: types.Yj(),
|
|
215
|
+
line_number: types.ai(),
|
|
216
|
+
line_content: types.Yj(),
|
|
217
|
+
context_before: types.YO(types.Yj()).optional(),
|
|
218
|
+
context_after: types.YO(types.Yj()).optional()
|
|
219
|
+
});
|
|
220
|
+
const filesSearchSchema = types.Ik({
|
|
221
|
+
path: types.Yj(),
|
|
222
|
+
pattern: types.Yj(),
|
|
223
|
+
matches: types.YO(fileSearchMatchSchema).optional(),
|
|
224
|
+
match_count: types.ai().optional(),
|
|
225
|
+
files_searched: types.ai().optional(),
|
|
226
|
+
files_matched: types.ai().optional(),
|
|
227
|
+
truncated: types.zM().optional()
|
|
228
|
+
});
|
|
229
|
+
const filesFindSchema = types.Ik({
|
|
230
|
+
path: types.Yj(),
|
|
231
|
+
files: types.YO(types.Yj()).optional()
|
|
232
|
+
});
|
|
233
|
+
const codeRunSchema = types.Ik({
|
|
234
|
+
language: types.k5([
|
|
235
|
+
"python",
|
|
236
|
+
"javascript"
|
|
237
|
+
]),
|
|
238
|
+
status: types.Yj(),
|
|
239
|
+
outputs: types.YO(types.g1(types.L5())).nullable().optional(),
|
|
240
|
+
code: types.Yj(),
|
|
241
|
+
stdout: types.Yj().nullable().optional(),
|
|
242
|
+
stderr: types.Yj().nullable().optional(),
|
|
243
|
+
exit_code: types.ai().nullable().optional(),
|
|
244
|
+
traceback: types.YO(types.Yj()).nullable().optional(),
|
|
245
|
+
session_id: types.Yj().nullable().optional()
|
|
246
|
+
});
|
|
247
|
+
const browserNavigationSchema = types.Ik({
|
|
248
|
+
url: types.Yj().optional(),
|
|
249
|
+
title: types.Yj().optional(),
|
|
250
|
+
status: types.ai().optional(),
|
|
251
|
+
load_time_ms: types.ai().optional()
|
|
252
|
+
});
|
|
253
|
+
function parse(schema, value, operation) {
|
|
254
|
+
const result = schema.safeParse(value);
|
|
255
|
+
if (result.success) return result.data;
|
|
256
|
+
const issue = result.error.issues[0];
|
|
257
|
+
const field = issue?.path.length ? ` at ${issue.path.join(".")}` : "";
|
|
258
|
+
throw new Error(`${operation} returned invalid result data${field}: ${issue?.message ?? "validation failed"}`);
|
|
259
|
+
}
|
|
260
|
+
function mapShellExecOutput(value) {
|
|
261
|
+
const data = parse(shellExecSchema, value, "sandbox.shell.execCommand");
|
|
262
|
+
return {
|
|
263
|
+
sessionId: data.session_id,
|
|
264
|
+
command: data.command,
|
|
265
|
+
...null != data.output ? {
|
|
266
|
+
output: data.output
|
|
267
|
+
} : {},
|
|
268
|
+
...null != data.console ? {
|
|
269
|
+
console: data.console.map(({ ps1, command, output })=>({
|
|
270
|
+
ps1,
|
|
271
|
+
command,
|
|
272
|
+
...null != output ? {
|
|
273
|
+
output
|
|
274
|
+
} : {}
|
|
275
|
+
}))
|
|
276
|
+
} : {},
|
|
277
|
+
...null != data.exit_code ? {
|
|
278
|
+
exitCode: data.exit_code
|
|
279
|
+
} : {}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function mapFilesReadOutput(value) {
|
|
283
|
+
return parse(filesReadSchema, value, "sandbox.file.readFile");
|
|
284
|
+
}
|
|
285
|
+
function mapFilesWriteOutput(value) {
|
|
286
|
+
const data = parse(filesWriteSchema, value, "sandbox.file.writeFile");
|
|
287
|
+
return {
|
|
288
|
+
file: data.file,
|
|
289
|
+
...void 0 !== data.bytes_written ? {
|
|
290
|
+
bytesWritten: data.bytes_written
|
|
291
|
+
} : {}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function mapFilesListOutput(value) {
|
|
295
|
+
const data = parse(filesListSchema, value, "sandbox.file.listPath");
|
|
296
|
+
return {
|
|
297
|
+
path: data.path,
|
|
298
|
+
...void 0 !== data.files ? {
|
|
299
|
+
files: data.files.map((file)=>({
|
|
300
|
+
name: file.name,
|
|
301
|
+
path: file.path,
|
|
302
|
+
isDirectory: file.is_directory,
|
|
303
|
+
...null != file.size ? {
|
|
304
|
+
size: file.size
|
|
305
|
+
} : {},
|
|
306
|
+
...null != file.modified_time ? {
|
|
307
|
+
modifiedTime: file.modified_time
|
|
308
|
+
} : {},
|
|
309
|
+
...null != file.permissions ? {
|
|
310
|
+
permissions: file.permissions
|
|
311
|
+
} : {},
|
|
312
|
+
...null != file.extension ? {
|
|
313
|
+
extension: file.extension
|
|
314
|
+
} : {}
|
|
315
|
+
}))
|
|
316
|
+
} : {},
|
|
317
|
+
...void 0 !== data.total_count ? {
|
|
318
|
+
totalCount: data.total_count
|
|
319
|
+
} : {},
|
|
320
|
+
...void 0 !== data.directory_count ? {
|
|
321
|
+
directoryCount: data.directory_count
|
|
322
|
+
} : {},
|
|
323
|
+
...void 0 !== data.file_count ? {
|
|
324
|
+
fileCount: data.file_count
|
|
325
|
+
} : {}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
function mapFilesSearchOutput(value) {
|
|
329
|
+
const data = parse(filesSearchSchema, value, "sandbox.file.grepFiles");
|
|
330
|
+
return {
|
|
331
|
+
path: data.path,
|
|
332
|
+
pattern: data.pattern,
|
|
333
|
+
...void 0 !== data.matches ? {
|
|
334
|
+
matches: data.matches.map((match)=>({
|
|
335
|
+
file: match.file,
|
|
336
|
+
lineNumber: match.line_number,
|
|
337
|
+
lineContent: match.line_content,
|
|
338
|
+
...void 0 !== match.context_before ? {
|
|
339
|
+
contextBefore: match.context_before
|
|
340
|
+
} : {},
|
|
341
|
+
...void 0 !== match.context_after ? {
|
|
342
|
+
contextAfter: match.context_after
|
|
343
|
+
} : {}
|
|
344
|
+
}))
|
|
345
|
+
} : {},
|
|
346
|
+
...void 0 !== data.match_count ? {
|
|
347
|
+
matchCount: data.match_count
|
|
348
|
+
} : {},
|
|
349
|
+
...void 0 !== data.files_searched ? {
|
|
350
|
+
filesSearched: data.files_searched
|
|
351
|
+
} : {},
|
|
352
|
+
...void 0 !== data.files_matched ? {
|
|
353
|
+
filesMatched: data.files_matched
|
|
354
|
+
} : {},
|
|
355
|
+
...void 0 !== data.truncated ? {
|
|
356
|
+
truncated: data.truncated
|
|
357
|
+
} : {}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function mapFilesFindOutput(value) {
|
|
361
|
+
return parse(filesFindSchema, value, "sandbox.file.findFiles");
|
|
362
|
+
}
|
|
363
|
+
function mapCodeRunOutput(value) {
|
|
364
|
+
const data = parse(codeRunSchema, value, "sandbox.code.executeCode");
|
|
365
|
+
return {
|
|
366
|
+
language: data.language,
|
|
367
|
+
...null != data.outputs ? {
|
|
368
|
+
outputs: data.outputs
|
|
369
|
+
} : {},
|
|
370
|
+
code: data.code,
|
|
371
|
+
...null != data.stdout ? {
|
|
372
|
+
stdout: data.stdout
|
|
373
|
+
} : {},
|
|
374
|
+
...null != data.stderr ? {
|
|
375
|
+
stderr: data.stderr
|
|
376
|
+
} : {},
|
|
377
|
+
...null != data.exit_code ? {
|
|
378
|
+
exitCode: data.exit_code
|
|
379
|
+
} : {},
|
|
380
|
+
...null != data.traceback ? {
|
|
381
|
+
traceback: data.traceback
|
|
382
|
+
} : {},
|
|
383
|
+
...null != data.session_id ? {
|
|
384
|
+
sessionId: data.session_id
|
|
385
|
+
} : {}
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function mapBrowserFetchOutput(navigation, content) {
|
|
389
|
+
const metadata = parse(browserNavigationSchema, navigation ?? {}, "sandbox.browser.navigate");
|
|
390
|
+
const html = parse(types.Yj(), content, "sandbox.browser.getHtml");
|
|
391
|
+
return {
|
|
392
|
+
content: html,
|
|
393
|
+
...void 0 !== metadata.url ? {
|
|
394
|
+
url: metadata.url
|
|
395
|
+
} : {},
|
|
396
|
+
...void 0 !== metadata.title ? {
|
|
397
|
+
title: metadata.title
|
|
398
|
+
} : {},
|
|
399
|
+
...void 0 !== metadata.status ? {
|
|
400
|
+
status: metadata.status
|
|
401
|
+
} : {},
|
|
402
|
+
...void 0 !== metadata.load_time_ms ? {
|
|
403
|
+
loadTimeMs: metadata.load_time_ms
|
|
404
|
+
} : {}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
async function mapBrowserScreenshotOutput(body) {
|
|
408
|
+
const binary = body;
|
|
409
|
+
if (!binary || "function" != typeof binary.arrayBuffer) throw new Error("Sandbox screenshot did not return image bytes.");
|
|
410
|
+
const buffer = Buffer.from(await binary.arrayBuffer());
|
|
411
|
+
let mimeType;
|
|
412
|
+
if (buffer.subarray(0, 8).equals(Buffer.from("89504e470d0a1a0a", "hex"))) mimeType = "image/png";
|
|
413
|
+
else if (buffer.length >= 3 && 0xff === buffer[0] && 0xd8 === buffer[1] && 0xff === buffer[2]) mimeType = "image/jpeg";
|
|
414
|
+
else if ("RIFF" === buffer.toString("ascii", 0, 4) && "WEBP" === buffer.toString("ascii", 8, 12)) mimeType = "image/webp";
|
|
415
|
+
else if (/^GIF8[79]a$/.test(buffer.toString("ascii", 0, 6))) mimeType = "image/gif";
|
|
416
|
+
else throw new Error("Sandbox screenshot returned an empty or unsupported image.");
|
|
417
|
+
const base64Image = buffer.toString("base64");
|
|
418
|
+
return {
|
|
419
|
+
base64Image,
|
|
420
|
+
mimeType,
|
|
421
|
+
base64ImageLength: base64Image.length
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
const strictObject = (properties, required)=>({
|
|
425
|
+
type: "object",
|
|
426
|
+
properties,
|
|
427
|
+
required,
|
|
428
|
+
additionalProperties: false
|
|
429
|
+
});
|
|
430
|
+
const looseBoolean = types.vk((value)=>{
|
|
431
|
+
if ("string" == typeof value) {
|
|
432
|
+
const normalized = value.trim().toLowerCase();
|
|
433
|
+
if ("true" === normalized) return true;
|
|
434
|
+
if ("false" === normalized) return false;
|
|
435
|
+
}
|
|
436
|
+
return value;
|
|
437
|
+
}, types.zM());
|
|
438
|
+
function requestOptions(options) {
|
|
439
|
+
return options?.abortSignal ? {
|
|
440
|
+
abortSignal: options.abortSignal
|
|
441
|
+
} : void 0;
|
|
442
|
+
}
|
|
443
|
+
function createSandboxTools(sandbox) {
|
|
444
|
+
return [
|
|
445
|
+
{
|
|
446
|
+
name: "shell_exec",
|
|
447
|
+
domain: "shell",
|
|
448
|
+
description: "Execute one shell command in the conversation sandbox. Use it for command-line tasks and inspect the returned command result before continuing.",
|
|
449
|
+
inputSchema: strictObject({
|
|
450
|
+
command: {
|
|
451
|
+
type: "string",
|
|
452
|
+
description: "Command to execute"
|
|
453
|
+
},
|
|
454
|
+
cwd: {
|
|
455
|
+
type: "string",
|
|
456
|
+
description: "Optional working directory"
|
|
457
|
+
},
|
|
458
|
+
timeout: {
|
|
459
|
+
type: "number",
|
|
460
|
+
description: "Optional timeout in seconds"
|
|
461
|
+
}
|
|
462
|
+
}, [
|
|
463
|
+
"command"
|
|
464
|
+
]),
|
|
465
|
+
validate: types.Ik({
|
|
466
|
+
command: types.Yj().min(1),
|
|
467
|
+
cwd: types.Yj().min(1).optional(),
|
|
468
|
+
timeout: types.au.number().positive().optional()
|
|
469
|
+
}).strict(),
|
|
470
|
+
execute: async (input, options)=>{
|
|
471
|
+
const response = await sandbox.shell.execCommand({
|
|
472
|
+
command: input.command,
|
|
473
|
+
exec_dir: input.cwd,
|
|
474
|
+
timeout: input.timeout
|
|
475
|
+
}, requestOptions(options));
|
|
476
|
+
return mapData(response, "sandbox.shell.execCommand", mapShellExecOutput);
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
name: "files_read",
|
|
481
|
+
domain: "files",
|
|
482
|
+
description: "Read a text file from the conversation sandbox. Use a precise path and optional line range; do not use it for binary content.",
|
|
483
|
+
inputSchema: strictObject({
|
|
484
|
+
path: {
|
|
485
|
+
type: "string",
|
|
486
|
+
description: "File path"
|
|
487
|
+
},
|
|
488
|
+
startLine: {
|
|
489
|
+
type: "number",
|
|
490
|
+
minimum: 1,
|
|
491
|
+
description: "Optional 1-based first line; must be a positive integer"
|
|
492
|
+
},
|
|
493
|
+
endLine: {
|
|
494
|
+
type: "number",
|
|
495
|
+
minimum: 1,
|
|
496
|
+
description: "Optional 1-based last line; must be a positive integer"
|
|
497
|
+
}
|
|
498
|
+
}, [
|
|
499
|
+
"path"
|
|
500
|
+
]),
|
|
501
|
+
validate: types.Ik({
|
|
502
|
+
path: types.Yj().min(1),
|
|
503
|
+
startLine: types.au.number().int().positive().optional(),
|
|
504
|
+
endLine: types.au.number().int().positive().optional()
|
|
505
|
+
}).strict(),
|
|
506
|
+
execute: async (input, options)=>mapData(await sandbox.file.readFile({
|
|
507
|
+
file: input.path,
|
|
508
|
+
start_line: input.startLine,
|
|
509
|
+
end_line: input.endLine
|
|
510
|
+
}, requestOptions(options)), "sandbox.file.readFile", mapFilesReadOutput)
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
name: "files_write",
|
|
514
|
+
domain: "files",
|
|
515
|
+
description: "Write complete text content to a file in the conversation sandbox. This may overwrite an existing file.",
|
|
516
|
+
inputSchema: strictObject({
|
|
517
|
+
path: {
|
|
518
|
+
type: "string",
|
|
519
|
+
description: "File path"
|
|
520
|
+
},
|
|
521
|
+
content: {
|
|
522
|
+
type: "string",
|
|
523
|
+
description: "Complete file content"
|
|
524
|
+
},
|
|
525
|
+
append: {
|
|
526
|
+
type: "boolean",
|
|
527
|
+
description: "Append instead of overwrite"
|
|
528
|
+
}
|
|
529
|
+
}, [
|
|
530
|
+
"path",
|
|
531
|
+
"content"
|
|
532
|
+
]),
|
|
533
|
+
validate: types.Ik({
|
|
534
|
+
path: types.Yj().min(1),
|
|
535
|
+
content: types.Yj(),
|
|
536
|
+
append: looseBoolean.optional()
|
|
537
|
+
}).strict(),
|
|
538
|
+
execute: async (input, options)=>mapData(await sandbox.file.writeFile({
|
|
539
|
+
file: input.path,
|
|
540
|
+
content: input.content,
|
|
541
|
+
append: input.append
|
|
542
|
+
}, requestOptions(options)), "sandbox.file.writeFile", mapFilesWriteOutput)
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
name: "files_list",
|
|
546
|
+
domain: "files",
|
|
547
|
+
description: "List files and directories under a sandbox path. Use this before reading an unknown directory tree.",
|
|
548
|
+
inputSchema: strictObject({
|
|
549
|
+
path: {
|
|
550
|
+
type: "string",
|
|
551
|
+
description: "Directory path"
|
|
552
|
+
},
|
|
553
|
+
recursive: {
|
|
554
|
+
type: "boolean",
|
|
555
|
+
description: "Whether to recurse"
|
|
556
|
+
}
|
|
557
|
+
}, [
|
|
558
|
+
"path"
|
|
559
|
+
]),
|
|
560
|
+
validate: types.Ik({
|
|
561
|
+
path: types.Yj().min(1),
|
|
562
|
+
recursive: looseBoolean.optional()
|
|
563
|
+
}).strict(),
|
|
564
|
+
execute: async (input, options)=>mapData(await sandbox.file.listPath({
|
|
565
|
+
path: input.path,
|
|
566
|
+
recursive: input.recursive
|
|
567
|
+
}, requestOptions(options)), "sandbox.file.listPath", mapFilesListOutput)
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
name: "files_search",
|
|
571
|
+
domain: "files",
|
|
572
|
+
description: "Search file contents in the sandbox using a text or regular-expression pattern. Prefer this to reading every file.",
|
|
573
|
+
inputSchema: strictObject({
|
|
574
|
+
path: {
|
|
575
|
+
type: "string",
|
|
576
|
+
description: "Search root path"
|
|
577
|
+
},
|
|
578
|
+
pattern: {
|
|
579
|
+
type: "string",
|
|
580
|
+
description: "Content pattern"
|
|
581
|
+
},
|
|
582
|
+
maxResults: {
|
|
583
|
+
type: "number",
|
|
584
|
+
description: "Maximum matches"
|
|
585
|
+
}
|
|
586
|
+
}, [
|
|
587
|
+
"path",
|
|
588
|
+
"pattern"
|
|
589
|
+
]),
|
|
590
|
+
validate: types.Ik({
|
|
591
|
+
path: types.Yj().min(1),
|
|
592
|
+
pattern: types.Yj().min(1),
|
|
593
|
+
maxResults: types.au.number().int().positive().optional()
|
|
594
|
+
}).strict(),
|
|
595
|
+
execute: async (input, options)=>mapData(await sandbox.file.grepFiles({
|
|
596
|
+
path: input.path,
|
|
597
|
+
pattern: input.pattern,
|
|
598
|
+
max_results: input.maxResults
|
|
599
|
+
}, requestOptions(options)), "sandbox.file.grepFiles", mapFilesSearchOutput)
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
name: "files_find",
|
|
603
|
+
domain: "files",
|
|
604
|
+
description: "Find sandbox files by glob pattern. Use it to discover files by name without searching their contents.",
|
|
605
|
+
inputSchema: strictObject({
|
|
606
|
+
path: {
|
|
607
|
+
type: "string",
|
|
608
|
+
description: "Search root path"
|
|
609
|
+
},
|
|
610
|
+
glob: {
|
|
611
|
+
type: "string",
|
|
612
|
+
description: "Glob pattern"
|
|
613
|
+
}
|
|
614
|
+
}, [
|
|
615
|
+
"path",
|
|
616
|
+
"glob"
|
|
617
|
+
]),
|
|
618
|
+
validate: types.Ik({
|
|
619
|
+
path: types.Yj().min(1),
|
|
620
|
+
glob: types.Yj().min(1)
|
|
621
|
+
}).strict(),
|
|
622
|
+
execute: async (input, options)=>mapData(await sandbox.file.findFiles({
|
|
623
|
+
path: input.path,
|
|
624
|
+
glob: input.glob
|
|
625
|
+
}, requestOptions(options)), "sandbox.file.findFiles", mapFilesFindOutput)
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
name: "code_run",
|
|
629
|
+
domain: "code",
|
|
630
|
+
description: "Execute a short JavaScript or Python program in the sandbox. Use shell_exec when command-line behavior is required.",
|
|
631
|
+
inputSchema: strictObject({
|
|
632
|
+
language: {
|
|
633
|
+
type: "string",
|
|
634
|
+
enum: [
|
|
635
|
+
"python",
|
|
636
|
+
"javascript"
|
|
637
|
+
],
|
|
638
|
+
description: "Execution language"
|
|
639
|
+
},
|
|
640
|
+
code: {
|
|
641
|
+
type: "string",
|
|
642
|
+
description: "Source code"
|
|
643
|
+
},
|
|
644
|
+
timeout: {
|
|
645
|
+
type: "number",
|
|
646
|
+
description: "Optional timeout in seconds"
|
|
647
|
+
}
|
|
648
|
+
}, [
|
|
649
|
+
"language",
|
|
650
|
+
"code"
|
|
651
|
+
]),
|
|
652
|
+
validate: types.Ik({
|
|
653
|
+
language: types.k5([
|
|
654
|
+
"python",
|
|
655
|
+
"javascript"
|
|
656
|
+
]),
|
|
657
|
+
code: types.Yj().min(1),
|
|
658
|
+
timeout: types.au.number().positive().optional()
|
|
659
|
+
}).strict(),
|
|
660
|
+
execute: async (input, options)=>mapData(await sandbox.code.executeCode({
|
|
661
|
+
language: input.language,
|
|
662
|
+
code: input.code,
|
|
663
|
+
timeout: input.timeout
|
|
664
|
+
}, requestOptions(options)), "sandbox.code.executeCode", mapCodeRunOutput)
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
name: "browser_fetch",
|
|
668
|
+
domain: "browser",
|
|
669
|
+
description: "Navigate the sandbox browser to a URL and inspect the DOM content at that URL. Use this for web content that needs browser rendering. Output semantics: returns page metadata (url, title, status) plus the page HTML document returned by the sandbox, without truncation. Navigation or content failures return status:error with an error summary and the upstream business response in error.upstream. Side effects: navigation changes the current sandbox browser page. Common mistakes: do not use browser_fetch for general web search or information discovery.",
|
|
670
|
+
inputSchema: strictObject({
|
|
671
|
+
url: {
|
|
672
|
+
type: "string",
|
|
673
|
+
description: "Absolute URL"
|
|
674
|
+
}
|
|
675
|
+
}, [
|
|
676
|
+
"url"
|
|
677
|
+
]),
|
|
678
|
+
validate: types.Ik({
|
|
679
|
+
url: types.Yj().url()
|
|
680
|
+
}).strict(),
|
|
681
|
+
execute: async (input, options)=>{
|
|
682
|
+
const opts = requestOptions(options);
|
|
683
|
+
const browser = sandbox.browserPage;
|
|
684
|
+
const navigation = unwrapDict(await browser.navigate({
|
|
685
|
+
url: input.url
|
|
686
|
+
}, opts), "sandbox.browser.navigate");
|
|
687
|
+
const html = unwrapDict(await browser.getHtml({}, opts), "sandbox.browser.getHtml");
|
|
688
|
+
return mapBrowserFetchOutput(navigation.data, html.data);
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
name: "browser_screenshot",
|
|
693
|
+
domain: "browser",
|
|
694
|
+
description: "Capture a screenshot of the current sandbox browser page. Returns the image content with its MIME type and Base64 length. Framework adapters send it as an image to vision-capable models; it is not a file path. Use browser_fetch for page text and browser_fetch before this tool to navigate to the target page first.",
|
|
695
|
+
inputSchema: strictObject({
|
|
696
|
+
fullPage: {
|
|
697
|
+
type: "boolean",
|
|
698
|
+
description: "Capture the full page"
|
|
699
|
+
}
|
|
700
|
+
}, []),
|
|
701
|
+
validate: types.Ik({
|
|
702
|
+
fullPage: looseBoolean.optional()
|
|
703
|
+
}).strict(),
|
|
704
|
+
execute: async (input, options)=>{
|
|
705
|
+
const response = await sandbox.browserPage.screenshot({
|
|
706
|
+
full_page: input.fullPage
|
|
707
|
+
}, requestOptions(options));
|
|
708
|
+
if (!response.ok) return unwrap(response, "sandbox.browser.screenshot");
|
|
709
|
+
return mapBrowserScreenshotOutput(response.body);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
];
|
|
713
|
+
}
|
|
714
|
+
function bindSandboxTool(spec) {
|
|
715
|
+
const schema = spec.validate.extend(Object.fromEntries(Object.entries(spec.validate.shape).map(([name, field])=>{
|
|
716
|
+
const property = spec.inputSchema.properties[name];
|
|
717
|
+
const validator = field;
|
|
718
|
+
return [
|
|
719
|
+
name,
|
|
720
|
+
property?.description === void 0 ? validator : validator.describe(property.description)
|
|
721
|
+
];
|
|
722
|
+
})));
|
|
723
|
+
return {
|
|
724
|
+
schema,
|
|
725
|
+
definition: {
|
|
726
|
+
name: spec.name,
|
|
727
|
+
description: spec.description,
|
|
728
|
+
inputSchema: spec.inputSchema,
|
|
729
|
+
async execute (input, options) {
|
|
730
|
+
const parsed = schema.safeParse(input);
|
|
731
|
+
if (!parsed.success) return {
|
|
732
|
+
status: "error",
|
|
733
|
+
error: {
|
|
734
|
+
tool: spec.name,
|
|
735
|
+
code: "UnknownError",
|
|
736
|
+
message: sanitizeMessage(parsed.error.issues[0]?.message ?? "The tool input is invalid."),
|
|
737
|
+
issues: redactErrorDetails(parsed.error.issues)
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
try {
|
|
741
|
+
return success(await spec.execute(parsed.data, options), "browser_screenshot" === spec.name);
|
|
742
|
+
} catch (error) {
|
|
743
|
+
return failure(spec.name, error);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
function unwrap(response, operation) {
|
|
750
|
+
if (response.ok) {
|
|
751
|
+
checkSandboxBusinessResult(response.body, operation, response.rawResponse?.status);
|
|
752
|
+
return response.body;
|
|
753
|
+
}
|
|
754
|
+
throw sandboxResponseError(response);
|
|
755
|
+
}
|
|
756
|
+
function mapData(response, operation, mapper) {
|
|
757
|
+
const body = unwrap(response, operation);
|
|
758
|
+
if (!body || "object" != typeof body || !("data" in body) || void 0 === body.data || null === body.data) throw new Error(`${operation} returned no result data.`);
|
|
759
|
+
return mapper(body.data);
|
|
760
|
+
}
|
|
761
|
+
function unwrapDict(response, operation) {
|
|
762
|
+
const body = unwrap(response, operation);
|
|
763
|
+
if (null !== body && "object" == typeof body && !Array.isArray(body)) return body;
|
|
764
|
+
return {};
|
|
765
|
+
}
|
|
766
|
+
const DOMAINS = {
|
|
767
|
+
files: "files",
|
|
768
|
+
shell: "shell",
|
|
769
|
+
code: "code",
|
|
770
|
+
browser: "browser"
|
|
771
|
+
};
|
|
772
|
+
function getTools(sandbox) {
|
|
773
|
+
return createToolRegistry(sandbox, (sources)=>sources.map((source)=>source.definition));
|
|
774
|
+
}
|
|
775
|
+
function createToolRegistry(sandbox, adapt, extend) {
|
|
776
|
+
const sources = createSandboxTools(sandbox).map(bindSandboxTool);
|
|
777
|
+
const definitions = sources.map((source)=>source.definition);
|
|
778
|
+
const adapted = adapt(sources);
|
|
779
|
+
const get = (name)=>{
|
|
780
|
+
const index = definitions.findIndex((candidate)=>candidate.name === name);
|
|
781
|
+
if (index < 0) getDefinition(definitions, name);
|
|
782
|
+
return adapted[index];
|
|
783
|
+
};
|
|
784
|
+
const methods = {
|
|
785
|
+
all: ()=>[
|
|
786
|
+
...adapted
|
|
787
|
+
],
|
|
788
|
+
get,
|
|
789
|
+
files: ()=>byDomain(definitions, adapted, DOMAINS.files),
|
|
790
|
+
shell: ()=>byDomain(definitions, adapted, DOMAINS.shell),
|
|
791
|
+
code: ()=>byDomain(definitions, adapted, DOMAINS.code),
|
|
792
|
+
browser: ()=>byDomain(definitions, adapted, DOMAINS.browser),
|
|
793
|
+
definitions: (names)=>selectDefinitions(definitions, names),
|
|
794
|
+
...extend?.(sources, adapted)
|
|
795
|
+
};
|
|
796
|
+
return new Proxy(methods, {
|
|
797
|
+
get (target, property, receiver) {
|
|
798
|
+
if ("then" === property) return;
|
|
799
|
+
if ("symbol" == typeof property) return Reflect.get(target, property, receiver);
|
|
800
|
+
if (property in target) return Reflect.get(target, property, target);
|
|
801
|
+
return get(property);
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
function byDomain(definitions, adapted, domain) {
|
|
806
|
+
const names = DOMAIN_TOOL_NAMES[domain];
|
|
807
|
+
return definitions.flatMap((tool, index)=>names.has(tool.name) ? [
|
|
808
|
+
adapted[index]
|
|
809
|
+
] : []);
|
|
810
|
+
}
|
|
811
|
+
const DOMAIN_TOOL_NAMES = {
|
|
812
|
+
shell: new Set([
|
|
813
|
+
"shell_exec"
|
|
814
|
+
]),
|
|
815
|
+
files: new Set([
|
|
816
|
+
"files_read",
|
|
817
|
+
"files_write",
|
|
818
|
+
"files_list",
|
|
819
|
+
"files_search",
|
|
820
|
+
"files_find"
|
|
821
|
+
]),
|
|
822
|
+
code: new Set([
|
|
823
|
+
"code_run"
|
|
824
|
+
]),
|
|
825
|
+
browser: new Set([
|
|
826
|
+
"browser_fetch",
|
|
827
|
+
"browser_screenshot"
|
|
828
|
+
])
|
|
829
|
+
};
|
|
830
|
+
function selectDefinitions(definitions, names) {
|
|
831
|
+
if (!names) return [
|
|
832
|
+
...definitions
|
|
833
|
+
];
|
|
834
|
+
return names.map((name)=>getDefinition(definitions, name));
|
|
835
|
+
}
|
|
836
|
+
function selectSources(sources, names) {
|
|
837
|
+
if (!names) return [
|
|
838
|
+
...sources
|
|
839
|
+
];
|
|
840
|
+
return names.map((name)=>{
|
|
841
|
+
const source = sources.find((candidate)=>candidate.definition.name === name);
|
|
842
|
+
if (source) return source;
|
|
843
|
+
getDefinition(sources.map((candidate)=>candidate.definition), name);
|
|
844
|
+
throw new Error("Unreachable: unknown tool lookup must throw");
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
function getDefinition(definitions, name) {
|
|
848
|
+
const tool = definitions.find((candidate)=>candidate.name === name);
|
|
849
|
+
if (tool) return tool;
|
|
850
|
+
const available = definitions.map((candidate)=>candidate.name).join(", ");
|
|
851
|
+
throw new Error(`Unknown tool "${name}". Available tools: ${available}`);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
};
|