@ai-zen/agents-sdk 0.5.6 → 0.6.0
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 +32 -0
- package/dist/capabilities/implements/builtin/BatchEditTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/BatchEditTool.js +36 -38
- package/dist/capabilities/implements/builtin/CopyTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/CopyTool.js +23 -25
- package/dist/capabilities/implements/builtin/CwdTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/CwdTool.js +10 -12
- package/dist/capabilities/implements/builtin/DownloadFileTool.d.ts +3 -1
- package/dist/capabilities/implements/builtin/DownloadFileTool.js +32 -24
- package/dist/capabilities/implements/builtin/EditTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/EditTool.js +28 -30
- package/dist/capabilities/implements/builtin/ExecAsyncTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/ExecAsyncTool.js +23 -25
- package/dist/capabilities/implements/builtin/ExecTool.d.ts +3 -1
- package/dist/capabilities/implements/builtin/ExecTool.js +62 -29
- package/dist/capabilities/implements/builtin/ExistTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/ExistTool.js +15 -17
- package/dist/capabilities/implements/builtin/FindTextTool.d.ts +3 -1
- package/dist/capabilities/implements/builtin/FindTextTool.js +43 -35
- package/dist/capabilities/implements/builtin/GenerateImageTool.d.ts +3 -1
- package/dist/capabilities/implements/builtin/GenerateImageTool.js +39 -31
- package/dist/capabilities/implements/builtin/GlobTool.d.ts +3 -1
- package/dist/capabilities/implements/builtin/GlobTool.js +32 -28
- package/dist/capabilities/implements/builtin/LsTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/LsTool.js +15 -17
- package/dist/capabilities/implements/builtin/MkdirTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/MkdirTool.js +19 -21
- package/dist/capabilities/implements/builtin/ReadFileTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/ReadFileTool.js +15 -17
- package/dist/capabilities/implements/builtin/RenameTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/RenameTool.js +19 -21
- package/dist/capabilities/implements/builtin/RmTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/RmTool.js +19 -21
- package/dist/capabilities/implements/builtin/SleepTool.d.ts +3 -1
- package/dist/capabilities/implements/builtin/SleepTool.js +39 -19
- package/dist/capabilities/implements/builtin/WriteFileTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/WriteFileTool.js +19 -21
- package/dist/capabilities/implements/mcpTools.js +4 -6
- package/dist/capabilities/implements/skillTools.js +13 -3
- package/dist/capabilities/implements/subAgentTools.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/runtime/SdkCallbackTool.d.ts +14 -6
- package/dist/runtime/SdkCallbackTool.js +3 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.0] - 2026-08-14
|
|
4
|
+
|
|
5
|
+
### ⚠️ Breaking
|
|
6
|
+
|
|
7
|
+
- **`SdkCallbackTool` constructor no longer takes `function` — construction is now `super({ env })` only** — the tool definition (`function`) is declared by each tool as a **class-body field**, colocated with its `call` implementation. The constructor now takes an options container (`SdkCallbackToolOptions`, currently containing `env` as its core field and open to future extension). Any custom tool previously writing `super({ function, env })` must move its `function` definition into a class-body field and call `super({ env })`. `SdkCallbackToolOptions` is exported for external consumers
|
|
8
|
+
- **`SdkCallbackTool.call` now forwards the full `ToolCallContext`** — `call(input)` becomes `call(input, ctx?)`. Concrete tools may read the second argument (e.g. `ctx?.signal`) for abort support. This is additive (optional argument), so existing single-argument `call`s keep compiling
|
|
9
|
+
- **`@ai-zen/agents-core` upgraded to 3.4.0** — the `Tool` base class no longer requires passing `function`/`type` via its constructor; `CallbackTool` / `AgentToolLazy.buildAgent` no longer use `this`-injection and now receive `(parsed_args, ctx)`. SDK callbacks that previously read `this.agent` now read `ctx.agent` instead (`call_skill_sub_agent` in skillTools, `buildAgent` in subAgentTools)
|
|
10
|
+
|
|
11
|
+
### 🛠 Optimized
|
|
12
|
+
|
|
13
|
+
- **All 18 built-in tools now declare their `function` definition as a class-body field** — the definition lives next to the `call` implementation (single source of truth), instead of being passed separately through the constructor
|
|
14
|
+
- Aligned SDK tool context access with core's explicit `(parsed_args, ctx)` convention
|
|
15
|
+
- **Per-tool abort signal support** — high-value tools now honor interruption via `ctx?.signal`:
|
|
16
|
+
- **`sleep`** — listening for abort on the wait timer, returning early so a long wait is interrupted instead of blocking
|
|
17
|
+
- **`exec`** — killing the child process on abort (marking `terminated: "aborted"` distinct from `"timeout"`), with a fallback to avoid hanging if the signal kills the shell
|
|
18
|
+
- **`downloadFile`** — passing the signal to `fetch`, and cleaning up any partially-written file on abort
|
|
19
|
+
- **`generateImage`** — passing the signal to the image-model request (the underlying `fetch` already supports it), returning an aborted result on interruption
|
|
20
|
+
- **`glob` / `findText`** — checking `ctx.signal` during directory-tree traversal (and after each file read), stopping the scan early and returning the partial results with an `aborted` flag when interrupted
|
|
21
|
+
- **MCP tool signal forwarding** — `call_mcp_tool` and `read_mcp_resource` now forward `ctx.signal` into the underlying MCP SDK `callTool` / `readResource` request options, so a remote call can be interrupted
|
|
22
|
+
- **Sub-agent abort linkage** — sub-agent tools (`AgentTool`, `AgentToolLazy`; used by `createSubAgentTool` and `call_skill_sub_agent`) now listen for the outer `ctx.signal` and call `agent.abort()` on the child agent, so a long-running sub-agent is stopped when the parent call is aborted
|
|
23
|
+
|
|
24
|
+
### ✅ Tests
|
|
25
|
+
|
|
26
|
+
- Updated `SdkCallbackTool` / `capabilities` tests for the new `function` assignment and `super({ env })` construction; added a test asserting `SdkCallbackTool.call` receives the forwarded `ToolCallContext`
|
|
27
|
+
- **Added abort tests** for `sleep` (early return + immediate abort), `exec` (child killed + `terminated: "aborted"`), `downloadFile` (abort cleanup of the partial file), `generateImage` (aborted result), `glob`/`findText` (early scan stop), plus MCP `callTool`/`readResource` signal forwarding and sub-agent abort linkage. SDK suite now at **435 passed**, **3 skipped**; core at **198 passed**, **17 skipped**
|
|
28
|
+
|
|
29
|
+
## [0.5.7] - 2026-08-13
|
|
30
|
+
|
|
31
|
+
### 🛠 Optimized
|
|
32
|
+
|
|
33
|
+
- **`@ai-zen/agents-core` dependency upgraded to 3.3.1** — dual-set inner-loop task semantics + unified Assistant placeholder at inner-loop start; SDK 426 tests (incl. real DeepSeek e2e) all pass, fully compatible
|
|
34
|
+
|
|
3
35
|
## [0.5.6] - 2026-08-14
|
|
4
36
|
|
|
5
37
|
### 🚀 New Features
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
3
4
|
interface Replacement {
|
|
4
5
|
oldText: string;
|
|
5
6
|
newText: string;
|
|
6
7
|
isReplaceAll?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export declare class BatchEditTool extends SdkCallbackTool {
|
|
10
|
+
function: AgentNS.FunctionDefine;
|
|
9
11
|
constructor(env: ToolEnv);
|
|
10
12
|
call(input: {
|
|
11
13
|
path: string;
|
|
@@ -1,49 +1,47 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class BatchEditTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
description: "是否替换所有匹配的文本(默认仅替换首次匹配)。使用此功能前应确保你提供的 oldText 足够精确,避免误替换",
|
|
33
|
-
default: false,
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
required: ["oldText", "newText"],
|
|
37
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "batchEdit",
|
|
6
|
+
description: "批量编辑文件文本,可以优先使用这个工具对文件进行编辑",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
path: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "文件路径",
|
|
13
|
+
},
|
|
14
|
+
replacements: {
|
|
15
|
+
type: "array",
|
|
16
|
+
description: "要替换的文本数组",
|
|
17
|
+
items: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
oldText: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "要替换的文本",
|
|
23
|
+
},
|
|
24
|
+
newText: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "替换后的文本",
|
|
27
|
+
},
|
|
28
|
+
isReplaceAll: {
|
|
29
|
+
type: "boolean",
|
|
30
|
+
description: "是否替换所有匹配的文本(默认仅替换首次匹配)。使用此功能前应确保你提供的 oldText 足够精确,避免误替换",
|
|
31
|
+
default: false,
|
|
38
32
|
},
|
|
39
33
|
},
|
|
34
|
+
required: ["oldText", "newText"],
|
|
35
|
+
additionalProperties: false,
|
|
40
36
|
},
|
|
41
|
-
required: ["path", "replacements"],
|
|
42
|
-
additionalProperties: false,
|
|
43
37
|
},
|
|
44
38
|
},
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
required: ["path", "replacements"],
|
|
40
|
+
additionalProperties: false,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
constructor(env) {
|
|
44
|
+
super({ env });
|
|
47
45
|
}
|
|
48
46
|
async call(input) {
|
|
49
47
|
try {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class CopyTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
src: string;
|
|
@@ -1,33 +1,31 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class CopyTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type: "boolean",
|
|
22
|
-
description: "是否递归复制目录,复制目录时需设为 true",
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
required: ["src", "dest"],
|
|
26
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "copy",
|
|
6
|
+
description: "复制文件或目录(相当于 cp 命令)",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
src: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "源路径",
|
|
13
|
+
},
|
|
14
|
+
dest: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "目标路径",
|
|
17
|
+
},
|
|
18
|
+
recursive: {
|
|
19
|
+
type: "boolean",
|
|
20
|
+
description: "是否递归复制目录,复制目录时需设为 true",
|
|
27
21
|
},
|
|
28
22
|
},
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
required: ["src", "dest"],
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
constructor(env) {
|
|
28
|
+
super({ env });
|
|
31
29
|
}
|
|
32
30
|
async call(input) {
|
|
33
31
|
try {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class CwdTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(): string;
|
|
6
8
|
}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
export class CwdTool extends SdkCallbackTool {
|
|
3
|
+
function = {
|
|
4
|
+
name: "cwd",
|
|
5
|
+
description: "获取当前工作目录 cwd",
|
|
6
|
+
parameters: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {},
|
|
9
|
+
required: [],
|
|
10
|
+
},
|
|
11
|
+
};
|
|
3
12
|
constructor(env) {
|
|
4
|
-
super({
|
|
5
|
-
function: {
|
|
6
|
-
name: "cwd",
|
|
7
|
-
description: "获取当前工作目录 cwd",
|
|
8
|
-
parameters: {
|
|
9
|
-
type: "object",
|
|
10
|
-
properties: {},
|
|
11
|
-
required: [],
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
env,
|
|
15
|
-
});
|
|
13
|
+
super({ env });
|
|
16
14
|
}
|
|
17
15
|
call() {
|
|
18
16
|
return this.env.cwd;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS, ToolCallContext } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class DownloadFileTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
url: string;
|
|
7
9
|
outputPath?: string;
|
|
8
|
-
}): Promise<string>;
|
|
10
|
+
}, ctx?: ToolCallContext): Promise<string>;
|
|
9
11
|
}
|
|
@@ -2,36 +2,35 @@ import * as fsp from "fs/promises";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
4
4
|
export class DownloadFileTool extends SdkCallbackTool {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "保存路径(可选)。可以是目录或完整文件路径。不指定则下载到当前工作目录,自动从 URL 推断文件名。",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
required: ["url"],
|
|
23
|
-
additionalProperties: false,
|
|
5
|
+
function = {
|
|
6
|
+
name: "downloadFile",
|
|
7
|
+
description: "从 URL 下载文件(图片、PDF 等二进制文件)并保存到本地磁盘。自动从 URL 推断文件名,也可指定保存路径。",
|
|
8
|
+
parameters: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
url: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "文件下载链接",
|
|
14
|
+
},
|
|
15
|
+
outputPath: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "保存路径(可选)。可以是目录或完整文件路径。不指定则下载到当前工作目录,自动从 URL 推断文件名。",
|
|
24
18
|
},
|
|
25
19
|
},
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
required: ["url"],
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
constructor(env) {
|
|
25
|
+
super({ env });
|
|
28
26
|
}
|
|
29
|
-
async call(input) {
|
|
27
|
+
async call(input, ctx) {
|
|
28
|
+
const signal = ctx?.signal;
|
|
29
|
+
let savePath;
|
|
30
30
|
try {
|
|
31
31
|
const url = input.url;
|
|
32
32
|
if (!url)
|
|
33
33
|
throw new Error("url 不能为空");
|
|
34
|
-
let savePath;
|
|
35
34
|
if (input.outputPath) {
|
|
36
35
|
savePath = this.resolve(input.outputPath);
|
|
37
36
|
const stat = await fsp.stat(savePath).catch(() => null);
|
|
@@ -47,7 +46,7 @@ export class DownloadFileTool extends SdkCallbackTool {
|
|
|
47
46
|
savePath = path.join(this.env.cwd, fileName);
|
|
48
47
|
}
|
|
49
48
|
await fsp.mkdir(path.dirname(savePath), { recursive: true });
|
|
50
|
-
const response = await fetch(url);
|
|
49
|
+
const response = await fetch(url, { signal });
|
|
51
50
|
if (!response.ok) {
|
|
52
51
|
throw new Error(`下载失败: HTTP ${response.status} ${response.statusText}`);
|
|
53
52
|
}
|
|
@@ -66,6 +65,15 @@ export class DownloadFileTool extends SdkCallbackTool {
|
|
|
66
65
|
});
|
|
67
66
|
}
|
|
68
67
|
catch (error) {
|
|
68
|
+
// 中断(abort)时清理可能残留的半成品文件
|
|
69
|
+
if (signal?.aborted && savePath) {
|
|
70
|
+
await fsp.rm(savePath, { force: true }).catch(() => { });
|
|
71
|
+
return JSON.stringify({
|
|
72
|
+
success: false,
|
|
73
|
+
aborted: true,
|
|
74
|
+
error: "下载被中断(aborted)",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
69
77
|
return JSON.stringify({
|
|
70
78
|
success: false,
|
|
71
79
|
error: error?.message || "下载失败",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class EditTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|
|
@@ -13,38 +13,36 @@ function countOccurrences(content, text) {
|
|
|
13
13
|
return count;
|
|
14
14
|
}
|
|
15
15
|
export class EditTool extends SdkCallbackTool {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
description: "是否替换所有匹配的文本(默认 false,仅替换首次匹配)。使用此功能前应确保你提供的 oldText 足够精确,避免误替换",
|
|
39
|
-
default: false,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
required: ["path", "oldText", "newText"],
|
|
43
|
-
additionalProperties: false,
|
|
16
|
+
function = {
|
|
17
|
+
name: "edit",
|
|
18
|
+
description: "编辑文件中的文本,支持精确替换或替换所有匹配项",
|
|
19
|
+
parameters: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
path: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "文件路径",
|
|
25
|
+
},
|
|
26
|
+
oldText: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "要替换的文本",
|
|
29
|
+
},
|
|
30
|
+
newText: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "替换后的文本",
|
|
33
|
+
},
|
|
34
|
+
isReplaceAll: {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "是否替换所有匹配的文本(默认 false,仅替换首次匹配)。使用此功能前应确保你提供的 oldText 足够精确,避免误替换",
|
|
37
|
+
default: false,
|
|
44
38
|
},
|
|
45
39
|
},
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
required: ["path", "oldText", "newText"],
|
|
41
|
+
additionalProperties: false,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
constructor(env) {
|
|
45
|
+
super({ env });
|
|
48
46
|
}
|
|
49
47
|
async call(input) {
|
|
50
48
|
try {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class ExecAsyncTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
command: string;
|
|
@@ -1,33 +1,31 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class ExecAsyncTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type: "boolean",
|
|
22
|
-
description: "是否完全脱离当前进程组(可选,默认 false)。设为 true 时,即使当前 Agent 进程退出,启动的程序仍会继续运行。适用于需要独立运行的守护进程或 GUI 程序。",
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
required: ["command"],
|
|
26
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "exec_async",
|
|
6
|
+
description: "异步执行命令,启动程序后立即返回,不等待执行结果。适用于启动长期运行的进程(如服务器、监听程序、GUI应用等)或不需要等待结果的命令。注意:该工具本身不捕获命令的输出;若需获取/留存输出,可在命令中使用 shell 重定向写入文件(如 `> /path/file`,支持 `>>` 追加、`|` 管道)。命令经 shell 解析执行。",
|
|
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 程序。",
|
|
27
21
|
},
|
|
28
22
|
},
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
required: ["command"],
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
constructor(env) {
|
|
28
|
+
super({ env });
|
|
31
29
|
}
|
|
32
30
|
async call(input) {
|
|
33
31
|
const command = input.command;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS, ToolCallContext } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class ExecTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
command: string;
|
|
7
9
|
timeout: number;
|
|
8
|
-
}): Promise<string>;
|
|
10
|
+
}, ctx?: ToolCallContext): Promise<string>;
|
|
9
11
|
}
|
|
@@ -1,52 +1,85 @@
|
|
|
1
1
|
import { exec } from "child_process";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class ExecTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
type: "number",
|
|
18
|
-
description: "超时时间(毫秒),必填。超时后会终止进程;超过该时长仍未完成即视为超时并终止。建议长时间运行的命令使用 exec_async 异步执行。",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
required: ["command", "timeout"],
|
|
22
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "exec",
|
|
6
|
+
description: "执行命令",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
command: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "要执行的命令",
|
|
13
|
+
},
|
|
14
|
+
timeout: {
|
|
15
|
+
type: "number",
|
|
16
|
+
description: "超时时间(毫秒),必填。超时后会终止进程;超过该时长仍未完成即视为超时并终止。建议长时间运行的命令使用 exec_async 异步执行。",
|
|
23
17
|
},
|
|
24
18
|
},
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
required: ["command", "timeout"],
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
constructor(env) {
|
|
24
|
+
super({ env });
|
|
27
25
|
}
|
|
28
|
-
async call(input) {
|
|
26
|
+
async call(input, ctx) {
|
|
29
27
|
const command = input.command;
|
|
30
28
|
const { timeout } = input;
|
|
31
29
|
// 运行时双校验:timeout 必填且必须为正数
|
|
32
30
|
if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) {
|
|
33
31
|
throw new Error(`exec: 参数 timeout 为必填项,且必须是正数(毫秒),当前值: ${JSON.stringify(timeout)}`);
|
|
34
32
|
}
|
|
33
|
+
const signal = ctx?.signal;
|
|
35
34
|
const result = await new Promise((resolve) => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
timeout,
|
|
39
|
-
}, (error, stdout, stderr) => {
|
|
40
|
-
const killed = error?.killed ?? false;
|
|
35
|
+
// 若 signal 已处于 aborted,直接标记中断结果
|
|
36
|
+
if (signal?.aborted) {
|
|
41
37
|
resolve({
|
|
38
|
+
stdout: "",
|
|
39
|
+
stderr: "进程已中断(aborted)",
|
|
40
|
+
exitCode: null,
|
|
41
|
+
killed: true,
|
|
42
|
+
terminated: "aborted",
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let child;
|
|
47
|
+
let settled = false;
|
|
48
|
+
const settle = (value) => {
|
|
49
|
+
if (settled)
|
|
50
|
+
return;
|
|
51
|
+
settled = true;
|
|
52
|
+
signal?.removeEventListener("abort", onAbort);
|
|
53
|
+
resolve(value);
|
|
54
|
+
};
|
|
55
|
+
child = exec(command, { cwd: this.env.cwd, timeout }, (error, stdout, stderr) => {
|
|
56
|
+
const killed = error?.killed ?? false;
|
|
57
|
+
const terminated = killed
|
|
58
|
+
? (signal?.aborted ? "aborted" : "timeout")
|
|
59
|
+
: undefined;
|
|
60
|
+
settle({
|
|
42
61
|
stdout,
|
|
43
62
|
stderr,
|
|
44
63
|
exitCode: error?.code ?? (error ? 1 : null),
|
|
45
64
|
killed,
|
|
46
|
-
|
|
47
|
-
terminated: killed ? "timeout" : undefined,
|
|
65
|
+
terminated,
|
|
48
66
|
});
|
|
49
67
|
});
|
|
68
|
+
// 中断:kill 子进程,令其尽快结束
|
|
69
|
+
const onAbort = () => {
|
|
70
|
+
child?.kill("SIGKILL");
|
|
71
|
+
// 即便 exec 回调因信号处理而未能及时触发,也立即返回中断结果,避免挂起
|
|
72
|
+
settle({
|
|
73
|
+
stdout: "",
|
|
74
|
+
stderr: "进程已中断(aborted)",
|
|
75
|
+
exitCode: null,
|
|
76
|
+
killed: true,
|
|
77
|
+
terminated: "aborted",
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
if (signal) {
|
|
81
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
82
|
+
}
|
|
50
83
|
});
|
|
51
84
|
return JSON.stringify(result);
|
|
52
85
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
import type { ToolEnv } from "../../../types/index.js";
|
|
3
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
3
4
|
export declare class ExistTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|