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.
Files changed (105) hide show
  1. package/dist/agent.d.ts +28 -5
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +54 -37
  4. package/dist/constants/tools.d.ts +2 -2
  5. package/dist/constants/tools.js +2 -2
  6. package/dist/managers/MemoryRuleManager.js +1 -1
  7. package/dist/managers/aiManager.d.ts +3 -3
  8. package/dist/managers/aiManager.d.ts.map +1 -1
  9. package/dist/managers/aiManager.js +3 -4
  10. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  11. package/dist/managers/backgroundBashManager.js +1 -0
  12. package/dist/managers/backgroundTaskManager.d.ts +35 -0
  13. package/dist/managers/backgroundTaskManager.d.ts.map +1 -0
  14. package/dist/managers/backgroundTaskManager.js +249 -0
  15. package/dist/managers/foregroundTaskManager.d.ts +9 -0
  16. package/dist/managers/foregroundTaskManager.d.ts.map +1 -0
  17. package/dist/managers/foregroundTaskManager.js +20 -0
  18. package/dist/managers/liveConfigManager.d.ts +1 -1
  19. package/dist/managers/lspManager.d.ts.map +1 -1
  20. package/dist/managers/lspManager.js +3 -1
  21. package/dist/managers/messageManager.d.ts +12 -2
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +36 -2
  24. package/dist/managers/permissionManager.d.ts.map +1 -1
  25. package/dist/managers/permissionManager.js +1 -7
  26. package/dist/managers/pluginManager.d.ts.map +1 -1
  27. package/dist/managers/pluginManager.js +3 -2
  28. package/dist/managers/slashCommandManager.d.ts +3 -0
  29. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  30. package/dist/managers/slashCommandManager.js +1 -0
  31. package/dist/managers/subagentManager.d.ts +11 -2
  32. package/dist/managers/subagentManager.d.ts.map +1 -1
  33. package/dist/managers/subagentManager.js +137 -39
  34. package/dist/managers/toolManager.d.ts +7 -1
  35. package/dist/managers/toolManager.d.ts.map +1 -1
  36. package/dist/managers/toolManager.js +9 -3
  37. package/dist/services/GitService.d.ts.map +1 -1
  38. package/dist/services/GitService.js +6 -2
  39. package/dist/services/MarketplaceService.d.ts +2 -2
  40. package/dist/services/MarketplaceService.d.ts.map +1 -1
  41. package/dist/services/MarketplaceService.js +18 -11
  42. package/dist/services/MemoryRuleService.d.ts +1 -1
  43. package/dist/services/MemoryRuleService.d.ts.map +1 -1
  44. package/dist/services/MemoryRuleService.js +13 -2
  45. package/dist/services/memory.js +1 -1
  46. package/dist/tools/bashTool.d.ts +0 -8
  47. package/dist/tools/bashTool.d.ts.map +1 -1
  48. package/dist/tools/bashTool.js +44 -172
  49. package/dist/tools/editTool.d.ts.map +1 -1
  50. package/dist/tools/editTool.js +6 -5
  51. package/dist/tools/multiEditTool.d.ts.map +1 -1
  52. package/dist/tools/multiEditTool.js +7 -6
  53. package/dist/tools/taskOutputTool.d.ts +3 -0
  54. package/dist/tools/taskOutputTool.d.ts.map +1 -0
  55. package/dist/tools/taskOutputTool.js +149 -0
  56. package/dist/tools/taskStopTool.d.ts +3 -0
  57. package/dist/tools/taskStopTool.d.ts.map +1 -0
  58. package/dist/tools/taskStopTool.js +65 -0
  59. package/dist/tools/taskTool.d.ts.map +1 -1
  60. package/dist/tools/taskTool.js +105 -63
  61. package/dist/tools/types.d.ts +3 -0
  62. package/dist/tools/types.d.ts.map +1 -1
  63. package/dist/types/marketplace.d.ts +1 -0
  64. package/dist/types/marketplace.d.ts.map +1 -1
  65. package/dist/types/messaging.d.ts +1 -0
  66. package/dist/types/messaging.d.ts.map +1 -1
  67. package/dist/types/processes.d.ts +24 -4
  68. package/dist/types/processes.d.ts.map +1 -1
  69. package/dist/utils/editUtils.d.ts +2 -11
  70. package/dist/utils/editUtils.d.ts.map +1 -1
  71. package/dist/utils/editUtils.js +52 -79
  72. package/dist/utils/messageOperations.d.ts +3 -1
  73. package/dist/utils/messageOperations.d.ts.map +1 -1
  74. package/dist/utils/messageOperations.js +5 -1
  75. package/package.json +5 -5
  76. package/src/agent.ts +73 -45
  77. package/src/constants/tools.ts +2 -2
  78. package/src/managers/MemoryRuleManager.ts +1 -1
  79. package/src/managers/aiManager.ts +6 -9
  80. package/src/managers/backgroundBashManager.ts +1 -0
  81. package/src/managers/backgroundTaskManager.ts +306 -0
  82. package/src/managers/foregroundTaskManager.ts +26 -0
  83. package/src/managers/lspManager.ts +3 -1
  84. package/src/managers/messageManager.ts +48 -2
  85. package/src/managers/permissionManager.ts +1 -7
  86. package/src/managers/pluginManager.ts +4 -3
  87. package/src/managers/slashCommandManager.ts +4 -0
  88. package/src/managers/subagentManager.ts +167 -35
  89. package/src/managers/toolManager.ts +16 -4
  90. package/src/services/GitService.ts +6 -2
  91. package/src/services/MarketplaceService.ts +30 -12
  92. package/src/services/MemoryRuleService.ts +18 -6
  93. package/src/services/memory.ts +1 -1
  94. package/src/tools/bashTool.ts +59 -196
  95. package/src/tools/editTool.ts +6 -17
  96. package/src/tools/multiEditTool.ts +7 -18
  97. package/src/tools/taskOutputTool.ts +174 -0
  98. package/src/tools/taskStopTool.ts +72 -0
  99. package/src/tools/taskTool.ts +130 -74
  100. package/src/tools/types.ts +3 -0
  101. package/src/types/marketplace.ts +1 -0
  102. package/src/types/messaging.ts +1 -0
  103. package/src/types/processes.ts +33 -4
  104. package/src/utils/editUtils.ts +65 -103
  105. package/src/utils/messageOperations.ts +7 -0
@@ -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, BASH_OUTPUT_TOOL_NAME, KILL_BASH_TOOL_NAME, GLOB_TOOL_NAME, GREP_TOOL_NAME, READ_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, } from "../constants/tools.js";
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 ${BASH_OUTPUT_TOOL_NAME} to read the output later.`,
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 backgroundBashManager = context?.backgroundBashManager;
139
- if (!backgroundBashManager) {
138
+ const backgroundTaskManager = context?.backgroundTaskManager;
139
+ if (!backgroundTaskManager) {
140
140
  return {
141
141
  success: false,
142
142
  content: "",
143
- error: "Background bash manager not available",
143
+ error: "Background task manager not available",
144
144
  };
145
145
  }
146
- const shellId = backgroundBashManager.startShell(command, timeout);
146
+ const { id: taskId } = backgroundTaskManager.startShell(command, timeout);
147
147
  return {
148
148
  success: true,
149
- content: `Command started in background with ID: ${shellId}. Use ${BASH_OUTPUT_TOOL_NAME} tool with bash_id="${shellId}" to monitor output.`,
150
- shortResult: `Background process ${shellId} started`,
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 (!isAborted) {
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 (!isAborted) {
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;AAoBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAwNtB,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"}
@@ -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 { findIndentationInsensitiveMatch, escapeRegExp, saveEditErrorSnapshot, } from "../utils/editUtils.js";
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 (with smart indentation matching)
99
- const matchedOldString = findIndentationInsensitiveMatch(originalContent, oldString);
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: `old_string not found in file`,
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;AAiCtE;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAsR3B,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 { findIndentationInsensitiveMatch, escapeRegExp, saveEditErrorSnapshot, } from "../utils/editUtils.js";
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 (with smart indentation matching)
151
- const matchedOldString = findIndentationInsensitiveMatch(currentContent, edit.old_string);
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 not found in current content`,
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(matchedOldString), "g");
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,3 @@
1
+ import { ToolPlugin } from "./types.js";
2
+ export declare const taskOutputTool: ToolPlugin;
3
+ //# sourceMappingURL=taskOutputTool.d.ts.map
@@ -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,3 @@
1
+ import { ToolPlugin } from "./types.js";
2
+ export declare const taskStopTool: ToolPlugin;
3
+ //# sourceMappingURL=taskStopTool.d.ts.map
@@ -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,CAqI3E"}
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"}