wave-agent-sdk 0.10.3 → 0.10.4
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/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +28 -7
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +8 -32
- package/package.json +1 -1
- package/src/tools/bashTool.ts +36 -8
- package/src/tools/readTool.ts +11 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAyCtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA0XtB,CAAC"}
|
package/dist/tools/bashTool.js
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as os from "os";
|
|
2
5
|
import { logger } from "../utils/globalLogger.js";
|
|
3
6
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
4
7
|
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
8
|
const MAX_OUTPUT_LENGTH = 30000;
|
|
6
9
|
const BASH_DEFAULT_TIMEOUT_MS = 120000;
|
|
10
|
+
/**
|
|
11
|
+
* Helper function to handle large output by truncation and persistence to a temporary file.
|
|
12
|
+
*/
|
|
13
|
+
function processOutput(output) {
|
|
14
|
+
if (output.length <= MAX_OUTPUT_LENGTH) {
|
|
15
|
+
return output;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const tempDir = os.tmpdir();
|
|
19
|
+
const fileName = `bash_output_${Date.now()}_${Math.random().toString(36).substring(2, 11)}.txt`;
|
|
20
|
+
const filePath = path.join(tempDir, fileName);
|
|
21
|
+
fs.writeFileSync(filePath, output, "utf8");
|
|
22
|
+
return (output.substring(0, MAX_OUTPUT_LENGTH) +
|
|
23
|
+
`\n\n... (output truncated)\nFull output persisted to: ${filePath}`);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logger.error("Failed to persist large bash output:", error);
|
|
27
|
+
return (output.substring(0, MAX_OUTPUT_LENGTH) +
|
|
28
|
+
"\n\n... (output truncated, failed to persist full output)");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
7
31
|
/**
|
|
8
32
|
* Bash command execution tool - supports both foreground and background execution
|
|
9
33
|
*/
|
|
@@ -63,7 +87,7 @@ Usage notes:
|
|
|
63
87
|
- The command argument is required.
|
|
64
88
|
- You can specify an optional timeout in milliseconds (up to ${BASH_DEFAULT_TIMEOUT_MS}ms / ${BASH_DEFAULT_TIMEOUT_MS / 60000} minutes). If not specified, commands will timeout after ${BASH_DEFAULT_TIMEOUT_MS}ms (${BASH_DEFAULT_TIMEOUT_MS / 60000} minutes).
|
|
65
89
|
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
|
|
66
|
-
- If the output exceeds ${MAX_OUTPUT_LENGTH} characters, output will be truncated
|
|
90
|
+
- If the output exceeds ${MAX_OUTPUT_LENGTH} characters, output will be truncated and the full output will be persisted to a temporary file.
|
|
67
91
|
- You can use the \`run_in_background\` parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the ${BASH_TOOL_NAME} tool as it becomes available. You do not need to use '&' at the end of the command when using this parameter.
|
|
68
92
|
- Avoid using ${BASH_TOOL_NAME} with the \`find\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
|
|
69
93
|
- File search: Use ${GLOB_TOOL_NAME} (NOT find or ls)
|
|
@@ -248,7 +272,7 @@ Usage notes:
|
|
|
248
272
|
}
|
|
249
273
|
resolve({
|
|
250
274
|
success: false,
|
|
251
|
-
content: outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""),
|
|
275
|
+
content: processOutput(outputBuffer + (errorBuffer ? "\n" + errorBuffer : "")),
|
|
252
276
|
error: reason,
|
|
253
277
|
});
|
|
254
278
|
}
|
|
@@ -286,12 +310,9 @@ Usage notes:
|
|
|
286
310
|
}
|
|
287
311
|
const exitCode = code ?? 0;
|
|
288
312
|
const combinedOutput = outputBuffer + (errorBuffer ? "\n" + errorBuffer : "");
|
|
289
|
-
// Handle large output by truncation if needed
|
|
313
|
+
// Handle large output by truncation and persistence if needed
|
|
290
314
|
const finalOutput = combinedOutput || `Command executed with exit code: ${exitCode}`;
|
|
291
|
-
const content = finalOutput
|
|
292
|
-
? finalOutput.substring(0, MAX_OUTPUT_LENGTH) +
|
|
293
|
-
"\n\n... (output truncated)"
|
|
294
|
-
: finalOutput;
|
|
315
|
+
const content = processOutput(finalOutput);
|
|
295
316
|
const shortResult = combinedOutput
|
|
296
317
|
.trim()
|
|
297
318
|
.split("\n")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readTool.d.ts","sourceRoot":"","sources":["../../src/tools/readTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA8HtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"readTool.d.ts","sourceRoot":"","sources":["../../src/tools/readTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA8HtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA2MtB,CAAC"}
|
package/dist/tools/readTool.js
CHANGED
|
@@ -204,26 +204,14 @@ Usage:
|
|
|
204
204
|
shortResult: "Empty file",
|
|
205
205
|
};
|
|
206
206
|
}
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
let contentToProcess = fileContent;
|
|
210
|
-
let contentTruncated = false;
|
|
211
|
-
if (fileContent.length > MAX_CONTENT_SIZE) {
|
|
212
|
-
contentToProcess = fileContent.substring(0, MAX_CONTENT_SIZE);
|
|
213
|
-
contentTruncated = true;
|
|
214
|
-
}
|
|
215
|
-
const lines = contentToProcess.split("\n");
|
|
216
|
-
const totalLines = lines.length;
|
|
217
|
-
const originalTotalLines = fileContent.split("\n").length;
|
|
207
|
+
const allLines = fileContent.split("\n");
|
|
208
|
+
const totalLines = allLines.length;
|
|
218
209
|
// Handle offset and limit
|
|
219
210
|
let startLine = 1;
|
|
220
|
-
let endLine = Math.min(totalLines, 2000); // Default maximum read 2000 lines
|
|
221
211
|
if (typeof offset === "number") {
|
|
222
212
|
startLine = Math.max(1, offset);
|
|
223
213
|
}
|
|
224
|
-
|
|
225
|
-
endLine = Math.min(totalLines, startLine + limit - 1);
|
|
226
|
-
}
|
|
214
|
+
let endLine = Math.min(totalLines, startLine + (typeof limit === "number" ? limit : 2000) - 1);
|
|
227
215
|
// If no offset and limit specified, read entire file (maximum 2000 lines)
|
|
228
216
|
if (typeof offset !== "number" && typeof limit !== "number") {
|
|
229
217
|
startLine = 1;
|
|
@@ -238,7 +226,7 @@ Usage:
|
|
|
238
226
|
};
|
|
239
227
|
}
|
|
240
228
|
// Extract specified line range
|
|
241
|
-
const selectedLines =
|
|
229
|
+
const selectedLines = allLines.slice(startLine - 1, endLine);
|
|
242
230
|
// Format output (cat -n format, with line numbers)
|
|
243
231
|
const formattedContent = selectedLines
|
|
244
232
|
.map((line, index) => {
|
|
@@ -250,11 +238,7 @@ Usage:
|
|
|
250
238
|
.join("\n");
|
|
251
239
|
// Add file information header
|
|
252
240
|
let content = `File: ${filePath}\n`;
|
|
253
|
-
if (
|
|
254
|
-
content += `Content truncated at ${MAX_CONTENT_SIZE} bytes\n`;
|
|
255
|
-
content += `Lines ${startLine}-${endLine} of ${totalLines} (original file: ${originalTotalLines} lines)\n`;
|
|
256
|
-
}
|
|
257
|
-
else if (startLine > 1 || endLine < totalLines) {
|
|
241
|
+
if (startLine > 1 || endLine < totalLines) {
|
|
258
242
|
content += `Lines ${startLine}-${endLine} of ${totalLines}\n`;
|
|
259
243
|
}
|
|
260
244
|
else {
|
|
@@ -263,22 +247,14 @@ Usage:
|
|
|
263
247
|
content += "─".repeat(50) + "\n";
|
|
264
248
|
content += formattedContent;
|
|
265
249
|
// If only showing partial content, add prompt
|
|
266
|
-
if (endLine < totalLines
|
|
250
|
+
if (endLine < totalLines) {
|
|
267
251
|
content += `\n${"─".repeat(50)}\n`;
|
|
268
|
-
|
|
269
|
-
content += `... content truncated due to size limit (${MAX_CONTENT_SIZE} bytes)`;
|
|
270
|
-
if (endLine < totalLines) {
|
|
271
|
-
content += ` and ${totalLines - endLine} more lines not shown`;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
content += `... ${totalLines - endLine} more lines not shown`;
|
|
276
|
-
}
|
|
252
|
+
content += `... ${totalLines - endLine} more lines not shown`;
|
|
277
253
|
}
|
|
278
254
|
return {
|
|
279
255
|
success: true,
|
|
280
256
|
content,
|
|
281
|
-
shortResult: `Read ${selectedLines.length} lines${totalLines > 2000
|
|
257
|
+
shortResult: `Read ${selectedLines.length} lines${totalLines > 2000 ? " (truncated)" : ""}`,
|
|
282
258
|
};
|
|
283
259
|
}
|
|
284
260
|
catch (error) {
|
package/package.json
CHANGED
package/src/tools/bashTool.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { spawn, ChildProcess } from "child_process";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as os from "os";
|
|
2
5
|
import { logger } from "../utils/globalLogger.js";
|
|
3
6
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
4
7
|
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
@@ -15,6 +18,33 @@ import {
|
|
|
15
18
|
const MAX_OUTPUT_LENGTH = 30000;
|
|
16
19
|
const BASH_DEFAULT_TIMEOUT_MS = 120000;
|
|
17
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Helper function to handle large output by truncation and persistence to a temporary file.
|
|
23
|
+
*/
|
|
24
|
+
function processOutput(output: string): string {
|
|
25
|
+
if (output.length <= MAX_OUTPUT_LENGTH) {
|
|
26
|
+
return output;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const tempDir = os.tmpdir();
|
|
31
|
+
const fileName = `bash_output_${Date.now()}_${Math.random().toString(36).substring(2, 11)}.txt`;
|
|
32
|
+
const filePath = path.join(tempDir, fileName);
|
|
33
|
+
fs.writeFileSync(filePath, output, "utf8");
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
output.substring(0, MAX_OUTPUT_LENGTH) +
|
|
37
|
+
`\n\n... (output truncated)\nFull output persisted to: ${filePath}`
|
|
38
|
+
);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
logger.error("Failed to persist large bash output:", error);
|
|
41
|
+
return (
|
|
42
|
+
output.substring(0, MAX_OUTPUT_LENGTH) +
|
|
43
|
+
"\n\n... (output truncated, failed to persist full output)"
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
18
48
|
/**
|
|
19
49
|
* Bash command execution tool - supports both foreground and background execution
|
|
20
50
|
*/
|
|
@@ -75,7 +105,7 @@ Usage notes:
|
|
|
75
105
|
- The command argument is required.
|
|
76
106
|
- You can specify an optional timeout in milliseconds (up to ${BASH_DEFAULT_TIMEOUT_MS}ms / ${BASH_DEFAULT_TIMEOUT_MS / 60000} minutes). If not specified, commands will timeout after ${BASH_DEFAULT_TIMEOUT_MS}ms (${BASH_DEFAULT_TIMEOUT_MS / 60000} minutes).
|
|
77
107
|
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
|
|
78
|
-
- If the output exceeds ${MAX_OUTPUT_LENGTH} characters, output will be truncated
|
|
108
|
+
- If the output exceeds ${MAX_OUTPUT_LENGTH} characters, output will be truncated and the full output will be persisted to a temporary file.
|
|
79
109
|
- You can use the \`run_in_background\` parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the ${BASH_TOOL_NAME} tool as it becomes available. You do not need to use '&' at the end of the command when using this parameter.
|
|
80
110
|
- Avoid using ${BASH_TOOL_NAME} with the \`find\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
|
|
81
111
|
- File search: Use ${GLOB_TOOL_NAME} (NOT find or ls)
|
|
@@ -292,7 +322,9 @@ Usage notes:
|
|
|
292
322
|
|
|
293
323
|
resolve({
|
|
294
324
|
success: false,
|
|
295
|
-
content:
|
|
325
|
+
content: processOutput(
|
|
326
|
+
outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""),
|
|
327
|
+
),
|
|
296
328
|
error: reason,
|
|
297
329
|
});
|
|
298
330
|
}
|
|
@@ -340,14 +372,10 @@ Usage notes:
|
|
|
340
372
|
const combinedOutput =
|
|
341
373
|
outputBuffer + (errorBuffer ? "\n" + errorBuffer : "");
|
|
342
374
|
|
|
343
|
-
// Handle large output by truncation if needed
|
|
375
|
+
// Handle large output by truncation and persistence if needed
|
|
344
376
|
const finalOutput =
|
|
345
377
|
combinedOutput || `Command executed with exit code: ${exitCode}`;
|
|
346
|
-
const content =
|
|
347
|
-
finalOutput.length > MAX_OUTPUT_LENGTH
|
|
348
|
-
? finalOutput.substring(0, MAX_OUTPUT_LENGTH) +
|
|
349
|
-
"\n\n... (output truncated)"
|
|
350
|
-
: finalOutput;
|
|
378
|
+
const content = processOutput(finalOutput);
|
|
351
379
|
|
|
352
380
|
const shortResult = combinedOutput
|
|
353
381
|
.trim()
|
package/src/tools/readTool.ts
CHANGED
|
@@ -243,31 +243,19 @@ Usage:
|
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
let contentToProcess = fileContent;
|
|
249
|
-
let contentTruncated = false;
|
|
250
|
-
|
|
251
|
-
if (fileContent.length > MAX_CONTENT_SIZE) {
|
|
252
|
-
contentToProcess = fileContent.substring(0, MAX_CONTENT_SIZE);
|
|
253
|
-
contentTruncated = true;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const lines = contentToProcess.split("\n");
|
|
257
|
-
const totalLines = lines.length;
|
|
258
|
-
const originalTotalLines = fileContent.split("\n").length;
|
|
246
|
+
const allLines = fileContent.split("\n");
|
|
247
|
+
const totalLines = allLines.length;
|
|
259
248
|
|
|
260
249
|
// Handle offset and limit
|
|
261
250
|
let startLine = 1;
|
|
262
|
-
let endLine = Math.min(totalLines, 2000); // Default maximum read 2000 lines
|
|
263
|
-
|
|
264
251
|
if (typeof offset === "number") {
|
|
265
252
|
startLine = Math.max(1, offset);
|
|
266
253
|
}
|
|
267
254
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
255
|
+
let endLine = Math.min(
|
|
256
|
+
totalLines,
|
|
257
|
+
startLine + (typeof limit === "number" ? limit : 2000) - 1,
|
|
258
|
+
);
|
|
271
259
|
|
|
272
260
|
// If no offset and limit specified, read entire file (maximum 2000 lines)
|
|
273
261
|
if (typeof offset !== "number" && typeof limit !== "number") {
|
|
@@ -285,7 +273,7 @@ Usage:
|
|
|
285
273
|
}
|
|
286
274
|
|
|
287
275
|
// Extract specified line range
|
|
288
|
-
const selectedLines =
|
|
276
|
+
const selectedLines = allLines.slice(startLine - 1, endLine);
|
|
289
277
|
|
|
290
278
|
// Format output (cat -n format, with line numbers)
|
|
291
279
|
const formattedContent = selectedLines
|
|
@@ -300,10 +288,7 @@ Usage:
|
|
|
300
288
|
|
|
301
289
|
// Add file information header
|
|
302
290
|
let content = `File: ${filePath}\n`;
|
|
303
|
-
if (
|
|
304
|
-
content += `Content truncated at ${MAX_CONTENT_SIZE} bytes\n`;
|
|
305
|
-
content += `Lines ${startLine}-${endLine} of ${totalLines} (original file: ${originalTotalLines} lines)\n`;
|
|
306
|
-
} else if (startLine > 1 || endLine < totalLines) {
|
|
291
|
+
if (startLine > 1 || endLine < totalLines) {
|
|
307
292
|
content += `Lines ${startLine}-${endLine} of ${totalLines}\n`;
|
|
308
293
|
} else {
|
|
309
294
|
content += `Total lines: ${totalLines}\n`;
|
|
@@ -312,22 +297,15 @@ Usage:
|
|
|
312
297
|
content += formattedContent;
|
|
313
298
|
|
|
314
299
|
// If only showing partial content, add prompt
|
|
315
|
-
if (endLine < totalLines
|
|
300
|
+
if (endLine < totalLines) {
|
|
316
301
|
content += `\n${"─".repeat(50)}\n`;
|
|
317
|
-
|
|
318
|
-
content += `... content truncated due to size limit (${MAX_CONTENT_SIZE} bytes)`;
|
|
319
|
-
if (endLine < totalLines) {
|
|
320
|
-
content += ` and ${totalLines - endLine} more lines not shown`;
|
|
321
|
-
}
|
|
322
|
-
} else {
|
|
323
|
-
content += `... ${totalLines - endLine} more lines not shown`;
|
|
324
|
-
}
|
|
302
|
+
content += `... ${totalLines - endLine} more lines not shown`;
|
|
325
303
|
}
|
|
326
304
|
|
|
327
305
|
return {
|
|
328
306
|
success: true,
|
|
329
307
|
content,
|
|
330
|
-
shortResult: `Read ${selectedLines.length} lines${totalLines > 2000
|
|
308
|
+
shortResult: `Read ${selectedLines.length} lines${totalLines > 2000 ? " (truncated)" : ""}`,
|
|
331
309
|
};
|
|
332
310
|
} catch (error) {
|
|
333
311
|
return {
|