@ai-zen/agents-sdk 0.5.3 → 0.5.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.4] - 2026-08-05
|
|
4
|
+
|
|
5
|
+
### 🚀 新功能
|
|
6
|
+
|
|
7
|
+
- **`ExecAsyncTool`(exec_async)统一走 shell 解析** — 移除 Unix 平台手动分词逻辑,所有平台均经 `spawn(command, [], { shell: true })` 执行。工具描述明确告知 agent:其本身不捕获输出,如需留存/查看输出可在命令中使用 shell 重定向写入文件(`>` / `>>`),并支持管道(`|`)等 shell 语法
|
|
8
|
+
|
|
9
|
+
### 🎯 优化
|
|
10
|
+
|
|
11
|
+
- **`ExecTool`(exec)的 `timeout` 改为必填** — schema `required` 由 `["command"]` 扩为 `["command", "timeout"]`,`call()` 类型签名 `timeout: number`(必填),并在运行时双校验(缺失/非正数/非有限数即抛错)。`timeout` 必填后,命令始终受超时保护,避免无超时长跑
|
|
12
|
+
- **超时原因明确告知 agent** — `exec` 超时被终止(`error.killed` 为 true)时返回结构新增 `terminated: "timeout"` 字段。弥补 Node 不会自动在 stderr 写入超时提示的限制,使 agent 能明确判断命令因超时被终止,从而灵活应对
|
|
13
|
+
|
|
3
14
|
## [0.5.3] - 2026-08-05
|
|
4
15
|
|
|
5
16
|
### 🚀 新功能
|
|
@@ -5,7 +5,7 @@ export class ExecAsyncTool extends SdkCallbackTool {
|
|
|
5
5
|
super({
|
|
6
6
|
function: {
|
|
7
7
|
name: "exec_async",
|
|
8
|
-
description: "异步执行命令,启动程序后立即返回,不等待执行结果。适用于启动长期运行的进程(如服务器、监听程序、GUI
|
|
8
|
+
description: "异步执行命令,启动程序后立即返回,不等待执行结果。适用于启动长期运行的进程(如服务器、监听程序、GUI应用等)或不需要等待结果的命令。注意:该工具本身不捕获命令的输出;若需获取/留存输出,可在命令中使用 shell 重定向写入文件(如 `> /path/file`,支持 `>>` 追加、`|` 管道)。命令经 shell 解析执行。",
|
|
9
9
|
parameters: {
|
|
10
10
|
type: "object",
|
|
11
11
|
properties: {
|
|
@@ -33,62 +33,15 @@ export class ExecAsyncTool extends SdkCallbackTool {
|
|
|
33
33
|
const command = input.command;
|
|
34
34
|
const cwd = input.cwd ? this.resolve(input.cwd) : this.env.cwd;
|
|
35
35
|
const detached = input.detached ?? false;
|
|
36
|
-
//
|
|
37
|
-
const useShell = process.platform === "win32";
|
|
36
|
+
// 统一走 shell:允许 shell 语法(重定向 > / >>、管道 | 等)
|
|
38
37
|
return new Promise((resolve) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
windowsHide: true,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
// Unix: 解析命令和参数,直接 spawn
|
|
51
|
-
const args = [];
|
|
52
|
-
let current = "";
|
|
53
|
-
let inQuote = null;
|
|
54
|
-
for (const ch of command) {
|
|
55
|
-
if (inQuote) {
|
|
56
|
-
if (ch === "\\") {
|
|
57
|
-
current += command[command.indexOf(ch) + 1] ?? "";
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
if (ch === inQuote) {
|
|
61
|
-
inQuote = null;
|
|
62
|
-
if (current)
|
|
63
|
-
args.push(current);
|
|
64
|
-
current = "";
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
current += ch;
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
if (ch === '"' || ch === "'") {
|
|
71
|
-
inQuote = ch;
|
|
72
|
-
}
|
|
73
|
-
else if (ch === " ") {
|
|
74
|
-
if (current) {
|
|
75
|
-
args.push(current);
|
|
76
|
-
current = "";
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
current += ch;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (current)
|
|
85
|
-
args.push(current);
|
|
86
|
-
child = spawn(args[0], args.slice(1), {
|
|
87
|
-
cwd,
|
|
88
|
-
detached,
|
|
89
|
-
stdio: "ignore",
|
|
90
|
-
});
|
|
91
|
-
}
|
|
38
|
+
const child = spawn(command, [], {
|
|
39
|
+
cwd,
|
|
40
|
+
detached,
|
|
41
|
+
stdio: "ignore",
|
|
42
|
+
shell: true,
|
|
43
|
+
windowsHide: true,
|
|
44
|
+
});
|
|
92
45
|
let resolved = false;
|
|
93
46
|
child.on("error", (err) => {
|
|
94
47
|
if (resolved)
|
|
@@ -15,10 +15,10 @@ export class ExecTool extends SdkCallbackTool {
|
|
|
15
15
|
},
|
|
16
16
|
timeout: {
|
|
17
17
|
type: "number",
|
|
18
|
-
description: "
|
|
18
|
+
description: "超时时间(毫秒),必填。超时后会终止进程;超过该时长仍未完成即视为超时并终止。建议长时间运行的命令使用 exec_async 异步执行。",
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
|
-
required: ["command"],
|
|
21
|
+
required: ["command", "timeout"],
|
|
22
22
|
additionalProperties: false,
|
|
23
23
|
},
|
|
24
24
|
},
|
|
@@ -27,17 +27,24 @@ export class ExecTool extends SdkCallbackTool {
|
|
|
27
27
|
}
|
|
28
28
|
async call(input) {
|
|
29
29
|
const command = input.command;
|
|
30
|
-
const timeout = input
|
|
30
|
+
const { timeout } = input;
|
|
31
|
+
// 运行时双校验:timeout 必填且必须为正数
|
|
32
|
+
if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) {
|
|
33
|
+
throw new Error(`exec: 参数 timeout 为必填项,且必须是正数(毫秒),当前值: ${JSON.stringify(timeout)}`);
|
|
34
|
+
}
|
|
31
35
|
const result = await new Promise((resolve) => {
|
|
32
36
|
const child = exec(command, {
|
|
33
37
|
cwd: this.env.cwd,
|
|
34
|
-
timeout
|
|
38
|
+
timeout,
|
|
35
39
|
}, (error, stdout, stderr) => {
|
|
40
|
+
const killed = error?.killed ?? false;
|
|
36
41
|
resolve({
|
|
37
42
|
stdout,
|
|
38
43
|
stderr,
|
|
39
44
|
exitCode: error?.code ?? (error ? 1 : null),
|
|
40
|
-
killed
|
|
45
|
+
killed,
|
|
46
|
+
// 明确告知 agent 命令是因超时被终止(Node 不会自动在 stderr 写入该提示)
|
|
47
|
+
terminated: killed ? "timeout" : undefined,
|
|
41
48
|
});
|
|
42
49
|
});
|
|
43
50
|
});
|