ai-code-agents 0.1.0-beta.1 → 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 +27 -23
- package/dist/index.cjs +703 -635
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +289 -567
- package/dist/index.d.ts +289 -567
- package/dist/index.js +752 -639
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +27 -7
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,19 +79,23 @@ __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,
|
|
86
85
|
RunCommandToolOutput: () => RunCommandToolOutput,
|
|
86
|
+
SubmitTool: () => SubmitTool,
|
|
87
|
+
SubmitToolInput: () => SubmitToolInput,
|
|
88
|
+
SubmitToolName: () => SubmitToolName,
|
|
89
|
+
SubmitToolOutput: () => SubmitToolOutput,
|
|
87
90
|
UnsafeLocalEnvironment: () => UnsafeLocalEnvironment,
|
|
88
91
|
UnsafeLocalEnvironmentName: () => UnsafeLocalEnvironmentName,
|
|
89
|
-
WriteFileResult: () => WriteFileResult,
|
|
90
92
|
WriteFileTool: () => WriteFileTool,
|
|
91
93
|
WriteFileToolInput: () => WriteFileToolInput,
|
|
92
94
|
WriteFileToolName: () => WriteFileToolName,
|
|
93
95
|
WriteFileToolOutput: () => WriteFileToolOutput,
|
|
94
96
|
createCodeAgent: () => createCodeAgent,
|
|
97
|
+
createCodeAgentSettings: () => createCodeAgentSettings,
|
|
98
|
+
createCodeAgentTools: () => createCodeAgentTools,
|
|
95
99
|
createEnvironment: () => createEnvironment,
|
|
96
100
|
createEnvironmentTool: () => createEnvironmentTool,
|
|
97
101
|
createToolsForEnvironment: () => createToolsForEnvironment,
|
|
@@ -101,290 +105,17 @@ module.exports = __toCommonJS(index_exports);
|
|
|
101
105
|
|
|
102
106
|
// src/environments/docker-environment.ts
|
|
103
107
|
var import_node_child_process = require("child_process");
|
|
108
|
+
var import_environment_utils = require("@ai-code-agents/environment-utils");
|
|
104
109
|
|
|
105
|
-
// src/util/escape-command
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// src/util/validate-relative-path.ts
|
|
114
|
-
var path = __toESM(require("path"), 1);
|
|
115
|
-
function validateRelativePath(filePath) {
|
|
116
|
-
if (path.isAbsolute(filePath)) {
|
|
117
|
-
throw new Error("Absolute paths are not allowed.");
|
|
118
|
-
}
|
|
119
|
-
if (filePath.startsWith("~")) {
|
|
120
|
-
throw new Error('Paths starting with "~" are not allowed.');
|
|
121
|
-
}
|
|
122
|
-
if (filePath.includes("\0")) {
|
|
123
|
-
throw new Error("Paths must not contain null bytes.");
|
|
124
|
-
}
|
|
125
|
-
const normalizedPath = path.normalize(filePath);
|
|
126
|
-
if (normalizedPath.startsWith("..")) {
|
|
127
|
-
throw new Error("Path traversal is not allowed.");
|
|
128
|
-
}
|
|
110
|
+
// src/util/escape-command.ts
|
|
111
|
+
function escapeCommand(command) {
|
|
112
|
+
const escaped = command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
113
|
+
return `"${escaped}"`;
|
|
129
114
|
}
|
|
130
115
|
|
|
131
|
-
// src/environments/filesystem-environment-base.ts
|
|
132
|
-
var FilesystemEnvironmentBase = class {
|
|
133
|
-
_envConfig;
|
|
134
|
-
/**
|
|
135
|
-
* Constructs a new environment instance.
|
|
136
|
-
*
|
|
137
|
-
* @param config - Environment configuration.
|
|
138
|
-
*/
|
|
139
|
-
constructor(config) {
|
|
140
|
-
this._envConfig = config;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Reads the content of a file at the specified path.
|
|
144
|
-
*
|
|
145
|
-
* @param path - The path to the file to read, relative to the project directory.
|
|
146
|
-
* @returns A promise that resolves to a ReadFileResult.
|
|
147
|
-
*/
|
|
148
|
-
async readFile(path5) {
|
|
149
|
-
validateRelativePath(path5);
|
|
150
|
-
if (!await this.fileExists(path5)) {
|
|
151
|
-
throw new Error(`File not found: ${path5}`);
|
|
152
|
-
}
|
|
153
|
-
const content = await this.readFileContent(path5);
|
|
154
|
-
return {
|
|
155
|
-
path: path5,
|
|
156
|
-
content
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Writes content to a file at the specified path.
|
|
161
|
-
*
|
|
162
|
-
* If a file is already present at the path, it will be overwritten.
|
|
163
|
-
*
|
|
164
|
-
* @param path - The path to the file to write, relative to the project directory.
|
|
165
|
-
* @param content - The content to write to the file.
|
|
166
|
-
* @returns A promise that resolves to a WriteFileResult.
|
|
167
|
-
*/
|
|
168
|
-
async writeFile(path5, content) {
|
|
169
|
-
validateRelativePath(path5);
|
|
170
|
-
await this.writeFileContent(path5, content);
|
|
171
|
-
return {
|
|
172
|
-
path: path5,
|
|
173
|
-
message: "File written successfully."
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Deletes a file at the specified path.
|
|
178
|
-
*
|
|
179
|
-
* @param path - The path to the file to delete, relative to the project directory.
|
|
180
|
-
* @returns A promise that resolves to a DeleteFileResult.
|
|
181
|
-
*/
|
|
182
|
-
async deleteFile(path5) {
|
|
183
|
-
validateRelativePath(path5);
|
|
184
|
-
if (!await this.fileExists(path5)) {
|
|
185
|
-
return {
|
|
186
|
-
path: path5,
|
|
187
|
-
message: "File was already deleted."
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
await this.deleteFileContent(path5);
|
|
191
|
-
return {
|
|
192
|
-
path: path5,
|
|
193
|
-
message: "File deleted successfully."
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Moves a file from a source path to a destination path.
|
|
198
|
-
*
|
|
199
|
-
* If a file is already present at the destination path, it will be overwritten.
|
|
200
|
-
*
|
|
201
|
-
* @param sourcePath - The path to the file to move.
|
|
202
|
-
* @param destinationPath - The path to move the file to.
|
|
203
|
-
* @returns A promise that resolves to a MoveFileResult.
|
|
204
|
-
*/
|
|
205
|
-
async moveFile(sourcePath, destinationPath) {
|
|
206
|
-
validateRelativePath(sourcePath);
|
|
207
|
-
validateRelativePath(destinationPath);
|
|
208
|
-
if (!await this.fileExists(sourcePath)) {
|
|
209
|
-
throw new Error(`File not found: ${sourcePath}`);
|
|
210
|
-
}
|
|
211
|
-
await this.moveFileContent(sourcePath, destinationPath);
|
|
212
|
-
return {
|
|
213
|
-
sourcePath,
|
|
214
|
-
destinationPath,
|
|
215
|
-
message: "File moved successfully."
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Copies a file from a source path to a destination path.
|
|
220
|
-
*
|
|
221
|
-
* If a file is already present at the destination path, it will be overwritten.
|
|
222
|
-
*
|
|
223
|
-
* @param sourcePath - The path to the file to copy.
|
|
224
|
-
* @param destinationPath - The path to copy the file to.
|
|
225
|
-
* @returns A promise that resolves to a CopyFileResult.
|
|
226
|
-
*/
|
|
227
|
-
async copyFile(sourcePath, destinationPath) {
|
|
228
|
-
validateRelativePath(sourcePath);
|
|
229
|
-
validateRelativePath(destinationPath);
|
|
230
|
-
if (!await this.fileExists(sourcePath)) {
|
|
231
|
-
throw new Error(`File not found: ${sourcePath}`);
|
|
232
|
-
}
|
|
233
|
-
await this.copyFileContent(sourcePath, destinationPath);
|
|
234
|
-
return {
|
|
235
|
-
sourcePath,
|
|
236
|
-
destinationPath,
|
|
237
|
-
message: "File copied successfully."
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Moves the content of a file from a source path to a destination path, relative to the project directory.
|
|
242
|
-
*
|
|
243
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
244
|
-
* This method unconditionally moves the content, even if a file already exists at the destination path.
|
|
245
|
-
*
|
|
246
|
-
* @param relativeSourcePath - The path to the file to move, relative to the project directory.
|
|
247
|
-
* @param relativeDestinationPath - The path to move the file to, relative to the project directory.
|
|
248
|
-
*/
|
|
249
|
-
async moveFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
250
|
-
const content = await this.readFileContent(relativeSourcePath);
|
|
251
|
-
this.writeFileContent(relativeDestinationPath, content);
|
|
252
|
-
this.deleteFileContent(relativeSourcePath);
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Copies the content of a file from a source path to a destination path, relative to the project directory.
|
|
256
|
-
*
|
|
257
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
258
|
-
* This method unconditionally copies the content, even if a file already exists at the destination path.
|
|
259
|
-
*
|
|
260
|
-
* @param relativeSourcePath - The path to the file to copy, relative to the project directory.
|
|
261
|
-
* @param relativeDestinationPath - The path to copy the file to, relative to the project directory.
|
|
262
|
-
*/
|
|
263
|
-
async copyFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
264
|
-
const content = await this.readFileContent(relativeSourcePath);
|
|
265
|
-
this.writeFileContent(relativeDestinationPath, content);
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
// src/environments/command-line-environment-base.ts
|
|
270
|
-
var CommandLineEnvironmentBase = class extends FilesystemEnvironmentBase {
|
|
271
|
-
/**
|
|
272
|
-
* Runs a CLI command in environment.
|
|
273
|
-
*
|
|
274
|
-
* @param command - The command to run.
|
|
275
|
-
* @returns A promise that resolves to a RunCommandResult.
|
|
276
|
-
*/
|
|
277
|
-
async runCommand(command) {
|
|
278
|
-
const [exitCode, stdout, stderr] = await this.executeCommand(command);
|
|
279
|
-
return {
|
|
280
|
-
command,
|
|
281
|
-
exitCode,
|
|
282
|
-
stdout,
|
|
283
|
-
stderr
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
// src/environments/unix-environment-base.ts
|
|
289
|
-
var UnixEnvironmentBase = class extends CommandLineEnvironmentBase {
|
|
290
|
-
/**
|
|
291
|
-
* Checks whether a file exists at the specified path relative to the project directory.
|
|
292
|
-
*
|
|
293
|
-
* @param relativePath - The path to the file to check, relative to the project directory.
|
|
294
|
-
* @returns True if the file exists, false otherwise.
|
|
295
|
-
*/
|
|
296
|
-
async fileExists(relativePath) {
|
|
297
|
-
const command = `if [ -e ${escapeCommandArg(relativePath)} ]; then echo "yes"; else echo "no"; fi`;
|
|
298
|
-
const { exitCode, stdout } = await this.runCommand(command);
|
|
299
|
-
return exitCode === 0 && stdout.trim() === "yes";
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Gets the content of a file at the specified path, relative to the project directory.
|
|
303
|
-
*
|
|
304
|
-
* When this method is called, it is guaranteed that the file exists.
|
|
305
|
-
*
|
|
306
|
-
* @param relativePath - The path to the file to read, relative to the project directory.
|
|
307
|
-
* @returns The content of the file.
|
|
308
|
-
*/
|
|
309
|
-
async readFileContent(relativePath) {
|
|
310
|
-
const command = `cat ${escapeCommandArg(relativePath)}`;
|
|
311
|
-
const { exitCode, stdout } = await this.runCommand(command);
|
|
312
|
-
return exitCode === 0 ? stdout : "";
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Writes content to a file at the specified path, relative to the project directory.
|
|
316
|
-
*
|
|
317
|
-
* This method unconditionally writes the content, even if a file already exists at the path, or if the file is new.
|
|
318
|
-
*
|
|
319
|
-
* @param relativePath - The path to the file to write, relative to the project directory.
|
|
320
|
-
* @param content - The content to write to the file.
|
|
321
|
-
*/
|
|
322
|
-
async writeFileContent(relativePath, content) {
|
|
323
|
-
const command = `sh -c "echo ${escapeCommandArg(
|
|
324
|
-
content
|
|
325
|
-
)} > ${escapeCommandArg(relativePath)}"`;
|
|
326
|
-
const { exitCode, stderr } = await this.runCommand(command);
|
|
327
|
-
if (exitCode !== 0) {
|
|
328
|
-
throw new Error(`Failed to write file: ${stderr || "Unknown error"}`);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Deletes a file at the specified path, relative to the project directory.
|
|
333
|
-
*
|
|
334
|
-
* When this method is called, it is guaranteed that the file exists.
|
|
335
|
-
*
|
|
336
|
-
* @param relativePath - The path to the file to delete, relative to the project directory.
|
|
337
|
-
*/
|
|
338
|
-
async deleteFileContent(relativePath) {
|
|
339
|
-
const command = `rm ${escapeCommandArg(relativePath)}`;
|
|
340
|
-
const { exitCode, stderr } = await this.runCommand(command);
|
|
341
|
-
if (exitCode !== 0) {
|
|
342
|
-
throw new Error(`Failed to delete file: ${stderr || "Unknown error"}`);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Moves the content of a file from a source path to a destination path, relative to the project directory.
|
|
347
|
-
*
|
|
348
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
349
|
-
* This method unconditionally moves the content, even if a file already exists at the destination path.
|
|
350
|
-
*
|
|
351
|
-
* @param relativeSourcePath - The path to the file to move, relative to the project directory.
|
|
352
|
-
* @param relativeDestinationPath - The path to move the file to, relative to the project directory.
|
|
353
|
-
*/
|
|
354
|
-
async moveFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
355
|
-
const command = `mv ${escapeCommandArg(relativeSourcePath)} ${escapeCommandArg(
|
|
356
|
-
relativeDestinationPath
|
|
357
|
-
)}`;
|
|
358
|
-
const { exitCode, stderr } = await this.runCommand(command);
|
|
359
|
-
if (exitCode !== 0) {
|
|
360
|
-
throw new Error(`Failed to move file: ${stderr || "Unknown error"}`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Copies the content of a file from a source path to a destination path, relative to the project directory.
|
|
365
|
-
*
|
|
366
|
-
* When this method is called, it is guaranteed that the source file exists.
|
|
367
|
-
* This method unconditionally copies the content, even if a file already exists at the destination path.
|
|
368
|
-
*
|
|
369
|
-
* @param relativeSourcePath - The path to the file to copy, relative to the project directory.
|
|
370
|
-
* @param relativeDestinationPath - The path to copy the file to, relative to the project directory.
|
|
371
|
-
*/
|
|
372
|
-
async copyFileContent(relativeSourcePath, relativeDestinationPath) {
|
|
373
|
-
const command = `cp ${escapeCommandArg(relativeSourcePath)} ${escapeCommandArg(
|
|
374
|
-
relativeDestinationPath
|
|
375
|
-
)}`;
|
|
376
|
-
const result = await this.runCommand(command);
|
|
377
|
-
if (result.exitCode !== 0) {
|
|
378
|
-
throw new Error(
|
|
379
|
-
`Failed to copy file: ${result.stderr || "Unknown error"}`
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
|
|
385
116
|
// src/environments/docker-environment.ts
|
|
386
117
|
var DockerEnvironmentName = "docker";
|
|
387
|
-
var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
118
|
+
var DockerEnvironment = class extends import_environment_utils.UnixEnvironmentBase {
|
|
388
119
|
_commandPrefix;
|
|
389
120
|
/**
|
|
390
121
|
* Constructs a new environment instance.
|
|
@@ -394,7 +125,7 @@ var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
|
394
125
|
constructor(config) {
|
|
395
126
|
super(config);
|
|
396
127
|
const { directoryPath } = this._envConfig;
|
|
397
|
-
this._commandPrefix = directoryPath ? `cd ${escapeCommandArg(directoryPath)} && ` : "";
|
|
128
|
+
this._commandPrefix = directoryPath ? `cd ${(0, import_environment_utils.escapeCommandArg)(directoryPath)} && ` : "";
|
|
398
129
|
}
|
|
399
130
|
/**
|
|
400
131
|
* Gets the environment name.
|
|
@@ -413,7 +144,7 @@ var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
|
413
144
|
async executeCommand(command) {
|
|
414
145
|
return new Promise((resolve) => {
|
|
415
146
|
(0, import_node_child_process.exec)(
|
|
416
|
-
`docker exec ${this._envConfig.containerId} ${this._commandPrefix
|
|
147
|
+
`docker exec ${this._envConfig.containerId} sh -c ${escapeCommand(this._commandPrefix + command)}`,
|
|
417
148
|
(error, stdout, stderr) => {
|
|
418
149
|
const exitCode = error ? error.code ?? 1 : 0;
|
|
419
150
|
resolve([exitCode, stdout, stderr]);
|
|
@@ -425,8 +156,9 @@ var DockerEnvironment = class extends UnixEnvironmentBase {
|
|
|
425
156
|
|
|
426
157
|
// src/environments/mock-filesystem-environment.ts
|
|
427
158
|
var import_node_path = __toESM(require("path"), 1);
|
|
159
|
+
var import_environment_utils2 = require("@ai-code-agents/environment-utils");
|
|
428
160
|
var MockFilesystemEnvironmentName = "mock-filesystem";
|
|
429
|
-
var MockFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
161
|
+
var MockFilesystemEnvironment = class extends import_environment_utils2.FilesystemEnvironmentBase {
|
|
430
162
|
files;
|
|
431
163
|
_preparePath;
|
|
432
164
|
/**
|
|
@@ -437,7 +169,7 @@ var MockFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
|
437
169
|
constructor(config = {}) {
|
|
438
170
|
super(config);
|
|
439
171
|
const { initialFiles, directoryPath } = this._envConfig;
|
|
440
|
-
this.files = initialFiles
|
|
172
|
+
this.files = initialFiles ? new Map(Object.entries(initialFiles)) : /* @__PURE__ */ new Map();
|
|
441
173
|
this._preparePath = directoryPath ? (filePath) => import_node_path.default.join(directoryPath, filePath) : (filePath) => filePath;
|
|
442
174
|
}
|
|
443
175
|
/**
|
|
@@ -492,8 +224,9 @@ var MockFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
|
492
224
|
// src/environments/node-filesystem-environment.ts
|
|
493
225
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
494
226
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
227
|
+
var import_environment_utils3 = require("@ai-code-agents/environment-utils");
|
|
495
228
|
var NodeFilesystemEnvironmentName = "node-filesystem";
|
|
496
|
-
var NodeFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
229
|
+
var NodeFilesystemEnvironment = class extends import_environment_utils3.FilesystemEnvironmentBase {
|
|
497
230
|
/**
|
|
498
231
|
* Constructs a new NodeFilesystemEnvironment instance.
|
|
499
232
|
*
|
|
@@ -587,8 +320,9 @@ var NodeFilesystemEnvironment = class extends FilesystemEnvironmentBase {
|
|
|
587
320
|
|
|
588
321
|
// src/environments/unsafe-local-environment.ts
|
|
589
322
|
var import_node_child_process2 = require("child_process");
|
|
323
|
+
var import_environment_utils4 = require("@ai-code-agents/environment-utils");
|
|
590
324
|
var UnsafeLocalEnvironmentName = "unsafe-local";
|
|
591
|
-
var UnsafeLocalEnvironment = class extends UnixEnvironmentBase {
|
|
325
|
+
var UnsafeLocalEnvironment = class extends import_environment_utils4.UnixEnvironmentBase {
|
|
592
326
|
_commandPrefix;
|
|
593
327
|
/**
|
|
594
328
|
* Constructs a new environment instance.
|
|
@@ -604,7 +338,7 @@ var UnsafeLocalEnvironment = class extends UnixEnvironmentBase {
|
|
|
604
338
|
throw new Error('The directory path must be absolute (start with "/")');
|
|
605
339
|
}
|
|
606
340
|
super(config);
|
|
607
|
-
this._commandPrefix = `cd ${escapeCommandArg(directoryPath)} && `;
|
|
341
|
+
this._commandPrefix = `cd ${(0, import_environment_utils4.escapeCommandArg)(directoryPath)} && `;
|
|
608
342
|
}
|
|
609
343
|
/**
|
|
610
344
|
* Gets the environment name.
|
|
@@ -632,173 +366,7 @@ var UnsafeLocalEnvironment = class extends UnixEnvironmentBase {
|
|
|
632
366
|
|
|
633
367
|
// src/tools/copy-file-tool.ts
|
|
634
368
|
var import_zod = require("zod");
|
|
635
|
-
|
|
636
|
-
// src/types.ts
|
|
637
|
-
var z = __toESM(require("zod"), 1);
|
|
638
|
-
var ReadFileResult = z.object({
|
|
639
|
-
path: z.string().meta({
|
|
640
|
-
description: "The path to the file that was read."
|
|
641
|
-
}),
|
|
642
|
-
content: z.string().meta({
|
|
643
|
-
description: "The content of the file that was read."
|
|
644
|
-
})
|
|
645
|
-
});
|
|
646
|
-
var WriteFileResult = z.object({
|
|
647
|
-
path: z.string().meta({
|
|
648
|
-
description: "The path to the file that was written."
|
|
649
|
-
}),
|
|
650
|
-
message: z.string().meta({
|
|
651
|
-
description: "A message indicating the result of the write operation."
|
|
652
|
-
})
|
|
653
|
-
});
|
|
654
|
-
var DeleteFileResult = z.object({
|
|
655
|
-
path: z.string().meta({
|
|
656
|
-
description: "The path to the file that was deleted."
|
|
657
|
-
}),
|
|
658
|
-
message: z.string().meta({
|
|
659
|
-
description: "A message indicating the result of the delete operation."
|
|
660
|
-
})
|
|
661
|
-
});
|
|
662
|
-
var MoveFileResult = z.object({
|
|
663
|
-
sourcePath: z.string().meta({
|
|
664
|
-
description: "The original path of the file that was moved."
|
|
665
|
-
}),
|
|
666
|
-
destinationPath: z.string().meta({
|
|
667
|
-
description: "The new path of the file that was moved to."
|
|
668
|
-
}),
|
|
669
|
-
message: z.string().meta({
|
|
670
|
-
description: "A message indicating the result of the move operation."
|
|
671
|
-
})
|
|
672
|
-
});
|
|
673
|
-
var CopyFileResult = z.object({
|
|
674
|
-
sourcePath: z.string().meta({
|
|
675
|
-
description: "The original path of the file that was copied."
|
|
676
|
-
}),
|
|
677
|
-
destinationPath: z.string().meta({
|
|
678
|
-
description: "The new path of the file that was copied to."
|
|
679
|
-
}),
|
|
680
|
-
message: z.string().meta({
|
|
681
|
-
description: "A message indicating the result of the copy operation."
|
|
682
|
-
})
|
|
683
|
-
});
|
|
684
|
-
var RunCommandResult = z.object({
|
|
685
|
-
command: z.string().meta({
|
|
686
|
-
description: "The command that was executed."
|
|
687
|
-
}),
|
|
688
|
-
exitCode: z.number().meta({
|
|
689
|
-
description: "The exit code of the command."
|
|
690
|
-
}),
|
|
691
|
-
stdout: z.string().meta({
|
|
692
|
-
description: "The standard output of the command."
|
|
693
|
-
}),
|
|
694
|
-
stderr: z.string().meta({
|
|
695
|
-
description: "The standard error output of the command."
|
|
696
|
-
})
|
|
697
|
-
});
|
|
698
|
-
|
|
699
|
-
// src/tools/tool-base.ts
|
|
700
|
-
var ToolBase = class {
|
|
701
|
-
_toolConfig;
|
|
702
|
-
_name;
|
|
703
|
-
_description;
|
|
704
|
-
_inputSchema;
|
|
705
|
-
_outputSchema;
|
|
706
|
-
_needsApproval;
|
|
707
|
-
/**
|
|
708
|
-
* Constructs a new tool instance.
|
|
709
|
-
*
|
|
710
|
-
* @param toolConfig - Optional tool config, can be used to override some defaults.
|
|
711
|
-
*/
|
|
712
|
-
constructor(toolConfig) {
|
|
713
|
-
const {
|
|
714
|
-
name: defaultName,
|
|
715
|
-
description: defaultDescription,
|
|
716
|
-
inputSchema,
|
|
717
|
-
outputSchema,
|
|
718
|
-
needsApproval: defaultNeedsApproval
|
|
719
|
-
} = this.getMetadata();
|
|
720
|
-
this._name = toolConfig?.name || defaultName;
|
|
721
|
-
this._description = toolConfig?.description || defaultDescription;
|
|
722
|
-
this._inputSchema = inputSchema;
|
|
723
|
-
this._outputSchema = outputSchema;
|
|
724
|
-
this._needsApproval = toolConfig?.needsApproval !== void 0 ? toolConfig.needsApproval : defaultNeedsApproval;
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* Gets the tool name.
|
|
728
|
-
*
|
|
729
|
-
* @returns The tool name.
|
|
730
|
-
*/
|
|
731
|
-
get name() {
|
|
732
|
-
return this._name;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Gets the tool description.
|
|
736
|
-
*
|
|
737
|
-
* @returns The tool description.
|
|
738
|
-
*/
|
|
739
|
-
get description() {
|
|
740
|
-
return this._description;
|
|
741
|
-
}
|
|
742
|
-
/**
|
|
743
|
-
* Gets the input schema for the tool.
|
|
744
|
-
*
|
|
745
|
-
* @returns The input schema.
|
|
746
|
-
*/
|
|
747
|
-
get inputSchema() {
|
|
748
|
-
return this._inputSchema;
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* Gets the input schema for the tool.
|
|
752
|
-
*
|
|
753
|
-
* @returns The input schema.
|
|
754
|
-
*/
|
|
755
|
-
get outputSchema() {
|
|
756
|
-
return this._outputSchema;
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* Gets whether the tool needs approval before use.
|
|
760
|
-
*
|
|
761
|
-
* @returns True if the tool needs approval, false otherwise.
|
|
762
|
-
*/
|
|
763
|
-
get needsApproval() {
|
|
764
|
-
return this._needsApproval;
|
|
765
|
-
}
|
|
766
|
-
};
|
|
767
|
-
|
|
768
|
-
// src/tools/environment-tool-base.ts
|
|
769
|
-
var EnvironmentToolBase = class extends ToolBase {
|
|
770
|
-
_environment;
|
|
771
|
-
/**
|
|
772
|
-
* Constructs a new `EnvironmentToolBase` instance.
|
|
773
|
-
*
|
|
774
|
-
* @param environment - The execution environment to apply the tool in.
|
|
775
|
-
* @param toolConfig - Optional tool config, can be used to override some defaults.
|
|
776
|
-
*/
|
|
777
|
-
constructor(environment, toolConfig) {
|
|
778
|
-
super(toolConfig);
|
|
779
|
-
this._environment = environment;
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* Gets the current execution environment for the tool.
|
|
783
|
-
*
|
|
784
|
-
* @returns The current execution environment.
|
|
785
|
-
*/
|
|
786
|
-
get environment() {
|
|
787
|
-
return this._environment;
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Executes the tool with the given input.
|
|
791
|
-
*
|
|
792
|
-
* @param input - The input for the tool.
|
|
793
|
-
* @param _options - Options from the tool call.
|
|
794
|
-
* @returns A promise that resolves to the tool execution result.
|
|
795
|
-
*/
|
|
796
|
-
execute(input, _options) {
|
|
797
|
-
return this.executeForEnvironment(this._environment, input);
|
|
798
|
-
}
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
// src/tools/copy-file-tool.ts
|
|
369
|
+
var import_environment_utils5 = require("@ai-code-agents/environment-utils");
|
|
802
370
|
var CopyFileToolName = "copy_file";
|
|
803
371
|
var CopyFileToolInput = import_zod.z.object({
|
|
804
372
|
sourcePath: import_zod.z.string().meta({
|
|
@@ -808,8 +376,8 @@ var CopyFileToolInput = import_zod.z.object({
|
|
|
808
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."
|
|
809
377
|
})
|
|
810
378
|
});
|
|
811
|
-
var CopyFileToolOutput = CopyFileResult;
|
|
812
|
-
var CopyFileTool = class extends EnvironmentToolBase {
|
|
379
|
+
var CopyFileToolOutput = import_environment_utils5.CopyFileResult;
|
|
380
|
+
var CopyFileTool = class extends import_environment_utils5.EnvironmentToolBase {
|
|
813
381
|
/**
|
|
814
382
|
* Returns the metadata for the tool.
|
|
815
383
|
*
|
|
@@ -839,10 +407,11 @@ var CopyFileTool = class extends EnvironmentToolBase {
|
|
|
839
407
|
/**
|
|
840
408
|
* Converts the tool output to a format suitable for model consumption.
|
|
841
409
|
*
|
|
842
|
-
* @param
|
|
410
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
843
411
|
* @returns The formatted tool result.
|
|
844
412
|
*/
|
|
845
|
-
toModelOutput(
|
|
413
|
+
toModelOutput(options) {
|
|
414
|
+
const { output } = options;
|
|
846
415
|
return {
|
|
847
416
|
type: "text",
|
|
848
417
|
value: `File \`${output.sourcePath}\` copied successfully to \`${output.destinationPath}\`.`
|
|
@@ -868,14 +437,15 @@ var CopyFileTool = class extends EnvironmentToolBase {
|
|
|
868
437
|
|
|
869
438
|
// src/tools/delete-file-tool.ts
|
|
870
439
|
var import_zod2 = require("zod");
|
|
440
|
+
var import_environment_utils6 = require("@ai-code-agents/environment-utils");
|
|
871
441
|
var DeleteFileToolName = "delete_file";
|
|
872
442
|
var DeleteFileToolInput = import_zod2.z.object({
|
|
873
443
|
path: import_zod2.z.string().meta({
|
|
874
444
|
description: "The path to the file to delete, relative to the project directory."
|
|
875
445
|
})
|
|
876
446
|
});
|
|
877
|
-
var DeleteFileToolOutput = DeleteFileResult;
|
|
878
|
-
var DeleteFileTool = class extends EnvironmentToolBase {
|
|
447
|
+
var DeleteFileToolOutput = import_environment_utils6.DeleteFileResult;
|
|
448
|
+
var DeleteFileTool = class extends import_environment_utils6.EnvironmentToolBase {
|
|
879
449
|
/**
|
|
880
450
|
* Returns the metadata for the tool.
|
|
881
451
|
*
|
|
@@ -905,10 +475,11 @@ var DeleteFileTool = class extends EnvironmentToolBase {
|
|
|
905
475
|
/**
|
|
906
476
|
* Converts the tool output to a format suitable for model consumption.
|
|
907
477
|
*
|
|
908
|
-
* @param
|
|
478
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
909
479
|
* @returns The formatted tool result.
|
|
910
480
|
*/
|
|
911
|
-
toModelOutput(
|
|
481
|
+
toModelOutput(options) {
|
|
482
|
+
const { output } = options;
|
|
912
483
|
return {
|
|
913
484
|
type: "text",
|
|
914
485
|
value: `File \`${output.path}\` deleted successfully.`
|
|
@@ -933,6 +504,7 @@ var DeleteFileTool = class extends EnvironmentToolBase {
|
|
|
933
504
|
|
|
934
505
|
// src/tools/edit-file-tool.ts
|
|
935
506
|
var import_zod3 = require("zod");
|
|
507
|
+
var import_environment_utils7 = require("@ai-code-agents/environment-utils");
|
|
936
508
|
var EditFileToolName = "edit_file";
|
|
937
509
|
var EditFileToolInput = import_zod3.z.object({
|
|
938
510
|
path: import_zod3.z.string().meta({
|
|
@@ -965,10 +537,10 @@ var EditFileToolOutput = import_zod3.z.object({
|
|
|
965
537
|
description: "A message indicating the result of the edit operation."
|
|
966
538
|
})
|
|
967
539
|
});
|
|
968
|
-
function escapeRegExp(
|
|
969
|
-
return
|
|
540
|
+
function escapeRegExp(string) {
|
|
541
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
970
542
|
}
|
|
971
|
-
var EditFileTool = class extends EnvironmentToolBase {
|
|
543
|
+
var EditFileTool = class extends import_environment_utils7.EnvironmentToolBase {
|
|
972
544
|
/**
|
|
973
545
|
* Returns the metadata for the tool.
|
|
974
546
|
*
|
|
@@ -1023,10 +595,11 @@ var EditFileTool = class extends EnvironmentToolBase {
|
|
|
1023
595
|
/**
|
|
1024
596
|
* Converts the tool output to a format suitable for model consumption.
|
|
1025
597
|
*
|
|
1026
|
-
* @param
|
|
598
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1027
599
|
* @returns The formatted tool result.
|
|
1028
600
|
*/
|
|
1029
|
-
toModelOutput(
|
|
601
|
+
toModelOutput(options) {
|
|
602
|
+
const { output } = options;
|
|
1030
603
|
return {
|
|
1031
604
|
type: "text",
|
|
1032
605
|
value: `Edited file \`${output.path}\` with ${output.replacements} replacement(s).`
|
|
@@ -1075,6 +648,7 @@ var EditFileTool = class extends EnvironmentToolBase {
|
|
|
1075
648
|
|
|
1076
649
|
// src/tools/get-project-file-structure-tool.ts
|
|
1077
650
|
var import_zod4 = require("zod");
|
|
651
|
+
var import_environment_utils9 = require("@ai-code-agents/environment-utils");
|
|
1078
652
|
|
|
1079
653
|
// src/util/build-tree-from-files.ts
|
|
1080
654
|
function renderTree(node, prefix = "") {
|
|
@@ -1111,6 +685,91 @@ function buildTreeFromFiles(files) {
|
|
|
1111
685
|
return renderTree(tree).trim();
|
|
1112
686
|
}
|
|
1113
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
|
+
|
|
1114
773
|
// src/tools/get-project-file-structure-tool.ts
|
|
1115
774
|
var GetProjectFileStructureToolName = "get_project_file_structure";
|
|
1116
775
|
var GetProjectFileStructureToolInput = import_zod4.z.object({
|
|
@@ -1129,7 +788,7 @@ var GetProjectFileStructureToolOutput = import_zod4.z.object({
|
|
|
1129
788
|
description: "Whether files ignored by Git were excluded."
|
|
1130
789
|
})
|
|
1131
790
|
});
|
|
1132
|
-
var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
791
|
+
var GetProjectFileStructureTool = class extends import_environment_utils9.EnvironmentToolBase {
|
|
1133
792
|
/**
|
|
1134
793
|
* Returns the metadata for the tool.
|
|
1135
794
|
*
|
|
@@ -1155,21 +814,16 @@ var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
|
1155
814
|
*/
|
|
1156
815
|
async executeForEnvironment(env, input) {
|
|
1157
816
|
const { path: path5 = ".", excludeGitIgnored = true } = input;
|
|
1158
|
-
const escapedPath = escapeCommandArg(path5);
|
|
817
|
+
const escapedPath = (0, import_environment_utils9.escapeCommandArg)(path5);
|
|
1159
818
|
let command = `find ${escapedPath} -type f`;
|
|
1160
819
|
if (excludeGitIgnored) {
|
|
1161
|
-
|
|
1162
|
-
try {
|
|
1163
|
-
const { content: gitignoreContent } = await env.readFile(".gitignore");
|
|
1164
|
-
gitIgnoredPaths = gitignoreContent.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
1165
|
-
} catch (_error) {
|
|
1166
|
-
}
|
|
820
|
+
const gitIgnoredPaths = await getGitIgnoredPaths(env);
|
|
1167
821
|
for (const gitIgnoredPath of gitIgnoredPaths) {
|
|
1168
822
|
if (!gitIgnoredPath.endsWith("/")) {
|
|
1169
|
-
const escapedPath2 = escapeCommandArg(`*/${gitIgnoredPath}/*`);
|
|
1170
|
-
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}`;
|
|
1171
825
|
} else {
|
|
1172
|
-
const escapedPath2 = escapeCommandArg(`*/${gitIgnoredPath}*`);
|
|
826
|
+
const escapedPath2 = (0, import_environment_utils9.escapeCommandArg)(`*/${gitIgnoredPath}*`);
|
|
1173
827
|
command += ` -not -path ${escapedPath2}`;
|
|
1174
828
|
}
|
|
1175
829
|
}
|
|
@@ -1191,10 +845,11 @@ var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
|
1191
845
|
/**
|
|
1192
846
|
* Converts the tool output to a format suitable for model consumption.
|
|
1193
847
|
*
|
|
1194
|
-
* @param
|
|
848
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1195
849
|
* @returns The formatted tool result.
|
|
1196
850
|
*/
|
|
1197
|
-
toModelOutput(
|
|
851
|
+
toModelOutput(options) {
|
|
852
|
+
const { output } = options;
|
|
1198
853
|
const tree = buildTreeFromFiles(output.files);
|
|
1199
854
|
if (!tree) {
|
|
1200
855
|
return {
|
|
@@ -1233,6 +888,7 @@ var GetProjectFileStructureTool = class extends EnvironmentToolBase {
|
|
|
1233
888
|
|
|
1234
889
|
// src/tools/glob-tool.ts
|
|
1235
890
|
var import_zod5 = require("zod");
|
|
891
|
+
var import_environment_utils10 = require("@ai-code-agents/environment-utils");
|
|
1236
892
|
|
|
1237
893
|
// src/util/glob-to-reg-exp.ts
|
|
1238
894
|
function globToRegExp(glob) {
|
|
@@ -1305,7 +961,7 @@ var GlobToolOutput = import_zod5.z.object({
|
|
|
1305
961
|
description: "The list of file paths that matched the glob search, relative to the project directory."
|
|
1306
962
|
})
|
|
1307
963
|
});
|
|
1308
|
-
var GlobTool = class extends EnvironmentToolBase {
|
|
964
|
+
var GlobTool = class extends import_environment_utils10.EnvironmentToolBase {
|
|
1309
965
|
/**
|
|
1310
966
|
* Returns the metadata for the tool.
|
|
1311
967
|
*
|
|
@@ -1337,24 +993,19 @@ var GlobTool = class extends EnvironmentToolBase {
|
|
|
1337
993
|
);
|
|
1338
994
|
}
|
|
1339
995
|
if (searchPath) {
|
|
1340
|
-
validateRelativePath(searchPath);
|
|
996
|
+
(0, import_environment_utils10.validateRelativePath)(searchPath);
|
|
1341
997
|
}
|
|
1342
998
|
const untrailingslashedSearchPath = searchPath === "" ? "." : searchPath.replace(/\/+$/, "");
|
|
1343
|
-
const escapedSearchPath = escapeCommandArg(untrailingslashedSearchPath);
|
|
999
|
+
const escapedSearchPath = (0, import_environment_utils10.escapeCommandArg)(untrailingslashedSearchPath);
|
|
1344
1000
|
let command = `find ${escapedSearchPath} -type f`;
|
|
1345
1001
|
if (excludeGitIgnored) {
|
|
1346
|
-
|
|
1347
|
-
try {
|
|
1348
|
-
const { content: gitignoreContent } = await env.readFile(".gitignore");
|
|
1349
|
-
gitIgnoredPaths = gitignoreContent.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
1350
|
-
} catch (_error) {
|
|
1351
|
-
}
|
|
1002
|
+
const gitIgnoredPaths = await getGitIgnoredPaths(env);
|
|
1352
1003
|
for (const gitIgnoredPath of gitIgnoredPaths) {
|
|
1353
1004
|
if (!gitIgnoredPath.endsWith("/")) {
|
|
1354
|
-
const escapedPath = escapeCommandArg(`*/${gitIgnoredPath}/*`);
|
|
1355
|
-
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}`;
|
|
1356
1007
|
} else {
|
|
1357
|
-
const escapedPath = escapeCommandArg(`*/${gitIgnoredPath}*`);
|
|
1008
|
+
const escapedPath = (0, import_environment_utils10.escapeCommandArg)(`*/${gitIgnoredPath}*`);
|
|
1358
1009
|
command += ` -not -path ${escapedPath}`;
|
|
1359
1010
|
}
|
|
1360
1011
|
}
|
|
@@ -1390,10 +1041,11 @@ var GlobTool = class extends EnvironmentToolBase {
|
|
|
1390
1041
|
/**
|
|
1391
1042
|
* Converts the tool output to a format suitable for model consumption.
|
|
1392
1043
|
*
|
|
1393
|
-
* @param
|
|
1044
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1394
1045
|
* @returns The formatted tool result.
|
|
1395
1046
|
*/
|
|
1396
|
-
toModelOutput(
|
|
1047
|
+
toModelOutput(options) {
|
|
1048
|
+
const { output } = options;
|
|
1397
1049
|
if (output.matchingPaths.length === 0) {
|
|
1398
1050
|
return {
|
|
1399
1051
|
type: "text",
|
|
@@ -1442,26 +1094,287 @@ ${bulletPoints}
|
|
|
1442
1094
|
}
|
|
1443
1095
|
};
|
|
1444
1096
|
|
|
1445
|
-
// src/tools/
|
|
1097
|
+
// src/tools/grep-tool.ts
|
|
1446
1098
|
var import_zod6 = require("zod");
|
|
1447
|
-
var
|
|
1448
|
-
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({
|
|
1449
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({
|
|
1450
1363
|
description: "The directory path to list, relative to the project directory."
|
|
1451
1364
|
})
|
|
1452
1365
|
});
|
|
1453
|
-
var ListDirectoryToolOutput =
|
|
1454
|
-
path:
|
|
1366
|
+
var ListDirectoryToolOutput = import_zod7.z.object({
|
|
1367
|
+
path: import_zod7.z.string().meta({
|
|
1455
1368
|
description: "The directory path that was listed."
|
|
1456
1369
|
}),
|
|
1457
|
-
files:
|
|
1370
|
+
files: import_zod7.z.array(import_zod7.z.string()).meta({
|
|
1458
1371
|
description: "List of files in the directory."
|
|
1459
1372
|
}),
|
|
1460
|
-
directories:
|
|
1373
|
+
directories: import_zod7.z.array(import_zod7.z.string()).meta({
|
|
1461
1374
|
description: "List of subdirectories in the directory."
|
|
1462
1375
|
})
|
|
1463
1376
|
});
|
|
1464
|
-
var ListDirectoryTool = class extends EnvironmentToolBase {
|
|
1377
|
+
var ListDirectoryTool = class extends import_environment_utils12.EnvironmentToolBase {
|
|
1465
1378
|
/**
|
|
1466
1379
|
* Returns the metadata for the tool.
|
|
1467
1380
|
*
|
|
@@ -1486,7 +1399,7 @@ var ListDirectoryTool = class extends EnvironmentToolBase {
|
|
|
1486
1399
|
* @returns A promise that resolves to the tool execution result.
|
|
1487
1400
|
*/
|
|
1488
1401
|
async executeForEnvironment(env, input) {
|
|
1489
|
-
const escapedPath = escapeCommandArg(input.path);
|
|
1402
|
+
const escapedPath = (0, import_environment_utils12.escapeCommandArg)(input.path);
|
|
1490
1403
|
const command = `ls -la ${escapedPath}`;
|
|
1491
1404
|
const { stdout, stderr, exitCode } = await env.runCommand(command);
|
|
1492
1405
|
if (exitCode !== 0) {
|
|
@@ -1519,10 +1432,11 @@ var ListDirectoryTool = class extends EnvironmentToolBase {
|
|
|
1519
1432
|
/**
|
|
1520
1433
|
* Converts the tool output to a format suitable for model consumption.
|
|
1521
1434
|
*
|
|
1522
|
-
* @param
|
|
1435
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1523
1436
|
* @returns The formatted tool result.
|
|
1524
1437
|
*/
|
|
1525
|
-
toModelOutput(
|
|
1438
|
+
toModelOutput(options) {
|
|
1439
|
+
const { output } = options;
|
|
1526
1440
|
const formatEntries = (entries, type) => {
|
|
1527
1441
|
if (entries.length === 0) {
|
|
1528
1442
|
return `No ${type} found.`;
|
|
@@ -1568,18 +1482,19 @@ Directories:
|
|
|
1568
1482
|
};
|
|
1569
1483
|
|
|
1570
1484
|
// src/tools/move-file-tool.ts
|
|
1571
|
-
var
|
|
1485
|
+
var import_zod8 = require("zod");
|
|
1486
|
+
var import_environment_utils13 = require("@ai-code-agents/environment-utils");
|
|
1572
1487
|
var MoveFileToolName = "move_file";
|
|
1573
|
-
var MoveFileToolInput =
|
|
1574
|
-
sourcePath:
|
|
1488
|
+
var MoveFileToolInput = import_zod8.z.object({
|
|
1489
|
+
sourcePath: import_zod8.z.string().meta({
|
|
1575
1490
|
description: "The path to the file to move, relative to the project directory."
|
|
1576
1491
|
}),
|
|
1577
|
-
destinationPath:
|
|
1492
|
+
destinationPath: import_zod8.z.string().meta({
|
|
1578
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."
|
|
1579
1494
|
})
|
|
1580
1495
|
});
|
|
1581
|
-
var MoveFileToolOutput = MoveFileResult;
|
|
1582
|
-
var MoveFileTool = class extends EnvironmentToolBase {
|
|
1496
|
+
var MoveFileToolOutput = import_environment_utils13.MoveFileResult;
|
|
1497
|
+
var MoveFileTool = class extends import_environment_utils13.EnvironmentToolBase {
|
|
1583
1498
|
/**
|
|
1584
1499
|
* Returns the metadata for the tool.
|
|
1585
1500
|
*
|
|
@@ -1609,10 +1524,11 @@ var MoveFileTool = class extends EnvironmentToolBase {
|
|
|
1609
1524
|
/**
|
|
1610
1525
|
* Converts the tool output to a format suitable for model consumption.
|
|
1611
1526
|
*
|
|
1612
|
-
* @param
|
|
1527
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1613
1528
|
* @returns The formatted tool result.
|
|
1614
1529
|
*/
|
|
1615
|
-
toModelOutput(
|
|
1530
|
+
toModelOutput(options) {
|
|
1531
|
+
const { output } = options;
|
|
1616
1532
|
return {
|
|
1617
1533
|
type: "text",
|
|
1618
1534
|
value: `File \`${output.sourcePath}\` moved successfully to \`${output.destinationPath}\`.`
|
|
@@ -1637,10 +1553,11 @@ var MoveFileTool = class extends EnvironmentToolBase {
|
|
|
1637
1553
|
};
|
|
1638
1554
|
|
|
1639
1555
|
// src/tools/read-file-tool.ts
|
|
1640
|
-
var
|
|
1556
|
+
var import_zod9 = require("zod");
|
|
1557
|
+
var import_environment_utils14 = require("@ai-code-agents/environment-utils");
|
|
1641
1558
|
|
|
1642
1559
|
// src/util/get-language-identifier-from-file-path.ts
|
|
1643
|
-
var
|
|
1560
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1644
1561
|
var jsLanguage = {
|
|
1645
1562
|
identifier: "javascript",
|
|
1646
1563
|
name: "JavaScript",
|
|
@@ -1790,7 +1707,7 @@ var EXTENSION_TO_LANGUAGE = {
|
|
|
1790
1707
|
}
|
|
1791
1708
|
};
|
|
1792
1709
|
function getLanguageFromFilePath(filePath) {
|
|
1793
|
-
const extension =
|
|
1710
|
+
const extension = import_node_path4.default.extname(filePath).slice(1).toLowerCase() || "";
|
|
1794
1711
|
return EXTENSION_TO_LANGUAGE[extension];
|
|
1795
1712
|
}
|
|
1796
1713
|
function getLanguageIdentifierFromFilePath(filePath) {
|
|
@@ -1800,12 +1717,12 @@ function getLanguageIdentifierFromFilePath(filePath) {
|
|
|
1800
1717
|
|
|
1801
1718
|
// src/tools/read-file-tool.ts
|
|
1802
1719
|
var ReadFileToolName = "read_file";
|
|
1803
|
-
var ReadFileToolInput =
|
|
1804
|
-
path:
|
|
1720
|
+
var ReadFileToolInput = import_zod9.z.object({
|
|
1721
|
+
path: import_zod9.z.string().meta({
|
|
1805
1722
|
description: "The path to the file to read, relative to the project directory."
|
|
1806
1723
|
})
|
|
1807
1724
|
});
|
|
1808
|
-
var ReadFileToolOutput = ReadFileResult;
|
|
1725
|
+
var ReadFileToolOutput = import_environment_utils14.ReadFileResult;
|
|
1809
1726
|
var formatModelResponse = (output) => {
|
|
1810
1727
|
const language = getLanguageIdentifierFromFilePath(output.path);
|
|
1811
1728
|
return `File: \`${output.path}\`
|
|
@@ -1815,7 +1732,7 @@ ${output.content}
|
|
|
1815
1732
|
\`\`\`
|
|
1816
1733
|
`;
|
|
1817
1734
|
};
|
|
1818
|
-
var ReadFileTool = class extends EnvironmentToolBase {
|
|
1735
|
+
var ReadFileTool = class extends import_environment_utils14.EnvironmentToolBase {
|
|
1819
1736
|
/**
|
|
1820
1737
|
* Returns the metadata for the tool.
|
|
1821
1738
|
*
|
|
@@ -1845,10 +1762,11 @@ var ReadFileTool = class extends EnvironmentToolBase {
|
|
|
1845
1762
|
/**
|
|
1846
1763
|
* Converts the tool output to a format suitable for model consumption.
|
|
1847
1764
|
*
|
|
1848
|
-
* @param
|
|
1765
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1849
1766
|
* @returns The formatted tool result.
|
|
1850
1767
|
*/
|
|
1851
|
-
toModelOutput(
|
|
1768
|
+
toModelOutput(options) {
|
|
1769
|
+
const { output } = options;
|
|
1852
1770
|
return {
|
|
1853
1771
|
type: "text",
|
|
1854
1772
|
value: formatModelResponse(output)
|
|
@@ -1891,14 +1809,15 @@ export function Loader(props: LoaderProps) {
|
|
|
1891
1809
|
};
|
|
1892
1810
|
|
|
1893
1811
|
// src/tools/read-many-files-tool.ts
|
|
1894
|
-
var
|
|
1812
|
+
var import_zod10 = require("zod");
|
|
1813
|
+
var import_environment_utils15 = require("@ai-code-agents/environment-utils");
|
|
1895
1814
|
var ReadManyFilesToolName = "read_many_files";
|
|
1896
|
-
var ReadManyFilesToolInput =
|
|
1897
|
-
paths:
|
|
1815
|
+
var ReadManyFilesToolInput = import_zod10.z.object({
|
|
1816
|
+
paths: import_zod10.z.array(import_zod10.z.string()).meta({
|
|
1898
1817
|
description: "The paths to the files to read, relative to the project directory."
|
|
1899
1818
|
})
|
|
1900
1819
|
});
|
|
1901
|
-
var ReadManyFilesToolOutput =
|
|
1820
|
+
var ReadManyFilesToolOutput = import_zod10.z.record(import_zod10.z.string(), import_environment_utils15.ReadFileResult);
|
|
1902
1821
|
var formatModelResponse2 = (output) => {
|
|
1903
1822
|
const language = getLanguageIdentifierFromFilePath(output.path);
|
|
1904
1823
|
return `File: \`${output.path}\`
|
|
@@ -1908,7 +1827,7 @@ ${output.content}
|
|
|
1908
1827
|
\`\`\`
|
|
1909
1828
|
`;
|
|
1910
1829
|
};
|
|
1911
|
-
var ReadManyFilesTool = class extends EnvironmentToolBase {
|
|
1830
|
+
var ReadManyFilesTool = class extends import_environment_utils15.EnvironmentToolBase {
|
|
1912
1831
|
/**
|
|
1913
1832
|
* Returns the metadata for the tool.
|
|
1914
1833
|
*
|
|
@@ -1944,10 +1863,11 @@ var ReadManyFilesTool = class extends EnvironmentToolBase {
|
|
|
1944
1863
|
/**
|
|
1945
1864
|
* Converts the tool output to a format suitable for model consumption.
|
|
1946
1865
|
*
|
|
1947
|
-
* @param
|
|
1866
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
1948
1867
|
* @returns The formatted tool result.
|
|
1949
1868
|
*/
|
|
1950
|
-
toModelOutput(
|
|
1869
|
+
toModelOutput(options) {
|
|
1870
|
+
const { output } = options;
|
|
1951
1871
|
const fileContentResponses = Object.values(output).map(
|
|
1952
1872
|
(fileResult) => formatModelResponse2(fileResult)
|
|
1953
1873
|
);
|
|
@@ -2003,12 +1923,13 @@ export function Loader(props: LoaderProps) {
|
|
|
2003
1923
|
};
|
|
2004
1924
|
|
|
2005
1925
|
// src/tools/run-command-tool.ts
|
|
2006
|
-
var
|
|
1926
|
+
var import_zod11 = require("zod");
|
|
1927
|
+
var import_environment_utils16 = require("@ai-code-agents/environment-utils");
|
|
2007
1928
|
var RunCommandToolName = "run_command";
|
|
2008
|
-
var RunCommandToolInput =
|
|
2009
|
-
command:
|
|
1929
|
+
var RunCommandToolInput = import_zod11.z.object({
|
|
1930
|
+
command: import_zod11.z.string().meta({ description: "The CLI command to run, including all arguments." })
|
|
2010
1931
|
});
|
|
2011
|
-
var RunCommandToolOutput = RunCommandResult;
|
|
1932
|
+
var RunCommandToolOutput = import_environment_utils16.RunCommandResult;
|
|
2012
1933
|
function formatCommandResultToModelResponse(output) {
|
|
2013
1934
|
const stdout = !output.stdout.trim() ? "(none)" : `
|
|
2014
1935
|
\`\`\`
|
|
@@ -2024,7 +1945,7 @@ Output (stdout): ${stdout}
|
|
|
2024
1945
|
Error Output (stderr): ${stderr}
|
|
2025
1946
|
`;
|
|
2026
1947
|
}
|
|
2027
|
-
var RunCommandTool = class extends EnvironmentToolBase {
|
|
1948
|
+
var RunCommandTool = class extends import_environment_utils16.EnvironmentToolBase {
|
|
2028
1949
|
/**
|
|
2029
1950
|
* Returns the metadata for the tool.
|
|
2030
1951
|
*
|
|
@@ -2054,10 +1975,11 @@ var RunCommandTool = class extends EnvironmentToolBase {
|
|
|
2054
1975
|
/**
|
|
2055
1976
|
* Converts the tool output to a format suitable for model consumption.
|
|
2056
1977
|
*
|
|
2057
|
-
* @param
|
|
1978
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
2058
1979
|
* @returns The formatted tool result.
|
|
2059
1980
|
*/
|
|
2060
|
-
toModelOutput(
|
|
1981
|
+
toModelOutput(options) {
|
|
1982
|
+
const { output } = options;
|
|
2061
1983
|
return {
|
|
2062
1984
|
type: "text",
|
|
2063
1985
|
value: formatCommandResultToModelResponse(output)
|
|
@@ -2128,18 +2050,19 @@ added 1 package, and changed 1 package in 2s
|
|
|
2128
2050
|
};
|
|
2129
2051
|
|
|
2130
2052
|
// src/tools/write-file-tool.ts
|
|
2131
|
-
var
|
|
2053
|
+
var import_zod12 = require("zod");
|
|
2054
|
+
var import_environment_utils17 = require("@ai-code-agents/environment-utils");
|
|
2132
2055
|
var WriteFileToolName = "write_file";
|
|
2133
|
-
var WriteFileToolInput =
|
|
2134
|
-
path:
|
|
2056
|
+
var WriteFileToolInput = import_zod12.z.object({
|
|
2057
|
+
path: import_zod12.z.string().meta({
|
|
2135
2058
|
description: "The path to the file to write, relative to the project directory."
|
|
2136
2059
|
}),
|
|
2137
|
-
content:
|
|
2060
|
+
content: import_zod12.z.string().meta({
|
|
2138
2061
|
description: "The content to write to the file. If the file already exists, the content will replace existing content."
|
|
2139
2062
|
})
|
|
2140
2063
|
});
|
|
2141
|
-
var WriteFileToolOutput = WriteFileResult;
|
|
2142
|
-
var WriteFileTool = class extends EnvironmentToolBase {
|
|
2064
|
+
var WriteFileToolOutput = import_environment_utils17.WriteFileResult;
|
|
2065
|
+
var WriteFileTool = class extends import_environment_utils17.EnvironmentToolBase {
|
|
2143
2066
|
/**
|
|
2144
2067
|
* Returns the metadata for the tool.
|
|
2145
2068
|
*
|
|
@@ -2169,10 +2092,11 @@ var WriteFileTool = class extends EnvironmentToolBase {
|
|
|
2169
2092
|
/**
|
|
2170
2093
|
* Converts the tool output to a format suitable for model consumption.
|
|
2171
2094
|
*
|
|
2172
|
-
* @param
|
|
2095
|
+
* @param options - The tool result, including the output from the tool execution.
|
|
2173
2096
|
* @returns The formatted tool result.
|
|
2174
2097
|
*/
|
|
2175
|
-
toModelOutput(
|
|
2098
|
+
toModelOutput(options) {
|
|
2099
|
+
const { output } = options;
|
|
2176
2100
|
return {
|
|
2177
2101
|
type: "text",
|
|
2178
2102
|
value: `File \`${output.path}\` written successfully.`
|
|
@@ -2200,15 +2124,13 @@ var WriteFileTool = class extends EnvironmentToolBase {
|
|
|
2200
2124
|
}
|
|
2201
2125
|
};
|
|
2202
2126
|
|
|
2203
|
-
// src/agent-creators.ts
|
|
2204
|
-
var import_ai = require("ai");
|
|
2205
|
-
|
|
2206
2127
|
// src/tools/submit-tool.ts
|
|
2207
|
-
var
|
|
2128
|
+
var import_zod13 = require("zod");
|
|
2129
|
+
var import_environment_utils18 = require("@ai-code-agents/environment-utils");
|
|
2208
2130
|
var SubmitToolName = "submit";
|
|
2209
|
-
var SubmitToolInput =
|
|
2210
|
-
var SubmitToolOutput =
|
|
2211
|
-
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 {
|
|
2212
2134
|
/**
|
|
2213
2135
|
* Returns the metadata for the tool.
|
|
2214
2136
|
*
|
|
@@ -2229,7 +2151,7 @@ var SubmitTool = class extends ToolBase {
|
|
|
2229
2151
|
* Executes the tool with the given input.
|
|
2230
2152
|
*
|
|
2231
2153
|
* @param _ - The input for the tool. Unused.
|
|
2232
|
-
* @param __ - Options
|
|
2154
|
+
* @param __ - Options for the tool execution. Unused.
|
|
2233
2155
|
* @returns A promise that resolves to the tool execution result.
|
|
2234
2156
|
*/
|
|
2235
2157
|
async execute(_, __) {
|
|
@@ -2238,7 +2160,7 @@ var SubmitTool = class extends ToolBase {
|
|
|
2238
2160
|
/**
|
|
2239
2161
|
* Converts the tool output to a format suitable for model consumption.
|
|
2240
2162
|
*
|
|
2241
|
-
* @param _ - The output from the tool execution. Unused.
|
|
2163
|
+
* @param _ - The tool result, including the output from the tool execution. Unused.
|
|
2242
2164
|
* @returns The formatted tool result.
|
|
2243
2165
|
*/
|
|
2244
2166
|
toModelOutput(_) {
|
|
@@ -2257,13 +2179,19 @@ var SubmitTool = class extends ToolBase {
|
|
|
2257
2179
|
}
|
|
2258
2180
|
};
|
|
2259
2181
|
|
|
2182
|
+
// src/agent-creators.ts
|
|
2183
|
+
var import_ai = require("ai");
|
|
2184
|
+
|
|
2260
2185
|
// src/instructions.ts
|
|
2261
2186
|
function getAdditionalInstructions(config) {
|
|
2262
2187
|
const { maxSteps, allowSubmit, tools } = config;
|
|
2263
|
-
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
|
+
];
|
|
2264
2192
|
for (const [toolName, tool] of Object.entries(tools)) {
|
|
2265
2193
|
if ("examples" in tool && Array.isArray(tool.examples) && tool.examples.length > 0) {
|
|
2266
|
-
let toolSection =
|
|
2194
|
+
let toolSection = `## Tool: \`${toolName}\`
|
|
2267
2195
|
|
|
2268
2196
|
`;
|
|
2269
2197
|
for (const example of tool.examples) {
|
|
@@ -2272,40 +2200,48 @@ function getAdditionalInstructions(config) {
|
|
|
2272
2200
|
exampleSections.push(toolSection.trim());
|
|
2273
2201
|
}
|
|
2274
2202
|
}
|
|
2275
|
-
const
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
"You have access to several tools to assist you in completing your task."
|
|
2282
|
-
] : [],
|
|
2283
|
-
"You must issue tool calls to complete your task. Do not engage with the user directly.",
|
|
2284
|
-
...allowSubmit ? [
|
|
2285
|
-
`Once you think you have completed your task, call the \`${SubmitToolName}\` tool to submit your results.`
|
|
2286
|
-
] : [],
|
|
2287
|
-
`You have a maximum of ${maxSteps} steps to complete your task.`
|
|
2288
|
-
];
|
|
2289
|
-
const importantWorkflowGuidelines = `## Important Workflow Guidelines
|
|
2290
|
-
|
|
2291
|
-
${workflowGuidelines.map((line) => `- ${line}`).join("\n")}
|
|
2292
|
-
|
|
2293
|
-
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}
|
|
2294
2209
|
`;
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2210
|
+
}
|
|
2211
|
+
constraintSections.push(constraintSection.trim());
|
|
2212
|
+
}
|
|
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());
|
|
2303
2236
|
}
|
|
2304
|
-
|
|
2237
|
+
const finalReminder = getCodeAgentFinalReminder();
|
|
2238
|
+
return [...exampleSections, ...constraintSections, finalReminder].join(
|
|
2239
|
+
"\n\n"
|
|
2240
|
+
);
|
|
2305
2241
|
}
|
|
2306
2242
|
function formatExampleForInstructions(toolName, example) {
|
|
2307
|
-
const input =
|
|
2308
|
-
const output =
|
|
2243
|
+
const input = formatValueForExample(example.input);
|
|
2244
|
+
const output = formatValueForExample(example.output);
|
|
2309
2245
|
if (output === "") {
|
|
2310
2246
|
return `<example>
|
|
2311
2247
|
<tool_call>
|
|
@@ -2322,8 +2258,40 @@ ${output}
|
|
|
2322
2258
|
</tool_response>
|
|
2323
2259
|
</example>`;
|
|
2324
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
|
+
}
|
|
2325
2292
|
|
|
2326
2293
|
// src/tool-creators.ts
|
|
2294
|
+
var import_environment_utils19 = require("@ai-code-agents/environment-utils");
|
|
2327
2295
|
var availableEnvironmentTools = {
|
|
2328
2296
|
[ReadFileToolName]: ReadFileTool,
|
|
2329
2297
|
[WriteFileToolName]: WriteFileTool,
|
|
@@ -2334,12 +2302,14 @@ var availableEnvironmentTools = {
|
|
|
2334
2302
|
[ReadManyFilesToolName]: ReadManyFilesTool,
|
|
2335
2303
|
[GetProjectFileStructureToolName]: GetProjectFileStructureTool,
|
|
2336
2304
|
[GlobToolName]: GlobTool,
|
|
2305
|
+
[GrepToolName]: GrepTool,
|
|
2337
2306
|
[ListDirectoryToolName]: ListDirectoryTool,
|
|
2338
2307
|
[RunCommandToolName]: RunCommandTool
|
|
2339
2308
|
};
|
|
2340
2309
|
var cliOnlyTools = [
|
|
2341
2310
|
GetProjectFileStructureToolName,
|
|
2342
2311
|
GlobToolName,
|
|
2312
|
+
GrepToolName,
|
|
2343
2313
|
ListDirectoryToolName,
|
|
2344
2314
|
RunCommandToolName
|
|
2345
2315
|
];
|
|
@@ -2348,6 +2318,7 @@ var readonlyTools = [
|
|
|
2348
2318
|
ReadManyFilesToolName,
|
|
2349
2319
|
GetProjectFileStructureToolName,
|
|
2350
2320
|
GlobToolName,
|
|
2321
|
+
GrepToolName,
|
|
2351
2322
|
ListDirectoryToolName
|
|
2352
2323
|
];
|
|
2353
2324
|
var dangerousTools = [
|
|
@@ -2375,7 +2346,7 @@ function createEnvironmentTool(toolName, environment, config) {
|
|
|
2375
2346
|
}
|
|
2376
2347
|
function createToolsForEnvironment(environment, toolsDefinition = "all") {
|
|
2377
2348
|
const sanitizedToolsDefinition = sanitizeToolsDefinition(toolsDefinition);
|
|
2378
|
-
const isCliEnvironment =
|
|
2349
|
+
const isCliEnvironment = (0, import_environment_utils19.isCommandLine)(environment);
|
|
2379
2350
|
const tools = {};
|
|
2380
2351
|
for (const toolDefinition of sanitizedToolsDefinition) {
|
|
2381
2352
|
const actualToolName = toolDefinition.toolName;
|
|
@@ -2396,7 +2367,7 @@ function createToolsForEnvironment(environment, toolsDefinition = "all") {
|
|
|
2396
2367
|
}
|
|
2397
2368
|
tools[toolNameToUse] = createEnvironmentTool(
|
|
2398
2369
|
actualToolName,
|
|
2399
|
-
|
|
2370
|
+
environment,
|
|
2400
2371
|
toolConfig
|
|
2401
2372
|
);
|
|
2402
2373
|
}
|
|
@@ -2452,6 +2423,54 @@ function sanitizeToolsDefinition(toolsDefinition) {
|
|
|
2452
2423
|
});
|
|
2453
2424
|
}
|
|
2454
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
|
+
|
|
2455
2474
|
// src/util/get-step-log.ts
|
|
2456
2475
|
function getStepLog(stepResult) {
|
|
2457
2476
|
const { content } = stepResult;
|
|
@@ -2465,13 +2484,17 @@ function getStepLog(stepResult) {
|
|
|
2465
2484
|
}
|
|
2466
2485
|
logEntry += ": ";
|
|
2467
2486
|
if (part.type === "tool-call" && "input" in part) {
|
|
2468
|
-
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
|
+
);
|
|
2469
2490
|
} else if (part.type === "tool-result" && "output" in part) {
|
|
2470
|
-
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
|
+
);
|
|
2471
2494
|
} else if (part.type === "tool-error" && "error" in part) {
|
|
2472
2495
|
logEntry += typeof part.error === "object" && part.error !== null && "message" in part.error ? part.error.message : String(part.error);
|
|
2473
2496
|
} else if (part.type === "text" && "text" in part) {
|
|
2474
|
-
logEntry += part.text;
|
|
2497
|
+
logEntry += truncateString(part.text);
|
|
2475
2498
|
}
|
|
2476
2499
|
logEntry += "\n";
|
|
2477
2500
|
});
|
|
@@ -2480,6 +2503,9 @@ function getStepLog(stepResult) {
|
|
|
2480
2503
|
|
|
2481
2504
|
// src/agent-creators.ts
|
|
2482
2505
|
function createCodeAgent(agentConfig) {
|
|
2506
|
+
return new import_ai.ToolLoopAgent(createCodeAgentSettings(agentConfig));
|
|
2507
|
+
}
|
|
2508
|
+
function createCodeAgentSettings(agentConfig) {
|
|
2483
2509
|
const {
|
|
2484
2510
|
maxSteps,
|
|
2485
2511
|
allowSubmit,
|
|
@@ -2488,46 +2514,29 @@ function createCodeAgent(agentConfig) {
|
|
|
2488
2514
|
tools: originalTools,
|
|
2489
2515
|
stopWhen: originalStopWhen,
|
|
2490
2516
|
prepareStep: originalPrepareStep,
|
|
2491
|
-
|
|
2517
|
+
instructions: originalSystemInstruction,
|
|
2492
2518
|
...remainingConfig
|
|
2493
2519
|
} = agentConfig;
|
|
2494
2520
|
let agentSettings;
|
|
2495
|
-
let
|
|
2521
|
+
let tools;
|
|
2496
2522
|
if ("environments" in remainingConfig) {
|
|
2497
2523
|
const { environments, environmentToolsDefinition, ...agentSettingsInput } = remainingConfig;
|
|
2498
2524
|
agentSettings = { ...agentSettingsInput };
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
`No tools definition provided for environment "${environmentName}". Please provide a tools definition for each environment.`
|
|
2504
|
-
);
|
|
2505
|
-
}
|
|
2506
|
-
const environmentTools2 = createToolsForNamedEnvironment(
|
|
2507
|
-
environmentName,
|
|
2508
|
-
environment,
|
|
2509
|
-
environmentToolsDefinition[environmentName]
|
|
2510
|
-
);
|
|
2511
|
-
for (const [toolName, tool] of Object.entries(environmentTools2)) {
|
|
2512
|
-
if (toolName in environmentTools2) {
|
|
2513
|
-
throw new Error(
|
|
2514
|
-
`Tool name conflict: The tool name "${toolName}" from environment "${environmentName}" is already used by another environment's tools.`
|
|
2515
|
-
);
|
|
2516
|
-
}
|
|
2517
|
-
environmentTools2[toolName] = tool;
|
|
2518
|
-
}
|
|
2519
|
-
}
|
|
2525
|
+
tools = createCodeAgentTools(
|
|
2526
|
+
{ environments, environmentToolsDefinition },
|
|
2527
|
+
originalTools
|
|
2528
|
+
);
|
|
2520
2529
|
} else if ("environment" in remainingConfig) {
|
|
2521
2530
|
const { environment, environmentToolsDefinition, ...agentSettingsInput } = remainingConfig;
|
|
2522
2531
|
agentSettings = { ...agentSettingsInput };
|
|
2523
|
-
|
|
2524
|
-
environment,
|
|
2525
|
-
|
|
2532
|
+
tools = createCodeAgentTools(
|
|
2533
|
+
{ environment, environmentToolsDefinition },
|
|
2534
|
+
originalTools
|
|
2526
2535
|
);
|
|
2527
2536
|
} else {
|
|
2528
2537
|
agentSettings = { ...remainingConfig };
|
|
2538
|
+
tools = originalTools || {};
|
|
2529
2539
|
}
|
|
2530
|
-
const tools = environmentTools && originalTools ? mergeTools(environmentTools, originalTools) : originalTools || environmentTools || {};
|
|
2531
2540
|
if (allowSubmit) {
|
|
2532
2541
|
if (SubmitToolName in tools) {
|
|
2533
2542
|
throw new Error(
|
|
@@ -2555,16 +2564,54 @@ ${stepLog}`, stepCount - 1);
|
|
|
2555
2564
|
} : originalPrepareStep;
|
|
2556
2565
|
const stopWhenCondition = allowSubmit ? [(0, import_ai.stepCountIs)(maxSteps), (0, import_ai.hasToolCall)(SubmitToolName)] : (0, import_ai.stepCountIs)(maxSteps);
|
|
2557
2566
|
const stopWhen = originalStopWhen ? mergeStopWhen(originalStopWhen, stopWhenCondition) : stopWhenCondition;
|
|
2558
|
-
const
|
|
2567
|
+
const instructions = !omitAdditionalInstructions ? mergeSystemInstructions(
|
|
2559
2568
|
originalSystemInstruction,
|
|
2560
2569
|
getAdditionalInstructions({ maxSteps, allowSubmit, tools })
|
|
2561
2570
|
) : originalSystemInstruction;
|
|
2562
|
-
return
|
|
2571
|
+
return {
|
|
2563
2572
|
...agentSettings,
|
|
2564
|
-
|
|
2573
|
+
instructions,
|
|
2565
2574
|
prepareStep,
|
|
2566
2575
|
stopWhen
|
|
2567
|
-
}
|
|
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
|
+
);
|
|
2568
2615
|
}
|
|
2569
2616
|
function mergeTools(baseTools, additionalTools) {
|
|
2570
2617
|
const tools = { ...baseTools };
|
|
@@ -2590,9 +2637,26 @@ function mergeStopWhen(baseStopWhen, additionalStopWhen) {
|
|
|
2590
2637
|
}
|
|
2591
2638
|
return [baseStopWhen, additionalStopWhen];
|
|
2592
2639
|
}
|
|
2593
|
-
function mergeSystemInstructions(
|
|
2594
|
-
if (
|
|
2595
|
-
|
|
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()}
|
|
2596
2660
|
|
|
2597
2661
|
${additionalInstructions}`;
|
|
2598
2662
|
}
|
|
@@ -2618,12 +2682,10 @@ function createEnvironment(environmentName, config) {
|
|
|
2618
2682
|
}
|
|
2619
2683
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2620
2684
|
0 && (module.exports = {
|
|
2621
|
-
CopyFileResult,
|
|
2622
2685
|
CopyFileTool,
|
|
2623
2686
|
CopyFileToolInput,
|
|
2624
2687
|
CopyFileToolName,
|
|
2625
2688
|
CopyFileToolOutput,
|
|
2626
|
-
DeleteFileResult,
|
|
2627
2689
|
DeleteFileTool,
|
|
2628
2690
|
DeleteFileToolInput,
|
|
2629
2691
|
DeleteFileToolName,
|
|
@@ -2645,20 +2707,22 @@ function createEnvironment(environmentName, config) {
|
|
|
2645
2707
|
GlobToolInput,
|
|
2646
2708
|
GlobToolName,
|
|
2647
2709
|
GlobToolOutput,
|
|
2710
|
+
GrepTool,
|
|
2711
|
+
GrepToolInput,
|
|
2712
|
+
GrepToolName,
|
|
2713
|
+
GrepToolOutput,
|
|
2648
2714
|
ListDirectoryTool,
|
|
2649
2715
|
ListDirectoryToolInput,
|
|
2650
2716
|
ListDirectoryToolName,
|
|
2651
2717
|
ListDirectoryToolOutput,
|
|
2652
2718
|
MockFilesystemEnvironment,
|
|
2653
2719
|
MockFilesystemEnvironmentName,
|
|
2654
|
-
MoveFileResult,
|
|
2655
2720
|
MoveFileTool,
|
|
2656
2721
|
MoveFileToolInput,
|
|
2657
2722
|
MoveFileToolName,
|
|
2658
2723
|
MoveFileToolOutput,
|
|
2659
2724
|
NodeFilesystemEnvironment,
|
|
2660
2725
|
NodeFilesystemEnvironmentName,
|
|
2661
|
-
ReadFileResult,
|
|
2662
2726
|
ReadFileTool,
|
|
2663
2727
|
ReadFileToolInput,
|
|
2664
2728
|
ReadFileToolName,
|
|
@@ -2667,19 +2731,23 @@ function createEnvironment(environmentName, config) {
|
|
|
2667
2731
|
ReadManyFilesToolInput,
|
|
2668
2732
|
ReadManyFilesToolName,
|
|
2669
2733
|
ReadManyFilesToolOutput,
|
|
2670
|
-
RunCommandResult,
|
|
2671
2734
|
RunCommandTool,
|
|
2672
2735
|
RunCommandToolInput,
|
|
2673
2736
|
RunCommandToolName,
|
|
2674
2737
|
RunCommandToolOutput,
|
|
2738
|
+
SubmitTool,
|
|
2739
|
+
SubmitToolInput,
|
|
2740
|
+
SubmitToolName,
|
|
2741
|
+
SubmitToolOutput,
|
|
2675
2742
|
UnsafeLocalEnvironment,
|
|
2676
2743
|
UnsafeLocalEnvironmentName,
|
|
2677
|
-
WriteFileResult,
|
|
2678
2744
|
WriteFileTool,
|
|
2679
2745
|
WriteFileToolInput,
|
|
2680
2746
|
WriteFileToolName,
|
|
2681
2747
|
WriteFileToolOutput,
|
|
2682
2748
|
createCodeAgent,
|
|
2749
|
+
createCodeAgentSettings,
|
|
2750
|
+
createCodeAgentTools,
|
|
2683
2751
|
createEnvironment,
|
|
2684
2752
|
createEnvironmentTool,
|
|
2685
2753
|
createToolsForEnvironment,
|