@ai-zen/agents-sdk 0.5.7 → 0.7.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 +53 -0
- package/README.md +10 -7
- package/README.zh.md +10 -7
- package/dist/capabilities/discovery/builtin.d.ts +3 -3
- package/dist/capabilities/discovery/builtin.js +4 -12
- 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 +11 -9
- package/dist/capabilities/implements/builtin/GenerateImageTool.js +63 -56
- 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/ViewImageTool.d.ts +24 -0
- package/dist/capabilities/implements/builtin/ViewImageTool.js +109 -0
- package/dist/capabilities/implements/builtin/WriteFileTool.d.ts +2 -0
- package/dist/capabilities/implements/builtin/WriteFileTool.js +19 -21
- package/dist/capabilities/implements/builtin/index.d.ts +6 -4
- package/dist/capabilities/implements/builtin/index.js +8 -4
- package/dist/capabilities/implements/mcpTools.js +4 -6
- package/dist/capabilities/implements/skillTools.js +18 -8
- package/dist/capabilities/implements/subAgentTools.js +17 -8
- package/dist/config/constants.js +12 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/plugin/AutoMigratePlugin.d.ts +1 -1
- package/dist/plugin/AutoMigratePlugin.js +1 -1
- package/dist/plugin/AutoRefreshToolsPlugin.d.ts +1 -1
- package/dist/plugin/AutoRefreshToolsPlugin.js +2 -2
- package/dist/plugin/ContextGuardPlugin.d.ts +2 -2
- package/dist/plugin/ContextGuardPlugin.js +1 -1
- package/dist/plugin/UnknownToolHintPlugin.d.ts +21 -0
- package/dist/plugin/UnknownToolHintPlugin.js +30 -0
- package/dist/runtime/Provider.d.ts +8 -7
- package/dist/runtime/Provider.js +14 -4
- package/dist/runtime/SdkAgent.d.ts +14 -107
- package/dist/runtime/SdkAgent.js +8 -120
- package/dist/runtime/SdkCallbackTool.d.ts +25 -9
- package/dist/runtime/SdkCallbackTool.js +7 -3
- package/dist/runtime/createAgent.js +4 -3
- package/dist/runtime/createModel.d.ts +17 -4
- package/dist/runtime/createModel.js +15 -11
- package/dist/types/index.d.ts +2 -0
- package/package.json +3 -2
|
@@ -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 LsTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class LsTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
type: "string",
|
|
14
|
-
description: "目录路径",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
required: ["path"],
|
|
18
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "ls",
|
|
6
|
+
description: "列出目录",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
path: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "目录路径",
|
|
19
13
|
},
|
|
20
14
|
},
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
required: ["path"],
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
constructor(env) {
|
|
20
|
+
super({ env });
|
|
23
21
|
}
|
|
24
22
|
async call(input) {
|
|
25
23
|
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 MkdirTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class MkdirTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
type: "boolean",
|
|
18
|
-
description: "是否递归创建子目录",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
required: ["path"],
|
|
22
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "mkdir",
|
|
6
|
+
description: "创建目录",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
path: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "目录路径",
|
|
13
|
+
},
|
|
14
|
+
recursive: {
|
|
15
|
+
type: "boolean",
|
|
16
|
+
description: "是否递归创建子目录",
|
|
23
17
|
},
|
|
24
18
|
},
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
required: ["path"],
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
constructor(env) {
|
|
24
|
+
super({ env });
|
|
27
25
|
}
|
|
28
26
|
async call(input) {
|
|
29
27
|
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 ReadFileTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class ReadFileTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
type: "string",
|
|
14
|
-
description: "文件路径",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
required: ["path"],
|
|
18
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "readFile",
|
|
6
|
+
description: "读取文件",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
path: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "文件路径",
|
|
19
13
|
},
|
|
20
14
|
},
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
required: ["path"],
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
constructor(env) {
|
|
20
|
+
super({ env });
|
|
23
21
|
}
|
|
24
22
|
async call(input) {
|
|
25
23
|
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 RenameTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
oldPath: string;
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class RenameTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
type: "string",
|
|
18
|
-
description: "新路径",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
required: ["oldPath", "newPath"],
|
|
22
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "rename",
|
|
6
|
+
description: "重命名或移动文件/目录(相当于 mv 命令)",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
oldPath: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "原路径",
|
|
13
|
+
},
|
|
14
|
+
newPath: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "新路径",
|
|
23
17
|
},
|
|
24
18
|
},
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
required: ["oldPath", "newPath"],
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
constructor(env) {
|
|
24
|
+
super({ env });
|
|
27
25
|
}
|
|
28
26
|
async call(input) {
|
|
29
27
|
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 RmTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
3
|
export class RmTool extends SdkCallbackTool {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
type: "boolean",
|
|
18
|
-
description: "是否递归删除子目录",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
required: ["path"],
|
|
22
|
-
additionalProperties: false,
|
|
4
|
+
function = {
|
|
5
|
+
name: "rm",
|
|
6
|
+
description: "删除文件或目录",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
path: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "文件或目录路径",
|
|
13
|
+
},
|
|
14
|
+
recursive: {
|
|
15
|
+
type: "boolean",
|
|
16
|
+
description: "是否递归删除子目录",
|
|
23
17
|
},
|
|
24
18
|
},
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
required: ["path"],
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
constructor(env) {
|
|
24
|
+
super({ env });
|
|
27
25
|
}
|
|
28
26
|
async call(input) {
|
|
29
27
|
try {
|
|
@@ -1,8 +1,10 @@
|
|
|
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 SleepTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
ms: number;
|
|
7
|
-
}): Promise<string>;
|
|
9
|
+
}, ctx?: ToolCallContext): Promise<string>;
|
|
8
10
|
}
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
2
2
|
export class SleepTool extends SdkCallbackTool {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
type: "number",
|
|
13
|
-
description: "等待的毫秒数(1 秒 = 1000 毫秒)。建议不超过 30000(30 秒)。",
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
required: ["ms"],
|
|
17
|
-
additionalProperties: false,
|
|
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 秒)。",
|
|
18
12
|
},
|
|
19
13
|
},
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
required: ["ms"],
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
constructor(env) {
|
|
19
|
+
super({ env });
|
|
22
20
|
}
|
|
23
|
-
async call(input) {
|
|
21
|
+
async call(input, ctx) {
|
|
24
22
|
const ms = input.ms;
|
|
25
23
|
if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) {
|
|
26
24
|
return JSON.stringify({
|
|
@@ -35,7 +33,29 @@ export class SleepTool extends SdkCallbackTool {
|
|
|
35
33
|
error: `等待时间 ${ms}ms 过长,建议不超过 300000ms(5 分钟)。如需长时间等待请分段执行。`,
|
|
36
34
|
});
|
|
37
35
|
}
|
|
38
|
-
|
|
36
|
+
// 若 signal 已处于 aborted,直接返回中断结果,避免不必要的等待
|
|
37
|
+
const signal = ctx?.signal;
|
|
38
|
+
// 等待 ms 毫秒,中断(abort)时提前结束
|
|
39
|
+
await new Promise((resolve) => {
|
|
40
|
+
if (signal?.aborted) {
|
|
41
|
+
resolve();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const timer = setTimeout(resolve, ms);
|
|
45
|
+
if (signal) {
|
|
46
|
+
signal.addEventListener("abort", () => {
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
resolve();
|
|
49
|
+
}, { once: true });
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
if (signal?.aborted) {
|
|
53
|
+
return JSON.stringify({
|
|
54
|
+
success: false,
|
|
55
|
+
aborted: true,
|
|
56
|
+
error: "等待被中断(aborted)",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
39
59
|
return JSON.stringify({
|
|
40
60
|
success: true,
|
|
41
61
|
waitedMs: ms,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentNS, ToolCallContext } from "@ai-zen/agents-core";
|
|
2
|
+
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
3
|
+
import type { AgentDefinition, AppConfig, ToolEnv } from "../../../types/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* 查看图片工具 — 让 Agent 主动查看/分析一张图片。**仅对视觉模型可用**:
|
|
6
|
+
* 由 `isAvailable(config, definition)` 声明(从 definition.modelId 解析模型,检查 Model.vision),
|
|
7
|
+
* buildTools 阶段按声明过滤——非视觉模型不会拿到该工具,故无需运行时重复校验。
|
|
8
|
+
*
|
|
9
|
+
* 输入 `path_or_url`:
|
|
10
|
+
* - http(s) URL → 直接以 `image_url` 内容块返回,模型直接查看;
|
|
11
|
+
* - 本地路径 → 自动通过 Files API(DeepSeek)上传,以 `file` 内容块(file_id)返回。
|
|
12
|
+
*
|
|
13
|
+
* 不使用 base64 内联(本地图片走 Files API,符合 DeepSeek 推荐与 48 MiB 请求体限制)。
|
|
14
|
+
* 依赖配置中的 deepseek 端点(Files API 能力);URL 场景不依赖上传。
|
|
15
|
+
*/
|
|
16
|
+
export declare class ViewImageTool extends SdkCallbackTool {
|
|
17
|
+
/** 仅视觉模型可用:从 definition.modelId 解析当前模型,非视觉模型由 buildTools 过滤 */
|
|
18
|
+
isAvailable(config: AppConfig, definition: AgentDefinition): boolean;
|
|
19
|
+
function: AgentNS.FunctionDefine;
|
|
20
|
+
constructor(env: ToolEnv);
|
|
21
|
+
call(input: {
|
|
22
|
+
path_or_url?: string;
|
|
23
|
+
}, ctx?: ToolCallContext): Promise<AgentNS.MessageContent>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import OpenAI, { toFile } from "openai";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
5
|
+
const SUPPORTED_EXT = [".jpg", ".jpeg", ".png", ".gif", ".webp"];
|
|
6
|
+
/**
|
|
7
|
+
* 查看图片工具 — 让 Agent 主动查看/分析一张图片。**仅对视觉模型可用**:
|
|
8
|
+
* 由 `isAvailable(config, definition)` 声明(从 definition.modelId 解析模型,检查 Model.vision),
|
|
9
|
+
* buildTools 阶段按声明过滤——非视觉模型不会拿到该工具,故无需运行时重复校验。
|
|
10
|
+
*
|
|
11
|
+
* 输入 `path_or_url`:
|
|
12
|
+
* - http(s) URL → 直接以 `image_url` 内容块返回,模型直接查看;
|
|
13
|
+
* - 本地路径 → 自动通过 Files API(DeepSeek)上传,以 `file` 内容块(file_id)返回。
|
|
14
|
+
*
|
|
15
|
+
* 不使用 base64 内联(本地图片走 Files API,符合 DeepSeek 推荐与 48 MiB 请求体限制)。
|
|
16
|
+
* 依赖配置中的 deepseek 端点(Files API 能力);URL 场景不依赖上传。
|
|
17
|
+
*/
|
|
18
|
+
export class ViewImageTool extends SdkCallbackTool {
|
|
19
|
+
/** 仅视觉模型可用:从 definition.modelId 解析当前模型,非视觉模型由 buildTools 过滤 */
|
|
20
|
+
isAvailable(config, definition) {
|
|
21
|
+
const modelId = definition.modelId ?? config.defaultModel;
|
|
22
|
+
const model = (config.models ?? []).find((m) => m.id === modelId);
|
|
23
|
+
return model?.vision === true;
|
|
24
|
+
}
|
|
25
|
+
function = {
|
|
26
|
+
name: "viewImage",
|
|
27
|
+
description: "查看一张图片并分析其内容。传入本地图片路径或 http(s) 图片 URL。本地图片会自动上传(Files API)后引用,网络图片直接引用。适合识别图片文字、描述图片内容、分析图表等。",
|
|
28
|
+
parameters: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
path_or_url: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "本地图片路径(相对/绝对)或 http(s) 图片 URL。支持的格式:JPEG、PNG、GIF、WebP。",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
required: ["path_or_url"],
|
|
37
|
+
additionalProperties: false,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
constructor(env) {
|
|
41
|
+
super({ env });
|
|
42
|
+
}
|
|
43
|
+
async call(input, ctx) {
|
|
44
|
+
const signal = ctx?.signal;
|
|
45
|
+
const target = input?.path_or_url;
|
|
46
|
+
if (!target || !target.trim()) {
|
|
47
|
+
return "viewImage 需要提供 path_or_url 参数(本地图片路径或 http(s) URL)。";
|
|
48
|
+
}
|
|
49
|
+
const value = target.trim();
|
|
50
|
+
try {
|
|
51
|
+
// 网络图片:直接返回 image_url 内容块(无需上传)
|
|
52
|
+
if (/^https?:\/\//i.test(value)) {
|
|
53
|
+
return [
|
|
54
|
+
{
|
|
55
|
+
type: "text",
|
|
56
|
+
text: `已获取网络图片:${value}`,
|
|
57
|
+
},
|
|
58
|
+
{ type: "image_url", image_url: { url: value } },
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
// 本地图片:解析路径 + 校验 + Files API 上传
|
|
62
|
+
const absPath = path.isAbsolute(value)
|
|
63
|
+
? value
|
|
64
|
+
: path.join(this.env.cwd, value);
|
|
65
|
+
let stat;
|
|
66
|
+
try {
|
|
67
|
+
stat = await fs.stat(absPath);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return `本地图片不存在: ${absPath}`;
|
|
71
|
+
}
|
|
72
|
+
if (!stat.isFile()) {
|
|
73
|
+
return `"${absPath}" 不是文件。`;
|
|
74
|
+
}
|
|
75
|
+
const ext = path.extname(absPath).toLowerCase();
|
|
76
|
+
if (!SUPPORTED_EXT.includes(ext)) {
|
|
77
|
+
return `不支持的图片格式 "${ext || "(无扩展名)"}"。支持的格式:JPEG、PNG、GIF、WebP。`;
|
|
78
|
+
}
|
|
79
|
+
// 上传端点:deepseek(Files API 能力)
|
|
80
|
+
const endpoint = (this.env.config.endpoints ?? []).find((e) => e.id === "deepseek");
|
|
81
|
+
if (!endpoint) {
|
|
82
|
+
return "未配置 deepseek 端点,无法上传本地图片(Files API)。如需查看本地图片,请先配置 deepseek 端点;网络图片 URL 可直接使用。";
|
|
83
|
+
}
|
|
84
|
+
if (!endpoint.apiKey) {
|
|
85
|
+
return `端点 "${endpoint.name}" 的 API Key 未设置,无法上传本地图片。`;
|
|
86
|
+
}
|
|
87
|
+
const client = new OpenAI({
|
|
88
|
+
apiKey: endpoint.apiKey,
|
|
89
|
+
baseURL: endpoint.baseUrl,
|
|
90
|
+
});
|
|
91
|
+
const file = await toFile(await fs.readFile(absPath), path.basename(absPath));
|
|
92
|
+
const uploaded = await client.files.create({ file, purpose: "user_data" }, { signal });
|
|
93
|
+
return [
|
|
94
|
+
{
|
|
95
|
+
type: "text",
|
|
96
|
+
text: `图片已上传(${path.basename(absPath)}),file_id: ${uploaded.id}`,
|
|
97
|
+
},
|
|
98
|
+
{ type: "file", file_id: uploaded.id },
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// 中断(abort)时返回明确的中断结果
|
|
103
|
+
if (signal?.aborted) {
|
|
104
|
+
return "图片查看被中断(aborted)";
|
|
105
|
+
}
|
|
106
|
+
return `查看图片失败: ${error instanceof Error ? error.message : String(error)}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -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 WriteFileTool extends SdkCallbackTool {
|
|
5
|
+
function: AgentNS.FunctionDefine;
|
|
4
6
|
constructor(env: ToolEnv);
|
|
5
7
|
call(input: {
|
|
6
8
|
path: string;
|
|
@@ -2,29 +2,27 @@ 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 WriteFileTool extends SdkCallbackTool {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "文件内容",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
required: ["path", "content"],
|
|
23
|
-
additionalProperties: false,
|
|
5
|
+
function = {
|
|
6
|
+
name: "writeFile",
|
|
7
|
+
description: "写入文件",
|
|
8
|
+
parameters: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
path: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "文件路径",
|
|
14
|
+
},
|
|
15
|
+
content: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "文件内容",
|
|
24
18
|
},
|
|
25
19
|
},
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
required: ["path", "content"],
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
constructor(env) {
|
|
25
|
+
super({ env });
|
|
28
26
|
}
|
|
29
27
|
async call(input) {
|
|
30
28
|
try {
|
|
@@ -17,13 +17,15 @@ import { BatchEditTool } from "./BatchEditTool.js";
|
|
|
17
17
|
import { EditTool } from "./EditTool.js";
|
|
18
18
|
import { ExecAsyncTool } from "./ExecAsyncTool.js";
|
|
19
19
|
import { SleepTool } from "./SleepTool.js";
|
|
20
|
+
import { ViewImageTool } from "./ViewImageTool.js";
|
|
20
21
|
import { GenerateImageTool } from "./GenerateImageTool.js";
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
+
* 全部内置工具类(19 个)。
|
|
23
24
|
* 工具类由 Provider 用 ToolEnv 实例化(每个 Provider 一套实例,注入其 cwd)。
|
|
24
25
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
26
|
+
* 发现层不做任何过滤——工具的可用性由各工具自行声明(SdkCallbackTool.isAvailable,
|
|
27
|
+
* 入参含完整 config + 模型信息),在 buildTools/filter 阶段按声明过滤。
|
|
28
|
+
* 如 GenerateImageTool 依赖 defaultImageModel、ViewImageTool 仅视觉模型可用。
|
|
27
29
|
*/
|
|
28
30
|
export declare const BUILTIN_TOOL_CLASSES: Array<new (env: ToolEnv) => SdkCallbackTool>;
|
|
29
|
-
export { CwdTool, ReadFileTool, WriteFileTool, ExecTool, MkdirTool, RmTool, GlobTool, LsTool, ExistTool, FindTextTool, DownloadFileTool, RenameTool, CopyTool, BatchEditTool, EditTool, ExecAsyncTool, SleepTool, GenerateImageTool, };
|
|
31
|
+
export { CwdTool, ReadFileTool, WriteFileTool, ExecTool, MkdirTool, RmTool, GlobTool, LsTool, ExistTool, FindTextTool, DownloadFileTool, RenameTool, CopyTool, BatchEditTool, EditTool, ExecAsyncTool, SleepTool, ViewImageTool, GenerateImageTool, };
|
|
@@ -15,13 +15,15 @@ import { BatchEditTool } from "./BatchEditTool.js";
|
|
|
15
15
|
import { EditTool } from "./EditTool.js";
|
|
16
16
|
import { ExecAsyncTool } from "./ExecAsyncTool.js";
|
|
17
17
|
import { SleepTool } from "./SleepTool.js";
|
|
18
|
+
import { ViewImageTool } from "./ViewImageTool.js";
|
|
18
19
|
import { GenerateImageTool } from "./GenerateImageTool.js";
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
+
* 全部内置工具类(19 个)。
|
|
21
22
|
* 工具类由 Provider 用 ToolEnv 实例化(每个 Provider 一套实例,注入其 cwd)。
|
|
22
23
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
24
|
+
* 发现层不做任何过滤——工具的可用性由各工具自行声明(SdkCallbackTool.isAvailable,
|
|
25
|
+
* 入参含完整 config + 模型信息),在 buildTools/filter 阶段按声明过滤。
|
|
26
|
+
* 如 GenerateImageTool 依赖 defaultImageModel、ViewImageTool 仅视觉模型可用。
|
|
25
27
|
*/
|
|
26
28
|
export const BUILTIN_TOOL_CLASSES = [
|
|
27
29
|
CwdTool,
|
|
@@ -41,5 +43,7 @@ export const BUILTIN_TOOL_CLASSES = [
|
|
|
41
43
|
EditTool,
|
|
42
44
|
ExecAsyncTool,
|
|
43
45
|
SleepTool,
|
|
46
|
+
ViewImageTool,
|
|
47
|
+
GenerateImageTool,
|
|
44
48
|
];
|
|
45
|
-
export { CwdTool, ReadFileTool, WriteFileTool, ExecTool, MkdirTool, RmTool, GlobTool, LsTool, ExistTool, FindTextTool, DownloadFileTool, RenameTool, CopyTool, BatchEditTool, EditTool, ExecAsyncTool, SleepTool, GenerateImageTool, };
|
|
49
|
+
export { CwdTool, ReadFileTool, WriteFileTool, ExecTool, MkdirTool, RmTool, GlobTool, LsTool, ExistTool, FindTextTool, DownloadFileTool, RenameTool, CopyTool, BatchEditTool, EditTool, ExecAsyncTool, SleepTool, ViewImageTool, GenerateImageTool, };
|
|
@@ -81,7 +81,7 @@ export function createCallMcpTool(mcpManager) {
|
|
|
81
81
|
additionalProperties: false,
|
|
82
82
|
},
|
|
83
83
|
},
|
|
84
|
-
callback: async (input) => {
|
|
84
|
+
callback: async (input, ctx) => {
|
|
85
85
|
const serverName = input.server;
|
|
86
86
|
const state = mcpManager.getState(serverName);
|
|
87
87
|
if (state !== "connected") {
|
|
@@ -96,7 +96,7 @@ export function createCallMcpTool(mcpManager) {
|
|
|
96
96
|
const result = await client.callTool({
|
|
97
97
|
name: input.tool,
|
|
98
98
|
arguments: input.arguments,
|
|
99
|
-
});
|
|
99
|
+
}, undefined, { signal: ctx?.signal });
|
|
100
100
|
const contents = result.content ?? [];
|
|
101
101
|
const textParts = contents
|
|
102
102
|
.filter((c) => c.type === "text")
|
|
@@ -131,7 +131,7 @@ export function createReadMcpResourceTool(mcpManager) {
|
|
|
131
131
|
additionalProperties: false,
|
|
132
132
|
},
|
|
133
133
|
},
|
|
134
|
-
callback: async (input) => {
|
|
134
|
+
callback: async (input, ctx) => {
|
|
135
135
|
const serverName = input.server;
|
|
136
136
|
const state = mcpManager.getState(serverName);
|
|
137
137
|
if (state !== "connected") {
|
|
@@ -143,9 +143,7 @@ export function createReadMcpResourceTool(mcpManager) {
|
|
|
143
143
|
}
|
|
144
144
|
try {
|
|
145
145
|
mcpManager.touch(serverName);
|
|
146
|
-
const result = await client.readResource({
|
|
147
|
-
uri: input.uri,
|
|
148
|
-
});
|
|
146
|
+
const result = await client.readResource({ uri: input.uri }, { signal: ctx?.signal });
|
|
149
147
|
const contents = result?.contents ?? [];
|
|
150
148
|
const textParts = contents
|
|
151
149
|
.filter((c) => c.text)
|