@robota-sdk/agent-tools 3.0.0-beta.60 → 3.0.0-beta.62
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/README.md +67 -21
- package/dist/browser/browser.d.ts +268 -0
- package/dist/browser/browser.js +1 -0
- package/dist/node/index.cjs +505 -257
- package/dist/node/index.d.cts +170 -15
- package/dist/node/index.d.ts +170 -15
- package/dist/node/index.js +444 -173
- package/package.json +10 -6
package/dist/node/index.js
CHANGED
|
@@ -1,6 +1,275 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { logger } from
|
|
1
|
+
import { readFile, readdir, stat, mkdir, writeFile, chmod, rename, rm } from 'fs/promises';
|
|
2
|
+
import { join, posix, isAbsolute, resolve, dirname, basename } from 'path';
|
|
3
|
+
import { ValidationError, ToolExecutionError, logger } from '@robota-sdk/agent-core';
|
|
4
|
+
import { spawn } from 'child_process';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { randomBytes } from 'crypto';
|
|
7
|
+
import fg from 'fast-glob';
|
|
8
|
+
|
|
9
|
+
// src/sandbox/e2b-sandbox-client.ts
|
|
10
|
+
var E2BSandboxClient = class {
|
|
11
|
+
sandbox;
|
|
12
|
+
connectSandbox;
|
|
13
|
+
createSandboxFromSnapshot;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.sandbox = options.sandbox;
|
|
16
|
+
this.connectSandbox = options.connectSandbox;
|
|
17
|
+
this.createSandboxFromSnapshot = options.createSandboxFromSnapshot;
|
|
18
|
+
}
|
|
19
|
+
async run(command, options) {
|
|
20
|
+
const result = await this.sandbox.commands.run(command, {
|
|
21
|
+
background: false,
|
|
22
|
+
timeoutMs: options?.timeoutMs,
|
|
23
|
+
cwd: options?.workingDirectory
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
stdout: result.stdout ?? "",
|
|
27
|
+
stderr: result.stderr ?? "",
|
|
28
|
+
exitCode: result.exitCode ?? result.exit_code ?? 0
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async readFile(path) {
|
|
32
|
+
const content = await this.sandbox.files.read(path);
|
|
33
|
+
return typeof content === "string" ? content : Buffer.from(content).toString("utf8");
|
|
34
|
+
}
|
|
35
|
+
async writeFile(path, content) {
|
|
36
|
+
await this.sandbox.files.write(path, content);
|
|
37
|
+
}
|
|
38
|
+
async snapshot() {
|
|
39
|
+
if (this.sandbox.createSnapshot) {
|
|
40
|
+
const snapshot = await this.sandbox.createSnapshot();
|
|
41
|
+
const snapshotId = snapshot.snapshotId ?? snapshot.id;
|
|
42
|
+
if (!snapshotId) {
|
|
43
|
+
throw new Error("E2B createSnapshot() did not return a snapshot id.");
|
|
44
|
+
}
|
|
45
|
+
return snapshotId;
|
|
46
|
+
}
|
|
47
|
+
const sandboxId = this.sandbox.sandboxId;
|
|
48
|
+
if (!sandboxId) {
|
|
49
|
+
throw new Error("E2B sandboxId is required to create a resumable sandbox snapshot.");
|
|
50
|
+
}
|
|
51
|
+
if (!this.sandbox.pause) {
|
|
52
|
+
throw new Error("E2B sandbox adapter does not expose pause().");
|
|
53
|
+
}
|
|
54
|
+
await this.sandbox.pause();
|
|
55
|
+
return sandboxId;
|
|
56
|
+
}
|
|
57
|
+
async restore(snapshotId) {
|
|
58
|
+
if (this.createSandboxFromSnapshot) {
|
|
59
|
+
this.sandbox = await this.createSandboxFromSnapshot(snapshotId);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (this.connectSandbox) {
|
|
63
|
+
this.sandbox = await this.connectSandbox(snapshotId);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (this.sandbox.sandboxId === snapshotId && this.sandbox.connect) {
|
|
67
|
+
this.sandbox = await this.sandbox.connect();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
throw new Error(
|
|
71
|
+
"E2B sandbox restore requires connectSandbox(snapshotId) or sandbox.connect()."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/sandbox/in-memory-sandbox-client.ts
|
|
77
|
+
var InMemorySandboxClient = class {
|
|
78
|
+
files = /* @__PURE__ */ new Map();
|
|
79
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
80
|
+
runHandler;
|
|
81
|
+
snapshotSequence = 0;
|
|
82
|
+
constructor(options = {}) {
|
|
83
|
+
for (const [path, content] of Object.entries(options.files ?? {})) {
|
|
84
|
+
this.files.set(path, content);
|
|
85
|
+
}
|
|
86
|
+
this.runHandler = options.runHandler;
|
|
87
|
+
}
|
|
88
|
+
async run(command, options) {
|
|
89
|
+
if (this.runHandler) {
|
|
90
|
+
return this.runHandler(command, options, this.files);
|
|
91
|
+
}
|
|
92
|
+
return { stdout: "", stderr: "", exitCode: 0 };
|
|
93
|
+
}
|
|
94
|
+
async readFile(path) {
|
|
95
|
+
const content = this.files.get(path);
|
|
96
|
+
if (content === void 0) {
|
|
97
|
+
throw new Error(`Sandbox file not found: ${path}`);
|
|
98
|
+
}
|
|
99
|
+
return content;
|
|
100
|
+
}
|
|
101
|
+
async writeFile(path, content) {
|
|
102
|
+
this.files.set(path, content);
|
|
103
|
+
}
|
|
104
|
+
async snapshot() {
|
|
105
|
+
const snapshotId = `snapshot-${++this.snapshotSequence}`;
|
|
106
|
+
this.snapshots.set(snapshotId, new Map(this.files));
|
|
107
|
+
return snapshotId;
|
|
108
|
+
}
|
|
109
|
+
async restore(snapshotId) {
|
|
110
|
+
const snapshot = this.snapshots.get(snapshotId);
|
|
111
|
+
if (!snapshot) {
|
|
112
|
+
throw new Error(`Sandbox snapshot not found: ${snapshotId}`);
|
|
113
|
+
}
|
|
114
|
+
this.files.clear();
|
|
115
|
+
for (const [path, content] of snapshot.entries()) {
|
|
116
|
+
this.files.set(path, content);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
getFile(path) {
|
|
120
|
+
return this.files.get(path);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var DEFAULT_TARGET_ROOT = "/workspace";
|
|
124
|
+
var WINDOWS_ABSOLUTE_PATH_PATTERN = /^[A-Za-z]:[\\/]/;
|
|
125
|
+
var SHELL_QUOTE_PATTERN = /'/g;
|
|
126
|
+
async function applyWorkspaceManifest(sandboxClient, manifest, options = {}) {
|
|
127
|
+
if (sandboxClient.applyManifest) {
|
|
128
|
+
return sandboxClient.applyManifest(manifest, options);
|
|
129
|
+
}
|
|
130
|
+
const targetRoot = normalizeSandboxRoot(options.targetRoot ?? DEFAULT_TARGET_ROOT);
|
|
131
|
+
const appliedEntries = [];
|
|
132
|
+
for (const [rawPath, entry] of Object.entries(manifest.entries)) {
|
|
133
|
+
const path = validateWorkspaceManifestPath(rawPath);
|
|
134
|
+
const targetPath = joinSandboxPath(targetRoot, path);
|
|
135
|
+
appliedEntries.push(
|
|
136
|
+
await applyManifestEntry(sandboxClient, path, targetPath, targetRoot, entry, options)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return { entries: appliedEntries };
|
|
140
|
+
}
|
|
141
|
+
function validateWorkspaceManifestPath(path) {
|
|
142
|
+
if (path.length === 0) {
|
|
143
|
+
throw new Error("workspace manifest path must not be empty");
|
|
144
|
+
}
|
|
145
|
+
if (path.includes("\0")) {
|
|
146
|
+
throw new Error("workspace manifest path must not contain NUL bytes");
|
|
147
|
+
}
|
|
148
|
+
if (path.startsWith("/") || path.startsWith("\\") || WINDOWS_ABSOLUTE_PATH_PATTERN.test(path)) {
|
|
149
|
+
throw new Error("workspace manifest path must be workspace-relative");
|
|
150
|
+
}
|
|
151
|
+
const parts = path.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
152
|
+
if (parts.length === 0) {
|
|
153
|
+
throw new Error("workspace manifest path must not resolve to the workspace root");
|
|
154
|
+
}
|
|
155
|
+
if (parts.some((part) => part === "..")) {
|
|
156
|
+
throw new Error("workspace manifest path cannot contain traversal segments");
|
|
157
|
+
}
|
|
158
|
+
const normalizedParts = parts.filter((part) => part !== ".");
|
|
159
|
+
if (normalizedParts.length === 0) {
|
|
160
|
+
throw new Error("workspace manifest path must not resolve to the workspace root");
|
|
161
|
+
}
|
|
162
|
+
return normalizedParts.join("/");
|
|
163
|
+
}
|
|
164
|
+
async function applyManifestEntry(sandboxClient, path, targetPath, targetRoot, entry, options) {
|
|
165
|
+
switch (entry.type) {
|
|
166
|
+
case "file":
|
|
167
|
+
await writeSandboxFile(sandboxClient, targetPath, targetRoot, entry.content);
|
|
168
|
+
return createAppliedEntry(path, entry.type);
|
|
169
|
+
case "dir":
|
|
170
|
+
await createSandboxDirectory(sandboxClient, targetPath);
|
|
171
|
+
return createAppliedEntry(path, entry.type);
|
|
172
|
+
case "localFile":
|
|
173
|
+
await copyLocalFile(sandboxClient, entry.src, targetPath, targetRoot, options);
|
|
174
|
+
return createAppliedEntry(path, entry.type);
|
|
175
|
+
case "localDir":
|
|
176
|
+
await copyLocalDirectory(sandboxClient, entry.src, targetPath, options);
|
|
177
|
+
return createAppliedEntry(path, entry.type);
|
|
178
|
+
case "gitRepo":
|
|
179
|
+
await cloneGitRepository(sandboxClient, entry, targetPath);
|
|
180
|
+
return createAppliedEntry(path, entry.type);
|
|
181
|
+
case "s3Mount":
|
|
182
|
+
case "gcsMount":
|
|
183
|
+
case "r2Mount":
|
|
184
|
+
case "azureBlobMount":
|
|
185
|
+
return {
|
|
186
|
+
path,
|
|
187
|
+
type: entry.type,
|
|
188
|
+
status: "unsupported",
|
|
189
|
+
message: `${entry.type} requires a provider-specific sandbox adapter.`
|
|
190
|
+
};
|
|
191
|
+
default:
|
|
192
|
+
return assertUnreachable(entry);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function createAppliedEntry(path, type) {
|
|
196
|
+
return { path, type, status: "applied" };
|
|
197
|
+
}
|
|
198
|
+
async function copyLocalFile(sandboxClient, source, targetPath, targetRoot, options) {
|
|
199
|
+
const hostSourcePath = resolveHostSourcePath(source, options.hostRoot);
|
|
200
|
+
const content = await readFile(hostSourcePath, "utf8");
|
|
201
|
+
await writeSandboxFile(sandboxClient, targetPath, targetRoot, content);
|
|
202
|
+
}
|
|
203
|
+
async function copyLocalDirectory(sandboxClient, source, targetPath, options) {
|
|
204
|
+
const hostSourcePath = resolveHostSourcePath(source, options.hostRoot);
|
|
205
|
+
await copyLocalDirectoryRecursive(sandboxClient, hostSourcePath, targetPath);
|
|
206
|
+
}
|
|
207
|
+
async function copyLocalDirectoryRecursive(sandboxClient, sourcePath, targetPath) {
|
|
208
|
+
await createSandboxDirectory(sandboxClient, targetPath);
|
|
209
|
+
const entries = await readdir(sourcePath, { withFileTypes: true });
|
|
210
|
+
for (const entry of entries) {
|
|
211
|
+
const childSourcePath = join(sourcePath, entry.name);
|
|
212
|
+
const childTargetPath = joinSandboxPath(targetPath, entry.name);
|
|
213
|
+
if (entry.isDirectory()) {
|
|
214
|
+
await copyLocalDirectoryRecursive(sandboxClient, childSourcePath, childTargetPath);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (entry.isFile()) {
|
|
218
|
+
const content = await readFile(childSourcePath, "utf8");
|
|
219
|
+
await sandboxClient.writeFile(childTargetPath, content);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async function cloneGitRepository(sandboxClient, entry, targetPath) {
|
|
224
|
+
const shallowArgs = entry.shallow === false ? "" : " --depth 1";
|
|
225
|
+
const refArgs = entry.ref ? ` --branch ${quoteShellArg(entry.ref)}` : "";
|
|
226
|
+
await runSandboxCommand(
|
|
227
|
+
sandboxClient,
|
|
228
|
+
`git clone${shallowArgs}${refArgs} ${quoteShellArg(entry.url)} ${quoteShellArg(targetPath)}`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
async function writeSandboxFile(sandboxClient, targetPath, targetRoot, content) {
|
|
232
|
+
const parentPath = posix.dirname(targetPath);
|
|
233
|
+
if (parentPath !== targetRoot) {
|
|
234
|
+
await createSandboxDirectory(sandboxClient, parentPath);
|
|
235
|
+
}
|
|
236
|
+
await sandboxClient.writeFile(targetPath, content);
|
|
237
|
+
}
|
|
238
|
+
async function createSandboxDirectory(sandboxClient, targetPath) {
|
|
239
|
+
await runSandboxCommand(sandboxClient, `mkdir -p ${quoteShellArg(targetPath)}`);
|
|
240
|
+
}
|
|
241
|
+
async function runSandboxCommand(sandboxClient, command) {
|
|
242
|
+
const result = await sandboxClient.run(command);
|
|
243
|
+
if (result.exitCode !== 0) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`workspace manifest command failed: ${command}
|
|
246
|
+
${result.stderr ?? result.stdout}`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function resolveHostSourcePath(source, hostRoot) {
|
|
251
|
+
return isAbsolute(source) ? resolve(source) : resolve(hostRoot ?? process.cwd(), source);
|
|
252
|
+
}
|
|
253
|
+
function normalizeSandboxRoot(root) {
|
|
254
|
+
const normalized = root.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
255
|
+
if (!normalized.startsWith("/")) {
|
|
256
|
+
throw new Error("workspace manifest targetRoot must be an absolute sandbox path");
|
|
257
|
+
}
|
|
258
|
+
return normalized.length === 0 ? "/" : normalized;
|
|
259
|
+
}
|
|
260
|
+
function joinSandboxPath(root, path) {
|
|
261
|
+
const normalizedRoot = normalizeSandboxRoot(root);
|
|
262
|
+
if (normalizedRoot === "/") {
|
|
263
|
+
return `/${path}`;
|
|
264
|
+
}
|
|
265
|
+
return `${normalizedRoot}/${path}`;
|
|
266
|
+
}
|
|
267
|
+
function quoteShellArg(value) {
|
|
268
|
+
return `'${value.replace(SHELL_QUOTE_PATTERN, "'\\''")}'`;
|
|
269
|
+
}
|
|
270
|
+
function assertUnreachable(value) {
|
|
271
|
+
throw new Error(`unsupported workspace manifest entry: ${JSON.stringify(value)}`);
|
|
272
|
+
}
|
|
4
273
|
var ToolRegistry = class {
|
|
5
274
|
tools = /* @__PURE__ */ new Map();
|
|
6
275
|
/**
|
|
@@ -140,9 +409,6 @@ var ToolRegistry = class {
|
|
|
140
409
|
}
|
|
141
410
|
};
|
|
142
411
|
|
|
143
|
-
// src/implementations/function-tool.ts
|
|
144
|
-
import { ToolExecutionError, ValidationError as ValidationError2 } from "@robota-sdk/agent-core";
|
|
145
|
-
|
|
146
412
|
// src/implementations/function-tool/schema-converter.ts
|
|
147
413
|
function zodToJsonSchema(schema, options = {}) {
|
|
148
414
|
const properties = {};
|
|
@@ -376,14 +642,14 @@ var FunctionTool = class {
|
|
|
376
642
|
this.schema.parameters.properties || {},
|
|
377
643
|
this.schema.parameters.additionalProperties
|
|
378
644
|
);
|
|
379
|
-
throw new
|
|
645
|
+
throw new ValidationError(`Invalid parameters for tool "${toolName}": ${errors.join(", ")}`);
|
|
380
646
|
}
|
|
381
647
|
const startTime = Date.now();
|
|
382
648
|
let result;
|
|
383
649
|
try {
|
|
384
650
|
result = await this.fn(parameters, context);
|
|
385
651
|
} catch (error) {
|
|
386
|
-
if (error instanceof ToolExecutionError || error instanceof
|
|
652
|
+
if (error instanceof ToolExecutionError || error instanceof ValidationError) {
|
|
387
653
|
throw error;
|
|
388
654
|
}
|
|
389
655
|
throw new ToolExecutionError(
|
|
@@ -440,13 +706,13 @@ var FunctionTool = class {
|
|
|
440
706
|
*/
|
|
441
707
|
validateConstructorInputs() {
|
|
442
708
|
if (!this.schema) {
|
|
443
|
-
throw new
|
|
709
|
+
throw new ValidationError("Tool schema is required");
|
|
444
710
|
}
|
|
445
711
|
if (!this.fn || typeof this.fn !== "function") {
|
|
446
|
-
throw new
|
|
712
|
+
throw new ValidationError("Tool function is required and must be a function");
|
|
447
713
|
}
|
|
448
714
|
if (!this.schema.name) {
|
|
449
|
-
throw new
|
|
715
|
+
throw new ValidationError("Tool schema must have a name");
|
|
450
716
|
}
|
|
451
717
|
}
|
|
452
718
|
};
|
|
@@ -468,7 +734,7 @@ function createZodFunctionTool(name, description, zodSchema, fn) {
|
|
|
468
734
|
const wrappedFn = async (parameters2, context) => {
|
|
469
735
|
const parseResult = zodSchema.safeParse(parameters2);
|
|
470
736
|
if (!parseResult.success) {
|
|
471
|
-
throw new
|
|
737
|
+
throw new ValidationError(`Zod validation failed: ${parseResult.error}`);
|
|
472
738
|
}
|
|
473
739
|
const result = await fn(parseResult.data || parameters2, context);
|
|
474
740
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
@@ -476,9 +742,6 @@ function createZodFunctionTool(name, description, zodSchema, fn) {
|
|
|
476
742
|
return new FunctionTool(schema, wrappedFn);
|
|
477
743
|
}
|
|
478
744
|
|
|
479
|
-
// src/implementations/openapi-tool.ts
|
|
480
|
-
import { ToolExecutionError as ToolExecutionError2, ValidationError as ValidationError3 } from "@robota-sdk/agent-core";
|
|
481
|
-
|
|
482
745
|
// src/implementations/openapi-schema-converter.ts
|
|
483
746
|
var HTTP_METHODS = [
|
|
484
747
|
"get",
|
|
@@ -630,7 +893,7 @@ var OpenAPITool = class {
|
|
|
630
893
|
const toolName = this.schema.name;
|
|
631
894
|
const validation = this.validateParameters(parameters);
|
|
632
895
|
if (!validation.isValid) {
|
|
633
|
-
throw new
|
|
896
|
+
throw new ValidationError(
|
|
634
897
|
`Invalid parameters for OpenAPI tool "${toolName}": ${validation.errors.join(", ")}`
|
|
635
898
|
);
|
|
636
899
|
}
|
|
@@ -649,11 +912,11 @@ var OpenAPITool = class {
|
|
|
649
912
|
}
|
|
650
913
|
};
|
|
651
914
|
} catch (error) {
|
|
652
|
-
if (error instanceof
|
|
915
|
+
if (error instanceof ToolExecutionError || error instanceof ValidationError) {
|
|
653
916
|
throw error;
|
|
654
917
|
}
|
|
655
918
|
const safeError = error instanceof Error ? error : new Error(String(error));
|
|
656
|
-
throw new
|
|
919
|
+
throw new ToolExecutionError(
|
|
657
920
|
`OpenAPI tool execution failed: ${safeError.message}`,
|
|
658
921
|
toolName,
|
|
659
922
|
safeError,
|
|
@@ -800,19 +1063,39 @@ var OpenAPITool = class {
|
|
|
800
1063
|
function createOpenAPITool(config) {
|
|
801
1064
|
return new OpenAPITool(config);
|
|
802
1065
|
}
|
|
803
|
-
|
|
804
|
-
// src/builtins/bash-tool.ts
|
|
805
|
-
import { spawn } from "child_process";
|
|
806
|
-
import { z } from "zod";
|
|
807
1066
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
808
1067
|
var BashSchema = z.object({
|
|
809
1068
|
command: z.string().describe("The bash command to execute"),
|
|
810
1069
|
timeout: z.number().optional().describe("Optional timeout in milliseconds (max 600000). Default is 120000 (2 minutes)"),
|
|
811
1070
|
workingDirectory: z.string().optional().describe("Working directory for the command. Defaults to the current working directory")
|
|
812
1071
|
});
|
|
813
|
-
async function runBash(args) {
|
|
1072
|
+
async function runBash(args, options = {}) {
|
|
814
1073
|
const { command, timeout = DEFAULT_TIMEOUT_MS, workingDirectory } = args;
|
|
815
|
-
|
|
1074
|
+
if (options.sandboxClient) {
|
|
1075
|
+
try {
|
|
1076
|
+
const sandboxResult = await options.sandboxClient.run(command, {
|
|
1077
|
+
timeoutMs: timeout,
|
|
1078
|
+
workingDirectory
|
|
1079
|
+
});
|
|
1080
|
+
const output = sandboxResult.stderr ? `${sandboxResult.stdout}
|
|
1081
|
+
stderr:
|
|
1082
|
+
${sandboxResult.stderr}` : sandboxResult.stdout;
|
|
1083
|
+
const result = {
|
|
1084
|
+
success: true,
|
|
1085
|
+
output,
|
|
1086
|
+
exitCode: sandboxResult.exitCode
|
|
1087
|
+
};
|
|
1088
|
+
return JSON.stringify(result);
|
|
1089
|
+
} catch (err) {
|
|
1090
|
+
const result = {
|
|
1091
|
+
success: false,
|
|
1092
|
+
output: "",
|
|
1093
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1094
|
+
};
|
|
1095
|
+
return JSON.stringify(result);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return new Promise((resolve4) => {
|
|
816
1099
|
const stdoutChunks = [];
|
|
817
1100
|
const stderrChunks = [];
|
|
818
1101
|
let timedOut = false;
|
|
@@ -841,7 +1124,7 @@ async function runBash(args) {
|
|
|
841
1124
|
if (settled) return;
|
|
842
1125
|
settled = true;
|
|
843
1126
|
clearTimeout(timer);
|
|
844
|
-
|
|
1127
|
+
resolve4(JSON.stringify(result));
|
|
845
1128
|
}
|
|
846
1129
|
child.on("error", (err) => {
|
|
847
1130
|
settle({
|
|
@@ -874,25 +1157,24 @@ ${stderr}` : stdout;
|
|
|
874
1157
|
});
|
|
875
1158
|
});
|
|
876
1159
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
import { z as z2 } from "zod";
|
|
1160
|
+
function createBashTool(options = {}) {
|
|
1161
|
+
return createZodFunctionTool(
|
|
1162
|
+
"Bash",
|
|
1163
|
+
"Executes a given bash command and returns its output.\n\nThe working directory persists between commands, but shell state does not.\n\nIMPORTANT: Avoid using this tool to run `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands. Instead, use the appropriate dedicated tool:\n - File search: Use Glob (NOT find or ls)\n - Content search: Use Grep (NOT grep or rg)\n - Read files: Use Read (NOT cat/head/tail)\n - Edit files: Use Edit (NOT sed/awk)\n\nFor simple commands, keep the description brief (5-10 words). For complex commands, include enough context to clarify what the command does.\n\nOutput is limited to 30,000 characters. Longer output will be middle-truncated.",
|
|
1164
|
+
BashSchema,
|
|
1165
|
+
async (params) => {
|
|
1166
|
+
return runBash(params, options);
|
|
1167
|
+
}
|
|
1168
|
+
);
|
|
1169
|
+
}
|
|
1170
|
+
var bashTool = createBashTool();
|
|
889
1171
|
var DEFAULT_LIMIT = 2e3;
|
|
890
|
-
var ReadSchema =
|
|
891
|
-
filePath:
|
|
892
|
-
offset:
|
|
1172
|
+
var ReadSchema = z.object({
|
|
1173
|
+
filePath: z.string().describe("The absolute path to the file to read"),
|
|
1174
|
+
offset: z.number().optional().describe(
|
|
893
1175
|
"The line number to start reading from (1-based). Only provide if the file is too large to read at once"
|
|
894
1176
|
),
|
|
895
|
-
limit:
|
|
1177
|
+
limit: z.number().optional().describe(
|
|
896
1178
|
`The number of lines to read (default: ${DEFAULT_LIMIT}). Only provide if the file is too large to read at once`
|
|
897
1179
|
)
|
|
898
1180
|
});
|
|
@@ -911,82 +1193,93 @@ function formatWithLineNumbers(lines, startLine) {
|
|
|
911
1193
|
return `${lineNum} ${line}`;
|
|
912
1194
|
}).join("\n");
|
|
913
1195
|
}
|
|
914
|
-
|
|
1196
|
+
function formatReadResult(filePath, content, startLine, limit) {
|
|
1197
|
+
const allLines = content.split("\n");
|
|
1198
|
+
if (allLines[allLines.length - 1] === "") {
|
|
1199
|
+
allLines.pop();
|
|
1200
|
+
}
|
|
1201
|
+
const zeroBasedStart = startLine - 1;
|
|
1202
|
+
const selectedLines = allLines.slice(zeroBasedStart, zeroBasedStart + limit);
|
|
1203
|
+
const output = formatWithLineNumbers(selectedLines, startLine);
|
|
1204
|
+
const totalLines = allLines.length;
|
|
1205
|
+
const returnedLines = selectedLines.length;
|
|
1206
|
+
const header = returnedLines < totalLines ? `[File: ${filePath} (lines ${startLine}-${startLine + returnedLines - 1} of ${totalLines})]
|
|
1207
|
+
` : `[File: ${filePath} (${totalLines} lines)]
|
|
1208
|
+
`;
|
|
1209
|
+
const result = {
|
|
1210
|
+
success: true,
|
|
1211
|
+
output: header + output
|
|
1212
|
+
};
|
|
1213
|
+
return JSON.stringify(result);
|
|
1214
|
+
}
|
|
1215
|
+
async function readFileTool(args, options = {}) {
|
|
915
1216
|
const { filePath, offset, limit = DEFAULT_LIMIT } = args;
|
|
916
1217
|
const startLine = offset !== void 0 && offset > 0 ? offset : 1;
|
|
1218
|
+
if (options.sandboxClient) {
|
|
1219
|
+
try {
|
|
1220
|
+
const content2 = await options.sandboxClient.readFile(filePath);
|
|
1221
|
+
return formatReadResult(filePath, content2, startLine, limit);
|
|
1222
|
+
} catch (err) {
|
|
1223
|
+
const result = {
|
|
1224
|
+
success: false,
|
|
1225
|
+
output: "",
|
|
1226
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1227
|
+
};
|
|
1228
|
+
return JSON.stringify(result);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
917
1231
|
let fileStats;
|
|
918
1232
|
try {
|
|
919
1233
|
fileStats = await stat(filePath);
|
|
920
1234
|
} catch (err) {
|
|
921
|
-
const
|
|
1235
|
+
const result = {
|
|
922
1236
|
success: false,
|
|
923
1237
|
output: "",
|
|
924
1238
|
error: `File not found: ${filePath}`
|
|
925
1239
|
};
|
|
926
|
-
return JSON.stringify(
|
|
1240
|
+
return JSON.stringify(result);
|
|
927
1241
|
}
|
|
928
1242
|
if (!fileStats.isFile()) {
|
|
929
|
-
const
|
|
1243
|
+
const result = {
|
|
930
1244
|
success: false,
|
|
931
1245
|
output: "",
|
|
932
1246
|
error: `Path is not a file: ${filePath}`
|
|
933
1247
|
};
|
|
934
|
-
return JSON.stringify(
|
|
1248
|
+
return JSON.stringify(result);
|
|
935
1249
|
}
|
|
936
1250
|
let buffer;
|
|
937
1251
|
try {
|
|
938
1252
|
buffer = await readFile(filePath);
|
|
939
1253
|
} catch (err) {
|
|
940
|
-
const
|
|
1254
|
+
const result = {
|
|
941
1255
|
success: false,
|
|
942
1256
|
output: "",
|
|
943
1257
|
error: err instanceof Error ? err.message : String(err)
|
|
944
1258
|
};
|
|
945
|
-
return JSON.stringify(
|
|
1259
|
+
return JSON.stringify(result);
|
|
946
1260
|
}
|
|
947
1261
|
if (isBinary(buffer)) {
|
|
948
|
-
const
|
|
1262
|
+
const result = {
|
|
949
1263
|
success: false,
|
|
950
1264
|
output: "",
|
|
951
1265
|
error: `Binary file not supported: ${filePath}`
|
|
952
1266
|
};
|
|
953
|
-
return JSON.stringify(
|
|
1267
|
+
return JSON.stringify(result);
|
|
954
1268
|
}
|
|
955
1269
|
const content = buffer.toString("utf8");
|
|
956
|
-
|
|
957
|
-
if (allLines[allLines.length - 1] === "") {
|
|
958
|
-
allLines.pop();
|
|
959
|
-
}
|
|
960
|
-
const zeroBasedStart = startLine - 1;
|
|
961
|
-
const selectedLines = allLines.slice(zeroBasedStart, zeroBasedStart + limit);
|
|
962
|
-
const output = formatWithLineNumbers(selectedLines, startLine);
|
|
963
|
-
const totalLines = allLines.length;
|
|
964
|
-
const returnedLines = selectedLines.length;
|
|
965
|
-
const header = returnedLines < totalLines ? `[File: ${filePath} (lines ${startLine}-${startLine + returnedLines - 1} of ${totalLines})]
|
|
966
|
-
` : `[File: ${filePath} (${totalLines} lines)]
|
|
967
|
-
`;
|
|
968
|
-
const result = {
|
|
969
|
-
success: true,
|
|
970
|
-
output: header + output
|
|
971
|
-
};
|
|
972
|
-
return JSON.stringify(result);
|
|
1270
|
+
return formatReadResult(filePath, content, startLine, limit);
|
|
973
1271
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
// src/builtins/atomic-file-write.ts
|
|
987
|
-
import { randomBytes } from "crypto";
|
|
988
|
-
import { chmod, mkdir, rename, rm, stat as stat2, writeFile } from "fs/promises";
|
|
989
|
-
import { basename, dirname, join } from "path";
|
|
1272
|
+
function createReadTool(options = {}) {
|
|
1273
|
+
return createZodFunctionTool(
|
|
1274
|
+
"Read",
|
|
1275
|
+
"Reads a file from the local filesystem.\n\nBy default, reads up to 2000 lines from the beginning of the file. You can optionally specify offset and limit for partial reads.\n\nResults are returned using cat -n format, with line numbers starting at 1.\n\nThe file_path parameter must be an absolute path, not a relative path.",
|
|
1276
|
+
ReadSchema,
|
|
1277
|
+
async (params) => {
|
|
1278
|
+
return readFileTool(params, options);
|
|
1279
|
+
}
|
|
1280
|
+
);
|
|
1281
|
+
}
|
|
1282
|
+
var readTool = createReadTool();
|
|
990
1283
|
var TEMP_RANDOM_BYTES = 6;
|
|
991
1284
|
var PRESERVED_MODE_BITS = 4095;
|
|
992
1285
|
var MISSING_FILE_ERROR_CODE = "ENOENT";
|
|
@@ -998,7 +1291,7 @@ function createTempFilePath(filePath) {
|
|
|
998
1291
|
}
|
|
999
1292
|
async function readExistingMode(filePath) {
|
|
1000
1293
|
try {
|
|
1001
|
-
const fileStats = await
|
|
1294
|
+
const fileStats = await stat(filePath);
|
|
1002
1295
|
return fileStats.mode & PRESERVED_MODE_BITS;
|
|
1003
1296
|
} catch (error) {
|
|
1004
1297
|
if (error instanceof Error && hasErrorCode(error, MISSING_FILE_ERROR_CODE)) return void 0;
|
|
@@ -1026,14 +1319,18 @@ async function atomicWriteUtf8File(filePath, content) {
|
|
|
1026
1319
|
}
|
|
1027
1320
|
|
|
1028
1321
|
// src/builtins/write-tool.ts
|
|
1029
|
-
var WriteSchema =
|
|
1030
|
-
filePath:
|
|
1031
|
-
content:
|
|
1322
|
+
var WriteSchema = z.object({
|
|
1323
|
+
filePath: z.string().describe("The absolute path to the file to write"),
|
|
1324
|
+
content: z.string().describe("The content to write to the file")
|
|
1032
1325
|
});
|
|
1033
|
-
async function writeFileTool(args) {
|
|
1326
|
+
async function writeFileTool(args, options = {}) {
|
|
1034
1327
|
const { filePath, content } = args;
|
|
1035
1328
|
try {
|
|
1036
|
-
|
|
1329
|
+
if (options.sandboxClient) {
|
|
1330
|
+
await options.sandboxClient.writeFile(filePath, content);
|
|
1331
|
+
} else {
|
|
1332
|
+
await atomicWriteUtf8File(filePath, content);
|
|
1333
|
+
}
|
|
1037
1334
|
const result = {
|
|
1038
1335
|
success: true,
|
|
1039
1336
|
output: `Written ${Buffer.byteLength(content, "utf8")} bytes to ${filePath}`
|
|
@@ -1048,31 +1345,30 @@ async function writeFileTool(args) {
|
|
|
1048
1345
|
return JSON.stringify(result);
|
|
1049
1346
|
}
|
|
1050
1347
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
replaceAll: z4.boolean().optional().describe(
|
|
1348
|
+
function createWriteTool(options = {}) {
|
|
1349
|
+
return createZodFunctionTool(
|
|
1350
|
+
"Write",
|
|
1351
|
+
"Writes a file to the local filesystem. This will overwrite an existing file if one exists.\n\nALWAYS prefer the Edit tool for modifying existing files \u2014 it only sends the diff. Only use this tool to create new files or for complete rewrites.\n\nNEVER create documentation files (*.md) or README files unless explicitly requested by the user.",
|
|
1352
|
+
WriteSchema,
|
|
1353
|
+
async (params) => {
|
|
1354
|
+
return writeFileTool(params, options);
|
|
1355
|
+
}
|
|
1356
|
+
);
|
|
1357
|
+
}
|
|
1358
|
+
var writeTool = createWriteTool();
|
|
1359
|
+
var EditSchema = z.object({
|
|
1360
|
+
filePath: z.string().describe("The absolute path to the file to modify"),
|
|
1361
|
+
oldString: z.string().describe("The text to replace (must be an exact match of existing content)"),
|
|
1362
|
+
newString: z.string().describe("The text to replace it with (must be different from old_string)"),
|
|
1363
|
+
replaceAll: z.boolean().optional().describe(
|
|
1068
1364
|
"Replace all occurrences of old_string (default: false). Useful for renaming variables"
|
|
1069
1365
|
)
|
|
1070
1366
|
});
|
|
1071
|
-
async function editFileTool(args) {
|
|
1367
|
+
async function editFileTool(args, options = {}) {
|
|
1072
1368
|
const { filePath, oldString, newString, replaceAll = false } = args;
|
|
1073
1369
|
let content;
|
|
1074
1370
|
try {
|
|
1075
|
-
content = await
|
|
1371
|
+
content = options.sandboxClient ? await options.sandboxClient.readFile(filePath) : await readFile(filePath, "utf8");
|
|
1076
1372
|
} catch (err) {
|
|
1077
1373
|
const result2 = {
|
|
1078
1374
|
success: false,
|
|
@@ -1104,7 +1400,11 @@ async function editFileTool(args) {
|
|
|
1104
1400
|
}
|
|
1105
1401
|
const updated = replaceAll ? content.split(oldString).join(newString) : content.slice(0, content.indexOf(oldString)) + newString + content.slice(content.indexOf(oldString) + oldString.length);
|
|
1106
1402
|
try {
|
|
1107
|
-
|
|
1403
|
+
if (options.sandboxClient) {
|
|
1404
|
+
await options.sandboxClient.writeFile(filePath, updated);
|
|
1405
|
+
} else {
|
|
1406
|
+
await atomicWriteUtf8File(filePath, updated);
|
|
1407
|
+
}
|
|
1108
1408
|
} catch (err) {
|
|
1109
1409
|
const result2 = {
|
|
1110
1410
|
success: false,
|
|
@@ -1123,27 +1423,24 @@ async function editFileTool(args) {
|
|
|
1123
1423
|
};
|
|
1124
1424
|
return JSON.stringify(result);
|
|
1125
1425
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
import { resolve } from "path";
|
|
1138
|
-
import fg from "fast-glob";
|
|
1139
|
-
import { z as z5 } from "zod";
|
|
1426
|
+
function createEditTool(options = {}) {
|
|
1427
|
+
return createZodFunctionTool(
|
|
1428
|
+
"Edit",
|
|
1429
|
+
"Performs exact string replacements in files.\n\nYou must use the Read tool at least once before editing. When editing text from Read output, preserve the exact indentation.\n\nThe edit will FAIL if old_string is not unique in the file. Either provide more surrounding context to make it unique, or use replace_all to change every instance.\n\nALWAYS prefer editing existing files over creating new ones.",
|
|
1430
|
+
EditSchema,
|
|
1431
|
+
async (params) => {
|
|
1432
|
+
return editFileTool(params, options);
|
|
1433
|
+
}
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
var editTool = createEditTool();
|
|
1140
1437
|
var DEFAULT_MAX_RESULTS = 1e3;
|
|
1141
|
-
var GlobSchema =
|
|
1142
|
-
pattern:
|
|
1143
|
-
path:
|
|
1438
|
+
var GlobSchema = z.object({
|
|
1439
|
+
pattern: z.string().describe('The glob pattern to match files against (e.g. "**/*.ts", "src/**/*.tsx")'),
|
|
1440
|
+
path: z.string().optional().describe(
|
|
1144
1441
|
"The directory to search in. Defaults to the current working directory. Must be a valid directory path if provided"
|
|
1145
1442
|
),
|
|
1146
|
-
limit:
|
|
1443
|
+
limit: z.number().optional().describe(
|
|
1147
1444
|
"Maximum number of results to return (default: 1000). Use a smaller limit to save context space"
|
|
1148
1445
|
)
|
|
1149
1446
|
});
|
|
@@ -1170,7 +1467,7 @@ async function globFileTool(args) {
|
|
|
1170
1467
|
matches.map(async (p) => {
|
|
1171
1468
|
const absPath = resolve(cwd, p);
|
|
1172
1469
|
try {
|
|
1173
|
-
const s = await
|
|
1470
|
+
const s = await stat(absPath);
|
|
1174
1471
|
return { path: p, mtime: s.mtimeMs };
|
|
1175
1472
|
} catch {
|
|
1176
1473
|
return { path: p, mtime: 0 };
|
|
@@ -1203,21 +1500,16 @@ var globTool = createZodFunctionTool(
|
|
|
1203
1500
|
return globFileTool(params);
|
|
1204
1501
|
}
|
|
1205
1502
|
);
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
import { z as z6 } from "zod";
|
|
1211
|
-
var GrepSchema = z6.object({
|
|
1212
|
-
pattern: z6.string().describe("The regular expression pattern to search for in file contents"),
|
|
1213
|
-
path: z6.string().optional().describe("File or directory to search in. Defaults to the current working directory"),
|
|
1214
|
-
glob: z6.string().optional().describe(
|
|
1503
|
+
var GrepSchema = z.object({
|
|
1504
|
+
pattern: z.string().describe("The regular expression pattern to search for in file contents"),
|
|
1505
|
+
path: z.string().optional().describe("File or directory to search in. Defaults to the current working directory"),
|
|
1506
|
+
glob: z.string().optional().describe(
|
|
1215
1507
|
'Glob pattern to filter files (e.g. "*.ts", "*.{ts,tsx}"). Only files matching this pattern will be searched'
|
|
1216
1508
|
),
|
|
1217
|
-
contextLines:
|
|
1509
|
+
contextLines: z.number().optional().describe(
|
|
1218
1510
|
'Number of context lines to show before and after each match. Only applies when outputMode is "content". Default: 0'
|
|
1219
1511
|
),
|
|
1220
|
-
outputMode:
|
|
1512
|
+
outputMode: z.enum(["files_with_matches", "content"]).optional().describe(
|
|
1221
1513
|
'Output mode: "files_with_matches" shows only file paths (default), "content" shows matching lines with context'
|
|
1222
1514
|
)
|
|
1223
1515
|
});
|
|
@@ -1240,10 +1532,10 @@ async function collectFiles(dirPath, glob) {
|
|
|
1240
1532
|
}
|
|
1241
1533
|
for (const name of entryNames) {
|
|
1242
1534
|
if (name === "node_modules" || name === ".git") continue;
|
|
1243
|
-
const fullPath =
|
|
1535
|
+
const fullPath = join(current, name);
|
|
1244
1536
|
let fileStat;
|
|
1245
1537
|
try {
|
|
1246
|
-
fileStat = await
|
|
1538
|
+
fileStat = await stat(fullPath);
|
|
1247
1539
|
} catch {
|
|
1248
1540
|
continue;
|
|
1249
1541
|
}
|
|
@@ -1299,7 +1591,7 @@ async function grepFileTool(args) {
|
|
|
1299
1591
|
contextLines = 0,
|
|
1300
1592
|
outputMode = "files_with_matches"
|
|
1301
1593
|
} = args;
|
|
1302
|
-
const targetPath = searchPath ?
|
|
1594
|
+
const targetPath = searchPath ? resolve(searchPath) : process.cwd();
|
|
1303
1595
|
let regex;
|
|
1304
1596
|
try {
|
|
1305
1597
|
regex = new RegExp(pattern);
|
|
@@ -1313,7 +1605,7 @@ async function grepFileTool(args) {
|
|
|
1313
1605
|
}
|
|
1314
1606
|
let targetStat;
|
|
1315
1607
|
try {
|
|
1316
|
-
targetStat = await
|
|
1608
|
+
targetStat = await stat(targetPath);
|
|
1317
1609
|
} catch {
|
|
1318
1610
|
const result2 = {
|
|
1319
1611
|
success: false,
|
|
@@ -1332,7 +1624,7 @@ async function grepFileTool(args) {
|
|
|
1332
1624
|
for (const filePath of files) {
|
|
1333
1625
|
let content;
|
|
1334
1626
|
try {
|
|
1335
|
-
const buffer = await
|
|
1627
|
+
const buffer = await readFile(filePath);
|
|
1336
1628
|
const checkLen = Math.min(buffer.length, 8192);
|
|
1337
1629
|
let hasBinary = false;
|
|
1338
1630
|
for (let i = 0; i < checkLen; i++) {
|
|
@@ -1363,14 +1655,11 @@ var grepTool = createZodFunctionTool(
|
|
|
1363
1655
|
return grepFileTool(params);
|
|
1364
1656
|
}
|
|
1365
1657
|
);
|
|
1366
|
-
|
|
1367
|
-
// src/builtins/web-fetch-tool.ts
|
|
1368
|
-
import { z as z7 } from "zod";
|
|
1369
1658
|
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
1370
1659
|
var MAX_RESPONSE_BYTES = 5e6;
|
|
1371
|
-
var WebFetchSchema =
|
|
1372
|
-
url:
|
|
1373
|
-
headers:
|
|
1660
|
+
var WebFetchSchema = z.object({
|
|
1661
|
+
url: z.string().describe("The URL to fetch"),
|
|
1662
|
+
headers: z.record(z.string()).optional().describe("Optional HTTP headers as key-value pairs")
|
|
1374
1663
|
});
|
|
1375
1664
|
function htmlToText(html) {
|
|
1376
1665
|
return html.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -1431,14 +1720,11 @@ var webFetchTool = createZodFunctionTool(
|
|
|
1431
1720
|
WebFetchSchema,
|
|
1432
1721
|
async (params) => runWebFetch(params)
|
|
1433
1722
|
);
|
|
1434
|
-
|
|
1435
|
-
// src/builtins/web-search-tool.ts
|
|
1436
|
-
import { z as z8 } from "zod";
|
|
1437
1723
|
var DEFAULT_LIMIT2 = 10;
|
|
1438
1724
|
var DEFAULT_TIMEOUT_MS3 = 15e3;
|
|
1439
|
-
var WebSearchSchema =
|
|
1440
|
-
query:
|
|
1441
|
-
limit:
|
|
1725
|
+
var WebSearchSchema = z.object({
|
|
1726
|
+
query: z.string().describe("The search query"),
|
|
1727
|
+
limit: z.number().optional().describe(`Maximum number of results to return (default: ${DEFAULT_LIMIT2})`)
|
|
1442
1728
|
});
|
|
1443
1729
|
async function runWebSearch(args) {
|
|
1444
1730
|
const { query, limit = DEFAULT_LIMIT2 } = args;
|
|
@@ -1495,20 +1781,5 @@ var webSearchTool = createZodFunctionTool(
|
|
|
1495
1781
|
WebSearchSchema,
|
|
1496
1782
|
async (params) => runWebSearch(params)
|
|
1497
1783
|
);
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
OpenAPITool,
|
|
1501
|
-
ToolRegistry,
|
|
1502
|
-
bashTool,
|
|
1503
|
-
createFunctionTool,
|
|
1504
|
-
createOpenAPITool,
|
|
1505
|
-
createZodFunctionTool,
|
|
1506
|
-
editTool,
|
|
1507
|
-
globTool,
|
|
1508
|
-
grepTool,
|
|
1509
|
-
readTool,
|
|
1510
|
-
webFetchTool,
|
|
1511
|
-
webSearchTool,
|
|
1512
|
-
writeTool,
|
|
1513
|
-
zodToJsonSchema
|
|
1514
|
-
};
|
|
1784
|
+
|
|
1785
|
+
export { E2BSandboxClient, FunctionTool, InMemorySandboxClient, OpenAPITool, ToolRegistry, applyWorkspaceManifest, bashTool, createBashTool, createEditTool, createFunctionTool, createOpenAPITool, createReadTool, createWriteTool, createZodFunctionTool, editTool, globTool, grepTool, readTool, validateWorkspaceManifestPath, webFetchTool, webSearchTool, writeTool, zodToJsonSchema };
|