@ai-zen/agents-sdk 0.2.0-alpha.2 → 0.2.0-alpha.3
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 +29 -1
- package/dist/capabilities/implements/builtin/exec.js +8 -1
- package/dist/capabilities/implements/builtin/execAsync.d.ts +2 -0
- package/dist/capabilities/implements/builtin/execAsync.js +148 -0
- package/dist/capabilities/implements/builtin/index.d.ts +4 -2
- package/dist/capabilities/implements/builtin/index.js +6 -2
- package/dist/capabilities/implements/builtin/sleep.d.ts +2 -0
- package/dist/capabilities/implements/builtin/sleep.js +41 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,7 +77,35 @@ await agent.send("你好");
|
|
|
77
77
|
| `runtime` | ✅ 已实现 — Provider、Capabilities、createAgent、MCP 连接管理、任务迁移 |
|
|
78
78
|
| `plugin` | ✅ 已实现 — AutoMigratePlugin / AutoDraftPlugin / AutoRefreshToolsPlugin |
|
|
79
79
|
| `shared` | ✅ 已实现 — SdkError + 可注入 Logger |
|
|
80
|
-
| 测试 | ✅
|
|
80
|
+
| 测试 | ✅ 359 个测试,45 个文件,全通过(含真实 API 聊天 e2e) |
|
|
81
|
+
|
|
82
|
+
## 内置工具
|
|
83
|
+
|
|
84
|
+
| 工具 | 说明 |
|
|
85
|
+
|------|------|
|
|
86
|
+
| `cwd` | 获取当前工作目录 |
|
|
87
|
+
| `readFile` | 读取文件 |
|
|
88
|
+
| `writeFile` | 写入文件 |
|
|
89
|
+
| `exec` | 执行命令(支持 `timeout` 超时参数) |
|
|
90
|
+
| `exec_async` | 异步执行命令,启动后立即返回,不等待结果 |
|
|
91
|
+
| `mkdir` | 创建目录 |
|
|
92
|
+
| `rm` | 删除文件或目录 |
|
|
93
|
+
| `glob` | 使用 glob 模式扫描查找文件 |
|
|
94
|
+
| `ls` | 列出目录内容 |
|
|
95
|
+
| `exist` | 检查文件或目录是否存在 |
|
|
96
|
+
| `findText` | 在文件中搜索文本或正则 |
|
|
97
|
+
| `downloadFile` | 从 URL 下载文件并保存到本地 |
|
|
98
|
+
| `rename` | 重命名或移动文件/目录 |
|
|
99
|
+
| `copy` | 复制文件或目录 |
|
|
100
|
+
| `batchEdit` | 批量编辑文件文本 |
|
|
101
|
+
| `edit` | 编辑文件中的文本 |
|
|
102
|
+
| `sleep` | 等待指定毫秒数后继续 |
|
|
103
|
+
|
|
104
|
+
条件注入(需配置 `imageModels`):
|
|
105
|
+
|
|
106
|
+
| 工具 | 说明 |
|
|
107
|
+
|------|------|
|
|
108
|
+
| `generateImage` | 根据文字描述生成图片 |
|
|
81
109
|
|
|
82
110
|
## 内置插件
|
|
83
111
|
|
|
@@ -11,18 +11,25 @@ export const execTool = new CallbackTool({
|
|
|
11
11
|
type: "string",
|
|
12
12
|
description: "要执行的命令",
|
|
13
13
|
},
|
|
14
|
+
timeout: {
|
|
15
|
+
type: "number",
|
|
16
|
+
description: "超时时间(毫秒),超时后会终止进程。默认无超时。建议长时间运行的命令使用 exec_async 异步执行。",
|
|
17
|
+
},
|
|
14
18
|
},
|
|
15
19
|
required: ["command"],
|
|
16
20
|
additionalProperties: false,
|
|
17
21
|
},
|
|
18
22
|
},
|
|
19
23
|
async callback(input) {
|
|
24
|
+
const command = input.command;
|
|
25
|
+
const timeout = input.timeout;
|
|
20
26
|
const result = await new Promise((resolve) => {
|
|
21
|
-
exec(
|
|
27
|
+
const child = exec(command, { timeout: timeout && timeout > 0 ? timeout : undefined }, (error, stdout, stderr) => {
|
|
22
28
|
resolve({
|
|
23
29
|
stdout,
|
|
24
30
|
stderr,
|
|
25
31
|
exitCode: error?.code ?? (error ? 1 : null),
|
|
32
|
+
killed: error?.killed ?? false,
|
|
26
33
|
});
|
|
27
34
|
});
|
|
28
35
|
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { CallbackTool } from "@ai-zen/agents-core";
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
export const execAsyncTool = new CallbackTool({
|
|
4
|
+
function: {
|
|
5
|
+
name: "exec_async",
|
|
6
|
+
description: "异步执行命令,启动程序后立即返回,不等待执行结果。适用于启动长期运行的进程(如服务器、监听程序、GUI应用等)或不需要等待结果的命令。注意:该工具不会捕获命令的输出,如果需要获取输出请使用 exec。",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
command: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "要执行的命令(含参数)",
|
|
13
|
+
},
|
|
14
|
+
cwd: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "工作目录(可选,默认当前目录)",
|
|
17
|
+
},
|
|
18
|
+
detached: {
|
|
19
|
+
type: "boolean",
|
|
20
|
+
description: "是否完全脱离当前进程组(可选,默认 false)。设为 true 时,即使当前 Agent 进程退出,启动的程序仍会继续运行。适用于需要独立运行的守护进程或 GUI 程序。",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
required: ["command"],
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
async callback(input) {
|
|
28
|
+
const command = input.command;
|
|
29
|
+
const cwd = input.cwd ?? undefined;
|
|
30
|
+
const detached = input.detached ?? false;
|
|
31
|
+
// Windows 用 shell 模式,其他平台直接 spawn 避免 shell 安全问题
|
|
32
|
+
const useShell = process.platform === "win32";
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
let child;
|
|
35
|
+
if (useShell) {
|
|
36
|
+
// Windows: 通过 shell 执行整条命令
|
|
37
|
+
child = spawn(command, [], {
|
|
38
|
+
cwd,
|
|
39
|
+
detached,
|
|
40
|
+
stdio: "ignore",
|
|
41
|
+
shell: true,
|
|
42
|
+
windowsHide: true,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Unix: 解析命令和参数,直接 spawn
|
|
47
|
+
const args = [];
|
|
48
|
+
let current = "";
|
|
49
|
+
let inQuote = null;
|
|
50
|
+
for (const ch of command) {
|
|
51
|
+
if (inQuote) {
|
|
52
|
+
if (ch === "\\") {
|
|
53
|
+
current += command[command.indexOf(ch) + 1] ?? "";
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (ch === inQuote) {
|
|
57
|
+
inQuote = null;
|
|
58
|
+
if (current)
|
|
59
|
+
args.push(current);
|
|
60
|
+
current = "";
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
current += ch;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (ch === '"' || ch === "'") {
|
|
67
|
+
inQuote = ch;
|
|
68
|
+
}
|
|
69
|
+
else if (ch === " ") {
|
|
70
|
+
if (current) {
|
|
71
|
+
args.push(current);
|
|
72
|
+
current = "";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
current += ch;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (current)
|
|
81
|
+
args.push(current);
|
|
82
|
+
child = spawn(args[0], args.slice(1), {
|
|
83
|
+
cwd,
|
|
84
|
+
detached,
|
|
85
|
+
stdio: "ignore",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// 记录是否已 resolve
|
|
89
|
+
let resolved = false;
|
|
90
|
+
child.on("error", (err) => {
|
|
91
|
+
if (resolved)
|
|
92
|
+
return;
|
|
93
|
+
resolved = true;
|
|
94
|
+
resolve(JSON.stringify({
|
|
95
|
+
success: false,
|
|
96
|
+
pid: null,
|
|
97
|
+
error: `启动失败: ${err.message}`,
|
|
98
|
+
}));
|
|
99
|
+
});
|
|
100
|
+
child.on("spawn", () => {
|
|
101
|
+
if (resolved)
|
|
102
|
+
return;
|
|
103
|
+
resolved = true;
|
|
104
|
+
resolve(JSON.stringify({
|
|
105
|
+
success: true,
|
|
106
|
+
pid: child.pid ?? null,
|
|
107
|
+
message: `进程已启动 (PID: ${child.pid ?? "unknown"})`,
|
|
108
|
+
}));
|
|
109
|
+
});
|
|
110
|
+
// 如果进程很快退出(如命令不存在被 shell 拒绝),捕获退出码
|
|
111
|
+
child.on("exit", (code) => {
|
|
112
|
+
if (resolved)
|
|
113
|
+
return;
|
|
114
|
+
resolved = true;
|
|
115
|
+
resolve(JSON.stringify({
|
|
116
|
+
success: code === 0,
|
|
117
|
+
pid: child.pid ?? null,
|
|
118
|
+
exitCode: code,
|
|
119
|
+
message: code === null
|
|
120
|
+
? `进程已退出 (PID: ${child.pid ?? "unknown"})`
|
|
121
|
+
: `进程已退出 (PID: ${child.pid ?? "unknown"}, 退出码: ${code})`,
|
|
122
|
+
}));
|
|
123
|
+
});
|
|
124
|
+
// 给子进程一点时间来触发 spawn/error/exit 事件
|
|
125
|
+
// 若 500ms 后仍未触发,认为启动成功
|
|
126
|
+
const timeout = setTimeout(() => {
|
|
127
|
+
if (resolved)
|
|
128
|
+
return;
|
|
129
|
+
resolved = true;
|
|
130
|
+
resolve(JSON.stringify({
|
|
131
|
+
success: true,
|
|
132
|
+
pid: child.pid ?? null,
|
|
133
|
+
message: `进程已启动 (PID: ${child.pid ?? "unknown"})`,
|
|
134
|
+
}));
|
|
135
|
+
}, 500);
|
|
136
|
+
// 超时后清理
|
|
137
|
+
const cleanup = () => {
|
|
138
|
+
clearTimeout(timeout);
|
|
139
|
+
child.removeAllListeners();
|
|
140
|
+
};
|
|
141
|
+
child.on("spawn", cleanup);
|
|
142
|
+
child.on("error", cleanup);
|
|
143
|
+
child.on("exit", cleanup);
|
|
144
|
+
// 允许子进程独立运行(不阻止父进程退出)
|
|
145
|
+
child.unref();
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
});
|
|
@@ -14,6 +14,8 @@ import { renameTool } from "./rename.js";
|
|
|
14
14
|
import { copyTool } from "./copy.js";
|
|
15
15
|
import { batchEditTool } from "./batchEdit.js";
|
|
16
16
|
import { editTool } from "./edit.js";
|
|
17
|
-
|
|
17
|
+
import { execAsyncTool } from "./execAsync.js";
|
|
18
|
+
import { sleepTool } from "./sleep.js";
|
|
19
|
+
/** 17 个内置工具实例,注册与实现一体。 */
|
|
18
20
|
export declare const BUILTIN_TOOLS: Tool[];
|
|
19
|
-
export { cwdTool, readFileTool, writeFileTool, execTool, mkdirTool, rmTool, globTool, lsTool, existTool, findTextTool, downloadFileTool, renameTool, copyTool, batchEditTool, editTool };
|
|
21
|
+
export { cwdTool, readFileTool, writeFileTool, execTool, mkdirTool, rmTool, globTool, lsTool, existTool, findTextTool, downloadFileTool, renameTool, copyTool, batchEditTool, editTool, execAsyncTool, sleepTool };
|
|
@@ -13,7 +13,9 @@ import { renameTool } from "./rename.js";
|
|
|
13
13
|
import { copyTool } from "./copy.js";
|
|
14
14
|
import { batchEditTool } from "./batchEdit.js";
|
|
15
15
|
import { editTool } from "./edit.js";
|
|
16
|
-
|
|
16
|
+
import { execAsyncTool } from "./execAsync.js";
|
|
17
|
+
import { sleepTool } from "./sleep.js";
|
|
18
|
+
/** 17 个内置工具实例,注册与实现一体。 */
|
|
17
19
|
export const BUILTIN_TOOLS = [
|
|
18
20
|
cwdTool,
|
|
19
21
|
readFileTool,
|
|
@@ -30,5 +32,7 @@ export const BUILTIN_TOOLS = [
|
|
|
30
32
|
copyTool,
|
|
31
33
|
batchEditTool,
|
|
32
34
|
editTool,
|
|
35
|
+
execAsyncTool,
|
|
36
|
+
sleepTool,
|
|
33
37
|
];
|
|
34
|
-
export { cwdTool, readFileTool, writeFileTool, execTool, mkdirTool, rmTool, globTool, lsTool, existTool, findTextTool, downloadFileTool, renameTool, copyTool, batchEditTool, editTool };
|
|
38
|
+
export { cwdTool, readFileTool, writeFileTool, execTool, mkdirTool, rmTool, globTool, lsTool, existTool, findTextTool, downloadFileTool, renameTool, copyTool, batchEditTool, editTool, execAsyncTool, sleepTool };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CallbackTool } from "@ai-zen/agents-core";
|
|
2
|
+
export const sleepTool = new CallbackTool({
|
|
3
|
+
function: {
|
|
4
|
+
name: "sleep",
|
|
5
|
+
description: "等待指定的时间(毫秒)。用于需要延迟执行的场景,例如等待其他操作完成、操作间隔控制等。注意:过长的等待时间会影响响应速度,建议不超过 30000 毫秒(30 秒)。",
|
|
6
|
+
parameters: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
ms: {
|
|
10
|
+
type: "number",
|
|
11
|
+
description: "等待的毫秒数(1 秒 = 1000 毫秒)。建议不超过 30000(30 秒)。",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
required: ["ms"],
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
async callback(input) {
|
|
19
|
+
const ms = input.ms;
|
|
20
|
+
if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) {
|
|
21
|
+
return JSON.stringify({
|
|
22
|
+
success: false,
|
|
23
|
+
error: "ms 必须是正整数",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (ms > 300_000) {
|
|
27
|
+
// 超过 5 分钟给出警告
|
|
28
|
+
return JSON.stringify({
|
|
29
|
+
success: false,
|
|
30
|
+
error: `等待时间 ${ms}ms 过长,建议不超过 300000ms(5 分钟)。如需长时间等待请分段执行。`,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
34
|
+
return JSON.stringify({
|
|
35
|
+
success: true,
|
|
36
|
+
waitedMs: ms,
|
|
37
|
+
waitedSeconds: (ms / 1000).toFixed(1),
|
|
38
|
+
message: `已等待 ${ms}ms(${(ms / 1000).toFixed(1)} 秒)`,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export type { AutoDraftOptions } from "./plugin/AutoDraftPlugin.js";
|
|
|
32
32
|
export { AutoRefreshToolsPlugin } from "./plugin/AutoRefreshToolsPlugin.js";
|
|
33
33
|
export { BUILTIN_TOOLS } from "./capabilities/implements/builtin/index.js";
|
|
34
34
|
export { createGenerateImageTool } from "./capabilities/implements/builtin/generateImage.js";
|
|
35
|
+
export { execAsyncTool } from "./capabilities/implements/builtin/execAsync.js";
|
|
36
|
+
export { sleepTool } from "./capabilities/implements/builtin/sleep.js";
|
|
35
37
|
export { createLoadSkillTool, createCallSkillSubAgentTool } from "./capabilities/implements/skillTools.js";
|
|
36
38
|
export { createLoadMcpTool, createCallMcpTool, createReadMcpResourceTool } from "./capabilities/implements/mcpTools.js";
|
|
37
39
|
export { createSubAgentTool } from "./capabilities/implements/subAgentTools.js";
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,8 @@ export { AutoRefreshToolsPlugin } from "./plugin/AutoRefreshToolsPlugin.js";
|
|
|
29
29
|
// 工具
|
|
30
30
|
export { BUILTIN_TOOLS } from "./capabilities/implements/builtin/index.js";
|
|
31
31
|
export { createGenerateImageTool } from "./capabilities/implements/builtin/generateImage.js";
|
|
32
|
+
export { execAsyncTool } from "./capabilities/implements/builtin/execAsync.js";
|
|
33
|
+
export { sleepTool } from "./capabilities/implements/builtin/sleep.js";
|
|
32
34
|
export { createLoadSkillTool, createCallSkillSubAgentTool } from "./capabilities/implements/skillTools.js";
|
|
33
35
|
export { createLoadMcpTool, createCallMcpTool, createReadMcpResourceTool } from "./capabilities/implements/mcpTools.js";
|
|
34
36
|
export { createSubAgentTool } from "./capabilities/implements/subAgentTools.js";
|