ai-code-agents 0.1.0 → 0.2.0
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 +15 -16
- package/dist/index.cjs +687 -633
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +256 -575
- package/dist/index.d.ts +256 -575
- package/dist/index.js +751 -648
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -6
package/dist/index.cjs
CHANGED
|
@@ -30,12 +30,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
CopyFileResult: () => CopyFileResult,
|
|
34
33
|
CopyFileTool: () => CopyFileTool,
|
|
35
34
|
CopyFileToolInput: () => CopyFileToolInput,
|
|
36
35
|
CopyFileToolName: () => CopyFileToolName,
|
|
37
36
|
CopyFileToolOutput: () => CopyFileToolOutput,
|
|
38
|
-
DeleteFileResult: () => DeleteFileResult,
|
|
39
37
|
DeleteFileTool: () => DeleteFileTool,
|
|
40
38
|
DeleteFileToolInput: () => DeleteFileToolInput,
|
|
41
39
|
DeleteFileToolName: () => DeleteFileToolName,
|
|
@@ -57,20 +55,22 @@ __export(index_exports, {
|
|
|
57
55
|
GlobToolInput: () => GlobToolInput,
|
|
58
56
|
GlobToolName: () => GlobToolName,
|
|
59
57
|
GlobToolOutput: () => GlobToolOutput,
|
|
58
|
+
GrepTool: () => GrepTool,
|
|
59
|
+
GrepToolInput: () => GrepToolInput,
|
|
60
|
+
GrepToolName: () => GrepToolName,
|
|
61
|
+
GrepToolOutput: () => GrepToolOutput,
|
|
60
62
|
ListDirectoryTool: () => ListDirectoryTool,
|
|
61
63
|
ListDirectoryToolInput: () => ListDirectoryToolInput,
|
|
62
64
|
ListDirectoryToolName: () => ListDirectoryToolName,
|
|
63
65
|
ListDirectoryToolOutput: () => ListDirectoryToolOutput,
|
|
64
66
|
MockFilesystemEnvironment: () => MockFilesystemEnvironment,
|
|
65
67
|
MockFilesystemEnvironmentName: () => MockFilesystemEnvironmentName,
|
|
66
|
-
MoveFileResult: () => MoveFileResult,
|
|
67
68
|
MoveFileTool: () => MoveFileTool,
|
|
68
69
|
MoveFileToolInput: () => MoveFileToolInput,
|
|
69
70
|
MoveFileToolName: () => MoveFileToolName,
|
|
70
71
|
MoveFileToolOutput: () => MoveFileToolOutput,
|
|
71
72
|
NodeFilesystemEnvironment: () => NodeFilesystemEnvironment,
|
|
72
73
|
NodeFilesystemEnvironmentName: () => NodeFilesystemEnvironmentName,
|
|
73
|
-
ReadFileResult: () => ReadFileResult,
|
|
74
74
|
ReadFileTool: () => ReadFileTool,
|
|
75
75
|
ReadFileToolInput: () => ReadFileToolInput,
|
|
76
76
|
ReadFileToolName: () => ReadFileToolName,
|
|
@@ -79,7 +79,6 @@ __export(index_exports, {
|
|
|
79
79
|
ReadManyFilesToolInput: () => ReadManyFilesToolInput,
|
|
80
80
|
ReadManyFilesToolName: () => ReadManyFilesToolName,
|
|
81
81
|
ReadManyFilesToolOutput: () => ReadManyFilesToolOutput,
|
|
82
|
-
RunCommandResult: () => RunCommandResult,
|
|
83
82
|
RunCommandTool: () => RunCommandTool,
|
|
84
83
|
RunCommandToolInput: () => RunCommandToolInput,
|
|
85
84
|
RunCommandToolName: () => RunCommandToolName,
|
|
@@ -90,12 +89,13 @@ __export(index_exports, {
|
|
|
90
89
|
SubmitToolOutput: () => SubmitToolOutput,
|
|
91
90
|
UnsafeLocalEnvironment: () => UnsafeLocalEnvironment,
|
|
92
91
|
UnsafeLocalEnvironmentName: () => UnsafeLocalEnvironmentName,
|
|
93
|
-
WriteFileResult: () => WriteFileResult,
|
|
94
92
|
WriteFileTool: () => WriteFileTool,
|
|
95
93
|
WriteFileToolInput: () => WriteFileToolInput,
|
|
96
94
|
WriteFileToolName: () => WriteFileToolName,
|
|
97
95
|
WriteFileToolOutput: () => WriteFileToolOutput,
|
|
98
96
|
createCodeAgent: () => createCodeAgent,
|
|
97
|
+
createCodeAgentSettings: () => createCodeAgentSettings,
|
|
98
|
+
createCodeAgentTools: () => createCodeAgentTools,
|
|
99
99
|
createEnvironment: () => createEnvironment,
|
|
100
100
|
createEnvironmentTool: () => createEnvironmentTool,
|
|
101
101
|
createToolsForEnvironment: () => createToolsForEnvironment,
|
|
@@ -105,14 +105,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
105
105
|
|
|
106
106
|
// src/environments/docker-environment.ts
|
|
107
107
|
var import_node_child_process = require("child_process");
|
|
108
|
-
|
|
109
|
-
// src/util/escape-command-arg.ts
|
|
110
|
-
function escapeCommandArg(arg) {
|
|
111
|
-
if ("" === arg) {
|
|
112
|
-
return "''";
|
|
113
|
-
}
|
|
114
|
-
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
115
|
-
}
|
|
108
|
+
var import_environment_utils = require("@ai-code-agents/environment-utils");
|
|
116
109
|
|
|
117
110
|
// src/util/escape-command.ts
|
|
118
111
|
function escapeCommand(command) {
|
|
@@ -120,281 +113,9 @@ function escapeCommand(command) {
|
|
|
120
113
|
return `"${escaped}"`;
|
|
121
114
|
}
|
|
122
115
|
|
|
123
|
-
// src/util/validate-relative-path.ts
|
|
124
|
-
var path = __toESM(require("path"), 1);
|
|
125
|
-
function validateRelativePath(filePath) {
|
|
126
|
-
if (path.isAbsolute(filePath)) {
|
|
127
|
-
throw new Error("Absolute paths are not allowed.");
|
|
128
|
-
}
|
|
129
|
-
if (filePath.startsWith("~")) {
|
|
130
|
-
throw new Error('Paths starting with "~" are not allowed.');
|
|
131
|
-
}
|
|
132
|
-
if (filePath.includes("\0")) {
|
|
133
|
-
throw new Error("Paths must not contain null bytes.");
|
|
134
|
-
}
|
|
135
|
-
const normalizedPath = path.normalize(filePath);
|
|
136
|
-
if (normalizedPath.startsWith("..")) {
|
|
137
|
-
throw new Error("Path traversal is not allowed.");
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// src/environments/filesystem-environment-base.ts
|
|
142
|
-
var FilesystemEnvironmentBase = class {
|
|
143
|
-
_envConfig;
|
|
144
|
-
/**
|
|
145
|
-
* Constructs a new environment instance.
|
|
146
|
-
*
|
|
147
|
-
* @param config - Environment configuration.
|
|
148
|
-
*/
|
|
149
|
-
constructor(config) {
|
|
150
|
-
this._envConfig = config;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Reads the content of a file at the specified path.
|
|
154
|
-
*
|
|
155
|
-
* @param path - The path to the file to read, relative to the project directory.
|
|
156
|
-
* @returns A promise that resolves to a ReadFileResult.
|
|
157
|
-
*/
|
|
158
|
-
async readFile(path5) {
|
|
159
|
-
validateRelativePath(path5);
|
|
160
|
-
if (!await this.fileExists(path5)) {
|
|
161
|
-
throw new Error(`File not found: ${path5}`);
|
|
162
|
-
}
|
|
163
|
-
const content = await this.readFileContent(path5);
|
|
164
|
-
return {
|
|
165
|
-
path: path5,
|
|
166
|
-
content
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Writes content to a file at the specified path.
|
|
171
|
-
*
|
|
172
|
-
* If a file is already present at the path, it will be overwritten.
|
|
173
|
-
*
|
|
174
|
-
* @param path - The path to the file to write, relative to the project directory.
|
|
175
|
-
* @param content - The content to write to the file.
|
|
176
|
-
* @returns A promise that resolves to a WriteFileResult.
|
|
177
|
-
*/
|
|
178
|
-
async writeFile(path5, content) {
|
|
179
|
-
validateRelativePath(path5);
|
|
180
|
-
await this.writeFileContent(path5, content);
|
|
181
|
-
return {
|
|
182
|
-
path: path5,
|
|
183
|
-
message: "File written successfully."
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Deletes a file at the specified path.
|
|
188
|
-
*
|
|
189
|
-
* @param path - The path to the file to delete, relative to the project directory.
|
|
190
|
-
* @returns A promise that resolves to a DeleteFileResult.
|
|
191
|
-
*/
|
|
192
|
-
async deleteFile(path5) {
|
|
193
|
-
validateRelativePath(path5);
|
|
194
|
-
if (!await this.fileExists(path5)) {
|
|
195
|
-
return {
|
|
196
|
-
path: path5,
|
|
197
|
-
message: "File was already deleted."
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
await this.deleteFileContent(path5);
|
|
201
|
-
return {
|
|
202
|
-
path: path5,
|
|
203
|
-
message: "File deleted successfully."
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Moves a file from a source path to a destination path.
|
|
208
|
-
*
|
|
209
|
-
* If a file is already present at the destination path, it will be overwritten.
|
|
210
|
-
*
|
|
211
|
-
* @param sourcePath - The path to the file to move.
|
|
212
|
-
* @param destinationPath - The path to move the file to.
|
|
213
|
-
* @returns A promise that resolves to a MoveFileResult.
|
|
214
|
-
*/
|
|
215
|
-
async moveFile(sourcePath, destinationPath) {
|
|
216
|
-
validateRelativePath(sourcePath);
|
|
217
|
-
validateRelativePath(destinationPath);
|
|
218
|
-
if (!await this.fileExists(sourcePath)) {
|
|
219
|
-
throw new Error(`File not found: ${sourcePath}`);
|
|
220
|
-
}
|
|
221
|
-
await this.moveFileContent(sourcePath, destinationPath);
|
|
222
|
-
return {
|
|
223
|
-
sourcePath,
|
|
224
|
-
destinationPath,
|
|
225
|
-
message: "File moved successfully."
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Copies a file from a source path to a destination path.
|
|
230
|
-
*
|
|
231
|
-
* If a file is already present at the destination path, it will be overwritten.
|
|
232
|
-
*
|
|
233
|
-
* @param sourcePath - The path to the file to copy.
|
|
234
|
-
* @param destinationPath - The path to copy the file to.
|
|
235
|
-
* @returns A promise that resolves to a CopyFileResult.
|
|
236
|
-
*/
|
|
237
|
-
async copyFile(sourcePath, destinationPath) {
|
|
238
|
-
validateRelativePath(sourcePath);
|
|
239
|
-
validateRelativePath(destinationPath);
|
|
240
|
-
if (!await this.fileExists(sourcePath)) {
|
|
241
|
-
throw new Error(`File not found: ${sourcePath}`);
|
|
242
|
-
}
|
|
243
|
-
await this.copyFileContent(sourcePath, destinationPath);
|
|
244
|
-
return {
|
|
245
|
-
sourcePath,
|
|
246
|
-
destinationPath,
|
|
247
|
-
message: "File copied successfully."
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Moves the content of a file from a source path to a destination path, relative to the project directory.
|
|
252
|
-
*
|
|
253
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
254
|
-
* This method unconditionally moves the content, even if a file already exists at the destination path.
|
|
255
|
-
*
|
|
256
|
-
* @param relativeSourcePath - The path to the file to move, relative to the project directory.
|
|
257
|
-
* @param relativeDestinationPath - The path to move the file to, relative to the project directory.
|
|
258
|
-
*/
|
|
259
|
-
async moveFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
260
|
-
const content = await this.readFileContent(relativeSourcePath);
|
|
261
|
-
this.writeFileContent(relativeDestinationPath, content);
|
|
262
|
-
this.deleteFileContent(relativeSourcePath);
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Copies the content of a file from a source path to a destination path, relative to the project directory.
|
|
266
|
-
*
|
|
267
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
268
|
-
* This method unconditionally copies the content, even if a file already exists at the destination path.
|
|
269
|
-
*
|
|
270
|
-
* @param relativeSourcePath - The path to the file to copy, relative to the project directory.
|
|
271
|
-
* @param relativeDestinationPath - The path to copy the file to, relative to the project directory.
|
|
272
|
-
*/
|
|
273
|
-
async copyFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
274
|
-
const content = await this.readFileContent(relativeSourcePath);
|
|
275
|
-
this.writeFileContent(relativeDestinationPath, content);
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
// src/environments/command-line-environment-base.ts
|
|
280
|
-
var CommandLineEnvironmentBase = class extends FilesystemEnvironmentBase {
|
|
281
|
-
/**
|
|
282
|
-
* Runs a CLI command in environment.
|
|
283
|
-
*
|
|
284
|
-
* @param command - The command to run.
|
|
285
|
-
* @returns A promise that resolves to a RunCommandResult.
|
|
286
|
-
*/
|
|
287
|
-
async runCommand(command) {
|
|
288
|
-
const [exitCode, stdout, stderr] = await this.executeCommand(command);
|
|
289
|
-
return {
|
|
290
|
-
command,
|
|
291
|
-
exitCode,
|
|
292
|
-
stdout,
|
|
293
|
-
stderr
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
// src/environments/unix-environment-base.ts
|
|
299
|
-
var UnixEnvironmentBase = class extends CommandLineEnvironmentBase {
|
|
300
|
-
/**
|
|
301
|
-
* Checks whether a file exists at the specified path relative to the project directory.
|
|
302
|
-
*
|
|
303
|
-
* @param relativePath - The path to the file to check, relative to the project directory.
|
|
304
|
-
* @returns True if the file exists, false otherwise.
|
|
305
|
-
*/
|
|
306
|
-
async fileExists(relativePath) {
|
|
307
|
-
const command = `if [ -e ${escapeCommandArg(relativePath)} ]; then echo "yes"; else echo "no"; fi`;
|
|
308
|
-
const { exitCode, stdout } = await this.runCommand(command);
|
|
309
|
-
return exitCode === 0 && stdout.trim() === "yes";
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Gets the content of a file at the specified path, relative to the project directory.
|
|
313
|
-
*
|
|
314
|
-
* When this method is called, it is guaranteed that the file exists.
|
|
315
|
-
*
|
|
316
|
-
* @param relativePath - The path to the file to read, relative to the project directory.
|
|
317
|
-
* @returns The content of the file.
|
|
318
|
-
*/
|
|
319
|
-
async readFileContent(relativePath) {
|
|
320
|
-
const command = `cat ${escapeCommandArg(relativePath)}`;
|
|
321
|
-
const { exitCode, stdout } = await this.runCommand(command);
|
|
322
|
-
return exitCode === 0 ? stdout : "";
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Writes content to a file at the specified path, relative to the project directory.
|
|
326
|
-
*
|
|
327
|
-
* This method unconditionally writes the content, even if a file already exists at the path, or if the file is new.
|
|
328
|
-
*
|
|
329
|
-
* @param relativePath - The path to the file to write, relative to the project directory.
|
|
330
|
-
* @param content - The content to write to the file.
|
|
331
|
-
*/
|
|
332
|
-
async writeFileContent(relativePath, content) {
|
|
333
|
-
const command = `sh -c "echo ${escapeCommandArg(
|
|
334
|
-
content
|
|
335
|
-
)} > ${escapeCommandArg(relativePath)}"`;
|
|
336
|
-
const { exitCode, stderr } = await this.runCommand(command);
|
|
337
|
-
if (exitCode !== 0) {
|
|
338
|
-
throw new Error(`Failed to write file: ${stderr || "Unknown error"}`);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Deletes a file at the specified path, relative to the project directory.
|
|
343
|
-
*
|
|
344
|
-
* When this method is called, it is guaranteed that the file exists.
|
|
345
|
-
*
|
|
346
|
-
* @param relativePath - The path to the file to delete, relative to the project directory.
|
|
347
|
-
*/
|
|
348
|
-
async deleteFileContent(relativePath) {
|
|
349
|
-
const command = `rm ${escapeCommandArg(relativePath)}`;
|
|
350
|
-
const { exitCode, stderr } = await this.runCommand(command);
|
|
351
|
-
if (exitCode !== 0) {
|
|
352
|
-
throw new Error(`Failed to delete file: ${stderr || "Unknown error"}`);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Moves the content of a file from a source path to a destination path, relative to the project directory.
|
|
357
|
-
*
|
|
358
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
359
|
-
* This method unconditionally moves the content, even if a file already exists at the destination path.
|
|
360
|
-
*
|
|
361
|
-
* @param relativeSourcePath - The path to the file to move, relative to the project directory.
|
|
362
|
-
* @param relativeDestinationPath - The path to move the file to, relative to the project directory.
|
|
363
|
-
*/
|
|
364
|
-
async moveFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
365
|
-
const command = `mv ${escapeCommandArg(relativeSourcePath)} ${escapeCommandArg(
|
|
366
|
-
relativeDestinationPath
|
|
367
|
-
)}`;
|
|
368
|
-
const { exitCode, stderr } = await this.runCommand(command);
|
|
369
|
-
if (exitCode !== 0) {
|
|
370
|
-
throw new Error(`Failed to move file: ${stderr || "Unknown error"}`);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Copies the content of a file from a source path to a destination path, relative to the project directory.
|
|
375
|
-
*
|
|
376
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
377
|
-
* This method unconditionally copies the content, even if a file already exists at the destination path.
|
|
378
|
-
*
|
|
379
|
-
* @param relativeSourcePath - The path to the file to copy, relative to the project directory.
|
|
380
|
-
* @param relativeDestinationPath - The path to copy the file to, relative to the project directory.
|
|
381
|
-
*/
|
|
382
|
-
async copyFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
383
|
-
const command = `cp ${escapeCommandArg(relativeSourcePath)} ${escapeCommandArg(
|
|
384
|
-
relativeDestinationPath
|
|
385
|
-
)}`;
|
|
386
|
-
const result = await this.runCommand(command);
|
|
387
|
-
if (result.exitCode !== 0) {
|
|
388
|
-
throw new Error(
|
|
389
|
-
`Failed to copy file: ${result.stderr || "Unknown error"}`
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
|
|
395
116
|
// src/environments/docker-environment.ts
|
|
396
117
|
var DockerEnvironmentName = "docker";
|
|
397
|
-
var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
118
|
+
var DockerEnvironment = class extends import_environment_utils.UnixEnvironmentBase {
|
|
398
119
|
_commandPrefix;
|
|
399
120
|
/**
|
|
400
121
|
* Constructs a new environment instance.
|
|
@@ -404,7 +125,7 @@ var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
|
404
125
|
constructor(config) {
|
|
405
126
|
super(config);
|
|
406
127
|
const { directoryPath } = this._envConfig;
|
|
407
|
-
this._commandPrefix = directoryPath ? `cd ${escapeCommandArg(directoryPath)} && ` : "";
|
|
128
|
+
this._commandPrefix = directoryPath ? `cd ${(0, import_environment_utils.escapeCommandArg)(directoryPath)} && ` : "";
|
|
408
129
|
}
|
|
409
130
|
/**
|
|
410
131
|
* Gets the environment name.
|
|
@@ -435,8 +156,9 @@ var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
|
435
156
|
|
|
436
157
|
// src/environments/mock-filesystem-environment.ts
|
|
437
158
|
var import_node_path = __toESM(require("path"), 1);
|
|
159
|
+
var import_environment_utils2 = require("@ai-code-agents/environment-utils");
|
|
438
160
|
var MockFilesystemEnvironmentName = "mock-filesystem";
|
|
439
|
-
var MockFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
161
|
+
var MockFilesystemEnvironment = class extends import_environment_utils2.FilesystemEnvironmentBase {
|
|
440
162
|
files;
|
|
441
163
|
_preparePath;
|
|
442
164
|
/**
|
|
@@ -447,7 +169,7 @@ var MockFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
|
447
169
|
constructor(config = {}) {
|
|
448
170
|
super(config);
|
|
449
171
|
const { initialFiles, directoryPath } = this._envConfig;
|
|
450
|
-
this.files = initialFiles
|
|
172
|
+
this.files = initialFiles ? new Map(Object.entries(initialFiles)) : /* @__PURE__ */ new Map();
|
|
451
173
|
this._preparePath = directoryPath ? (filePath) => import_node_path.default.join(directoryPath, filePath) : (filePath) => filePath;
|
|
452
174
|
}
|
|
453
175
|
/**
|
|
@@ -502,8 +224,9 @@ var MockFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
|
502
224
|
// src/environments/node-filesystem-environment.ts
|
|
503
225
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
504
226
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
227
|
+
var import_environment_utils3 = require("@ai-code-agents/environment-utils");
|
|
505
228
|
var NodeFilesystemEnvironmentName = "node-filesystem";
|
|
506
|
-
var NodeFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
229
|
+
var NodeFilesystemEnvironment = class extends import_environment_utils3.FilesystemEnvironmentBase {
|
|
507
230
|
/**
|
|
508
231
|
* Constructs a new NodeFilesystemEnvironment instance.
|
|
509
232
|
*
|
|
@@ -597,8 +320,9 @@ var NodeFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
|
597
320
|
|
|
598
321
|
// src/environments/unsafe-local-environment.ts
|
|
599
322
|
var import_node_child_process2 = require("child_process");
|
|
323
|
+
var import_environment_utils4 = require("@ai-code-agents/environment-utils");
|
|
600
324
|
var UnsafeLocalEnvironmentName = "unsafe-local";
|
|
601
|
-
var UnsafeLocalEnvironment = class extends UnixEnvironmentBase {
|
|
325
|
+
var UnsafeLocalEnvironment = class extends import_environment_utils4.UnixEnvironmentBase {
|
|
602
326
|
_commandPrefix;
|
|
603
327
|
/**
|
|
604
328
|
* Constructs a new environment instance.
|
|
@@ -614,7 +338,7 @@ var UnsafeLocalEnvironment = class extends UnixEnvironmentBase {
|
|
|
614
338
|
throw new Error('The directory path must be absolute (start with "/")');
|
|
615
339
|
}
|
|
616
340
|
super(config);
|
|
617
|
-
this._commandPrefix = `cd ${escapeCommandArg(directoryPath)} && `;
|
|
341
|
+
this._commandPrefix = `cd ${(0, import_environment_utils4.escapeCommandArg)(directoryPath)} && `;
|
|
618
342
|
}
|
|
619
343
|
/**
|
|
620
344
|
* Gets the environment name.
|
|
@@ -642,173 +366,7 @@ var UnsafeLocalEnvironment = class extends UnixEnvironmentBase {
|
|
|
642
366
|
|
|
643
367
|
// src/tools/copy-file-tool.ts
|
|
644
368
|
var import_zod = require("zod");
|
|
645
|
-
|
|
646
|
-
// src/types.ts
|
|
647
|
-
var z = __toESM(require("zod"), 1);
|
|
648
|
-
var ReadFileResult = z.object({
|
|
649
|
-
path: z.string().meta({
|
|
650
|
-
description: "The path to the file that was read."
|
|
651
|
-
}),
|
|
652
|
-
content: z.string().meta({
|
|
653
|
-
description: "The content of the file that was read."
|
|
654
|
-
})
|
|
655
|
-
});
|
|
656
|
-
var WriteFileResult = z.object({
|
|
657
|
-
path: z.string().meta({
|
|
658
|
-
description: "The path to the file that was written."
|
|
659
|
-
}),
|
|
660
|
-
message: z.string().meta({
|
|
661
|
-
description: "A message indicating the result of the write operation."
|
|
662
|
-
})
|
|
663
|
-
});
|
|
664
|
-
var DeleteFileResult = z.object({
|
|
665
|
-
path: z.string().meta({
|
|
666
|
-
description: "The path to the file that was deleted."
|
|
667
|
-
}),
|
|
668
|
-
message: z.string().meta({
|
|
669
|
-
description: "A message indicating the result of the delete operation."
|
|
670
|
-
})
|
|
671
|
-
});
|
|
672
|
-
var MoveFileResult = z.object({
|
|
673
|
-
sourcePath: z.string().meta({
|
|
674
|
-
description: "The original path of the file that was moved."
|
|
675
|
-
}),
|
|
676
|
-
destinationPath: z.string().meta({
|
|
677
|
-
description: "The new path of the file that was moved to."
|
|
678
|
-
}),
|
|
679
|
-
message: z.string().meta({
|
|
680
|
-
description: "A message indicating the result of the move operation."
|
|
681
|
-
})
|
|
682
|
-
});
|
|
683
|
-
var CopyFileResult = z.object({
|
|
684
|
-
sourcePath: z.string().meta({
|
|
685
|
-
description: "The original path of the file that was copied."
|
|
686
|
-
}),
|
|
687
|
-
destinationPath: z.string().meta({
|
|
688
|
-
description: "The new path of the file that was copied to."
|
|
689
|
-
}),
|
|
690
|
-
message: z.string().meta({
|
|
691
|
-
description: "A message indicating the result of the copy operation."
|
|
692
|
-
})
|
|
693
|
-
});
|
|
694
|
-
var RunCommandResult = z.object({
|
|
695
|
-
command: z.string().meta({
|
|
696
|
-
description: "The command that was executed."
|
|
697
|
-
}),
|
|
698
|
-
exitCode: z.number().meta({
|
|
699
|
-
description: "The exit code of the command."
|
|
700
|
-
}),
|
|
701
|
-
stdout: z.string().meta({
|
|
702
|
-
description: "The standard output of the command."
|
|
703
|
-
}),
|
|
704
|
-
stderr: z.string().meta({
|
|
705
|
-
description: "The standard error output of the command."
|
|
706
|
-
})
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
// src/tools/tool-base.ts
|
|
710
|
-
var ToolBase = class {
|
|
711
|
-
_toolConfig;
|
|
712
|
-
_name;
|
|
713
|
-
_description;
|
|
714
|
-
_inputSchema;
|
|
715
|
-
_outputSchema;
|
|
716
|
-
_needsApproval;
|
|
717
|
-
/**
|
|
718
|
-
* Constructs a new tool instance.
|
|
719
|
-
*
|
|
720
|
-
* @param toolConfig - Optional tool config, can be used to override some defaults.
|
|
721
|
-
*/
|
|
722
|
-
constructor(toolConfig) {
|
|
723
|
-
const {
|
|
724
|
-
name: defaultName,
|
|
725
|
-
description: defaultDescription,
|
|
726
|
-
inputSchema,
|
|
727
|
-
outputSchema,
|
|
728
|
-
needsApproval: defaultNeedsApproval
|
|
729
|
-
} = this.getMetadata();
|
|
730
|
-
this._name = toolConfig?.name || defaultName;
|
|
731
|
-
this._description = toolConfig?.description || defaultDescription;
|
|
732
|
-
this._inputSchema = inputSchema;
|
|
733
|
-
this._outputSchema = outputSchema;
|
|
734
|
-
this._needsApproval = toolConfig?.needsApproval !== void 0 ? toolConfig.needsApproval : defaultNeedsApproval;
|
|
735
|
-
}
|
|
736
|
-
/**
|
|
737
|
-
* Gets the tool name.
|
|
738
|
-
*
|
|
739
|
-
* @returns The tool name.
|
|
740
|
-
*/
|
|
741
|
-
get name() {
|
|
742
|
-
return this._name;
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* Gets the tool description.
|
|
746
|
-
*
|
|
747
|
-
* @returns The tool description.
|
|
748
|
-
*/
|
|
749
|
-
get description() {
|
|
750
|
-
return this._description;
|
|
751
|
-
}
|
|
752
|
-
/**
|
|
753
|
-
* Gets the input schema for the tool.
|
|
754
|
-
*
|
|
755
|
-
* @returns The input schema.
|
|
756
|
-
*/
|
|
757
|
-
get inputSchema() {
|
|
758
|
-
return this._inputSchema;
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* Gets the input schema for the tool.
|
|
762
|
-
*
|
|
763
|
-
* @returns The input schema.
|
|
764
|
-
*/
|
|
765
|
-
get outputSchema() {
|
|
766
|
-
return this._outputSchema;
|
|
767
|
-
}
|
|
768
|
-
/**
|
|
769
|
-
* Gets whether the tool needs approval before use.
|
|
770
|
-
*
|
|
771
|
-
* @returns True if the tool needs approval, false otherwise.
|
|
772
|
-
*/
|
|
773
|
-
get needsApproval() {
|
|
774
|
-
return this._needsApproval;
|
|
775
|
-
}
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
// src/tools/environment-tool-base.ts
|
|
779
|
-
var EnvironmentToolBase = class extends ToolBase {
|
|
780
|
-
_environment;
|
|
781
|
-
/**
|
|
782
|
-
* Constructs a new `EnvironmentToolBase` instance.
|
|
783
|
-
*
|
|
784
|
-
* @param environment - The execution environment to apply the tool in.
|
|
785
|
-
* @param toolConfig - Optional tool config, can be used to override some defaults.
|
|
786
|
-
*/
|
|
787
|
-
constructor(environment, toolConfig) {
|
|
788
|
-
super(toolConfig);
|
|
789
|
-
this._environment = environment;
|
|
790
|
-
}
|
|
791
|
-
/**
|
|
792
|
-
* Gets the current execution environment for the tool.
|
|
793
|
-
*
|
|
794
|
-
* @returns The current execution environment.
|
|
795
|
-
*/
|
|
796
|
-
get environment() {
|
|
797
|
-
return this._environment;
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Executes the tool with the given input.
|
|
801
|
-
*
|
|
802
|
-
* @param input - The input for the tool.
|
|
803
|
-
* @param _options - Options from the tool call.
|
|
804
|
-
* @returns A promise that resolves to the tool execution result.
|
|
805
|
-
*/
|
|
806
|
-
execute(input, _options) {
|
|
807
|
-
return this.executeForEnvironment(this._environment, input);
|
|
808
|
-
}
|
|
809
|
-
};
|
|
810
|
-
|
|
811
|
-
// src/tools/copy-file-tool.ts
|
|
369
|
+
var import_environment_utils5 = require("@ai-code-agents/environment-utils");
|
|
812
370
|
var CopyFileToolName = "copy_file";
|
|
813
371
|
var CopyFileToolInput = import_zod.z.object({
|
|
814
372
|
sourcePath: import_zod.z.string().meta({
|
|
@@ -818,8 +376,8 @@ var CopyFileToolInput = import_zod.z.object({
|
|
|
818
376
|
description: "The path to the destination where the file should be copied, relative to the project directory. If the file already exists, it will be overwritten."
|
|
819
377
|
})
|
|
820
378
|
});
|
|
821
|
-
var CopyFileToolOutput = CopyFileResult;
|
|
822
|
-
var CopyFileTool = class extends EnvironmentToolBase {
|
|
379
|
+
var CopyFileToolOutput = import_environment_utils5.CopyFileResult;
|
|
380
|
+
var CopyFileTool = class extends import_environment_utils5.EnvironmentToolBase {
|
|
823
381
|
/**
|
|
824
382
|
* Returns the metadata for the tool.
|
|
825
383
|
*
|
|
@@ -849,10 +407,11 @@ var CopyFileTool = class extends EnvironmentToolBase {
|
|
|
849
407
|
/**
|
|
850
408
|
* Converts the tool output to a format suitable for model consumption.
|
|
851
409
|
*
|
|
852
|
-
* @param
|
|
410
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
853
411
|
* @returns The formatted tool result.
|
|
854
412
|
*/
|
|
855
|
-
toModelOutput(
|
|
413
|
+
toModelOutput(options) {
|
|
414
|
+
const { output } = options;
|
|
856
415
|
return {
|
|
857
416
|
type: "text",
|
|
858
417
|
value: `File \`${output.sourcePath}\` copied successfully to \`${output.destinationPath}\`.`
|
|
@@ -878,14 +437,15 @@ var CopyFileTool = class extends EnvironmentToolBase {
|
|
|
878
437
|
|
|
879
438
|
// src/tools/delete-file-tool.ts
|
|
880
439
|
var import_zod2 = require("zod");
|
|
440
|
+
var import_environment_utils6 = require("@ai-code-agents/environment-utils");
|
|
881
441
|
var DeleteFileToolName = "delete_file";
|
|
882
442
|
var DeleteFileToolInput = import_zod2.z.object({
|
|
883
443
|
path: import_zod2.z.string().meta({
|
|
884
444
|
description: "The path to the file to delete, relative to the project directory."
|
|
885
445
|
})
|
|
886
446
|
});
|
|
887
|
-
var DeleteFileToolOutput = DeleteFileResult;
|
|
888
|
-
var DeleteFileTool = class extends EnvironmentToolBase {
|
|
447
|
+
var DeleteFileToolOutput = import_environment_utils6.DeleteFileResult;
|
|
448
|
+
var DeleteFileTool = class extends import_environment_utils6.EnvironmentToolBase {
|
|
889
449
|
/**
|
|
890
450
|
* Returns the metadata for the tool.
|
|
891
451
|
*
|
|
@@ -915,10 +475,11 @@ var DeleteFileTool = class extends EnvironmentToolBase {
|
|
|
915
475
|
/**
|
|
916
476
|
* Converts the tool output to a format suitable for model consumption.
|
|
917
477
|
*
|
|
918
|
-
* @param
|
|
478
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
919
479
|
* @returns The formatted tool result.
|
|
920
480
|
*/
|
|
921
|
-
toModelOutput(
|
|
481
|
+
toModelOutput(options) {
|
|
482
|
+
const { output } = options;
|
|
922
483
|
return {
|
|
923
484
|
type: "text",
|
|
924
485
|
value: `File \`${output.path}\` deleted successfully.`
|
|
@@ -943,6 +504,7 @@ var DeleteFileTool = class extends EnvironmentToolBase {
|
|
|
943
504
|
|
|
944
505
|
// src/tools/edit-file-tool.ts
|
|
945
506
|
var import_zod3 = require("zod");
|
|
507
|
+
var import_environment_utils7 = require("@ai-code-agents/environment-utils");
|
|
946
508
|
var EditFileToolName = "edit_file";
|
|
947
509
|
var EditFileToolInput = import_zod3.z.object({
|
|
948
510
|
path: import_zod3.z.string().meta({
|
|
@@ -975,10 +537,10 @@ var EditFileToolOutput = import_zod3.z.object({
|
|
|
975
537
|
description: "A message indicating the result of the edit operation."
|
|
976
538
|
})
|
|
977
539
|
});
|
|
978
|
-
function escapeRegExp(
|
|
979
|
-
return
|
|
540
|
+
function escapeRegExp(string) {
|
|
541
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
980
542
|
}
|
|
981
|
-
var EditFileTool = class extends EnvironmentToolBase {
|
|
543
|
+
var EditFileTool = class extends import_environment_utils7.EnvironmentToolBase {
|
|
982
544
|
/**
|
|
983
545
|
* Returns the metadata for the tool.
|
|
984
546
|
*
|
|
@@ -1033,10 +595,11 @@ var EditFileTool = class extends EnvironmentToolBase {
|
|
|
1033
595
|
/**
|
|
1034
596
|
* Converts the tool output to a format suitable for model consumption.
|
|
1035
597
|
*
|
|
1036
|
-
* @param
|
|
598
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1037
599
|
* @returns The formatted tool result.
|
|
1038
600
|
*/
|
|
1039
|
-
toModelOutput(
|
|
601
|
+
toModelOutput(options) {
|
|
602
|
+
const { output } = options;
|
|
1040
603
|
return {
|
|
1041
604
|
type: "text",
|
|
1042
605
|
value: `Edited file \`${output.path}\` with ${output.replacements} replacement(s).`
|
|
@@ -1085,6 +648,7 @@ var EditFileTool = class extends EnvironmentToolBase {
|
|
|
1085
648
|
|
|
1086
649
|
// src/tools/get-project-file-structure-tool.ts
|
|
1087
650
|
var import_zod4 = require("zod");
|
|
651
|
+
var import_environment_utils9 = require("@ai-code-agents/environment-utils");
|
|
1088
652
|
|
|
1089
653
|
// src/util/build-tree-from-files.ts
|
|
1090
654
|
function renderTree(node, prefix = "") {
|
|
@@ -1121,6 +685,91 @@ function buildTreeFromFiles(files) {
|
|
|
1121
685
|
return renderTree(tree).trim();
|
|
1122
686
|
}
|
|
1123
687
|
|
|
688
|
+
// src/util/get-gitignored-paths.ts
|
|
689
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
690
|
+
var import_environment_utils8 = require("@ai-code-agents/environment-utils");
|
|
691
|
+
async function getGitIgnoredPaths(env) {
|
|
692
|
+
const gitignorePath = await getClosestGitIgnorePath(env);
|
|
693
|
+
if (!gitignorePath) {
|
|
694
|
+
return [];
|
|
695
|
+
}
|
|
696
|
+
const { stdout: pwd } = await env.runCommand("pwd");
|
|
697
|
+
const currentDir = pwd.trim();
|
|
698
|
+
const gitignoreDir = import_node_path3.default.dirname(gitignorePath);
|
|
699
|
+
try {
|
|
700
|
+
const { stdout, exitCode } = await env.runCommand(
|
|
701
|
+
`cat ${(0, import_environment_utils8.escapeCommandArg)(gitignorePath)}`
|
|
702
|
+
);
|
|
703
|
+
if (exitCode !== 0) {
|
|
704
|
+
return [];
|
|
705
|
+
}
|
|
706
|
+
const rawRules = stdout.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
707
|
+
const relPath = import_node_path3.default.relative(gitignoreDir, currentDir);
|
|
708
|
+
if (relPath === "") {
|
|
709
|
+
return rawRules.map(
|
|
710
|
+
(rule) => rule.startsWith("/") ? rule.slice(1) : rule
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
const relPathSegments = relPath.split(import_node_path3.default.sep);
|
|
714
|
+
const sanitizedRules = [];
|
|
715
|
+
for (const rule of rawRules) {
|
|
716
|
+
const isAnchored = rule.startsWith("/") || rule.includes("/") && rule.indexOf("/") !== rule.length - 1;
|
|
717
|
+
if (!isAnchored || rule.startsWith("**/")) {
|
|
718
|
+
sanitizedRules.push(rule.startsWith("**/") ? rule.slice(3) : rule);
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
const normalizedRule = rule.startsWith("/") ? rule.slice(1) : rule;
|
|
722
|
+
const cleanRule = normalizedRule.endsWith("/") ? normalizedRule.slice(0, -1) : normalizedRule;
|
|
723
|
+
const ruleSegments = cleanRule.split("/");
|
|
724
|
+
let matches = true;
|
|
725
|
+
let i = 0;
|
|
726
|
+
for (; i < relPathSegments.length; i++) {
|
|
727
|
+
if (i >= ruleSegments.length) {
|
|
728
|
+
sanitizedRules.push(".");
|
|
729
|
+
matches = false;
|
|
730
|
+
break;
|
|
731
|
+
}
|
|
732
|
+
if (!matchSegment(ruleSegments[i], relPathSegments[i])) {
|
|
733
|
+
matches = false;
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (matches) {
|
|
738
|
+
const remaining = ruleSegments.slice(i).join("/");
|
|
739
|
+
if (remaining) {
|
|
740
|
+
sanitizedRules.push(
|
|
741
|
+
normalizedRule.endsWith("/") && !remaining.endsWith("/") ? `${remaining}/` : remaining
|
|
742
|
+
);
|
|
743
|
+
} else {
|
|
744
|
+
sanitizedRules.push(".");
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return [...new Set(sanitizedRules)];
|
|
749
|
+
} catch (_error) {
|
|
750
|
+
return [];
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
function matchSegment(pattern, segment) {
|
|
754
|
+
if (pattern === "*") {
|
|
755
|
+
return true;
|
|
756
|
+
}
|
|
757
|
+
if (pattern === segment) {
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
if (pattern.includes("*") || pattern.includes("?")) {
|
|
761
|
+
const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
762
|
+
const regex = new RegExp(`^${regexStr}$`);
|
|
763
|
+
return regex.test(segment);
|
|
764
|
+
}
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
async function getClosestGitIgnorePath(env) {
|
|
768
|
+
const command = 'd=$PWD; while [ -n "$d" ] && [ ! -f "$d/.gitignore" ]; do d=${d%/*}; done; [ -f "$d/.gitignore" ] && echo "$d/.gitignore"';
|
|
769
|
+
const { stdout } = await env.runCommand(command);
|
|
770
|
+
return stdout.trim();
|
|
771
|
+
}
|
|
772
|
+
|
|
1124
773
|
// src/tools/get-project-file-structure-tool.ts
|
|
1125
774
|
var GetProjectFileStructureToolName = "get_project_file_structure";
|
|
1126
775
|
var GetProjectFileStructureToolInput = import_zod4.z.object({
|
|
@@ -1139,7 +788,7 @@ var GetProjectFileStructureToolOutput = import_zod4.z.object({
|
|
|
1139
788
|
description: "Whether files ignored by Git were excluded."
|
|
1140
789
|
})
|
|
1141
790
|
});
|
|
1142
|
-
var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
791
|
+
var GetProjectFileStructureTool = class extends import_environment_utils9.EnvironmentToolBase {
|
|
1143
792
|
/**
|
|
1144
793
|
* Returns the metadata for the tool.
|
|
1145
794
|
*
|
|
@@ -1165,21 +814,16 @@ var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
|
1165
814
|
*/
|
|
1166
815
|
async executeForEnvironment(env, input) {
|
|
1167
816
|
const { path: path5 = ".", excludeGitIgnored = true } = input;
|
|
1168
|
-
const escapedPath = escapeCommandArg(path5);
|
|
817
|
+
const escapedPath = (0, import_environment_utils9.escapeCommandArg)(path5);
|
|
1169
818
|
let command = `find ${escapedPath} -type f`;
|
|
1170
819
|
if (excludeGitIgnored) {
|
|
1171
|
-
|
|
1172
|
-
try {
|
|
1173
|
-
const { content: gitignoreContent } = await env.readFile(".gitignore");
|
|
1174
|
-
gitIgnoredPaths = gitignoreContent.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
1175
|
-
} catch (_error) {
|
|
1176
|
-
}
|
|
820
|
+
const gitIgnoredPaths = await getGitIgnoredPaths(env);
|
|
1177
821
|
for (const gitIgnoredPath of gitIgnoredPaths) {
|
|
1178
822
|
if (!gitIgnoredPath.endsWith("/")) {
|
|
1179
|
-
const escapedPath2 = escapeCommandArg(`*/${gitIgnoredPath}/*`);
|
|
1180
|
-
command += ` -not -name ${escapeCommandArg(gitIgnoredPath)} -not -path ${escapedPath2}`;
|
|
823
|
+
const escapedPath2 = (0, import_environment_utils9.escapeCommandArg)(`*/${gitIgnoredPath}/*`);
|
|
824
|
+
command += ` -not -name ${(0, import_environment_utils9.escapeCommandArg)(gitIgnoredPath)} -not -path ${escapedPath2}`;
|
|
1181
825
|
} else {
|
|
1182
|
-
const escapedPath2 = escapeCommandArg(`*/${gitIgnoredPath}*`);
|
|
826
|
+
const escapedPath2 = (0, import_environment_utils9.escapeCommandArg)(`*/${gitIgnoredPath}*`);
|
|
1183
827
|
command += ` -not -path ${escapedPath2}`;
|
|
1184
828
|
}
|
|
1185
829
|
}
|
|
@@ -1201,10 +845,11 @@ var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
|
1201
845
|
/**
|
|
1202
846
|
* Converts the tool output to a format suitable for model consumption.
|
|
1203
847
|
*
|
|
1204
|
-
* @param
|
|
848
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1205
849
|
* @returns The formatted tool result.
|
|
1206
850
|
*/
|
|
1207
|
-
toModelOutput(
|
|
851
|
+
toModelOutput(options) {
|
|
852
|
+
const { output } = options;
|
|
1208
853
|
const tree = buildTreeFromFiles(output.files);
|
|
1209
854
|
if (!tree) {
|
|
1210
855
|
return {
|
|
@@ -1243,6 +888,7 @@ var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
|
1243
888
|
|
|
1244
889
|
// src/tools/glob-tool.ts
|
|
1245
890
|
var import_zod5 = require("zod");
|
|
891
|
+
var import_environment_utils10 = require("@ai-code-agents/environment-utils");
|
|
1246
892
|
|
|
1247
893
|
// src/util/glob-to-reg-exp.ts
|
|
1248
894
|
function globToRegExp(glob) {
|
|
@@ -1315,7 +961,7 @@ var GlobToolOutput = import_zod5.z.object({
|
|
|
1315
961
|
description: "The list of file paths that matched the glob search, relative to the project directory."
|
|
1316
962
|
})
|
|
1317
963
|
});
|
|
1318
|
-
var GlobTool = class extends EnvironmentToolBase {
|
|
964
|
+
var GlobTool = class extends import_environment_utils10.EnvironmentToolBase {
|
|
1319
965
|
/**
|
|
1320
966
|
* Returns the metadata for the tool.
|
|
1321
967
|
*
|
|
@@ -1347,24 +993,19 @@ var GlobTool = class extends EnvironmentToolBase {
|
|
|
1347
993
|
);
|
|
1348
994
|
}
|
|
1349
995
|
if (searchPath) {
|
|
1350
|
-
validateRelativePath(searchPath);
|
|
996
|
+
(0, import_environment_utils10.validateRelativePath)(searchPath);
|
|
1351
997
|
}
|
|
1352
998
|
const untrailingslashedSearchPath = searchPath === "" ? "." : searchPath.replace(/\/+$/, "");
|
|
1353
|
-
const escapedSearchPath = escapeCommandArg(untrailingslashedSearchPath);
|
|
999
|
+
const escapedSearchPath = (0, import_environment_utils10.escapeCommandArg)(untrailingslashedSearchPath);
|
|
1354
1000
|
let command = `find ${escapedSearchPath} -type f`;
|
|
1355
1001
|
if (excludeGitIgnored) {
|
|
1356
|
-
|
|
1357
|
-
try {
|
|
1358
|
-
const { content: gitignoreContent } = await env.readFile(".gitignore");
|
|
1359
|
-
gitIgnoredPaths = gitignoreContent.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
1360
|
-
} catch (_error) {
|
|
1361
|
-
}
|
|
1002
|
+
const gitIgnoredPaths = await getGitIgnoredPaths(env);
|
|
1362
1003
|
for (const gitIgnoredPath of gitIgnoredPaths) {
|
|
1363
1004
|
if (!gitIgnoredPath.endsWith("/")) {
|
|
1364
|
-
const escapedPath = escapeCommandArg(`*/${gitIgnoredPath}/*`);
|
|
1365
|
-
command += ` -not -name ${escapeCommandArg(gitIgnoredPath)} -not -path ${escapedPath}`;
|
|
1005
|
+
const escapedPath = (0, import_environment_utils10.escapeCommandArg)(`*/${gitIgnoredPath}/*`);
|
|
1006
|
+
command += ` -not -name ${(0, import_environment_utils10.escapeCommandArg)(gitIgnoredPath)} -not -path ${escapedPath}`;
|
|
1366
1007
|
} else {
|
|
1367
|
-
const escapedPath = escapeCommandArg(`*/${gitIgnoredPath}*`);
|
|
1008
|
+
const escapedPath = (0, import_environment_utils10.escapeCommandArg)(`*/${gitIgnoredPath}*`);
|
|
1368
1009
|
command += ` -not -path ${escapedPath}`;
|
|
1369
1010
|
}
|
|
1370
1011
|
}
|
|
@@ -1400,10 +1041,11 @@ var GlobTool = class extends EnvironmentToolBase {
|
|
|
1400
1041
|
/**
|
|
1401
1042
|
* Converts the tool output to a format suitable for model consumption.
|
|
1402
1043
|
*
|
|
1403
|
-
* @param
|
|
1044
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1404
1045
|
* @returns The formatted tool result.
|
|
1405
1046
|
*/
|
|
1406
|
-
toModelOutput(
|
|
1047
|
+
toModelOutput(options) {
|
|
1048
|
+
const { output } = options;
|
|
1407
1049
|
if (output.matchingPaths.length === 0) {
|
|
1408
1050
|
return {
|
|
1409
1051
|
type: "text",
|
|
@@ -1452,26 +1094,287 @@ ${bulletPoints}
|
|
|
1452
1094
|
}
|
|
1453
1095
|
};
|
|
1454
1096
|
|
|
1455
|
-
// src/tools/
|
|
1097
|
+
// src/tools/grep-tool.ts
|
|
1456
1098
|
var import_zod6 = require("zod");
|
|
1457
|
-
var
|
|
1458
|
-
var
|
|
1099
|
+
var import_environment_utils11 = require("@ai-code-agents/environment-utils");
|
|
1100
|
+
var GrepToolName = "grep";
|
|
1101
|
+
var GrepToolInput = import_zod6.z.object({
|
|
1102
|
+
regexpPattern: import_zod6.z.string().meta({
|
|
1103
|
+
description: "The regular expression pattern to search for in file contents."
|
|
1104
|
+
}),
|
|
1105
|
+
searchPattern: import_zod6.z.string().optional().meta({
|
|
1106
|
+
description: 'The glob pattern to filter which files are searched (e.g. "**/*.ts"). If omitted, searches all files.'
|
|
1107
|
+
}),
|
|
1108
|
+
searchPath: import_zod6.z.string().optional().meta({
|
|
1109
|
+
description: "The path to search within, relative to the project directory. Defaults to the project directory."
|
|
1110
|
+
}),
|
|
1111
|
+
contextLines: import_zod6.z.number().int().nonnegative().optional().meta({
|
|
1112
|
+
description: "The number of context lines to include before and after each match."
|
|
1113
|
+
})
|
|
1114
|
+
});
|
|
1115
|
+
var GrepMatch = import_zod6.z.object({
|
|
1459
1116
|
path: import_zod6.z.string().meta({
|
|
1117
|
+
description: "The path to the file containing the match, relative to the project directory."
|
|
1118
|
+
}),
|
|
1119
|
+
lineNumber: import_zod6.z.number().int().meta({
|
|
1120
|
+
description: "The line number of the match (1-based)."
|
|
1121
|
+
}),
|
|
1122
|
+
line: import_zod6.z.string().meta({
|
|
1123
|
+
description: "The content of the matching line."
|
|
1124
|
+
}),
|
|
1125
|
+
beforeContext: import_zod6.z.array(import_zod6.z.string()).optional().meta({
|
|
1126
|
+
description: "Lines of context before the match."
|
|
1127
|
+
}),
|
|
1128
|
+
afterContext: import_zod6.z.array(import_zod6.z.string()).optional().meta({
|
|
1129
|
+
description: "Lines of context after the match."
|
|
1130
|
+
})
|
|
1131
|
+
});
|
|
1132
|
+
var GrepToolOutput = import_zod6.z.object({
|
|
1133
|
+
regexpPattern: import_zod6.z.string().meta({
|
|
1134
|
+
description: "The regular expression pattern that was searched for."
|
|
1135
|
+
}),
|
|
1136
|
+
searchPattern: import_zod6.z.string().optional().meta({
|
|
1137
|
+
description: "The glob pattern used to filter files."
|
|
1138
|
+
}),
|
|
1139
|
+
searchPath: import_zod6.z.string().optional().meta({
|
|
1140
|
+
description: "The path that was searched within."
|
|
1141
|
+
}),
|
|
1142
|
+
contextLines: import_zod6.z.number().optional().meta({
|
|
1143
|
+
description: "The number of context lines included."
|
|
1144
|
+
}),
|
|
1145
|
+
matches: import_zod6.z.array(GrepMatch).meta({
|
|
1146
|
+
description: "The list of matches found."
|
|
1147
|
+
})
|
|
1148
|
+
});
|
|
1149
|
+
var GrepTool = class extends import_environment_utils11.EnvironmentToolBase {
|
|
1150
|
+
/**
|
|
1151
|
+
* Returns the metadata for the tool.
|
|
1152
|
+
*
|
|
1153
|
+
* The name, description, and needsApproval properties are defaults which can be overridden in the constructor.
|
|
1154
|
+
*
|
|
1155
|
+
* @returns The tool metadata.
|
|
1156
|
+
*/
|
|
1157
|
+
getMetadata() {
|
|
1158
|
+
return {
|
|
1159
|
+
name: GrepToolName,
|
|
1160
|
+
description: "Searches for a regular expression pattern within the content of files in the project.",
|
|
1161
|
+
inputSchema: GrepToolInput,
|
|
1162
|
+
outputSchema: GrepToolOutput,
|
|
1163
|
+
needsApproval: false
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Executes the tool in the given execution environment with the given input.
|
|
1168
|
+
*
|
|
1169
|
+
* @param env - The execution environment to use.
|
|
1170
|
+
* @param input - The input for the tool.
|
|
1171
|
+
* @returns A promise that resolves to the tool execution result.
|
|
1172
|
+
*/
|
|
1173
|
+
async executeForEnvironment(env, input) {
|
|
1174
|
+
const {
|
|
1175
|
+
regexpPattern,
|
|
1176
|
+
searchPattern,
|
|
1177
|
+
searchPath = "",
|
|
1178
|
+
contextLines = 0
|
|
1179
|
+
} = input;
|
|
1180
|
+
if (searchPath) {
|
|
1181
|
+
(0, import_environment_utils11.validateRelativePath)(searchPath);
|
|
1182
|
+
}
|
|
1183
|
+
const globTool = new GlobTool(env);
|
|
1184
|
+
const globResult = await globTool.execute(
|
|
1185
|
+
{
|
|
1186
|
+
searchPattern: searchPattern || "**/*",
|
|
1187
|
+
searchPath
|
|
1188
|
+
},
|
|
1189
|
+
{}
|
|
1190
|
+
);
|
|
1191
|
+
const filesToSearch = globResult.matchingPaths;
|
|
1192
|
+
if (filesToSearch.length === 0) {
|
|
1193
|
+
return {
|
|
1194
|
+
regexpPattern,
|
|
1195
|
+
searchPattern,
|
|
1196
|
+
searchPath,
|
|
1197
|
+
contextLines,
|
|
1198
|
+
matches: []
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
const BATCH_SIZE = 50;
|
|
1202
|
+
const matches = [];
|
|
1203
|
+
for (let i = 0; i < filesToSearch.length; i += BATCH_SIZE) {
|
|
1204
|
+
const batch = filesToSearch.slice(i, i + BATCH_SIZE);
|
|
1205
|
+
const escapedFilePaths = batch.map(import_environment_utils11.escapeCommandArg).join(" ");
|
|
1206
|
+
const command = `grep -n -H -I -E ${(0, import_environment_utils11.escapeCommandArg)(regexpPattern)} ${escapedFilePaths}`;
|
|
1207
|
+
const { stdout, exitCode } = await env.runCommand(command);
|
|
1208
|
+
if (exitCode > 1) {
|
|
1209
|
+
throw new Error(`Failed to execute grep command "${command}".`);
|
|
1210
|
+
}
|
|
1211
|
+
if (stdout) {
|
|
1212
|
+
const lines = stdout.split("\n");
|
|
1213
|
+
for (const line of lines) {
|
|
1214
|
+
if (!line.trim()) continue;
|
|
1215
|
+
const firstColonIndex = line.indexOf(":");
|
|
1216
|
+
if (firstColonIndex === -1) continue;
|
|
1217
|
+
const secondColonIndex = line.indexOf(":", firstColonIndex + 1);
|
|
1218
|
+
if (secondColonIndex === -1) continue;
|
|
1219
|
+
const filePath = line.substring(0, firstColonIndex);
|
|
1220
|
+
const lineNumberStr = line.substring(
|
|
1221
|
+
firstColonIndex + 1,
|
|
1222
|
+
secondColonIndex
|
|
1223
|
+
);
|
|
1224
|
+
const content = line.substring(secondColonIndex + 1);
|
|
1225
|
+
const lineNumber = parseInt(lineNumberStr, 10);
|
|
1226
|
+
if (isNaN(lineNumber)) continue;
|
|
1227
|
+
matches.push({
|
|
1228
|
+
path: filePath,
|
|
1229
|
+
lineNumber,
|
|
1230
|
+
line: content
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
if (contextLines > 0 && matches.length > 0) {
|
|
1236
|
+
const matchesByFile = /* @__PURE__ */ new Map();
|
|
1237
|
+
for (const match of matches) {
|
|
1238
|
+
if (!matchesByFile.has(match.path)) {
|
|
1239
|
+
matchesByFile.set(match.path, []);
|
|
1240
|
+
}
|
|
1241
|
+
matchesByFile.get(match.path).push(match);
|
|
1242
|
+
}
|
|
1243
|
+
for (const [filePath, fileMatches] of matchesByFile) {
|
|
1244
|
+
try {
|
|
1245
|
+
const { content } = await env.readFile(filePath);
|
|
1246
|
+
const lines = content.split("\n");
|
|
1247
|
+
for (const match of fileMatches) {
|
|
1248
|
+
const lineIndex = match.lineNumber - 1;
|
|
1249
|
+
const start = Math.max(0, lineIndex - contextLines);
|
|
1250
|
+
const end = Math.min(lines.length, lineIndex + contextLines + 1);
|
|
1251
|
+
match.beforeContext = lines.slice(start, lineIndex);
|
|
1252
|
+
match.afterContext = lines.slice(lineIndex + 1, end);
|
|
1253
|
+
}
|
|
1254
|
+
} catch (_error) {
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
return {
|
|
1259
|
+
regexpPattern,
|
|
1260
|
+
searchPattern,
|
|
1261
|
+
searchPath,
|
|
1262
|
+
contextLines,
|
|
1263
|
+
matches
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
/**
|
|
1267
|
+
* Converts the tool output to a format suitable for model consumption.
|
|
1268
|
+
*
|
|
1269
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1270
|
+
* @returns The formatted tool result.
|
|
1271
|
+
*/
|
|
1272
|
+
toModelOutput(options) {
|
|
1273
|
+
const { output } = options;
|
|
1274
|
+
if (output.matches.length === 0) {
|
|
1275
|
+
return {
|
|
1276
|
+
type: "text",
|
|
1277
|
+
value: "No matches found."
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
let result = `Found ${output.matches.length} matches:
|
|
1281
|
+
`;
|
|
1282
|
+
const matchesByFile = /* @__PURE__ */ new Map();
|
|
1283
|
+
for (const match of output.matches) {
|
|
1284
|
+
if (!matchesByFile.has(match.path)) {
|
|
1285
|
+
matchesByFile.set(match.path, []);
|
|
1286
|
+
}
|
|
1287
|
+
matchesByFile.get(match.path).push(match);
|
|
1288
|
+
}
|
|
1289
|
+
for (const [filePath, matches] of matchesByFile) {
|
|
1290
|
+
result += `
|
|
1291
|
+
File: ${filePath}
|
|
1292
|
+
`;
|
|
1293
|
+
for (const match of matches) {
|
|
1294
|
+
if (match.beforeContext && match.beforeContext.length > 0) {
|
|
1295
|
+
match.beforeContext.forEach((line, idx) => {
|
|
1296
|
+
result += ` ${match.lineNumber - match.beforeContext.length + idx}: ${line}
|
|
1297
|
+
`;
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
result += `> ${match.lineNumber}: ${match.line}
|
|
1301
|
+
`;
|
|
1302
|
+
if (match.afterContext && match.afterContext.length > 0) {
|
|
1303
|
+
match.afterContext.forEach((line, idx) => {
|
|
1304
|
+
result += ` ${match.lineNumber + 1 + idx}: ${line}
|
|
1305
|
+
`;
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
if (output.contextLines && output.contextLines > 0) {
|
|
1309
|
+
result += "---\n";
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
return {
|
|
1314
|
+
type: "text",
|
|
1315
|
+
value: result
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Gets the examples for the tool.
|
|
1320
|
+
*
|
|
1321
|
+
* @returns The tool examples.
|
|
1322
|
+
*/
|
|
1323
|
+
get examples() {
|
|
1324
|
+
return [
|
|
1325
|
+
{
|
|
1326
|
+
input: {
|
|
1327
|
+
regexpPattern: "interface.*Tool",
|
|
1328
|
+
searchPattern: "src/**/*.ts"
|
|
1329
|
+
},
|
|
1330
|
+
output: `Found 2 matches:
|
|
1331
|
+
|
|
1332
|
+
File: src/types.ts
|
|
1333
|
+
> 120: export interface ToolInterface<ToolInputType, ToolOutputType> {
|
|
1334
|
+
> 135: export interface EnvironmentToolInterface<
|
|
1335
|
+
|
|
1336
|
+
File: src/tools/tool-base.ts
|
|
1337
|
+
> 10: export abstract class ToolBase<
|
|
1338
|
+
`
|
|
1339
|
+
},
|
|
1340
|
+
{
|
|
1341
|
+
input: {
|
|
1342
|
+
regexpPattern: "TODO",
|
|
1343
|
+
contextLines: 1
|
|
1344
|
+
},
|
|
1345
|
+
output: `Found 1 matches:
|
|
1346
|
+
|
|
1347
|
+
File: src/index.ts
|
|
1348
|
+
10: // Some code before
|
|
1349
|
+
> 11: // TODO: Implement feature X
|
|
1350
|
+
12: // Some code after
|
|
1351
|
+
`
|
|
1352
|
+
}
|
|
1353
|
+
];
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1357
|
+
// src/tools/list-directory-tool.ts
|
|
1358
|
+
var import_zod7 = require("zod");
|
|
1359
|
+
var import_environment_utils12 = require("@ai-code-agents/environment-utils");
|
|
1360
|
+
var ListDirectoryToolName = "list_directory";
|
|
1361
|
+
var ListDirectoryToolInput = import_zod7.z.object({
|
|
1362
|
+
path: import_zod7.z.string().meta({
|
|
1460
1363
|
description: "The directory path to list, relative to the project directory."
|
|
1461
1364
|
})
|
|
1462
1365
|
});
|
|
1463
|
-
var ListDirectoryToolOutput =
|
|
1464
|
-
path:
|
|
1366
|
+
var ListDirectoryToolOutput = import_zod7.z.object({
|
|
1367
|
+
path: import_zod7.z.string().meta({
|
|
1465
1368
|
description: "The directory path that was listed."
|
|
1466
1369
|
}),
|
|
1467
|
-
files:
|
|
1370
|
+
files: import_zod7.z.array(import_zod7.z.string()).meta({
|
|
1468
1371
|
description: "List of files in the directory."
|
|
1469
1372
|
}),
|
|
1470
|
-
directories:
|
|
1373
|
+
directories: import_zod7.z.array(import_zod7.z.string()).meta({
|
|
1471
1374
|
description: "List of subdirectories in the directory."
|
|
1472
1375
|
})
|
|
1473
1376
|
});
|
|
1474
|
-
var ListDirectoryTool = class extends EnvironmentToolBase {
|
|
1377
|
+
var ListDirectoryTool = class extends import_environment_utils12.EnvironmentToolBase {
|
|
1475
1378
|
/**
|
|
1476
1379
|
* Returns the metadata for the tool.
|
|
1477
1380
|
*
|
|
@@ -1496,7 +1399,7 @@ var ListDirectoryTool = class extends EnvironmentToolBase {
|
|
|
1496
1399
|
* @returns A promise that resolves to the tool execution result.
|
|
1497
1400
|
*/
|
|
1498
1401
|
async executeForEnvironment(env, input) {
|
|
1499
|
-
const escapedPath = escapeCommandArg(input.path);
|
|
1402
|
+
const escapedPath = (0, import_environment_utils12.escapeCommandArg)(input.path);
|
|
1500
1403
|
const command = `ls -la ${escapedPath}`;
|
|
1501
1404
|
const { stdout, stderr, exitCode } = await env.runCommand(command);
|
|
1502
1405
|
if (exitCode !== 0) {
|
|
@@ -1529,10 +1432,11 @@ var ListDirectoryTool = class extends EnvironmentToolBase {
|
|
|
1529
1432
|
/**
|
|
1530
1433
|
* Converts the tool output to a format suitable for model consumption.
|
|
1531
1434
|
*
|
|
1532
|
-
* @param
|
|
1435
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1533
1436
|
* @returns The formatted tool result.
|
|
1534
1437
|
*/
|
|
1535
|
-
toModelOutput(
|
|
1438
|
+
toModelOutput(options) {
|
|
1439
|
+
const { output } = options;
|
|
1536
1440
|
const formatEntries = (entries, type) => {
|
|
1537
1441
|
if (entries.length === 0) {
|
|
1538
1442
|
return `No ${type} found.`;
|
|
@@ -1578,18 +1482,19 @@ Directories:
|
|
|
1578
1482
|
};
|
|
1579
1483
|
|
|
1580
1484
|
// src/tools/move-file-tool.ts
|
|
1581
|
-
var
|
|
1485
|
+
var import_zod8 = require("zod");
|
|
1486
|
+
var import_environment_utils13 = require("@ai-code-agents/environment-utils");
|
|
1582
1487
|
var MoveFileToolName = "move_file";
|
|
1583
|
-
var MoveFileToolInput =
|
|
1584
|
-
sourcePath:
|
|
1488
|
+
var MoveFileToolInput = import_zod8.z.object({
|
|
1489
|
+
sourcePath: import_zod8.z.string().meta({
|
|
1585
1490
|
description: "The path to the file to move, relative to the project directory."
|
|
1586
1491
|
}),
|
|
1587
|
-
destinationPath:
|
|
1492
|
+
destinationPath: import_zod8.z.string().meta({
|
|
1588
1493
|
description: "The path to the destination where the file should be moved, relative to the project directory. If the file already exists, it will be overwritten."
|
|
1589
1494
|
})
|
|
1590
1495
|
});
|
|
1591
|
-
var MoveFileToolOutput = MoveFileResult;
|
|
1592
|
-
var MoveFileTool = class extends EnvironmentToolBase {
|
|
1496
|
+
var MoveFileToolOutput = import_environment_utils13.MoveFileResult;
|
|
1497
|
+
var MoveFileTool = class extends import_environment_utils13.EnvironmentToolBase {
|
|
1593
1498
|
/**
|
|
1594
1499
|
* Returns the metadata for the tool.
|
|
1595
1500
|
*
|
|
@@ -1619,10 +1524,11 @@ var MoveFileTool = class extends EnvironmentToolBase {
|
|
|
1619
1524
|
/**
|
|
1620
1525
|
* Converts the tool output to a format suitable for model consumption.
|
|
1621
1526
|
*
|
|
1622
|
-
* @param
|
|
1527
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1623
1528
|
* @returns The formatted tool result.
|
|
1624
1529
|
*/
|
|
1625
|
-
toModelOutput(
|
|
1530
|
+
toModelOutput(options) {
|
|
1531
|
+
const { output } = options;
|
|
1626
1532
|
return {
|
|
1627
1533
|
type: "text",
|
|
1628
1534
|
value: `File \`${output.sourcePath}\` moved successfully to \`${output.destinationPath}\`.`
|
|
@@ -1647,10 +1553,11 @@ var MoveFileTool = class extends EnvironmentToolBase {
|
|
|
1647
1553
|
};
|
|
1648
1554
|
|
|
1649
1555
|
// src/tools/read-file-tool.ts
|
|
1650
|
-
var
|
|
1556
|
+
var import_zod9 = require("zod");
|
|
1557
|
+
var import_environment_utils14 = require("@ai-code-agents/environment-utils");
|
|
1651
1558
|
|
|
1652
1559
|
// src/util/get-language-identifier-from-file-path.ts
|
|
1653
|
-
var
|
|
1560
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1654
1561
|
var jsLanguage = {
|
|
1655
1562
|
identifier: "javascript",
|
|
1656
1563
|
name: "JavaScript",
|
|
@@ -1800,7 +1707,7 @@ var EXTENSION_TO_LANGUAGE = {
|
|
|
1800
1707
|
}
|
|
1801
1708
|
};
|
|
1802
1709
|
function getLanguageFromFilePath(filePath) {
|
|
1803
|
-
const extension =
|
|
1710
|
+
const extension = import_node_path4.default.extname(filePath).slice(1).toLowerCase() || "";
|
|
1804
1711
|
return EXTENSION_TO_LANGUAGE[extension];
|
|
1805
1712
|
}
|
|
1806
1713
|
function getLanguageIdentifierFromFilePath(filePath) {
|
|
@@ -1810,12 +1717,12 @@ function getLanguageIdentifierFromFilePath(filePath) {
|
|
|
1810
1717
|
|
|
1811
1718
|
// src/tools/read-file-tool.ts
|
|
1812
1719
|
var ReadFileToolName = "read_file";
|
|
1813
|
-
var ReadFileToolInput =
|
|
1814
|
-
path:
|
|
1720
|
+
var ReadFileToolInput = import_zod9.z.object({
|
|
1721
|
+
path: import_zod9.z.string().meta({
|
|
1815
1722
|
description: "The path to the file to read, relative to the project directory."
|
|
1816
1723
|
})
|
|
1817
1724
|
});
|
|
1818
|
-
var ReadFileToolOutput = ReadFileResult;
|
|
1725
|
+
var ReadFileToolOutput = import_environment_utils14.ReadFileResult;
|
|
1819
1726
|
var formatModelResponse = (output) => {
|
|
1820
1727
|
const language = getLanguageIdentifierFromFilePath(output.path);
|
|
1821
1728
|
return `File: \`${output.path}\`
|
|
@@ -1825,7 +1732,7 @@ ${output.content}
|
|
|
1825
1732
|
\`\`\`
|
|
1826
1733
|
`;
|
|
1827
1734
|
};
|
|
1828
|
-
var ReadFileTool = class extends EnvironmentToolBase {
|
|
1735
|
+
var ReadFileTool = class extends import_environment_utils14.EnvironmentToolBase {
|
|
1829
1736
|
/**
|
|
1830
1737
|
* Returns the metadata for the tool.
|
|
1831
1738
|
*
|
|
@@ -1855,10 +1762,11 @@ var ReadFileTool = class extends EnvironmentToolBase {
|
|
|
1855
1762
|
/**
|
|
1856
1763
|
* Converts the tool output to a format suitable for model consumption.
|
|
1857
1764
|
*
|
|
1858
|
-
* @param
|
|
1765
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1859
1766
|
* @returns The formatted tool result.
|
|
1860
1767
|
*/
|
|
1861
|
-
toModelOutput(
|
|
1768
|
+
toModelOutput(options) {
|
|
1769
|
+
const { output } = options;
|
|
1862
1770
|
return {
|
|
1863
1771
|
type: "text",
|
|
1864
1772
|
value: formatModelResponse(output)
|
|
@@ -1901,14 +1809,15 @@ export function Loader(props: LoaderProps) {
|
|
|
1901
1809
|
};
|
|
1902
1810
|
|
|
1903
1811
|
// src/tools/read-many-files-tool.ts
|
|
1904
|
-
var
|
|
1812
|
+
var import_zod10 = require("zod");
|
|
1813
|
+
var import_environment_utils15 = require("@ai-code-agents/environment-utils");
|
|
1905
1814
|
var ReadManyFilesToolName = "read_many_files";
|
|
1906
|
-
var ReadManyFilesToolInput =
|
|
1907
|
-
paths:
|
|
1815
|
+
var ReadManyFilesToolInput = import_zod10.z.object({
|
|
1816
|
+
paths: import_zod10.z.array(import_zod10.z.string()).meta({
|
|
1908
1817
|
description: "The paths to the files to read, relative to the project directory."
|
|
1909
1818
|
})
|
|
1910
1819
|
});
|
|
1911
|
-
var ReadManyFilesToolOutput =
|
|
1820
|
+
var ReadManyFilesToolOutput = import_zod10.z.record(import_zod10.z.string(), import_environment_utils15.ReadFileResult);
|
|
1912
1821
|
var formatModelResponse2 = (output) => {
|
|
1913
1822
|
const language = getLanguageIdentifierFromFilePath(output.path);
|
|
1914
1823
|
return `File: \`${output.path}\`
|
|
@@ -1918,7 +1827,7 @@ ${output.content}
|
|
|
1918
1827
|
\`\`\`
|
|
1919
1828
|
`;
|
|
1920
1829
|
};
|
|
1921
|
-
var ReadManyFilesTool = class extends EnvironmentToolBase {
|
|
1830
|
+
var ReadManyFilesTool = class extends import_environment_utils15.EnvironmentToolBase {
|
|
1922
1831
|
/**
|
|
1923
1832
|
* Returns the metadata for the tool.
|
|
1924
1833
|
*
|
|
@@ -1954,10 +1863,11 @@ var ReadManyFilesTool = class extends EnvironmentToolBase {
|
|
|
1954
1863
|
/**
|
|
1955
1864
|
* Converts the tool output to a format suitable for model consumption.
|
|
1956
1865
|
*
|
|
1957
|
-
* @param
|
|
1866
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1958
1867
|
* @returns The formatted tool result.
|
|
1959
1868
|
*/
|
|
1960
|
-
toModelOutput(
|
|
1869
|
+
toModelOutput(options) {
|
|
1870
|
+
const { output } = options;
|
|
1961
1871
|
const fileContentResponses = Object.values(output).map(
|
|
1962
1872
|
(fileResult) => formatModelResponse2(fileResult)
|
|
1963
1873
|
);
|
|
@@ -2013,12 +1923,13 @@ export function Loader(props: LoaderProps) {
|
|
|
2013
1923
|
};
|
|
2014
1924
|
|
|
2015
1925
|
// src/tools/run-command-tool.ts
|
|
2016
|
-
var
|
|
1926
|
+
var import_zod11 = require("zod");
|
|
1927
|
+
var import_environment_utils16 = require("@ai-code-agents/environment-utils");
|
|
2017
1928
|
var RunCommandToolName = "run_command";
|
|
2018
|
-
var RunCommandToolInput =
|
|
2019
|
-
command:
|
|
1929
|
+
var RunCommandToolInput = import_zod11.z.object({
|
|
1930
|
+
command: import_zod11.z.string().meta({ description: "The CLI command to run, including all arguments." })
|
|
2020
1931
|
});
|
|
2021
|
-
var RunCommandToolOutput = RunCommandResult;
|
|
1932
|
+
var RunCommandToolOutput = import_environment_utils16.RunCommandResult;
|
|
2022
1933
|
function formatCommandResultToModelResponse(output) {
|
|
2023
1934
|
const stdout = !output.stdout.trim() ? "(none)" : `
|
|
2024
1935
|
\`\`\`
|
|
@@ -2034,7 +1945,7 @@ Output (stdout): ${stdout}
|
|
|
2034
1945
|
Error Output (stderr): ${stderr}
|
|
2035
1946
|
`;
|
|
2036
1947
|
}
|
|
2037
|
-
var RunCommandTool = class extends EnvironmentToolBase {
|
|
1948
|
+
var RunCommandTool = class extends import_environment_utils16.EnvironmentToolBase {
|
|
2038
1949
|
/**
|
|
2039
1950
|
* Returns the metadata for the tool.
|
|
2040
1951
|
*
|
|
@@ -2064,10 +1975,11 @@ var RunCommandTool = class extends EnvironmentToolBase {
|
|
|
2064
1975
|
/**
|
|
2065
1976
|
* Converts the tool output to a format suitable for model consumption.
|
|
2066
1977
|
*
|
|
2067
|
-
* @param
|
|
1978
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
2068
1979
|
* @returns The formatted tool result.
|
|
2069
1980
|
*/
|
|
2070
|
-
toModelOutput(
|
|
1981
|
+
toModelOutput(options) {
|
|
1982
|
+
const { output } = options;
|
|
2071
1983
|
return {
|
|
2072
1984
|
type: "text",
|
|
2073
1985
|
value: formatCommandResultToModelResponse(output)
|
|
@@ -2138,18 +2050,19 @@ added 1 package, and changed 1 package in 2s
|
|
|
2138
2050
|
};
|
|
2139
2051
|
|
|
2140
2052
|
// src/tools/write-file-tool.ts
|
|
2141
|
-
var
|
|
2053
|
+
var import_zod12 = require("zod");
|
|
2054
|
+
var import_environment_utils17 = require("@ai-code-agents/environment-utils");
|
|
2142
2055
|
var WriteFileToolName = "write_file";
|
|
2143
|
-
var WriteFileToolInput =
|
|
2144
|
-
path:
|
|
2056
|
+
var WriteFileToolInput = import_zod12.z.object({
|
|
2057
|
+
path: import_zod12.z.string().meta({
|
|
2145
2058
|
description: "The path to the file to write, relative to the project directory."
|
|
2146
2059
|
}),
|
|
2147
|
-
content:
|
|
2060
|
+
content: import_zod12.z.string().meta({
|
|
2148
2061
|
description: "The content to write to the file. If the file already exists, the content will replace existing content."
|
|
2149
2062
|
})
|
|
2150
2063
|
});
|
|
2151
|
-
var WriteFileToolOutput = WriteFileResult;
|
|
2152
|
-
var WriteFileTool = class extends EnvironmentToolBase {
|
|
2064
|
+
var WriteFileToolOutput = import_environment_utils17.WriteFileResult;
|
|
2065
|
+
var WriteFileTool = class extends import_environment_utils17.EnvironmentToolBase {
|
|
2153
2066
|
/**
|
|
2154
2067
|
* Returns the metadata for the tool.
|
|
2155
2068
|
*
|
|
@@ -2179,10 +2092,11 @@ var WriteFileTool = class extends EnvironmentToolBase {
|
|
|
2179
2092
|
/**
|
|
2180
2093
|
* Converts the tool output to a format suitable for model consumption.
|
|
2181
2094
|
*
|
|
2182
|
-
* @param
|
|
2095
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
2183
2096
|
* @returns The formatted tool result.
|
|
2184
2097
|
*/
|
|
2185
|
-
toModelOutput(
|
|
2098
|
+
toModelOutput(options) {
|
|
2099
|
+
const { output } = options;
|
|
2186
2100
|
return {
|
|
2187
2101
|
type: "text",
|
|
2188
2102
|
value: `File \`${output.path}\` written successfully.`
|
|
@@ -2211,11 +2125,12 @@ var WriteFileTool = class extends EnvironmentToolBase {
|
|
|
2211
2125
|
};
|
|
2212
2126
|
|
|
2213
2127
|
// src/tools/submit-tool.ts
|
|
2214
|
-
var
|
|
2128
|
+
var import_zod13 = require("zod");
|
|
2129
|
+
var import_environment_utils18 = require("@ai-code-agents/environment-utils");
|
|
2215
2130
|
var SubmitToolName = "submit";
|
|
2216
|
-
var SubmitToolInput =
|
|
2217
|
-
var SubmitToolOutput =
|
|
2218
|
-
var SubmitTool = class extends ToolBase {
|
|
2131
|
+
var SubmitToolInput = import_zod13.z.object({});
|
|
2132
|
+
var SubmitToolOutput = import_zod13.z.object({});
|
|
2133
|
+
var SubmitTool = class extends import_environment_utils18.ToolBase {
|
|
2219
2134
|
/**
|
|
2220
2135
|
* Returns the metadata for the tool.
|
|
2221
2136
|
*
|
|
@@ -2236,7 +2151,7 @@ var SubmitTool = class extends ToolBase {
|
|
|
2236
2151
|
* Executes the tool with the given input.
|
|
2237
2152
|
*
|
|
2238
2153
|
* @param _ - The input for the tool. Unused.
|
|
2239
|
-
* @param __ - Options
|
|
2154
|
+
* @param __ - Options for the tool execution. Unused.
|
|
2240
2155
|
* @returns A promise that resolves to the tool execution result.
|
|
2241
2156
|
*/
|
|
2242
2157
|
async execute(_, __) {
|
|
@@ -2245,7 +2160,7 @@ var SubmitTool = class extends ToolBase {
|
|
|
2245
2160
|
/**
|
|
2246
2161
|
* Converts the tool output to a format suitable for model consumption.
|
|
2247
2162
|
*
|
|
2248
|
-
* @param _ - The output from the tool execution. Unused.
|
|
2163
|
+
* @param _ - The tool result, including the output from the tool execution. Unused.
|
|
2249
2164
|
* @returns The formatted tool result.
|
|
2250
2165
|
*/
|
|
2251
2166
|
toModelOutput(_) {
|
|
@@ -2270,10 +2185,13 @@ var import_ai = require("ai");
|
|
|
2270
2185
|
// src/instructions.ts
|
|
2271
2186
|
function getAdditionalInstructions(config) {
|
|
2272
2187
|
const { maxSteps, allowSubmit, tools } = config;
|
|
2273
|
-
const exampleSections = [
|
|
2188
|
+
const exampleSections = [
|
|
2189
|
+
"# Tool Examples",
|
|
2190
|
+
"You have access to several tools to assist you in completing your task. Here are some examples of how to use them:"
|
|
2191
|
+
];
|
|
2274
2192
|
for (const [toolName, tool] of Object.entries(tools)) {
|
|
2275
2193
|
if ("examples" in tool && Array.isArray(tool.examples) && tool.examples.length > 0) {
|
|
2276
|
-
let toolSection =
|
|
2194
|
+
let toolSection = `## Tool: \`${toolName}\`
|
|
2277
2195
|
|
|
2278
2196
|
`;
|
|
2279
2197
|
for (const example of tool.examples) {
|
|
@@ -2282,40 +2200,48 @@ function getAdditionalInstructions(config) {
|
|
|
2282
2200
|
exampleSections.push(toolSection.trim());
|
|
2283
2201
|
}
|
|
2284
2202
|
}
|
|
2285
|
-
const
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
"You have access to several tools to assist you in completing your task."
|
|
2292
|
-
] : [],
|
|
2293
|
-
"You must issue tool calls to complete your task. Do not engage with the user directly.",
|
|
2294
|
-
...allowSubmit ? [
|
|
2295
|
-
`Once you think you have completed your task, call the \`${SubmitToolName}\` tool to submit your results.`
|
|
2296
|
-
] : [],
|
|
2297
|
-
`You have a maximum of ${maxSteps} steps to complete your task.`
|
|
2298
|
-
];
|
|
2299
|
-
const importantWorkflowGuidelines = `## Important Workflow Guidelines
|
|
2300
|
-
|
|
2301
|
-
${workflowGuidelines.map((line) => `- ${line}`).join("\n")}
|
|
2302
|
-
|
|
2303
|
-
Remember, you don't get to ask the user any clarifying questions, just use the tools available to complete your task. You're on your own now.
|
|
2203
|
+
const constraintSections = ["# Behavioral Guidelines"];
|
|
2204
|
+
const constraintsByType = getCodeAgentConstraints({ maxSteps, allowSubmit });
|
|
2205
|
+
if (constraintsByType.must && constraintsByType.must.length > 0) {
|
|
2206
|
+
let constraintSection = "## You MUST:\n\n";
|
|
2207
|
+
for (const constraint of constraintsByType.must) {
|
|
2208
|
+
constraintSection += `- ${constraint}
|
|
2304
2209
|
`;
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
You have access to several tools to assist you in completing your task. Here are some examples of how to use them:
|
|
2309
|
-
|
|
2310
|
-
${exampleSections.join("\n\n")}
|
|
2311
|
-
|
|
2312
|
-
` + importantWorkflowGuidelines;
|
|
2210
|
+
}
|
|
2211
|
+
constraintSections.push(constraintSection.trim());
|
|
2313
2212
|
}
|
|
2314
|
-
|
|
2213
|
+
if (constraintsByType.must_not && constraintsByType.must_not.length > 0) {
|
|
2214
|
+
let constraintSection = "## You MUST NOT:\n\n";
|
|
2215
|
+
for (const constraint of constraintsByType.must_not) {
|
|
2216
|
+
constraintSection += `- ${constraint}
|
|
2217
|
+
`;
|
|
2218
|
+
}
|
|
2219
|
+
constraintSections.push(constraintSection.trim());
|
|
2220
|
+
}
|
|
2221
|
+
if (constraintsByType.should && constraintsByType.should.length > 0) {
|
|
2222
|
+
let constraintSection = "## You SHOULD:\n\n";
|
|
2223
|
+
for (const constraint of constraintsByType.should) {
|
|
2224
|
+
constraintSection += `- ${constraint}
|
|
2225
|
+
`;
|
|
2226
|
+
}
|
|
2227
|
+
constraintSections.push(constraintSection.trim());
|
|
2228
|
+
}
|
|
2229
|
+
if (constraintsByType.should_not && constraintsByType.should_not.length > 0) {
|
|
2230
|
+
let constraintSection = "## You SHOULD NOT:\n\n";
|
|
2231
|
+
for (const constraint of constraintsByType.should_not) {
|
|
2232
|
+
constraintSection += `- ${constraint}
|
|
2233
|
+
`;
|
|
2234
|
+
}
|
|
2235
|
+
constraintSections.push(constraintSection.trim());
|
|
2236
|
+
}
|
|
2237
|
+
const finalReminder = getCodeAgentFinalReminder();
|
|
2238
|
+
return [...exampleSections, ...constraintSections, finalReminder].join(
|
|
2239
|
+
"\n\n"
|
|
2240
|
+
);
|
|
2315
2241
|
}
|
|
2316
2242
|
function formatExampleForInstructions(toolName, example) {
|
|
2317
|
-
const input =
|
|
2318
|
-
const output =
|
|
2243
|
+
const input = formatValueForExample(example.input);
|
|
2244
|
+
const output = formatValueForExample(example.output);
|
|
2319
2245
|
if (output === "") {
|
|
2320
2246
|
return `<example>
|
|
2321
2247
|
<tool_call>
|
|
@@ -2332,8 +2258,40 @@ ${output}
|
|
|
2332
2258
|
</tool_response>
|
|
2333
2259
|
</example>`;
|
|
2334
2260
|
}
|
|
2261
|
+
function formatValueForExample(value) {
|
|
2262
|
+
if (typeof value === "undefined") {
|
|
2263
|
+
return "";
|
|
2264
|
+
}
|
|
2265
|
+
if (typeof value === "string") {
|
|
2266
|
+
return `"${value}"`;
|
|
2267
|
+
}
|
|
2268
|
+
if (typeof value === "number") {
|
|
2269
|
+
return value.toString();
|
|
2270
|
+
}
|
|
2271
|
+
if (typeof value === "boolean") {
|
|
2272
|
+
return value ? "true" : "false";
|
|
2273
|
+
}
|
|
2274
|
+
return JSON.stringify(value, null, 2);
|
|
2275
|
+
}
|
|
2276
|
+
function getCodeAgentConstraints(config) {
|
|
2277
|
+
const { maxSteps, allowSubmit } = config;
|
|
2278
|
+
return {
|
|
2279
|
+
must: [
|
|
2280
|
+
"Always issue tool calls to complete your task",
|
|
2281
|
+
...allowSubmit ? [
|
|
2282
|
+
`Call the \`${SubmitToolName}\` tool once you think you have completed your task, to submit your results`
|
|
2283
|
+
] : [],
|
|
2284
|
+
`Complete your task within ${maxSteps} steps`
|
|
2285
|
+
],
|
|
2286
|
+
must_not: ["Engage with the user directly"]
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2289
|
+
function getCodeAgentFinalReminder() {
|
|
2290
|
+
return "Remember, you don't get to ask the user any clarifying questions, just use the tools available to complete your task. You're on your own now.";
|
|
2291
|
+
}
|
|
2335
2292
|
|
|
2336
2293
|
// src/tool-creators.ts
|
|
2294
|
+
var import_environment_utils19 = require("@ai-code-agents/environment-utils");
|
|
2337
2295
|
var availableEnvironmentTools = {
|
|
2338
2296
|
[ReadFileToolName]: ReadFileTool,
|
|
2339
2297
|
[WriteFileToolName]: WriteFileTool,
|
|
@@ -2344,12 +2302,14 @@ var availableEnvironmentTools = {
|
|
|
2344
2302
|
[ReadManyFilesToolName]: ReadManyFilesTool,
|
|
2345
2303
|
[GetProjectFileStructureToolName]: GetProjectFileStructureTool,
|
|
2346
2304
|
[GlobToolName]: GlobTool,
|
|
2305
|
+
[GrepToolName]: GrepTool,
|
|
2347
2306
|
[ListDirectoryToolName]: ListDirectoryTool,
|
|
2348
2307
|
[RunCommandToolName]: RunCommandTool
|
|
2349
2308
|
};
|
|
2350
2309
|
var cliOnlyTools = [
|
|
2351
2310
|
GetProjectFileStructureToolName,
|
|
2352
2311
|
GlobToolName,
|
|
2312
|
+
GrepToolName,
|
|
2353
2313
|
ListDirectoryToolName,
|
|
2354
2314
|
RunCommandToolName
|
|
2355
2315
|
];
|
|
@@ -2358,6 +2318,7 @@ var readonlyTools = [
|
|
|
2358
2318
|
ReadManyFilesToolName,
|
|
2359
2319
|
GetProjectFileStructureToolName,
|
|
2360
2320
|
GlobToolName,
|
|
2321
|
+
GrepToolName,
|
|
2361
2322
|
ListDirectoryToolName
|
|
2362
2323
|
];
|
|
2363
2324
|
var dangerousTools = [
|
|
@@ -2385,7 +2346,7 @@ function createEnvironmentTool(toolName, environment, config) {
|
|
|
2385
2346
|
}
|
|
2386
2347
|
function createToolsForEnvironment(environment, toolsDefinition = "all") {
|
|
2387
2348
|
const sanitizedToolsDefinition = sanitizeToolsDefinition(toolsDefinition);
|
|
2388
|
-
const isCliEnvironment =
|
|
2349
|
+
const isCliEnvironment = (0, import_environment_utils19.isCommandLine)(environment);
|
|
2389
2350
|
const tools = {};
|
|
2390
2351
|
for (const toolDefinition of sanitizedToolsDefinition) {
|
|
2391
2352
|
const actualToolName = toolDefinition.toolName;
|
|
@@ -2406,7 +2367,7 @@ function createToolsForEnvironment(environment, toolsDefinition = "all") {
|
|
|
2406
2367
|
}
|
|
2407
2368
|
tools[toolNameToUse] = createEnvironmentTool(
|
|
2408
2369
|
actualToolName,
|
|
2409
|
-
|
|
2370
|
+
environment,
|
|
2410
2371
|
toolConfig
|
|
2411
2372
|
);
|
|
2412
2373
|
}
|
|
@@ -2462,6 +2423,54 @@ function sanitizeToolsDefinition(toolsDefinition) {
|
|
|
2462
2423
|
});
|
|
2463
2424
|
}
|
|
2464
2425
|
|
|
2426
|
+
// src/util/truncate.ts
|
|
2427
|
+
function truncateString(str) {
|
|
2428
|
+
const lines = str.split("\n");
|
|
2429
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
2430
|
+
lines.pop();
|
|
2431
|
+
}
|
|
2432
|
+
const isMultiline = lines.length > 1;
|
|
2433
|
+
if (isMultiline) {
|
|
2434
|
+
if (lines.length > 5) {
|
|
2435
|
+
const truncatedLines = lines.slice(0, 5).join("\n");
|
|
2436
|
+
const moreLines = lines.length - 5;
|
|
2437
|
+
const lineSuffix = moreLines === 1 ? "line" : "lines";
|
|
2438
|
+
return `${truncatedLines}
|
|
2439
|
+
...(${moreLines} more ${lineSuffix})`;
|
|
2440
|
+
}
|
|
2441
|
+
return lines.join("\n");
|
|
2442
|
+
}
|
|
2443
|
+
const singleLine = lines[0] || "";
|
|
2444
|
+
if (singleLine.length > 300) {
|
|
2445
|
+
const moreChars = singleLine.length - 300;
|
|
2446
|
+
return `${singleLine.slice(0, 300)}...(${moreChars} more characters)`;
|
|
2447
|
+
}
|
|
2448
|
+
return singleLine;
|
|
2449
|
+
}
|
|
2450
|
+
function truncateObject(obj) {
|
|
2451
|
+
const result = {};
|
|
2452
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
2453
|
+
if (typeof value === "string") {
|
|
2454
|
+
result[key] = truncateString(value);
|
|
2455
|
+
} else if (Array.isArray(value)) {
|
|
2456
|
+
result[key] = value.map((item) => {
|
|
2457
|
+
if (typeof item === "string") {
|
|
2458
|
+
return truncateString(item);
|
|
2459
|
+
}
|
|
2460
|
+
if (typeof item === "object" && item !== null) {
|
|
2461
|
+
return truncateObject(item);
|
|
2462
|
+
}
|
|
2463
|
+
return item;
|
|
2464
|
+
});
|
|
2465
|
+
} else if (typeof value === "object" && value !== null) {
|
|
2466
|
+
result[key] = truncateObject(value);
|
|
2467
|
+
} else {
|
|
2468
|
+
result[key] = value;
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
return result;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2465
2474
|
// src/util/get-step-log.ts
|
|
2466
2475
|
function getStepLog(stepResult) {
|
|
2467
2476
|
const { content } = stepResult;
|
|
@@ -2475,13 +2484,17 @@ function getStepLog(stepResult) {
|
|
|
2475
2484
|
}
|
|
2476
2485
|
logEntry += ": ";
|
|
2477
2486
|
if (part.type === "tool-call" && "input" in part) {
|
|
2478
|
-
logEntry += typeof part.input === "string" ? part.input :
|
|
2487
|
+
logEntry += typeof part.input === "string" ? truncateString(part.input) : part.input === null || part.input === void 0 ? String(part.input) : JSON.stringify(
|
|
2488
|
+
truncateObject(part.input)
|
|
2489
|
+
);
|
|
2479
2490
|
} else if (part.type === "tool-result" && "output" in part) {
|
|
2480
|
-
logEntry += typeof part.output === "string" ? part.output :
|
|
2491
|
+
logEntry += typeof part.output === "string" ? truncateString(part.output) : part.output === null || part.output === void 0 ? String(part.output) : JSON.stringify(
|
|
2492
|
+
truncateObject(part.output)
|
|
2493
|
+
);
|
|
2481
2494
|
} else if (part.type === "tool-error" && "error" in part) {
|
|
2482
2495
|
logEntry += typeof part.error === "object" && part.error !== null && "message" in part.error ? part.error.message : String(part.error);
|
|
2483
2496
|
} else if (part.type === "text" && "text" in part) {
|
|
2484
|
-
logEntry += part.text;
|
|
2497
|
+
logEntry += truncateString(part.text);
|
|
2485
2498
|
}
|
|
2486
2499
|
logEntry += "\n";
|
|
2487
2500
|
});
|
|
@@ -2490,6 +2503,9 @@ function getStepLog(stepResult) {
|
|
|
2490
2503
|
|
|
2491
2504
|
// src/agent-creators.ts
|
|
2492
2505
|
function createCodeAgent(agentConfig) {
|
|
2506
|
+
return new import_ai.ToolLoopAgent(createCodeAgentSettings(agentConfig));
|
|
2507
|
+
}
|
|
2508
|
+
function createCodeAgentSettings(agentConfig) {
|
|
2493
2509
|
const {
|
|
2494
2510
|
maxSteps,
|
|
2495
2511
|
allowSubmit,
|
|
@@ -2498,46 +2514,29 @@ function createCodeAgent(agentConfig) {
|
|
|
2498
2514
|
tools: originalTools,
|
|
2499
2515
|
stopWhen: originalStopWhen,
|
|
2500
2516
|
prepareStep: originalPrepareStep,
|
|
2501
|
-
|
|
2517
|
+
instructions: originalSystemInstruction,
|
|
2502
2518
|
...remainingConfig
|
|
2503
2519
|
} = agentConfig;
|
|
2504
2520
|
let agentSettings;
|
|
2505
|
-
let
|
|
2521
|
+
let tools;
|
|
2506
2522
|
if ("environments" in remainingConfig) {
|
|
2507
2523
|
const { environments, environmentToolsDefinition, ...agentSettingsInput } = remainingConfig;
|
|
2508
2524
|
agentSettings = { ...agentSettingsInput };
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
`No tools definition provided for environment "${environmentName}". Please provide a tools definition for each environment.`
|
|
2514
|
-
);
|
|
2515
|
-
}
|
|
2516
|
-
const envTools = createToolsForNamedEnvironment(
|
|
2517
|
-
environmentName,
|
|
2518
|
-
environment,
|
|
2519
|
-
environmentToolsDefinition[environmentName]
|
|
2520
|
-
);
|
|
2521
|
-
for (const [toolName, tool] of Object.entries(envTools)) {
|
|
2522
|
-
if (toolName in environmentTools) {
|
|
2523
|
-
throw new Error(
|
|
2524
|
-
`Tool name conflict: The tool name "${toolName}" from environment "${environmentName}" is already used by another environment's tools.`
|
|
2525
|
-
);
|
|
2526
|
-
}
|
|
2527
|
-
environmentTools[toolName] = tool;
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2525
|
+
tools = createCodeAgentTools(
|
|
2526
|
+
{ environments, environmentToolsDefinition },
|
|
2527
|
+
originalTools
|
|
2528
|
+
);
|
|
2530
2529
|
} else if ("environment" in remainingConfig) {
|
|
2531
2530
|
const { environment, environmentToolsDefinition, ...agentSettingsInput } = remainingConfig;
|
|
2532
2531
|
agentSettings = { ...agentSettingsInput };
|
|
2533
|
-
|
|
2534
|
-
environment,
|
|
2535
|
-
|
|
2532
|
+
tools = createCodeAgentTools(
|
|
2533
|
+
{ environment, environmentToolsDefinition },
|
|
2534
|
+
originalTools
|
|
2536
2535
|
);
|
|
2537
2536
|
} else {
|
|
2538
2537
|
agentSettings = { ...remainingConfig };
|
|
2538
|
+
tools = originalTools || {};
|
|
2539
2539
|
}
|
|
2540
|
-
const tools = environmentTools && originalTools ? mergeTools(environmentTools, originalTools) : originalTools || environmentTools || {};
|
|
2541
2540
|
if (allowSubmit) {
|
|
2542
2541
|
if (SubmitToolName in tools) {
|
|
2543
2542
|
throw new Error(
|
|
@@ -2565,16 +2564,54 @@ ${stepLog}`, stepCount - 1);
|
|
|
2565
2564
|
} : originalPrepareStep;
|
|
2566
2565
|
const stopWhenCondition = allowSubmit ? [(0, import_ai.stepCountIs)(maxSteps), (0, import_ai.hasToolCall)(SubmitToolName)] : (0, import_ai.stepCountIs)(maxSteps);
|
|
2567
2566
|
const stopWhen = originalStopWhen ? mergeStopWhen(originalStopWhen, stopWhenCondition) : stopWhenCondition;
|
|
2568
|
-
const
|
|
2567
|
+
const instructions = !omitAdditionalInstructions ? mergeSystemInstructions(
|
|
2569
2568
|
originalSystemInstruction,
|
|
2570
2569
|
getAdditionalInstructions({ maxSteps, allowSubmit, tools })
|
|
2571
2570
|
) : originalSystemInstruction;
|
|
2572
|
-
return
|
|
2571
|
+
return {
|
|
2573
2572
|
...agentSettings,
|
|
2574
|
-
|
|
2573
|
+
instructions,
|
|
2575
2574
|
prepareStep,
|
|
2576
2575
|
stopWhen
|
|
2577
|
-
}
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
function createCodeAgentTools(agentToolsConfig, originalTools) {
|
|
2579
|
+
if ("environments" in agentToolsConfig) {
|
|
2580
|
+
const { environments, environmentToolsDefinition } = agentToolsConfig;
|
|
2581
|
+
const environmentTools = {};
|
|
2582
|
+
for (const [environmentName, environment] of Object.entries(environments)) {
|
|
2583
|
+
if (!(environmentName in environmentToolsDefinition)) {
|
|
2584
|
+
throw new Error(
|
|
2585
|
+
`No tools definition provided for environment "${environmentName}". Please provide a tools definition for each environment.`
|
|
2586
|
+
);
|
|
2587
|
+
}
|
|
2588
|
+
const envTools = createToolsForNamedEnvironment(
|
|
2589
|
+
environmentName,
|
|
2590
|
+
environment,
|
|
2591
|
+
environmentToolsDefinition[environmentName]
|
|
2592
|
+
);
|
|
2593
|
+
for (const [toolName, tool] of Object.entries(envTools)) {
|
|
2594
|
+
if (toolName in environmentTools) {
|
|
2595
|
+
throw new Error(
|
|
2596
|
+
`Tool name conflict: The tool name "${toolName}" from environment "${environmentName}" is already used by another environment's tools.`
|
|
2597
|
+
);
|
|
2598
|
+
}
|
|
2599
|
+
environmentTools[toolName] = tool;
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
return originalTools ? mergeTools(environmentTools, originalTools) : environmentTools;
|
|
2603
|
+
}
|
|
2604
|
+
if ("environment" in agentToolsConfig) {
|
|
2605
|
+
const { environment, environmentToolsDefinition } = agentToolsConfig;
|
|
2606
|
+
const environmentTools = createToolsForEnvironment(
|
|
2607
|
+
environment,
|
|
2608
|
+
environmentToolsDefinition
|
|
2609
|
+
);
|
|
2610
|
+
return originalTools ? mergeTools(environmentTools, originalTools) : environmentTools;
|
|
2611
|
+
}
|
|
2612
|
+
throw new Error(
|
|
2613
|
+
'No environments provided in agent tools configuration. Please provide either "environment" or "environments".'
|
|
2614
|
+
);
|
|
2578
2615
|
}
|
|
2579
2616
|
function mergeTools(baseTools, additionalTools) {
|
|
2580
2617
|
const tools = { ...baseTools };
|
|
@@ -2600,9 +2637,26 @@ function mergeStopWhen(baseStopWhen, additionalStopWhen) {
|
|
|
2600
2637
|
}
|
|
2601
2638
|
return [baseStopWhen, additionalStopWhen];
|
|
2602
2639
|
}
|
|
2603
|
-
function mergeSystemInstructions(
|
|
2604
|
-
if (
|
|
2605
|
-
|
|
2640
|
+
function mergeSystemInstructions(baseInstructions, additionalInstructions) {
|
|
2641
|
+
if (baseInstructions) {
|
|
2642
|
+
if (Array.isArray(baseInstructions)) {
|
|
2643
|
+
return [
|
|
2644
|
+
...baseInstructions,
|
|
2645
|
+
{
|
|
2646
|
+
role: "system",
|
|
2647
|
+
content: additionalInstructions
|
|
2648
|
+
}
|
|
2649
|
+
];
|
|
2650
|
+
}
|
|
2651
|
+
if (typeof baseInstructions === "object") {
|
|
2652
|
+
return {
|
|
2653
|
+
...baseInstructions,
|
|
2654
|
+
content: `${baseInstructions.content.trimEnd()}
|
|
2655
|
+
|
|
2656
|
+
${additionalInstructions}`
|
|
2657
|
+
};
|
|
2658
|
+
}
|
|
2659
|
+
return `${baseInstructions.trimEnd()}
|
|
2606
2660
|
|
|
2607
2661
|
${additionalInstructions}`;
|
|
2608
2662
|
}
|
|
@@ -2628,12 +2682,10 @@ function createEnvironment(environmentName, config) {
|
|
|
2628
2682
|
}
|
|
2629
2683
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2630
2684
|
0 && (module.exports = {
|
|
2631
|
-
CopyFileResult,
|
|
2632
2685
|
CopyFileTool,
|
|
2633
2686
|
CopyFileToolInput,
|
|
2634
2687
|
CopyFileToolName,
|
|
2635
2688
|
CopyFileToolOutput,
|
|
2636
|
-
DeleteFileResult,
|
|
2637
2689
|
DeleteFileTool,
|
|
2638
2690
|
DeleteFileToolInput,
|
|
2639
2691
|
DeleteFileToolName,
|
|
@@ -2655,20 +2707,22 @@ function createEnvironment(environmentName, config) {
|
|
|
2655
2707
|
GlobToolInput,
|
|
2656
2708
|
GlobToolName,
|
|
2657
2709
|
GlobToolOutput,
|
|
2710
|
+
GrepTool,
|
|
2711
|
+
GrepToolInput,
|
|
2712
|
+
GrepToolName,
|
|
2713
|
+
GrepToolOutput,
|
|
2658
2714
|
ListDirectoryTool,
|
|
2659
2715
|
ListDirectoryToolInput,
|
|
2660
2716
|
ListDirectoryToolName,
|
|
2661
2717
|
ListDirectoryToolOutput,
|
|
2662
2718
|
MockFilesystemEnvironment,
|
|
2663
2719
|
MockFilesystemEnvironmentName,
|
|
2664
|
-
MoveFileResult,
|
|
2665
2720
|
MoveFileTool,
|
|
2666
2721
|
MoveFileToolInput,
|
|
2667
2722
|
MoveFileToolName,
|
|
2668
2723
|
MoveFileToolOutput,
|
|
2669
2724
|
NodeFilesystemEnvironment,
|
|
2670
2725
|
NodeFilesystemEnvironmentName,
|
|
2671
|
-
ReadFileResult,
|
|
2672
2726
|
ReadFileTool,
|
|
2673
2727
|
ReadFileToolInput,
|
|
2674
2728
|
ReadFileToolName,
|
|
@@ -2677,7 +2731,6 @@ function createEnvironment(environmentName, config) {
|
|
|
2677
2731
|
ReadManyFilesToolInput,
|
|
2678
2732
|
ReadManyFilesToolName,
|
|
2679
2733
|
ReadManyFilesToolOutput,
|
|
2680
|
-
RunCommandResult,
|
|
2681
2734
|
RunCommandTool,
|
|
2682
2735
|
RunCommandToolInput,
|
|
2683
2736
|
RunCommandToolName,
|
|
@@ -2688,12 +2741,13 @@ function createEnvironment(environmentName, config) {
|
|
|
2688
2741
|
SubmitToolOutput,
|
|
2689
2742
|
UnsafeLocalEnvironment,
|
|
2690
2743
|
UnsafeLocalEnvironmentName,
|
|
2691
|
-
WriteFileResult,
|
|
2692
2744
|
WriteFileTool,
|
|
2693
2745
|
WriteFileToolInput,
|
|
2694
2746
|
WriteFileToolName,
|
|
2695
2747
|
WriteFileToolOutput,
|
|
2696
2748
|
createCodeAgent,
|
|
2749
|
+
createCodeAgentSettings,
|
|
2750
|
+
createCodeAgentTools,
|
|
2697
2751
|
createEnvironment,
|
|
2698
2752
|
createEnvironmentTool,
|
|
2699
2753
|
createToolsForEnvironment,
|