@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.
@@ -1,56 +1,281 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
1
+ 'use strict';
2
+
3
+ var promises = require('fs/promises');
4
+ var path = require('path');
5
+ var agentCore = require('@robota-sdk/agent-core');
6
+ var child_process = require('child_process');
7
+ var zod = require('zod');
8
+ var crypto = require('crypto');
9
+ var fg = require('fast-glob');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var fg__default = /*#__PURE__*/_interopDefault(fg);
14
+
15
+ // src/sandbox/e2b-sandbox-client.ts
16
+ var E2BSandboxClient = class {
17
+ sandbox;
18
+ connectSandbox;
19
+ createSandboxFromSnapshot;
20
+ constructor(options) {
21
+ this.sandbox = options.sandbox;
22
+ this.connectSandbox = options.connectSandbox;
23
+ this.createSandboxFromSnapshot = options.createSandboxFromSnapshot;
24
+ }
25
+ async run(command, options) {
26
+ const result = await this.sandbox.commands.run(command, {
27
+ background: false,
28
+ timeoutMs: options?.timeoutMs,
29
+ cwd: options?.workingDirectory
30
+ });
31
+ return {
32
+ stdout: result.stdout ?? "",
33
+ stderr: result.stderr ?? "",
34
+ exitCode: result.exitCode ?? result.exit_code ?? 0
35
+ };
36
+ }
37
+ async readFile(path) {
38
+ const content = await this.sandbox.files.read(path);
39
+ return typeof content === "string" ? content : Buffer.from(content).toString("utf8");
40
+ }
41
+ async writeFile(path, content) {
42
+ await this.sandbox.files.write(path, content);
43
+ }
44
+ async snapshot() {
45
+ if (this.sandbox.createSnapshot) {
46
+ const snapshot = await this.sandbox.createSnapshot();
47
+ const snapshotId = snapshot.snapshotId ?? snapshot.id;
48
+ if (!snapshotId) {
49
+ throw new Error("E2B createSnapshot() did not return a snapshot id.");
50
+ }
51
+ return snapshotId;
52
+ }
53
+ const sandboxId = this.sandbox.sandboxId;
54
+ if (!sandboxId) {
55
+ throw new Error("E2B sandboxId is required to create a resumable sandbox snapshot.");
56
+ }
57
+ if (!this.sandbox.pause) {
58
+ throw new Error("E2B sandbox adapter does not expose pause().");
59
+ }
60
+ await this.sandbox.pause();
61
+ return sandboxId;
62
+ }
63
+ async restore(snapshotId) {
64
+ if (this.createSandboxFromSnapshot) {
65
+ this.sandbox = await this.createSandboxFromSnapshot(snapshotId);
66
+ return;
67
+ }
68
+ if (this.connectSandbox) {
69
+ this.sandbox = await this.connectSandbox(snapshotId);
70
+ return;
71
+ }
72
+ if (this.sandbox.sandboxId === snapshotId && this.sandbox.connect) {
73
+ this.sandbox = await this.sandbox.connect();
74
+ return;
75
+ }
76
+ throw new Error(
77
+ "E2B sandbox restore requires connectSandbox(snapshotId) or sandbox.connect()."
78
+ );
17
79
  }
18
- return to;
19
80
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
81
 
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- FunctionTool: () => FunctionTool,
34
- OpenAPITool: () => OpenAPITool,
35
- ToolRegistry: () => ToolRegistry,
36
- bashTool: () => bashTool,
37
- createFunctionTool: () => createFunctionTool,
38
- createOpenAPITool: () => createOpenAPITool,
39
- createZodFunctionTool: () => createZodFunctionTool,
40
- editTool: () => editTool,
41
- globTool: () => globTool,
42
- grepTool: () => grepTool,
43
- readTool: () => readTool,
44
- webFetchTool: () => webFetchTool,
45
- webSearchTool: () => webSearchTool,
46
- writeTool: () => writeTool,
47
- zodToJsonSchema: () => zodToJsonSchema
48
- });
49
- module.exports = __toCommonJS(index_exports);
50
-
51
- // src/registry/tool-registry.ts
52
- var import_agent_core = require("@robota-sdk/agent-core");
53
- var import_agent_core2 = require("@robota-sdk/agent-core");
82
+ // src/sandbox/in-memory-sandbox-client.ts
83
+ var InMemorySandboxClient = class {
84
+ files = /* @__PURE__ */ new Map();
85
+ snapshots = /* @__PURE__ */ new Map();
86
+ runHandler;
87
+ snapshotSequence = 0;
88
+ constructor(options = {}) {
89
+ for (const [path, content] of Object.entries(options.files ?? {})) {
90
+ this.files.set(path, content);
91
+ }
92
+ this.runHandler = options.runHandler;
93
+ }
94
+ async run(command, options) {
95
+ if (this.runHandler) {
96
+ return this.runHandler(command, options, this.files);
97
+ }
98
+ return { stdout: "", stderr: "", exitCode: 0 };
99
+ }
100
+ async readFile(path) {
101
+ const content = this.files.get(path);
102
+ if (content === void 0) {
103
+ throw new Error(`Sandbox file not found: ${path}`);
104
+ }
105
+ return content;
106
+ }
107
+ async writeFile(path, content) {
108
+ this.files.set(path, content);
109
+ }
110
+ async snapshot() {
111
+ const snapshotId = `snapshot-${++this.snapshotSequence}`;
112
+ this.snapshots.set(snapshotId, new Map(this.files));
113
+ return snapshotId;
114
+ }
115
+ async restore(snapshotId) {
116
+ const snapshot = this.snapshots.get(snapshotId);
117
+ if (!snapshot) {
118
+ throw new Error(`Sandbox snapshot not found: ${snapshotId}`);
119
+ }
120
+ this.files.clear();
121
+ for (const [path, content] of snapshot.entries()) {
122
+ this.files.set(path, content);
123
+ }
124
+ }
125
+ getFile(path) {
126
+ return this.files.get(path);
127
+ }
128
+ };
129
+ var DEFAULT_TARGET_ROOT = "/workspace";
130
+ var WINDOWS_ABSOLUTE_PATH_PATTERN = /^[A-Za-z]:[\\/]/;
131
+ var SHELL_QUOTE_PATTERN = /'/g;
132
+ async function applyWorkspaceManifest(sandboxClient, manifest, options = {}) {
133
+ if (sandboxClient.applyManifest) {
134
+ return sandboxClient.applyManifest(manifest, options);
135
+ }
136
+ const targetRoot = normalizeSandboxRoot(options.targetRoot ?? DEFAULT_TARGET_ROOT);
137
+ const appliedEntries = [];
138
+ for (const [rawPath, entry] of Object.entries(manifest.entries)) {
139
+ const path = validateWorkspaceManifestPath(rawPath);
140
+ const targetPath = joinSandboxPath(targetRoot, path);
141
+ appliedEntries.push(
142
+ await applyManifestEntry(sandboxClient, path, targetPath, targetRoot, entry, options)
143
+ );
144
+ }
145
+ return { entries: appliedEntries };
146
+ }
147
+ function validateWorkspaceManifestPath(path) {
148
+ if (path.length === 0) {
149
+ throw new Error("workspace manifest path must not be empty");
150
+ }
151
+ if (path.includes("\0")) {
152
+ throw new Error("workspace manifest path must not contain NUL bytes");
153
+ }
154
+ if (path.startsWith("/") || path.startsWith("\\") || WINDOWS_ABSOLUTE_PATH_PATTERN.test(path)) {
155
+ throw new Error("workspace manifest path must be workspace-relative");
156
+ }
157
+ const parts = path.replace(/\\/g, "/").split("/").filter(Boolean);
158
+ if (parts.length === 0) {
159
+ throw new Error("workspace manifest path must not resolve to the workspace root");
160
+ }
161
+ if (parts.some((part) => part === "..")) {
162
+ throw new Error("workspace manifest path cannot contain traversal segments");
163
+ }
164
+ const normalizedParts = parts.filter((part) => part !== ".");
165
+ if (normalizedParts.length === 0) {
166
+ throw new Error("workspace manifest path must not resolve to the workspace root");
167
+ }
168
+ return normalizedParts.join("/");
169
+ }
170
+ async function applyManifestEntry(sandboxClient, path, targetPath, targetRoot, entry, options) {
171
+ switch (entry.type) {
172
+ case "file":
173
+ await writeSandboxFile(sandboxClient, targetPath, targetRoot, entry.content);
174
+ return createAppliedEntry(path, entry.type);
175
+ case "dir":
176
+ await createSandboxDirectory(sandboxClient, targetPath);
177
+ return createAppliedEntry(path, entry.type);
178
+ case "localFile":
179
+ await copyLocalFile(sandboxClient, entry.src, targetPath, targetRoot, options);
180
+ return createAppliedEntry(path, entry.type);
181
+ case "localDir":
182
+ await copyLocalDirectory(sandboxClient, entry.src, targetPath, options);
183
+ return createAppliedEntry(path, entry.type);
184
+ case "gitRepo":
185
+ await cloneGitRepository(sandboxClient, entry, targetPath);
186
+ return createAppliedEntry(path, entry.type);
187
+ case "s3Mount":
188
+ case "gcsMount":
189
+ case "r2Mount":
190
+ case "azureBlobMount":
191
+ return {
192
+ path,
193
+ type: entry.type,
194
+ status: "unsupported",
195
+ message: `${entry.type} requires a provider-specific sandbox adapter.`
196
+ };
197
+ default:
198
+ return assertUnreachable(entry);
199
+ }
200
+ }
201
+ function createAppliedEntry(path, type) {
202
+ return { path, type, status: "applied" };
203
+ }
204
+ async function copyLocalFile(sandboxClient, source, targetPath, targetRoot, options) {
205
+ const hostSourcePath = resolveHostSourcePath(source, options.hostRoot);
206
+ const content = await promises.readFile(hostSourcePath, "utf8");
207
+ await writeSandboxFile(sandboxClient, targetPath, targetRoot, content);
208
+ }
209
+ async function copyLocalDirectory(sandboxClient, source, targetPath, options) {
210
+ const hostSourcePath = resolveHostSourcePath(source, options.hostRoot);
211
+ await copyLocalDirectoryRecursive(sandboxClient, hostSourcePath, targetPath);
212
+ }
213
+ async function copyLocalDirectoryRecursive(sandboxClient, sourcePath, targetPath) {
214
+ await createSandboxDirectory(sandboxClient, targetPath);
215
+ const entries = await promises.readdir(sourcePath, { withFileTypes: true });
216
+ for (const entry of entries) {
217
+ const childSourcePath = path.join(sourcePath, entry.name);
218
+ const childTargetPath = joinSandboxPath(targetPath, entry.name);
219
+ if (entry.isDirectory()) {
220
+ await copyLocalDirectoryRecursive(sandboxClient, childSourcePath, childTargetPath);
221
+ continue;
222
+ }
223
+ if (entry.isFile()) {
224
+ const content = await promises.readFile(childSourcePath, "utf8");
225
+ await sandboxClient.writeFile(childTargetPath, content);
226
+ }
227
+ }
228
+ }
229
+ async function cloneGitRepository(sandboxClient, entry, targetPath) {
230
+ const shallowArgs = entry.shallow === false ? "" : " --depth 1";
231
+ const refArgs = entry.ref ? ` --branch ${quoteShellArg(entry.ref)}` : "";
232
+ await runSandboxCommand(
233
+ sandboxClient,
234
+ `git clone${shallowArgs}${refArgs} ${quoteShellArg(entry.url)} ${quoteShellArg(targetPath)}`
235
+ );
236
+ }
237
+ async function writeSandboxFile(sandboxClient, targetPath, targetRoot, content) {
238
+ const parentPath = path.posix.dirname(targetPath);
239
+ if (parentPath !== targetRoot) {
240
+ await createSandboxDirectory(sandboxClient, parentPath);
241
+ }
242
+ await sandboxClient.writeFile(targetPath, content);
243
+ }
244
+ async function createSandboxDirectory(sandboxClient, targetPath) {
245
+ await runSandboxCommand(sandboxClient, `mkdir -p ${quoteShellArg(targetPath)}`);
246
+ }
247
+ async function runSandboxCommand(sandboxClient, command) {
248
+ const result = await sandboxClient.run(command);
249
+ if (result.exitCode !== 0) {
250
+ throw new Error(
251
+ `workspace manifest command failed: ${command}
252
+ ${result.stderr ?? result.stdout}`
253
+ );
254
+ }
255
+ }
256
+ function resolveHostSourcePath(source, hostRoot) {
257
+ return path.isAbsolute(source) ? path.resolve(source) : path.resolve(hostRoot ?? process.cwd(), source);
258
+ }
259
+ function normalizeSandboxRoot(root) {
260
+ const normalized = root.replace(/\\/g, "/").replace(/\/+$/, "");
261
+ if (!normalized.startsWith("/")) {
262
+ throw new Error("workspace manifest targetRoot must be an absolute sandbox path");
263
+ }
264
+ return normalized.length === 0 ? "/" : normalized;
265
+ }
266
+ function joinSandboxPath(root, path) {
267
+ const normalizedRoot = normalizeSandboxRoot(root);
268
+ if (normalizedRoot === "/") {
269
+ return `/${path}`;
270
+ }
271
+ return `${normalizedRoot}/${path}`;
272
+ }
273
+ function quoteShellArg(value) {
274
+ return `'${value.replace(SHELL_QUOTE_PATTERN, "'\\''")}'`;
275
+ }
276
+ function assertUnreachable(value) {
277
+ throw new Error(`unsupported workspace manifest entry: ${JSON.stringify(value)}`);
278
+ }
54
279
  var ToolRegistry = class {
55
280
  tools = /* @__PURE__ */ new Map();
56
281
  /**
@@ -58,18 +283,18 @@ var ToolRegistry = class {
58
283
  */
59
284
  register(tool) {
60
285
  if (!tool.schema?.name) {
61
- throw new import_agent_core.ValidationError("Tool must have a valid schema with name");
286
+ throw new agentCore.ValidationError("Tool must have a valid schema with name");
62
287
  }
63
288
  const toolName = tool.schema.name;
64
289
  this.validateToolSchema(tool.schema);
65
290
  if (this.tools.has(toolName)) {
66
- import_agent_core2.logger.warn(`Tool "${toolName}" is already registered, overriding`, {
291
+ agentCore.logger.warn(`Tool "${toolName}" is already registered, overriding`, {
67
292
  toolName,
68
293
  existingTool: this.tools.get(toolName)?.constructor.name
69
294
  });
70
295
  }
71
296
  this.tools.set(toolName, tool);
72
- import_agent_core2.logger.debug(`Tool "${toolName}" registered successfully`, {
297
+ agentCore.logger.debug(`Tool "${toolName}" registered successfully`, {
73
298
  toolName,
74
299
  toolType: tool.constructor.name,
75
300
  parameters: Object.keys(tool.schema.parameters?.properties || {})
@@ -80,11 +305,11 @@ var ToolRegistry = class {
80
305
  */
81
306
  unregister(name) {
82
307
  if (!this.tools.has(name)) {
83
- import_agent_core2.logger.warn(`Attempted to unregister non-existent tool "${name}"`);
308
+ agentCore.logger.warn(`Attempted to unregister non-existent tool "${name}"`);
84
309
  return;
85
310
  }
86
311
  this.tools.delete(name);
87
- import_agent_core2.logger.debug(`Tool "${name}" unregistered successfully`);
312
+ agentCore.logger.debug(`Tool "${name}" unregistered successfully`);
88
313
  }
89
314
  /**
90
315
  * Get tool by name
@@ -103,7 +328,7 @@ var ToolRegistry = class {
103
328
  */
104
329
  getSchemas() {
105
330
  const tools = this.getAll();
106
- import_agent_core2.logger.debug("[TOOL-FLOW] ToolRegistry.getSchemas() - Tools before schema extraction", {
331
+ agentCore.logger.debug("[TOOL-FLOW] ToolRegistry.getSchemas() - Tools before schema extraction", {
107
332
  count: tools.length,
108
333
  tools: tools.map((t) => ({
109
334
  name: t.schema?.name ?? "unnamed",
@@ -126,7 +351,7 @@ var ToolRegistry = class {
126
351
  clear() {
127
352
  const toolCount = this.tools.size;
128
353
  this.tools.clear();
129
- import_agent_core2.logger.debug(`Cleared ${toolCount} tools from registry`);
354
+ agentCore.logger.debug(`Cleared ${toolCount} tools from registry`);
130
355
  }
131
356
  /**
132
357
  * Get tool names
@@ -152,26 +377,26 @@ var ToolRegistry = class {
152
377
  */
153
378
  validateToolSchema(schema) {
154
379
  if (!schema.name || typeof schema.name !== "string") {
155
- throw new import_agent_core.ValidationError("Tool schema must have a valid name");
380
+ throw new agentCore.ValidationError("Tool schema must have a valid name");
156
381
  }
157
382
  if (!schema.description || typeof schema.description !== "string") {
158
- throw new import_agent_core.ValidationError("Tool schema must have a description");
383
+ throw new agentCore.ValidationError("Tool schema must have a description");
159
384
  }
160
385
  if (!schema.parameters || typeof schema.parameters !== "object" || schema.parameters === null || Array.isArray(schema.parameters)) {
161
- throw new import_agent_core.ValidationError("Tool schema must have parameters object");
386
+ throw new agentCore.ValidationError("Tool schema must have parameters object");
162
387
  }
163
388
  if (schema.parameters.type !== "object") {
164
- throw new import_agent_core.ValidationError('Tool parameters type must be "object"');
389
+ throw new agentCore.ValidationError('Tool parameters type must be "object"');
165
390
  }
166
391
  if (schema.parameters.properties) {
167
392
  for (const propName of Object.keys(schema.parameters.properties)) {
168
393
  const propSchema = schema.parameters.properties[propName];
169
394
  if (!propSchema?.type) {
170
- throw new import_agent_core.ValidationError(`Parameter "${propName}" must have a type`);
395
+ throw new agentCore.ValidationError(`Parameter "${propName}" must have a type`);
171
396
  }
172
397
  const validTypes = ["string", "number", "boolean", "array", "object"];
173
398
  if (!validTypes.includes(propSchema.type)) {
174
- throw new import_agent_core.ValidationError(
399
+ throw new agentCore.ValidationError(
175
400
  `Parameter "${propName}" has invalid type "${propSchema.type}"`
176
401
  );
177
402
  }
@@ -181,7 +406,7 @@ var ToolRegistry = class {
181
406
  const properties = schema.parameters.properties || {};
182
407
  for (const requiredField of schema.parameters.required) {
183
408
  if (!properties[requiredField]) {
184
- throw new import_agent_core.ValidationError(
409
+ throw new agentCore.ValidationError(
185
410
  `Required parameter "${requiredField}" is not defined in properties`
186
411
  );
187
412
  }
@@ -190,9 +415,6 @@ var ToolRegistry = class {
190
415
  }
191
416
  };
192
417
 
193
- // src/implementations/function-tool.ts
194
- var import_agent_core3 = require("@robota-sdk/agent-core");
195
-
196
418
  // src/implementations/function-tool/schema-converter.ts
197
419
  function zodToJsonSchema(schema, options = {}) {
198
420
  const properties = {};
@@ -426,17 +648,17 @@ var FunctionTool = class {
426
648
  this.schema.parameters.properties || {},
427
649
  this.schema.parameters.additionalProperties
428
650
  );
429
- throw new import_agent_core3.ValidationError(`Invalid parameters for tool "${toolName}": ${errors.join(", ")}`);
651
+ throw new agentCore.ValidationError(`Invalid parameters for tool "${toolName}": ${errors.join(", ")}`);
430
652
  }
431
653
  const startTime = Date.now();
432
654
  let result;
433
655
  try {
434
656
  result = await this.fn(parameters, context);
435
657
  } catch (error) {
436
- if (error instanceof import_agent_core3.ToolExecutionError || error instanceof import_agent_core3.ValidationError) {
658
+ if (error instanceof agentCore.ToolExecutionError || error instanceof agentCore.ValidationError) {
437
659
  throw error;
438
660
  }
439
- throw new import_agent_core3.ToolExecutionError(
661
+ throw new agentCore.ToolExecutionError(
440
662
  `Function tool execution failed: ${error instanceof Error ? error.message : String(error)}`,
441
663
  toolName,
442
664
  error instanceof Error ? error : new Error(String(error)),
@@ -490,13 +712,13 @@ var FunctionTool = class {
490
712
  */
491
713
  validateConstructorInputs() {
492
714
  if (!this.schema) {
493
- throw new import_agent_core3.ValidationError("Tool schema is required");
715
+ throw new agentCore.ValidationError("Tool schema is required");
494
716
  }
495
717
  if (!this.fn || typeof this.fn !== "function") {
496
- throw new import_agent_core3.ValidationError("Tool function is required and must be a function");
718
+ throw new agentCore.ValidationError("Tool function is required and must be a function");
497
719
  }
498
720
  if (!this.schema.name) {
499
- throw new import_agent_core3.ValidationError("Tool schema must have a name");
721
+ throw new agentCore.ValidationError("Tool schema must have a name");
500
722
  }
501
723
  }
502
724
  };
@@ -518,7 +740,7 @@ function createZodFunctionTool(name, description, zodSchema, fn) {
518
740
  const wrappedFn = async (parameters2, context) => {
519
741
  const parseResult = zodSchema.safeParse(parameters2);
520
742
  if (!parseResult.success) {
521
- throw new import_agent_core3.ValidationError(`Zod validation failed: ${parseResult.error}`);
743
+ throw new agentCore.ValidationError(`Zod validation failed: ${parseResult.error}`);
522
744
  }
523
745
  const result = await fn(parseResult.data || parameters2, context);
524
746
  return typeof result === "string" ? result : JSON.stringify(result);
@@ -526,9 +748,6 @@ function createZodFunctionTool(name, description, zodSchema, fn) {
526
748
  return new FunctionTool(schema, wrappedFn);
527
749
  }
528
750
 
529
- // src/implementations/openapi-tool.ts
530
- var import_agent_core4 = require("@robota-sdk/agent-core");
531
-
532
751
  // src/implementations/openapi-schema-converter.ts
533
752
  var HTTP_METHODS = [
534
753
  "get",
@@ -680,7 +899,7 @@ var OpenAPITool = class {
680
899
  const toolName = this.schema.name;
681
900
  const validation = this.validateParameters(parameters);
682
901
  if (!validation.isValid) {
683
- throw new import_agent_core4.ValidationError(
902
+ throw new agentCore.ValidationError(
684
903
  `Invalid parameters for OpenAPI tool "${toolName}": ${validation.errors.join(", ")}`
685
904
  );
686
905
  }
@@ -699,11 +918,11 @@ var OpenAPITool = class {
699
918
  }
700
919
  };
701
920
  } catch (error) {
702
- if (error instanceof import_agent_core4.ToolExecutionError || error instanceof import_agent_core4.ValidationError) {
921
+ if (error instanceof agentCore.ToolExecutionError || error instanceof agentCore.ValidationError) {
703
922
  throw error;
704
923
  }
705
924
  const safeError = error instanceof Error ? error : new Error(String(error));
706
- throw new import_agent_core4.ToolExecutionError(
925
+ throw new agentCore.ToolExecutionError(
707
926
  `OpenAPI tool execution failed: ${safeError.message}`,
708
927
  toolName,
709
928
  safeError,
@@ -850,24 +1069,44 @@ var OpenAPITool = class {
850
1069
  function createOpenAPITool(config) {
851
1070
  return new OpenAPITool(config);
852
1071
  }
853
-
854
- // src/builtins/bash-tool.ts
855
- var import_node_child_process = require("child_process");
856
- var import_zod = require("zod");
857
1072
  var DEFAULT_TIMEOUT_MS = 12e4;
858
- var BashSchema = import_zod.z.object({
859
- command: import_zod.z.string().describe("The bash command to execute"),
860
- timeout: import_zod.z.number().optional().describe("Optional timeout in milliseconds (max 600000). Default is 120000 (2 minutes)"),
861
- workingDirectory: import_zod.z.string().optional().describe("Working directory for the command. Defaults to the current working directory")
1073
+ var BashSchema = zod.z.object({
1074
+ command: zod.z.string().describe("The bash command to execute"),
1075
+ timeout: zod.z.number().optional().describe("Optional timeout in milliseconds (max 600000). Default is 120000 (2 minutes)"),
1076
+ workingDirectory: zod.z.string().optional().describe("Working directory for the command. Defaults to the current working directory")
862
1077
  });
863
- async function runBash(args) {
1078
+ async function runBash(args, options = {}) {
864
1079
  const { command, timeout = DEFAULT_TIMEOUT_MS, workingDirectory } = args;
865
- return new Promise((resolve3) => {
1080
+ if (options.sandboxClient) {
1081
+ try {
1082
+ const sandboxResult = await options.sandboxClient.run(command, {
1083
+ timeoutMs: timeout,
1084
+ workingDirectory
1085
+ });
1086
+ const output = sandboxResult.stderr ? `${sandboxResult.stdout}
1087
+ stderr:
1088
+ ${sandboxResult.stderr}` : sandboxResult.stdout;
1089
+ const result = {
1090
+ success: true,
1091
+ output,
1092
+ exitCode: sandboxResult.exitCode
1093
+ };
1094
+ return JSON.stringify(result);
1095
+ } catch (err) {
1096
+ const result = {
1097
+ success: false,
1098
+ output: "",
1099
+ error: err instanceof Error ? err.message : String(err)
1100
+ };
1101
+ return JSON.stringify(result);
1102
+ }
1103
+ }
1104
+ return new Promise((resolve4) => {
866
1105
  const stdoutChunks = [];
867
1106
  const stderrChunks = [];
868
1107
  let timedOut = false;
869
1108
  let settled = false;
870
- const child = (0, import_node_child_process.spawn)("sh", ["-c", command], {
1109
+ const child = child_process.spawn("sh", ["-c", command], {
871
1110
  cwd: workingDirectory ?? process.cwd(),
872
1111
  env: process.env,
873
1112
  stdio: ["pipe", "pipe", "pipe"]
@@ -891,7 +1130,7 @@ async function runBash(args) {
891
1130
  if (settled) return;
892
1131
  settled = true;
893
1132
  clearTimeout(timer);
894
- resolve3(JSON.stringify(result));
1133
+ resolve4(JSON.stringify(result));
895
1134
  }
896
1135
  child.on("error", (err) => {
897
1136
  settle({
@@ -924,25 +1163,24 @@ ${stderr}` : stdout;
924
1163
  });
925
1164
  });
926
1165
  }
927
- var bashTool = createZodFunctionTool(
928
- "Bash",
929
- "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.",
930
- BashSchema,
931
- async (params) => {
932
- return runBash(params);
933
- }
934
- );
935
-
936
- // src/builtins/read-tool.ts
937
- var import_promises = require("fs/promises");
938
- var import_zod2 = require("zod");
1166
+ function createBashTool(options = {}) {
1167
+ return createZodFunctionTool(
1168
+ "Bash",
1169
+ "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.",
1170
+ BashSchema,
1171
+ async (params) => {
1172
+ return runBash(params, options);
1173
+ }
1174
+ );
1175
+ }
1176
+ var bashTool = createBashTool();
939
1177
  var DEFAULT_LIMIT = 2e3;
940
- var ReadSchema = import_zod2.z.object({
941
- filePath: import_zod2.z.string().describe("The absolute path to the file to read"),
942
- offset: import_zod2.z.number().optional().describe(
1178
+ var ReadSchema = zod.z.object({
1179
+ filePath: zod.z.string().describe("The absolute path to the file to read"),
1180
+ offset: zod.z.number().optional().describe(
943
1181
  "The line number to start reading from (1-based). Only provide if the file is too large to read at once"
944
1182
  ),
945
- limit: import_zod2.z.number().optional().describe(
1183
+ limit: zod.z.number().optional().describe(
946
1184
  `The number of lines to read (default: ${DEFAULT_LIMIT}). Only provide if the file is too large to read at once`
947
1185
  )
948
1186
  });
@@ -961,94 +1199,105 @@ function formatWithLineNumbers(lines, startLine) {
961
1199
  return `${lineNum} ${line}`;
962
1200
  }).join("\n");
963
1201
  }
964
- async function readFileTool(args) {
1202
+ function formatReadResult(filePath, content, startLine, limit) {
1203
+ const allLines = content.split("\n");
1204
+ if (allLines[allLines.length - 1] === "") {
1205
+ allLines.pop();
1206
+ }
1207
+ const zeroBasedStart = startLine - 1;
1208
+ const selectedLines = allLines.slice(zeroBasedStart, zeroBasedStart + limit);
1209
+ const output = formatWithLineNumbers(selectedLines, startLine);
1210
+ const totalLines = allLines.length;
1211
+ const returnedLines = selectedLines.length;
1212
+ const header = returnedLines < totalLines ? `[File: ${filePath} (lines ${startLine}-${startLine + returnedLines - 1} of ${totalLines})]
1213
+ ` : `[File: ${filePath} (${totalLines} lines)]
1214
+ `;
1215
+ const result = {
1216
+ success: true,
1217
+ output: header + output
1218
+ };
1219
+ return JSON.stringify(result);
1220
+ }
1221
+ async function readFileTool(args, options = {}) {
965
1222
  const { filePath, offset, limit = DEFAULT_LIMIT } = args;
966
1223
  const startLine = offset !== void 0 && offset > 0 ? offset : 1;
1224
+ if (options.sandboxClient) {
1225
+ try {
1226
+ const content2 = await options.sandboxClient.readFile(filePath);
1227
+ return formatReadResult(filePath, content2, startLine, limit);
1228
+ } catch (err) {
1229
+ const result = {
1230
+ success: false,
1231
+ output: "",
1232
+ error: err instanceof Error ? err.message : String(err)
1233
+ };
1234
+ return JSON.stringify(result);
1235
+ }
1236
+ }
967
1237
  let fileStats;
968
1238
  try {
969
- fileStats = await (0, import_promises.stat)(filePath);
1239
+ fileStats = await promises.stat(filePath);
970
1240
  } catch (err) {
971
- const result2 = {
1241
+ const result = {
972
1242
  success: false,
973
1243
  output: "",
974
1244
  error: `File not found: ${filePath}`
975
1245
  };
976
- return JSON.stringify(result2);
1246
+ return JSON.stringify(result);
977
1247
  }
978
1248
  if (!fileStats.isFile()) {
979
- const result2 = {
1249
+ const result = {
980
1250
  success: false,
981
1251
  output: "",
982
1252
  error: `Path is not a file: ${filePath}`
983
1253
  };
984
- return JSON.stringify(result2);
1254
+ return JSON.stringify(result);
985
1255
  }
986
1256
  let buffer;
987
1257
  try {
988
- buffer = await (0, import_promises.readFile)(filePath);
1258
+ buffer = await promises.readFile(filePath);
989
1259
  } catch (err) {
990
- const result2 = {
1260
+ const result = {
991
1261
  success: false,
992
1262
  output: "",
993
1263
  error: err instanceof Error ? err.message : String(err)
994
1264
  };
995
- return JSON.stringify(result2);
1265
+ return JSON.stringify(result);
996
1266
  }
997
1267
  if (isBinary(buffer)) {
998
- const result2 = {
1268
+ const result = {
999
1269
  success: false,
1000
1270
  output: "",
1001
1271
  error: `Binary file not supported: ${filePath}`
1002
1272
  };
1003
- return JSON.stringify(result2);
1273
+ return JSON.stringify(result);
1004
1274
  }
1005
1275
  const content = buffer.toString("utf8");
1006
- const allLines = content.split("\n");
1007
- if (allLines[allLines.length - 1] === "") {
1008
- allLines.pop();
1009
- }
1010
- const zeroBasedStart = startLine - 1;
1011
- const selectedLines = allLines.slice(zeroBasedStart, zeroBasedStart + limit);
1012
- const output = formatWithLineNumbers(selectedLines, startLine);
1013
- const totalLines = allLines.length;
1014
- const returnedLines = selectedLines.length;
1015
- const header = returnedLines < totalLines ? `[File: ${filePath} (lines ${startLine}-${startLine + returnedLines - 1} of ${totalLines})]
1016
- ` : `[File: ${filePath} (${totalLines} lines)]
1017
- `;
1018
- const result = {
1019
- success: true,
1020
- output: header + output
1021
- };
1022
- return JSON.stringify(result);
1276
+ return formatReadResult(filePath, content, startLine, limit);
1023
1277
  }
1024
- var readTool = createZodFunctionTool(
1025
- "Read",
1026
- "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.",
1027
- ReadSchema,
1028
- async (params) => {
1029
- return readFileTool(params);
1030
- }
1031
- );
1032
-
1033
- // src/builtins/write-tool.ts
1034
- var import_zod3 = require("zod");
1035
-
1036
- // src/builtins/atomic-file-write.ts
1037
- var import_node_crypto = require("crypto");
1038
- var import_promises2 = require("fs/promises");
1039
- var import_node_path = require("path");
1278
+ function createReadTool(options = {}) {
1279
+ return createZodFunctionTool(
1280
+ "Read",
1281
+ "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.",
1282
+ ReadSchema,
1283
+ async (params) => {
1284
+ return readFileTool(params, options);
1285
+ }
1286
+ );
1287
+ }
1288
+ var readTool = createReadTool();
1040
1289
  var TEMP_RANDOM_BYTES = 6;
1041
1290
  var PRESERVED_MODE_BITS = 4095;
1042
1291
  var MISSING_FILE_ERROR_CODE = "ENOENT";
1043
1292
  function createTempFilePath(filePath) {
1044
- const dir = (0, import_node_path.dirname)(filePath);
1045
- const name = (0, import_node_path.basename)(filePath);
1046
- const suffix = (0, import_node_crypto.randomBytes)(TEMP_RANDOM_BYTES).toString("hex");
1047
- return (0, import_node_path.join)(dir, `.${name}.robota-tmp-${process.pid}-${Date.now()}-${suffix}`);
1293
+ const dir = path.dirname(filePath);
1294
+ const name = path.basename(filePath);
1295
+ const suffix = crypto.randomBytes(TEMP_RANDOM_BYTES).toString("hex");
1296
+ return path.join(dir, `.${name}.robota-tmp-${process.pid}-${Date.now()}-${suffix}`);
1048
1297
  }
1049
1298
  async function readExistingMode(filePath) {
1050
1299
  try {
1051
- const fileStats = await (0, import_promises2.stat)(filePath);
1300
+ const fileStats = await promises.stat(filePath);
1052
1301
  return fileStats.mode & PRESERVED_MODE_BITS;
1053
1302
  } catch (error) {
1054
1303
  if (error instanceof Error && hasErrorCode(error, MISSING_FILE_ERROR_CODE)) return void 0;
@@ -1059,31 +1308,35 @@ function hasErrorCode(error, code) {
1059
1308
  return "code" in error && error.code === code;
1060
1309
  }
1061
1310
  async function atomicWriteUtf8File(filePath, content) {
1062
- const dir = (0, import_node_path.dirname)(filePath);
1063
- await (0, import_promises2.mkdir)(dir, { recursive: true });
1311
+ const dir = path.dirname(filePath);
1312
+ await promises.mkdir(dir, { recursive: true });
1064
1313
  const existingMode = await readExistingMode(filePath);
1065
1314
  const tempFilePath = createTempFilePath(filePath);
1066
1315
  try {
1067
- await (0, import_promises2.writeFile)(tempFilePath, content, "utf8");
1316
+ await promises.writeFile(tempFilePath, content, "utf8");
1068
1317
  if (existingMode !== void 0) {
1069
- await (0, import_promises2.chmod)(tempFilePath, existingMode);
1318
+ await promises.chmod(tempFilePath, existingMode);
1070
1319
  }
1071
- await (0, import_promises2.rename)(tempFilePath, filePath);
1320
+ await promises.rename(tempFilePath, filePath);
1072
1321
  } catch (error) {
1073
- await (0, import_promises2.rm)(tempFilePath, { force: true }).catch(() => void 0);
1322
+ await promises.rm(tempFilePath, { force: true }).catch(() => void 0);
1074
1323
  throw error;
1075
1324
  }
1076
1325
  }
1077
1326
 
1078
1327
  // src/builtins/write-tool.ts
1079
- var WriteSchema = import_zod3.z.object({
1080
- filePath: import_zod3.z.string().describe("The absolute path to the file to write"),
1081
- content: import_zod3.z.string().describe("The content to write to the file")
1328
+ var WriteSchema = zod.z.object({
1329
+ filePath: zod.z.string().describe("The absolute path to the file to write"),
1330
+ content: zod.z.string().describe("The content to write to the file")
1082
1331
  });
1083
- async function writeFileTool(args) {
1332
+ async function writeFileTool(args, options = {}) {
1084
1333
  const { filePath, content } = args;
1085
1334
  try {
1086
- await atomicWriteUtf8File(filePath, content);
1335
+ if (options.sandboxClient) {
1336
+ await options.sandboxClient.writeFile(filePath, content);
1337
+ } else {
1338
+ await atomicWriteUtf8File(filePath, content);
1339
+ }
1087
1340
  const result = {
1088
1341
  success: true,
1089
1342
  output: `Written ${Buffer.byteLength(content, "utf8")} bytes to ${filePath}`
@@ -1098,31 +1351,30 @@ async function writeFileTool(args) {
1098
1351
  return JSON.stringify(result);
1099
1352
  }
1100
1353
  }
1101
- var writeTool = createZodFunctionTool(
1102
- "Write",
1103
- "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.",
1104
- WriteSchema,
1105
- async (params) => {
1106
- return writeFileTool(params);
1107
- }
1108
- );
1109
-
1110
- // src/builtins/edit-tool.ts
1111
- var import_promises3 = require("fs/promises");
1112
- var import_zod4 = require("zod");
1113
- var EditSchema = import_zod4.z.object({
1114
- filePath: import_zod4.z.string().describe("The absolute path to the file to modify"),
1115
- oldString: import_zod4.z.string().describe("The text to replace (must be an exact match of existing content)"),
1116
- newString: import_zod4.z.string().describe("The text to replace it with (must be different from old_string)"),
1117
- replaceAll: import_zod4.z.boolean().optional().describe(
1354
+ function createWriteTool(options = {}) {
1355
+ return createZodFunctionTool(
1356
+ "Write",
1357
+ "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.",
1358
+ WriteSchema,
1359
+ async (params) => {
1360
+ return writeFileTool(params, options);
1361
+ }
1362
+ );
1363
+ }
1364
+ var writeTool = createWriteTool();
1365
+ var EditSchema = zod.z.object({
1366
+ filePath: zod.z.string().describe("The absolute path to the file to modify"),
1367
+ oldString: zod.z.string().describe("The text to replace (must be an exact match of existing content)"),
1368
+ newString: zod.z.string().describe("The text to replace it with (must be different from old_string)"),
1369
+ replaceAll: zod.z.boolean().optional().describe(
1118
1370
  "Replace all occurrences of old_string (default: false). Useful for renaming variables"
1119
1371
  )
1120
1372
  });
1121
- async function editFileTool(args) {
1373
+ async function editFileTool(args, options = {}) {
1122
1374
  const { filePath, oldString, newString, replaceAll = false } = args;
1123
1375
  let content;
1124
1376
  try {
1125
- content = await (0, import_promises3.readFile)(filePath, "utf8");
1377
+ content = options.sandboxClient ? await options.sandboxClient.readFile(filePath) : await promises.readFile(filePath, "utf8");
1126
1378
  } catch (err) {
1127
1379
  const result2 = {
1128
1380
  success: false,
@@ -1154,7 +1406,11 @@ async function editFileTool(args) {
1154
1406
  }
1155
1407
  const updated = replaceAll ? content.split(oldString).join(newString) : content.slice(0, content.indexOf(oldString)) + newString + content.slice(content.indexOf(oldString) + oldString.length);
1156
1408
  try {
1157
- await atomicWriteUtf8File(filePath, updated);
1409
+ if (options.sandboxClient) {
1410
+ await options.sandboxClient.writeFile(filePath, updated);
1411
+ } else {
1412
+ await atomicWriteUtf8File(filePath, updated);
1413
+ }
1158
1414
  } catch (err) {
1159
1415
  const result2 = {
1160
1416
  success: false,
@@ -1173,36 +1429,33 @@ async function editFileTool(args) {
1173
1429
  };
1174
1430
  return JSON.stringify(result);
1175
1431
  }
1176
- var editTool = createZodFunctionTool(
1177
- "Edit",
1178
- "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.",
1179
- EditSchema,
1180
- async (params) => {
1181
- return editFileTool(params);
1182
- }
1183
- );
1184
-
1185
- // src/builtins/glob-tool.ts
1186
- var import_promises4 = require("fs/promises");
1187
- var import_node_path2 = require("path");
1188
- var import_fast_glob = __toESM(require("fast-glob"), 1);
1189
- var import_zod5 = require("zod");
1432
+ function createEditTool(options = {}) {
1433
+ return createZodFunctionTool(
1434
+ "Edit",
1435
+ "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.",
1436
+ EditSchema,
1437
+ async (params) => {
1438
+ return editFileTool(params, options);
1439
+ }
1440
+ );
1441
+ }
1442
+ var editTool = createEditTool();
1190
1443
  var DEFAULT_MAX_RESULTS = 1e3;
1191
- var GlobSchema = import_zod5.z.object({
1192
- pattern: import_zod5.z.string().describe('The glob pattern to match files against (e.g. "**/*.ts", "src/**/*.tsx")'),
1193
- path: import_zod5.z.string().optional().describe(
1444
+ var GlobSchema = zod.z.object({
1445
+ pattern: zod.z.string().describe('The glob pattern to match files against (e.g. "**/*.ts", "src/**/*.tsx")'),
1446
+ path: zod.z.string().optional().describe(
1194
1447
  "The directory to search in. Defaults to the current working directory. Must be a valid directory path if provided"
1195
1448
  ),
1196
- limit: import_zod5.z.number().optional().describe(
1449
+ limit: zod.z.number().optional().describe(
1197
1450
  "Maximum number of results to return (default: 1000). Use a smaller limit to save context space"
1198
1451
  )
1199
1452
  });
1200
1453
  async function globFileTool(args) {
1201
1454
  const { pattern, path: basePath } = args;
1202
- const cwd = basePath ? (0, import_node_path2.resolve)(basePath) : process.cwd();
1455
+ const cwd = basePath ? path.resolve(basePath) : process.cwd();
1203
1456
  let matches;
1204
1457
  try {
1205
- matches = await (0, import_fast_glob.default)(pattern, {
1458
+ matches = await fg__default.default(pattern, {
1206
1459
  cwd,
1207
1460
  ignore: ["**/node_modules/**", "**/.git/**"],
1208
1461
  dot: true,
@@ -1218,9 +1471,9 @@ async function globFileTool(args) {
1218
1471
  }
1219
1472
  const withMtime = await Promise.all(
1220
1473
  matches.map(async (p) => {
1221
- const absPath = (0, import_node_path2.resolve)(cwd, p);
1474
+ const absPath = path.resolve(cwd, p);
1222
1475
  try {
1223
- const s = await (0, import_promises4.stat)(absPath);
1476
+ const s = await promises.stat(absPath);
1224
1477
  return { path: p, mtime: s.mtimeMs };
1225
1478
  } catch {
1226
1479
  return { path: p, mtime: 0 };
@@ -1253,21 +1506,16 @@ var globTool = createZodFunctionTool(
1253
1506
  return globFileTool(params);
1254
1507
  }
1255
1508
  );
1256
-
1257
- // src/builtins/grep-tool.ts
1258
- var import_promises5 = require("fs/promises");
1259
- var import_node_path3 = require("path");
1260
- var import_zod6 = require("zod");
1261
- var GrepSchema = import_zod6.z.object({
1262
- pattern: import_zod6.z.string().describe("The regular expression pattern to search for in file contents"),
1263
- path: import_zod6.z.string().optional().describe("File or directory to search in. Defaults to the current working directory"),
1264
- glob: import_zod6.z.string().optional().describe(
1509
+ var GrepSchema = zod.z.object({
1510
+ pattern: zod.z.string().describe("The regular expression pattern to search for in file contents"),
1511
+ path: zod.z.string().optional().describe("File or directory to search in. Defaults to the current working directory"),
1512
+ glob: zod.z.string().optional().describe(
1265
1513
  'Glob pattern to filter files (e.g. "*.ts", "*.{ts,tsx}"). Only files matching this pattern will be searched'
1266
1514
  ),
1267
- contextLines: import_zod6.z.number().optional().describe(
1515
+ contextLines: zod.z.number().optional().describe(
1268
1516
  'Number of context lines to show before and after each match. Only applies when outputMode is "content". Default: 0'
1269
1517
  ),
1270
- outputMode: import_zod6.z.enum(["files_with_matches", "content"]).optional().describe(
1518
+ outputMode: zod.z.enum(["files_with_matches", "content"]).optional().describe(
1271
1519
  'Output mode: "files_with_matches" shows only file paths (default), "content" shows matching lines with context'
1272
1520
  )
1273
1521
  });
@@ -1284,16 +1532,16 @@ async function collectFiles(dirPath, glob) {
1284
1532
  async function walk(current) {
1285
1533
  let entryNames;
1286
1534
  try {
1287
- entryNames = await (0, import_promises5.readdir)(current);
1535
+ entryNames = await promises.readdir(current);
1288
1536
  } catch {
1289
1537
  return;
1290
1538
  }
1291
1539
  for (const name of entryNames) {
1292
1540
  if (name === "node_modules" || name === ".git") continue;
1293
- const fullPath = (0, import_node_path3.join)(current, name);
1541
+ const fullPath = path.join(current, name);
1294
1542
  let fileStat;
1295
1543
  try {
1296
- fileStat = await (0, import_promises5.stat)(fullPath);
1544
+ fileStat = await promises.stat(fullPath);
1297
1545
  } catch {
1298
1546
  continue;
1299
1547
  }
@@ -1349,7 +1597,7 @@ async function grepFileTool(args) {
1349
1597
  contextLines = 0,
1350
1598
  outputMode = "files_with_matches"
1351
1599
  } = args;
1352
- const targetPath = searchPath ? (0, import_node_path3.resolve)(searchPath) : process.cwd();
1600
+ const targetPath = searchPath ? path.resolve(searchPath) : process.cwd();
1353
1601
  let regex;
1354
1602
  try {
1355
1603
  regex = new RegExp(pattern);
@@ -1363,7 +1611,7 @@ async function grepFileTool(args) {
1363
1611
  }
1364
1612
  let targetStat;
1365
1613
  try {
1366
- targetStat = await (0, import_promises5.stat)(targetPath);
1614
+ targetStat = await promises.stat(targetPath);
1367
1615
  } catch {
1368
1616
  const result2 = {
1369
1617
  success: false,
@@ -1382,7 +1630,7 @@ async function grepFileTool(args) {
1382
1630
  for (const filePath of files) {
1383
1631
  let content;
1384
1632
  try {
1385
- const buffer = await (0, import_promises5.readFile)(filePath);
1633
+ const buffer = await promises.readFile(filePath);
1386
1634
  const checkLen = Math.min(buffer.length, 8192);
1387
1635
  let hasBinary = false;
1388
1636
  for (let i = 0; i < checkLen; i++) {
@@ -1413,14 +1661,11 @@ var grepTool = createZodFunctionTool(
1413
1661
  return grepFileTool(params);
1414
1662
  }
1415
1663
  );
1416
-
1417
- // src/builtins/web-fetch-tool.ts
1418
- var import_zod7 = require("zod");
1419
1664
  var DEFAULT_TIMEOUT_MS2 = 3e4;
1420
1665
  var MAX_RESPONSE_BYTES = 5e6;
1421
- var WebFetchSchema = import_zod7.z.object({
1422
- url: import_zod7.z.string().describe("The URL to fetch"),
1423
- headers: import_zod7.z.record(import_zod7.z.string()).optional().describe("Optional HTTP headers as key-value pairs")
1666
+ var WebFetchSchema = zod.z.object({
1667
+ url: zod.z.string().describe("The URL to fetch"),
1668
+ headers: zod.z.record(zod.z.string()).optional().describe("Optional HTTP headers as key-value pairs")
1424
1669
  });
1425
1670
  function htmlToText(html) {
1426
1671
  return html.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, " ").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ").replace(/\s+/g, " ").trim();
@@ -1481,14 +1726,11 @@ var webFetchTool = createZodFunctionTool(
1481
1726
  WebFetchSchema,
1482
1727
  async (params) => runWebFetch(params)
1483
1728
  );
1484
-
1485
- // src/builtins/web-search-tool.ts
1486
- var import_zod8 = require("zod");
1487
1729
  var DEFAULT_LIMIT2 = 10;
1488
1730
  var DEFAULT_TIMEOUT_MS3 = 15e3;
1489
- var WebSearchSchema = import_zod8.z.object({
1490
- query: import_zod8.z.string().describe("The search query"),
1491
- limit: import_zod8.z.number().optional().describe(`Maximum number of results to return (default: ${DEFAULT_LIMIT2})`)
1731
+ var WebSearchSchema = zod.z.object({
1732
+ query: zod.z.string().describe("The search query"),
1733
+ limit: zod.z.number().optional().describe(`Maximum number of results to return (default: ${DEFAULT_LIMIT2})`)
1492
1734
  });
1493
1735
  async function runWebSearch(args) {
1494
1736
  const { query, limit = DEFAULT_LIMIT2 } = args;
@@ -1545,21 +1787,27 @@ var webSearchTool = createZodFunctionTool(
1545
1787
  WebSearchSchema,
1546
1788
  async (params) => runWebSearch(params)
1547
1789
  );
1548
- // Annotate the CommonJS export names for ESM import in node:
1549
- 0 && (module.exports = {
1550
- FunctionTool,
1551
- OpenAPITool,
1552
- ToolRegistry,
1553
- bashTool,
1554
- createFunctionTool,
1555
- createOpenAPITool,
1556
- createZodFunctionTool,
1557
- editTool,
1558
- globTool,
1559
- grepTool,
1560
- readTool,
1561
- webFetchTool,
1562
- webSearchTool,
1563
- writeTool,
1564
- zodToJsonSchema
1565
- });
1790
+
1791
+ exports.E2BSandboxClient = E2BSandboxClient;
1792
+ exports.FunctionTool = FunctionTool;
1793
+ exports.InMemorySandboxClient = InMemorySandboxClient;
1794
+ exports.OpenAPITool = OpenAPITool;
1795
+ exports.ToolRegistry = ToolRegistry;
1796
+ exports.applyWorkspaceManifest = applyWorkspaceManifest;
1797
+ exports.bashTool = bashTool;
1798
+ exports.createBashTool = createBashTool;
1799
+ exports.createEditTool = createEditTool;
1800
+ exports.createFunctionTool = createFunctionTool;
1801
+ exports.createOpenAPITool = createOpenAPITool;
1802
+ exports.createReadTool = createReadTool;
1803
+ exports.createWriteTool = createWriteTool;
1804
+ exports.createZodFunctionTool = createZodFunctionTool;
1805
+ exports.editTool = editTool;
1806
+ exports.globTool = globTool;
1807
+ exports.grepTool = grepTool;
1808
+ exports.readTool = readTool;
1809
+ exports.validateWorkspaceManifestPath = validateWorkspaceManifestPath;
1810
+ exports.webFetchTool = webFetchTool;
1811
+ exports.webSearchTool = webSearchTool;
1812
+ exports.writeTool = writeTool;
1813
+ exports.zodToJsonSchema = zodToJsonSchema;