wave-agent-sdk 0.4.0 → 0.5.1
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/dist/agent.d.ts +28 -5
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +54 -37
- package/dist/constants/tools.d.ts +2 -2
- package/dist/constants/tools.js +2 -2
- package/dist/managers/MemoryRuleManager.js +1 -1
- package/dist/managers/aiManager.d.ts +3 -3
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +3 -4
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +1 -0
- package/dist/managers/backgroundTaskManager.d.ts +35 -0
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -0
- package/dist/managers/backgroundTaskManager.js +249 -0
- package/dist/managers/foregroundTaskManager.d.ts +9 -0
- package/dist/managers/foregroundTaskManager.d.ts.map +1 -0
- package/dist/managers/foregroundTaskManager.js +20 -0
- package/dist/managers/liveConfigManager.d.ts +1 -1
- package/dist/managers/lspManager.d.ts.map +1 -1
- package/dist/managers/lspManager.js +3 -1
- package/dist/managers/messageManager.d.ts +12 -2
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +36 -2
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +1 -7
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +3 -2
- package/dist/managers/slashCommandManager.d.ts +3 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +1 -0
- package/dist/managers/subagentManager.d.ts +11 -2
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +137 -39
- package/dist/managers/toolManager.d.ts +7 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +9 -3
- package/dist/services/GitService.d.ts.map +1 -1
- package/dist/services/GitService.js +6 -2
- package/dist/services/MarketplaceService.d.ts +2 -2
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +18 -11
- package/dist/services/MemoryRuleService.d.ts +1 -1
- package/dist/services/MemoryRuleService.d.ts.map +1 -1
- package/dist/services/MemoryRuleService.js +13 -2
- package/dist/services/memory.js +1 -1
- package/dist/tools/bashTool.d.ts +0 -8
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +44 -172
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +6 -5
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +7 -6
- package/dist/tools/taskOutputTool.d.ts +3 -0
- package/dist/tools/taskOutputTool.d.ts.map +1 -0
- package/dist/tools/taskOutputTool.js +149 -0
- package/dist/tools/taskStopTool.d.ts +3 -0
- package/dist/tools/taskStopTool.d.ts.map +1 -0
- package/dist/tools/taskStopTool.js +65 -0
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +105 -63
- package/dist/tools/types.d.ts +3 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/types/marketplace.d.ts +1 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +1 -0
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/processes.d.ts +24 -4
- package/dist/types/processes.d.ts.map +1 -1
- package/dist/utils/editUtils.d.ts +2 -11
- package/dist/utils/editUtils.d.ts.map +1 -1
- package/dist/utils/editUtils.js +52 -79
- package/dist/utils/messageOperations.d.ts +3 -1
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +5 -1
- package/package.json +5 -5
- package/src/agent.ts +73 -45
- package/src/constants/tools.ts +2 -2
- package/src/managers/MemoryRuleManager.ts +1 -1
- package/src/managers/aiManager.ts +6 -9
- package/src/managers/backgroundBashManager.ts +1 -0
- package/src/managers/backgroundTaskManager.ts +306 -0
- package/src/managers/foregroundTaskManager.ts +26 -0
- package/src/managers/lspManager.ts +3 -1
- package/src/managers/messageManager.ts +48 -2
- package/src/managers/permissionManager.ts +1 -7
- package/src/managers/pluginManager.ts +4 -3
- package/src/managers/slashCommandManager.ts +4 -0
- package/src/managers/subagentManager.ts +167 -35
- package/src/managers/toolManager.ts +16 -4
- package/src/services/GitService.ts +6 -2
- package/src/services/MarketplaceService.ts +30 -12
- package/src/services/MemoryRuleService.ts +18 -6
- package/src/services/memory.ts +1 -1
- package/src/tools/bashTool.ts +59 -196
- package/src/tools/editTool.ts +6 -17
- package/src/tools/multiEditTool.ts +7 -18
- package/src/tools/taskOutputTool.ts +174 -0
- package/src/tools/taskStopTool.ts +72 -0
- package/src/tools/taskTool.ts +130 -74
- package/src/tools/types.ts +3 -0
- package/src/types/marketplace.ts +1 -0
- package/src/types/messaging.ts +1 -0
- package/src/types/processes.ts +33 -4
- package/src/utils/editUtils.ts +65 -103
- package/src/utils/messageOperations.ts +7 -0
package/dist/tools/bashTool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import { logger } from "../utils/globalLogger.js";
|
|
3
3
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
4
|
-
import { BASH_TOOL_NAME,
|
|
4
|
+
import { BASH_TOOL_NAME, TASK_OUTPUT_TOOL_NAME, GLOB_TOOL_NAME, GREP_TOOL_NAME, READ_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, } from "../constants/tools.js";
|
|
5
5
|
const MAX_OUTPUT_LENGTH = 30000;
|
|
6
6
|
const BASH_DEFAULT_TIMEOUT_MS = 120000;
|
|
7
7
|
/**
|
|
@@ -76,7 +76,7 @@ Usage notes:
|
|
|
76
76
|
},
|
|
77
77
|
run_in_background: {
|
|
78
78
|
type: "boolean",
|
|
79
|
-
description: `Set to true to run this command in the background. Use ${
|
|
79
|
+
description: `Set to true to run this command in the background. Use ${TASK_OUTPUT_TOOL_NAME} to read the output later.`,
|
|
80
80
|
},
|
|
81
81
|
},
|
|
82
82
|
required: ["command"],
|
|
@@ -135,19 +135,19 @@ Usage notes:
|
|
|
135
135
|
}
|
|
136
136
|
if (runInBackground) {
|
|
137
137
|
// Background execution
|
|
138
|
-
const
|
|
139
|
-
if (!
|
|
138
|
+
const backgroundTaskManager = context?.backgroundTaskManager;
|
|
139
|
+
if (!backgroundTaskManager) {
|
|
140
140
|
return {
|
|
141
141
|
success: false,
|
|
142
142
|
content: "",
|
|
143
|
-
error: "Background
|
|
143
|
+
error: "Background task manager not available",
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
|
-
const
|
|
146
|
+
const { id: taskId } = backgroundTaskManager.startShell(command, timeout);
|
|
147
147
|
return {
|
|
148
148
|
success: true,
|
|
149
|
-
content: `Command started in background with ID: ${
|
|
150
|
-
shortResult: `Background process ${
|
|
149
|
+
content: `Command started in background with ID: ${taskId}. Use TaskOutput tool with task_id="${taskId}" to monitor output.`,
|
|
150
|
+
shortResult: `Background process ${taskId} started`,
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
// Foreground execution (original behavior)
|
|
@@ -163,6 +163,32 @@ Usage notes:
|
|
|
163
163
|
let outputBuffer = "";
|
|
164
164
|
let errorBuffer = "";
|
|
165
165
|
let isAborted = false;
|
|
166
|
+
let isBackgrounded = false;
|
|
167
|
+
const foregroundTaskId = `bash_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
168
|
+
// Register as foreground task
|
|
169
|
+
if (context.foregroundTaskManager && command) {
|
|
170
|
+
context.foregroundTaskManager.registerForegroundTask({
|
|
171
|
+
id: foregroundTaskId,
|
|
172
|
+
backgroundHandler: async () => {
|
|
173
|
+
isBackgrounded = true;
|
|
174
|
+
if (timeoutHandle) {
|
|
175
|
+
clearTimeout(timeoutHandle);
|
|
176
|
+
}
|
|
177
|
+
const backgroundTaskManager = context.backgroundTaskManager;
|
|
178
|
+
if (backgroundTaskManager) {
|
|
179
|
+
const taskId = backgroundTaskManager.adoptProcess(child, command, outputBuffer, errorBuffer);
|
|
180
|
+
resolve({
|
|
181
|
+
success: true,
|
|
182
|
+
content: `Command moved to background with ID: ${taskId}. Use TaskOutput tool with task_id="${taskId}" to monitor output.`,
|
|
183
|
+
shortResult: `Process ${taskId} backgrounded`,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
handleAbort("Failed to background: Background task manager not available");
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
166
192
|
// Set up timeout
|
|
167
193
|
let timeoutHandle;
|
|
168
194
|
if (timeout && timeout > 0) {
|
|
@@ -230,17 +256,20 @@ Usage notes:
|
|
|
230
256
|
});
|
|
231
257
|
}
|
|
232
258
|
child.stdout?.on("data", (data) => {
|
|
233
|
-
if (!isAborted) {
|
|
259
|
+
if (!isAborted && !isBackgrounded) {
|
|
234
260
|
outputBuffer += stripAnsiColors(data.toString());
|
|
235
261
|
}
|
|
236
262
|
});
|
|
237
263
|
child.stderr?.on("data", (data) => {
|
|
238
|
-
if (!isAborted) {
|
|
264
|
+
if (!isAborted && !isBackgrounded) {
|
|
239
265
|
errorBuffer += stripAnsiColors(data.toString());
|
|
240
266
|
}
|
|
241
267
|
});
|
|
242
268
|
child.on("exit", (code) => {
|
|
243
|
-
if (
|
|
269
|
+
if (context.foregroundTaskManager) {
|
|
270
|
+
context.foregroundTaskManager.unregisterForegroundTask(foregroundTaskId);
|
|
271
|
+
}
|
|
272
|
+
if (!isAborted && !isBackgrounded) {
|
|
244
273
|
if (timeoutHandle) {
|
|
245
274
|
clearTimeout(timeoutHandle);
|
|
246
275
|
}
|
|
@@ -262,7 +291,10 @@ Usage notes:
|
|
|
262
291
|
}
|
|
263
292
|
});
|
|
264
293
|
child.on("error", (error) => {
|
|
265
|
-
if (
|
|
294
|
+
if (context.foregroundTaskManager) {
|
|
295
|
+
context.foregroundTaskManager.unregisterForegroundTask(foregroundTaskId);
|
|
296
|
+
}
|
|
297
|
+
if (!isAborted && !isBackgrounded) {
|
|
266
298
|
if (timeoutHandle) {
|
|
267
299
|
clearTimeout(timeoutHandle);
|
|
268
300
|
}
|
|
@@ -285,163 +317,3 @@ Usage notes:
|
|
|
285
317
|
return `${command}${runInBackground ? " (background)" : ""}`;
|
|
286
318
|
},
|
|
287
319
|
};
|
|
288
|
-
/**
|
|
289
|
-
* BashOutput tool - retrieves output from background bash shells
|
|
290
|
-
*/
|
|
291
|
-
export const bashOutputTool = {
|
|
292
|
-
name: BASH_OUTPUT_TOOL_NAME,
|
|
293
|
-
config: {
|
|
294
|
-
type: "function",
|
|
295
|
-
function: {
|
|
296
|
-
name: BASH_OUTPUT_TOOL_NAME,
|
|
297
|
-
description: "Retrieves output from a running or completed background bash shell",
|
|
298
|
-
parameters: {
|
|
299
|
-
type: "object",
|
|
300
|
-
properties: {
|
|
301
|
-
bash_id: {
|
|
302
|
-
type: "string",
|
|
303
|
-
description: "The ID of the background shell to retrieve output from",
|
|
304
|
-
},
|
|
305
|
-
filter: {
|
|
306
|
-
type: "string",
|
|
307
|
-
description: "Optional regular expression to filter the output lines. Only lines matching this regex will be included in the result. Any lines that do not match will no longer be available to read.",
|
|
308
|
-
},
|
|
309
|
-
},
|
|
310
|
-
required: ["bash_id"],
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
execute: async (args, context) => {
|
|
315
|
-
const bashId = args.bash_id;
|
|
316
|
-
const filter = args.filter;
|
|
317
|
-
if (!bashId || typeof bashId !== "string") {
|
|
318
|
-
return {
|
|
319
|
-
success: false,
|
|
320
|
-
content: "",
|
|
321
|
-
error: "bash_id parameter is required and must be a string",
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
const backgroundBashManager = context?.backgroundBashManager;
|
|
325
|
-
if (!backgroundBashManager) {
|
|
326
|
-
return {
|
|
327
|
-
success: false,
|
|
328
|
-
content: "",
|
|
329
|
-
error: "Background bash manager not available",
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
const output = backgroundBashManager.getOutput(bashId, filter);
|
|
333
|
-
if (!output) {
|
|
334
|
-
return {
|
|
335
|
-
success: false,
|
|
336
|
-
content: "",
|
|
337
|
-
error: `Background shell with ID ${bashId} not found`,
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
const shell = backgroundBashManager.getShell(bashId);
|
|
341
|
-
if (!shell) {
|
|
342
|
-
return {
|
|
343
|
-
success: false,
|
|
344
|
-
content: "",
|
|
345
|
-
error: `Background shell with ID ${bashId} not found`,
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
let content = "";
|
|
349
|
-
if (output.stdout) {
|
|
350
|
-
content += stripAnsiColors(output.stdout);
|
|
351
|
-
}
|
|
352
|
-
if (output.stderr) {
|
|
353
|
-
content += (content ? "\n" : "") + stripAnsiColors(output.stderr);
|
|
354
|
-
}
|
|
355
|
-
const finalContent = content || "No output available";
|
|
356
|
-
const processedContent = finalContent.length > MAX_OUTPUT_LENGTH
|
|
357
|
-
? finalContent.substring(0, MAX_OUTPUT_LENGTH) +
|
|
358
|
-
"\n\n... (output truncated)"
|
|
359
|
-
: finalContent;
|
|
360
|
-
return {
|
|
361
|
-
success: true,
|
|
362
|
-
content: processedContent,
|
|
363
|
-
shortResult: `${bashId}: ${output.status}${shell.exitCode !== undefined ? ` (${shell.exitCode})` : ""}`,
|
|
364
|
-
error: undefined,
|
|
365
|
-
};
|
|
366
|
-
},
|
|
367
|
-
formatCompactParams: (params) => {
|
|
368
|
-
const bashId = params.bash_id;
|
|
369
|
-
const filter = params.filter;
|
|
370
|
-
return filter ? `${bashId} filtered: ${filter}` : bashId;
|
|
371
|
-
},
|
|
372
|
-
};
|
|
373
|
-
/**
|
|
374
|
-
* KillBash tool - kills a running background bash shell
|
|
375
|
-
*/
|
|
376
|
-
export const killBashTool = {
|
|
377
|
-
name: KILL_BASH_TOOL_NAME,
|
|
378
|
-
config: {
|
|
379
|
-
type: "function",
|
|
380
|
-
function: {
|
|
381
|
-
name: KILL_BASH_TOOL_NAME,
|
|
382
|
-
description: "Kills a running background bash shell by its ID",
|
|
383
|
-
parameters: {
|
|
384
|
-
type: "object",
|
|
385
|
-
properties: {
|
|
386
|
-
shell_id: {
|
|
387
|
-
type: "string",
|
|
388
|
-
description: "The ID of the background shell to kill",
|
|
389
|
-
},
|
|
390
|
-
},
|
|
391
|
-
required: ["shell_id"],
|
|
392
|
-
},
|
|
393
|
-
},
|
|
394
|
-
},
|
|
395
|
-
execute: async (args, context) => {
|
|
396
|
-
const shellId = args.shell_id;
|
|
397
|
-
if (!shellId || typeof shellId !== "string") {
|
|
398
|
-
return {
|
|
399
|
-
success: false,
|
|
400
|
-
content: "",
|
|
401
|
-
error: "shell_id parameter is required and must be a string",
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
const backgroundBashManager = context?.backgroundBashManager;
|
|
405
|
-
if (!backgroundBashManager) {
|
|
406
|
-
return {
|
|
407
|
-
success: false,
|
|
408
|
-
content: "",
|
|
409
|
-
error: "Background bash manager not available",
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
const shell = backgroundBashManager.getShell(shellId);
|
|
413
|
-
if (!shell) {
|
|
414
|
-
return {
|
|
415
|
-
success: false,
|
|
416
|
-
content: "",
|
|
417
|
-
error: `Background shell with ID ${shellId} not found`,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
if (shell.status !== "running") {
|
|
421
|
-
return {
|
|
422
|
-
success: false,
|
|
423
|
-
content: "",
|
|
424
|
-
error: `Background shell ${shellId} is not running (status: ${shell.status})`,
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
const killed = backgroundBashManager.killShell(shellId);
|
|
428
|
-
if (killed) {
|
|
429
|
-
return {
|
|
430
|
-
success: true,
|
|
431
|
-
content: `Background shell ${shellId} has been killed`,
|
|
432
|
-
shortResult: `Killed ${shellId}`,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
return {
|
|
437
|
-
success: false,
|
|
438
|
-
content: "",
|
|
439
|
-
error: `Failed to kill background shell ${shellId}`,
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
},
|
|
443
|
-
formatCompactParams: (params) => {
|
|
444
|
-
const shellId = params.shell_id;
|
|
445
|
-
return shellId;
|
|
446
|
-
},
|
|
447
|
-
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.ts","sourceRoot":"","sources":["../../src/tools/editTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"editTool.d.ts","sourceRoot":"","sources":["../../src/tools/editTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAgBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAiNtB,CAAC"}
|
package/dist/tools/editTool.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile, writeFile } from "fs/promises";
|
|
2
2
|
import { logger } from "../utils/globalLogger.js";
|
|
3
3
|
import { resolvePath, getDisplayPath } from "../utils/path.js";
|
|
4
|
-
import {
|
|
4
|
+
import { escapeRegExp, analyzeEditMismatch } from "../utils/editUtils.js";
|
|
5
5
|
import { EDIT_TOOL_NAME, READ_TOOL_NAME } from "../constants/tools.js";
|
|
6
6
|
/**
|
|
7
7
|
* Format compact parameter display
|
|
@@ -95,14 +95,15 @@ export const editTool = {
|
|
|
95
95
|
error: `Failed to read file: ${readError instanceof Error ? readError.message : String(readError)}`,
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
// Check if old_string exists
|
|
99
|
-
const matchedOldString =
|
|
98
|
+
// Check if old_string exists
|
|
99
|
+
const matchedOldString = originalContent.includes(oldString)
|
|
100
|
+
? oldString
|
|
101
|
+
: null;
|
|
100
102
|
if (!matchedOldString) {
|
|
101
|
-
await saveEditErrorSnapshot(resolvedPath, oldString, originalContent, EDIT_TOOL_NAME);
|
|
102
103
|
return {
|
|
103
104
|
success: false,
|
|
104
105
|
content: "",
|
|
105
|
-
error:
|
|
106
|
+
error: analyzeEditMismatch(originalContent, oldString),
|
|
106
107
|
};
|
|
107
108
|
}
|
|
108
109
|
let newContent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multiEditTool.d.ts","sourceRoot":"","sources":["../../src/tools/multiEditTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"multiEditTool.d.ts","sourceRoot":"","sources":["../../src/tools/multiEditTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA6BtE;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UA+Q3B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile, writeFile } from "fs/promises";
|
|
2
2
|
import { logger } from "../utils/globalLogger.js";
|
|
3
3
|
import { resolvePath, getDisplayPath } from "../utils/path.js";
|
|
4
|
-
import {
|
|
4
|
+
import { escapeRegExp, analyzeEditMismatch } from "../utils/editUtils.js";
|
|
5
5
|
import { MULTI_EDIT_TOOL_NAME, EDIT_TOOL_NAME, READ_TOOL_NAME, } from "../constants/tools.js";
|
|
6
6
|
/**
|
|
7
7
|
* Format compact parameter display
|
|
@@ -147,20 +147,21 @@ export const multiEditTool = {
|
|
|
147
147
|
appliedEdits.push(`Created file with content (${edit.new_string.length} characters)`);
|
|
148
148
|
continue;
|
|
149
149
|
}
|
|
150
|
-
// Check if old_string exists
|
|
151
|
-
const matchedOldString =
|
|
150
|
+
// Check if old_string exists
|
|
151
|
+
const matchedOldString = currentContent.includes(edit.old_string)
|
|
152
|
+
? edit.old_string
|
|
153
|
+
: null;
|
|
152
154
|
if (!matchedOldString) {
|
|
153
|
-
await saveEditErrorSnapshot(resolvedPath, edit.old_string, currentContent, MULTI_EDIT_TOOL_NAME);
|
|
154
155
|
return {
|
|
155
156
|
success: false,
|
|
156
157
|
content: "",
|
|
157
|
-
error: `Edit operation ${i + 1}: old_string
|
|
158
|
+
error: `Edit operation ${i + 1}: ${analyzeEditMismatch(currentContent, edit.old_string)}`,
|
|
158
159
|
};
|
|
159
160
|
}
|
|
160
161
|
let replacementCount;
|
|
161
162
|
if (replaceAll) {
|
|
162
163
|
// Replace all matches
|
|
163
|
-
const regex = new RegExp(escapeRegExp(
|
|
164
|
+
const regex = new RegExp(escapeRegExp(edit.old_string), "g");
|
|
164
165
|
currentContent = currentContent.replace(regex, edit.new_string);
|
|
165
166
|
replacementCount = (currentContent.match(regex) || []).length;
|
|
166
167
|
appliedEdits.push(`Replaced ${replacementCount} instances of "${edit.old_string.substring(0, 50)}${edit.old_string.length > 50 ? "..." : ""}"`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskOutputTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskOutputTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,UAAU,EAAc,MAAM,YAAY,CAAC;AAKjE,eAAO,MAAM,cAAc,EAAE,UAuK5B,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { TASK_OUTPUT_TOOL_NAME } from "../constants/tools.js";
|
|
2
|
+
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
3
|
+
const MAX_OUTPUT_LENGTH = 30000;
|
|
4
|
+
export const taskOutputTool = {
|
|
5
|
+
name: TASK_OUTPUT_TOOL_NAME,
|
|
6
|
+
config: {
|
|
7
|
+
type: "function",
|
|
8
|
+
function: {
|
|
9
|
+
name: TASK_OUTPUT_TOOL_NAME,
|
|
10
|
+
description: "Retrieves output from a running or completed background task",
|
|
11
|
+
parameters: {
|
|
12
|
+
type: "object",
|
|
13
|
+
properties: {
|
|
14
|
+
task_id: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "The ID of the background task to retrieve output from",
|
|
17
|
+
},
|
|
18
|
+
filter: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "Optional regular expression to filter the output lines.",
|
|
21
|
+
},
|
|
22
|
+
block: {
|
|
23
|
+
type: "boolean",
|
|
24
|
+
description: "If true, wait for the task to complete before returning output. If false, return current output immediately.",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
required: ["task_id"],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
execute: async (args, context) => {
|
|
32
|
+
const taskId = args.task_id;
|
|
33
|
+
const filter = args.filter;
|
|
34
|
+
const block = args.block;
|
|
35
|
+
if (!taskId || typeof taskId !== "string") {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
content: "",
|
|
39
|
+
error: "task_id parameter is required and must be a string",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const backgroundTaskManager = context?.backgroundTaskManager;
|
|
43
|
+
if (!backgroundTaskManager) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
content: "",
|
|
47
|
+
error: "Background task manager not available",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const getResult = () => {
|
|
51
|
+
const output = backgroundTaskManager.getOutput(taskId, filter);
|
|
52
|
+
if (!output)
|
|
53
|
+
return null;
|
|
54
|
+
let content = "";
|
|
55
|
+
if (output.stdout) {
|
|
56
|
+
content += stripAnsiColors(output.stdout);
|
|
57
|
+
}
|
|
58
|
+
if (output.stderr) {
|
|
59
|
+
content += (content ? "\n" : "") + stripAnsiColors(output.stderr);
|
|
60
|
+
}
|
|
61
|
+
const finalContent = content || "No output available";
|
|
62
|
+
const processedContent = finalContent.length > MAX_OUTPUT_LENGTH
|
|
63
|
+
? finalContent.substring(0, MAX_OUTPUT_LENGTH) +
|
|
64
|
+
"\n\n... (output truncated)"
|
|
65
|
+
: finalContent;
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
content: processedContent,
|
|
69
|
+
shortResult: `${taskId}: ${output.status}`,
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
if (block) {
|
|
73
|
+
// Polling for completion
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
let timeoutHandle = null;
|
|
76
|
+
let isAborted = false;
|
|
77
|
+
const cleanup = () => {
|
|
78
|
+
if (timeoutHandle) {
|
|
79
|
+
clearTimeout(timeoutHandle);
|
|
80
|
+
timeoutHandle = null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const onAbort = () => {
|
|
84
|
+
isAborted = true;
|
|
85
|
+
cleanup();
|
|
86
|
+
resolve({
|
|
87
|
+
success: false,
|
|
88
|
+
content: "",
|
|
89
|
+
error: "Task output retrieval was aborted",
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
if (context.abortSignal) {
|
|
93
|
+
if (context.abortSignal.aborted) {
|
|
94
|
+
onAbort();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
context.abortSignal.addEventListener("abort", onAbort, {
|
|
98
|
+
once: true,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const check = () => {
|
|
102
|
+
if (isAborted)
|
|
103
|
+
return;
|
|
104
|
+
const task = backgroundTaskManager.getTask(taskId);
|
|
105
|
+
if (!task) {
|
|
106
|
+
if (context.abortSignal) {
|
|
107
|
+
context.abortSignal.removeEventListener("abort", onAbort);
|
|
108
|
+
}
|
|
109
|
+
resolve({
|
|
110
|
+
success: false,
|
|
111
|
+
content: "",
|
|
112
|
+
error: `Task with ID ${taskId} not found`,
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (task.status !== "running") {
|
|
117
|
+
if (context.abortSignal) {
|
|
118
|
+
context.abortSignal.removeEventListener("abort", onAbort);
|
|
119
|
+
}
|
|
120
|
+
const result = getResult();
|
|
121
|
+
resolve(result || {
|
|
122
|
+
success: false,
|
|
123
|
+
content: "",
|
|
124
|
+
error: "Task not found",
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
timeoutHandle = setTimeout(check, 500);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
check();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const result = getResult();
|
|
135
|
+
if (!result) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
content: "",
|
|
139
|
+
error: `Task with ID ${taskId} not found`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
},
|
|
144
|
+
formatCompactParams: (params) => {
|
|
145
|
+
const taskId = params.task_id;
|
|
146
|
+
const block = params.block;
|
|
147
|
+
return `${taskId}${block ? " (blocking)" : ""}`;
|
|
148
|
+
},
|
|
149
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskStopTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskStopTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,UAAU,EAAc,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,YAAY,EAAE,UAoE1B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { TASK_STOP_TOOL_NAME } from "../constants/tools.js";
|
|
2
|
+
export const taskStopTool = {
|
|
3
|
+
name: TASK_STOP_TOOL_NAME,
|
|
4
|
+
config: {
|
|
5
|
+
type: "function",
|
|
6
|
+
function: {
|
|
7
|
+
name: TASK_STOP_TOOL_NAME,
|
|
8
|
+
description: "Stops a running background task",
|
|
9
|
+
parameters: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
task_id: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "The ID of the background task to stop",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
required: ["task_id"],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
execute: async (args, context) => {
|
|
22
|
+
const taskId = args.task_id;
|
|
23
|
+
if (!taskId || typeof taskId !== "string") {
|
|
24
|
+
return {
|
|
25
|
+
success: false,
|
|
26
|
+
content: "",
|
|
27
|
+
error: "task_id parameter is required and must be a string",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const backgroundTaskManager = context?.backgroundTaskManager;
|
|
31
|
+
if (!backgroundTaskManager) {
|
|
32
|
+
return {
|
|
33
|
+
success: false,
|
|
34
|
+
content: "",
|
|
35
|
+
error: "Background task manager not available",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const stopped = backgroundTaskManager.stopTask(taskId);
|
|
39
|
+
if (stopped) {
|
|
40
|
+
return {
|
|
41
|
+
success: true,
|
|
42
|
+
content: `Task ${taskId} has been stopped`,
|
|
43
|
+
shortResult: `Stopped ${taskId}`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const task = backgroundTaskManager.getTask(taskId);
|
|
48
|
+
if (!task) {
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
content: "",
|
|
52
|
+
error: `Task with ID ${taskId} not found`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
content: "",
|
|
58
|
+
error: `Failed to stop task ${taskId} (status: ${task.status})`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
formatCompactParams: (params) => {
|
|
63
|
+
return params.task_id;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,eAAe,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"taskTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,eAAe,GAAG,UAAU,CA6L3E"}
|