@ai-zen/agents-sdk 0.2.8 → 0.3.2
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 +46 -0
- package/README.md +6 -7
- package/dist/capabilities/discovery/mcp.d.ts +1 -1
- package/dist/capabilities/discovery/mcp.js +8 -4
- package/dist/capabilities/discovery/skills.d.ts +2 -2
- package/dist/capabilities/discovery/skills.js +23 -11
- package/dist/capabilities/discovery/subagents.d.ts +1 -1
- package/dist/capabilities/discovery/subagents.js +10 -5
- package/dist/capabilities/discovery/usertools.d.ts +5 -8
- package/dist/capabilities/discovery/usertools.js +42 -68
- package/dist/capabilities/implements/skillTools.d.ts +2 -2
- package/dist/capabilities/implements/skillTools.js +7 -7
- package/dist/capabilities/implements/subAgentTools.d.ts +1 -2
- package/dist/capabilities/implements/subAgentTools.js +4 -8
- package/dist/config/ConfigManager.d.ts +8 -8
- package/dist/config/ConfigManager.js +66 -35
- package/dist/config/constants.js +9 -3
- package/dist/crud/DraftRepository.d.ts +3 -3
- package/dist/crud/DraftRepository.js +22 -11
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/plugin/AutoDraftPlugin.d.ts +1 -1
- package/dist/plugin/AutoDraftPlugin.js +10 -6
- package/dist/plugin/AutoRefreshToolsPlugin.js +2 -4
- package/dist/runtime/Provider.d.ts +84 -10
- package/dist/runtime/Provider.js +172 -12
- package/dist/runtime/SdkAgent.d.ts +8 -6
- package/dist/runtime/SdkAgent.js +18 -4
- package/dist/runtime/createAgent.d.ts +4 -5
- package/dist/runtime/createAgent.js +7 -24
- package/dist/runtime/createModel.d.ts +4 -7
- package/dist/runtime/createModel.js +4 -6
- package/dist/shared/EntityRepository.d.ts +4 -4
- package/dist/shared/EntityRepository.js +31 -15
- package/package.json +2 -2
- package/dist/capabilities/Capabilities.d.ts +0 -73
- package/dist/capabilities/Capabilities.js +0 -163
package/dist/runtime/Provider.js
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
import { McpConnectionManager } from "./McpConnectionManager.js";
|
|
2
|
+
import { PermissionEvaluator } from "../capabilities/PermissionEvaluator.js";
|
|
3
|
+
import { createLoadSkillTool, createCallSkillSubAgentTool } from "../capabilities/implements/skillTools.js";
|
|
4
|
+
import { createLoadMcpTool, createCallMcpTool, createReadMcpResourceTool } from "../capabilities/implements/mcpTools.js";
|
|
5
|
+
import { createSubAgentTool } from "../capabilities/implements/subAgentTools.js";
|
|
6
|
+
import { discoverBuiltinTools } from "../capabilities/discovery/builtin.js";
|
|
7
|
+
import { discoverSubAgents } from "../capabilities/discovery/subagents.js";
|
|
8
|
+
import { discoverSkills } from "../capabilities/discovery/skills.js";
|
|
9
|
+
import { discoverMcpServers } from "../capabilities/discovery/mcp.js";
|
|
10
|
+
import { discoverUserTools } from "../capabilities/discovery/usertools.js";
|
|
2
11
|
/**
|
|
3
|
-
* Provider —
|
|
12
|
+
* Provider — 全局上下文实例 + 能力注册表。
|
|
4
13
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
14
|
+
* Provider 是 SDK 的全局单例(按需创建),持有:
|
|
15
|
+
* - 应用配置(端点、模型等)
|
|
16
|
+
* - 文件系统路径(Agent 目录、Skill 目录等)
|
|
17
|
+
* - 全局能力注册表(内置工具、用户工具、SubAgent、Skill、MCP)
|
|
18
|
+
* - MCP 连接管理器
|
|
19
|
+
*
|
|
20
|
+
* 创建方式:
|
|
21
|
+
* ```ts
|
|
22
|
+
* // 推荐:一步完成构造 + 能力发现
|
|
23
|
+
* const provider = await Provider.create({ ... });
|
|
24
|
+
*
|
|
25
|
+
* // 仅构造(能力需后续加载)
|
|
26
|
+
* const provider = new Provider({ ... });
|
|
27
|
+
* await provider.init();
|
|
28
|
+
* ```
|
|
7
29
|
*
|
|
8
30
|
* 设计原则:
|
|
9
|
-
* - Provider 实例一旦创建不可变(路径、配置等不变),refresh
|
|
31
|
+
* - Provider 实例一旦创建不可变(路径、配置等不变),refresh 时重新发现能力
|
|
10
32
|
* - 各层不直接 import 散装函数,而是通过 Provider 实例获取
|
|
11
|
-
* - Provider 不关心能力的发现/过滤/实例化,那是 Capabilities 的事
|
|
12
33
|
*/
|
|
13
34
|
export class Provider {
|
|
14
35
|
/** 应用配置(端点、模型等) */
|
|
@@ -19,8 +40,16 @@ export class Provider {
|
|
|
19
40
|
skillsPaths;
|
|
20
41
|
toolsPaths;
|
|
21
42
|
mcpPaths;
|
|
43
|
+
// ---- 全局候选集(发现一次,全局复用)----
|
|
44
|
+
builtinTools;
|
|
45
|
+
userTools;
|
|
46
|
+
subagents;
|
|
47
|
+
/** 完整 SkillInfo,含 subAgent 标记,可据此区分枚举 */
|
|
48
|
+
skills;
|
|
49
|
+
/** 完整 MCP 服务器配置 */
|
|
50
|
+
mcps;
|
|
22
51
|
// ---- MCP ----
|
|
23
|
-
|
|
52
|
+
mcpManager;
|
|
24
53
|
constructor(options) {
|
|
25
54
|
this.config = options.config;
|
|
26
55
|
this.agentsDir = options.agentsDir;
|
|
@@ -28,15 +57,146 @@ export class Provider {
|
|
|
28
57
|
this.skillsPaths = options.skillsPaths ?? [];
|
|
29
58
|
this.toolsPaths = options.toolsPaths ?? [];
|
|
30
59
|
this.mcpPaths = options.mcpPaths ?? [];
|
|
60
|
+
this.builtinTools = [];
|
|
61
|
+
this.userTools = [];
|
|
62
|
+
this.subagents = [];
|
|
63
|
+
this.skills = [];
|
|
64
|
+
this.mcps = [];
|
|
65
|
+
this.mcpManager = this.mcpPaths.length > 0 ? new McpConnectionManager() : undefined;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 异步创建 Provider,一步完成构造 + 全局能力发现。
|
|
69
|
+
*/
|
|
70
|
+
static async create(options) {
|
|
71
|
+
const provider = new Provider(options);
|
|
72
|
+
await provider.init();
|
|
73
|
+
return provider;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 初始化:执行全局能力发现。
|
|
77
|
+
*/
|
|
78
|
+
async init() {
|
|
79
|
+
await this.refresh();
|
|
80
|
+
}
|
|
81
|
+
// ==================================================================
|
|
82
|
+
// 能力过滤与实例化
|
|
83
|
+
// ==================================================================
|
|
84
|
+
/**
|
|
85
|
+
* 按权限过滤候选集,返回过滤后的名称列表。
|
|
86
|
+
* 纯名称操作(安全预过滤 + 权限过滤),不涉及 Tool 实例化。
|
|
87
|
+
*/
|
|
88
|
+
filter(permissions, options) {
|
|
89
|
+
const exclude = options?.exclude ?? {};
|
|
90
|
+
const excludeTools = new Set(exclude.tools ?? []);
|
|
91
|
+
const excludeSkills = new Set(exclude.skills ?? []);
|
|
92
|
+
const excludeMcps = new Set(exclude.mcps ?? []);
|
|
93
|
+
const excludeSubAgents = new Set(exclude.subagents ?? []);
|
|
94
|
+
const safeSubagents = excludeSubAgents.size === 0
|
|
95
|
+
? this.subagents
|
|
96
|
+
: this.subagents.filter((def) => !excludeSubAgents.has(def.function?.name ?? ""));
|
|
97
|
+
const DYNAMIC_TOOL_NAMES = [
|
|
98
|
+
"load_skill",
|
|
99
|
+
"call_skill_sub_agent",
|
|
100
|
+
"load_mcp",
|
|
101
|
+
"call_mcp_tool",
|
|
102
|
+
"read_mcp_resource",
|
|
103
|
+
];
|
|
104
|
+
const toolNames = [
|
|
105
|
+
...this.builtinTools.map((t) => t.function.name),
|
|
106
|
+
...this.userTools.map((t) => t.function.name),
|
|
107
|
+
...DYNAMIC_TOOL_NAMES,
|
|
108
|
+
].filter((name) => !excludeTools.has(name));
|
|
109
|
+
const evaluator = new PermissionEvaluator(permissions);
|
|
110
|
+
const filtered = evaluator.filter({
|
|
111
|
+
tools: toolNames,
|
|
112
|
+
skills: this.skills
|
|
113
|
+
.filter((s) => !excludeSkills.has(s.id))
|
|
114
|
+
.map((s) => s.id),
|
|
115
|
+
mcps: this.mcps
|
|
116
|
+
.filter((m) => !excludeMcps.has(m.id))
|
|
117
|
+
.map((m) => m.id),
|
|
118
|
+
subagents: safeSubagents.map((d) => d.function.name),
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
tools: filtered.tools,
|
|
122
|
+
subagents: filtered.subagents,
|
|
123
|
+
skills: filtered.skills,
|
|
124
|
+
mcps: filtered.mcps,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 快捷方法:filter + instantiate 一步完成。
|
|
129
|
+
*/
|
|
130
|
+
buildTools(permissions, options) {
|
|
131
|
+
return this.instantiate(this.filter(permissions, options));
|
|
31
132
|
}
|
|
32
133
|
/**
|
|
33
|
-
*
|
|
34
|
-
* 首次访问时创建,后续复用同一实例。
|
|
134
|
+
* 将过滤后的名称列表实例化为 Tool 数组。
|
|
35
135
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
136
|
+
instantiate(filtered) {
|
|
137
|
+
const result = [];
|
|
138
|
+
const allowedToolNames = new Set(filtered.tools);
|
|
139
|
+
// 1. 内置 + 用户工具
|
|
140
|
+
for (const t of [...this.builtinTools, ...this.userTools]) {
|
|
141
|
+
if (allowedToolNames.has(t.function.name)) {
|
|
142
|
+
result.push(t);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// 2. 筛选候选项(保留完整信息,传给工具函数自行决定如何构建枚举)
|
|
146
|
+
const allowedSkillSet = new Set(filtered.skills);
|
|
147
|
+
const allowedMcpSet = new Set(filtered.mcps);
|
|
148
|
+
const filteredSkills = this.skills.filter((s) => allowedSkillSet.has(s.id));
|
|
149
|
+
const filteredMcps = this.mcps.filter((m) => allowedMcpSet.has(m.id));
|
|
150
|
+
// 3. 动态工具
|
|
151
|
+
if (allowedToolNames.has("load_skill") && filteredSkills.length > 0) {
|
|
152
|
+
result.push(createLoadSkillTool(this.skillsPaths, filteredSkills));
|
|
153
|
+
}
|
|
154
|
+
// call_skill_sub_agent:只要有支持子 Agent 的 skill 就注册
|
|
155
|
+
const hasSubAgentSkills = filteredSkills.some((s) => s.subAgent);
|
|
156
|
+
if (allowedToolNames.has("call_skill_sub_agent") && hasSubAgentSkills) {
|
|
157
|
+
result.push(createCallSkillSubAgentTool(this.skillsPaths, filteredSkills, this));
|
|
158
|
+
}
|
|
159
|
+
const mcpManager = this.mcpManager;
|
|
160
|
+
if (allowedToolNames.has("load_mcp") && mcpManager && filteredMcps.length > 0) {
|
|
161
|
+
result.push(createLoadMcpTool(mcpManager, filteredMcps));
|
|
162
|
+
}
|
|
163
|
+
if (allowedToolNames.has("call_mcp_tool") && mcpManager) {
|
|
164
|
+
result.push(createCallMcpTool(mcpManager));
|
|
165
|
+
}
|
|
166
|
+
if (allowedToolNames.has("read_mcp_resource") && mcpManager) {
|
|
167
|
+
result.push(createReadMcpResourceTool(mcpManager));
|
|
168
|
+
}
|
|
169
|
+
// 4. SubAgent
|
|
170
|
+
const allowedSubagentSet = new Set(filtered.subagents);
|
|
171
|
+
for (const def of this.subagents) {
|
|
172
|
+
if (!def.function || !allowedSubagentSet.has(def.function.name))
|
|
173
|
+
continue;
|
|
174
|
+
result.push(createSubAgentTool(def, this));
|
|
175
|
+
}
|
|
176
|
+
// 5. 去重
|
|
177
|
+
return dedupTools(result);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 重新执行全局发现(重新扫描文件系统)。
|
|
181
|
+
*/
|
|
182
|
+
async refresh(options) {
|
|
183
|
+
const silent = options?.silent ?? false;
|
|
184
|
+
this.builtinTools = discoverBuiltinTools(this.config);
|
|
185
|
+
this.userTools = await discoverUserTools(this.toolsPaths, { silent });
|
|
186
|
+
this.subagents = await discoverSubAgents(this.subAgentsPaths);
|
|
187
|
+
this.skills = await discoverSkills(this.skillsPaths, { silent });
|
|
188
|
+
this.mcps = await discoverMcpServers(this.mcpPaths);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function dedupTools(tools) {
|
|
192
|
+
const seen = new Set();
|
|
193
|
+
const result = [];
|
|
194
|
+
for (let i = tools.length - 1; i >= 0; i--) {
|
|
195
|
+
const name = tools[i].function.name;
|
|
196
|
+
if (!seen.has(name)) {
|
|
197
|
+
seen.add(name);
|
|
198
|
+
result.unshift(tools[i]);
|
|
39
199
|
}
|
|
40
|
-
return this._mcpManager;
|
|
41
200
|
}
|
|
201
|
+
return result;
|
|
42
202
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Agent, type ChatCompletionModel } from "@ai-zen/agents-core";
|
|
2
|
-
import type { AgentNS, Tool } from "@ai-zen/agents-core";
|
|
2
|
+
import type { AgentNS, Tool, UnknownToolContext } from "@ai-zen/agents-core";
|
|
3
3
|
import type { AgentDefinition, AgentPermissions } from "../types/index.js";
|
|
4
|
-
import type { Capabilities } from "../capabilities/Capabilities.js";
|
|
5
4
|
import type { Provider } from "./Provider.js";
|
|
6
5
|
/**
|
|
7
6
|
* Agent 插件上下文:当前 SdkAgent + 发送内容 + 消息列表。
|
|
@@ -50,7 +49,6 @@ export interface AgentPlugin {
|
|
|
50
49
|
* - provider:全局 Provider 实例
|
|
51
50
|
* - definition:Agent 原始定义
|
|
52
51
|
* - permissions:Agent 权限,供 call_skill_sub_agent 等回调读取
|
|
53
|
-
* - caps:Capabilities 全局注册表,供 refreshTools 刷新工具列表
|
|
54
52
|
*
|
|
55
53
|
* 插件能力:
|
|
56
54
|
* - use(plugin):注册插件
|
|
@@ -64,8 +62,13 @@ export declare class SdkAgent extends Agent {
|
|
|
64
62
|
readonly definition: AgentDefinition;
|
|
65
63
|
/** Agent 权限 */
|
|
66
64
|
readonly permissions?: AgentPermissions;
|
|
67
|
-
/**
|
|
68
|
-
|
|
65
|
+
/**
|
|
66
|
+
* 当 LLM 调用不存在的工具时,给出智能提示。
|
|
67
|
+
* 如果有 MCP 配置但 call_mcp_tool 不在工具列表中(权限禁用),提示权限问题;
|
|
68
|
+
* 如果有 MCP 配置且 call_mcp_tool 可用,提示使用 call_mcp_tool;
|
|
69
|
+
* 否则仅提示工具不存在。
|
|
70
|
+
*/
|
|
71
|
+
onUnknownTool: (ctx: UnknownToolContext) => string;
|
|
69
72
|
/** 已注册的插件列表 */
|
|
70
73
|
private _plugins;
|
|
71
74
|
constructor(params: {
|
|
@@ -76,7 +79,6 @@ export declare class SdkAgent extends Agent {
|
|
|
76
79
|
messages?: AgentNS.Message[];
|
|
77
80
|
tools?: Tool[];
|
|
78
81
|
permissions?: AgentPermissions;
|
|
79
|
-
caps?: Capabilities;
|
|
80
82
|
rag?: any;
|
|
81
83
|
allowJsonParseError?: boolean;
|
|
82
84
|
});
|
package/dist/runtime/SdkAgent.js
CHANGED
|
@@ -13,7 +13,6 @@ import { Agent } from "@ai-zen/agents-core";
|
|
|
13
13
|
* - provider:全局 Provider 实例
|
|
14
14
|
* - definition:Agent 原始定义
|
|
15
15
|
* - permissions:Agent 权限,供 call_skill_sub_agent 等回调读取
|
|
16
|
-
* - caps:Capabilities 全局注册表,供 refreshTools 刷新工具列表
|
|
17
16
|
*
|
|
18
17
|
* 插件能力:
|
|
19
18
|
* - use(plugin):注册插件
|
|
@@ -27,8 +26,24 @@ export class SdkAgent extends Agent {
|
|
|
27
26
|
definition;
|
|
28
27
|
/** Agent 权限 */
|
|
29
28
|
permissions;
|
|
30
|
-
/**
|
|
31
|
-
|
|
29
|
+
/**
|
|
30
|
+
* 当 LLM 调用不存在的工具时,给出智能提示。
|
|
31
|
+
* 如果有 MCP 配置但 call_mcp_tool 不在工具列表中(权限禁用),提示权限问题;
|
|
32
|
+
* 如果有 MCP 配置且 call_mcp_tool 可用,提示使用 call_mcp_tool;
|
|
33
|
+
* 否则仅提示工具不存在。
|
|
34
|
+
*/
|
|
35
|
+
onUnknownTool = (ctx) => {
|
|
36
|
+
const toolName = ctx.toolCall.function?.name ?? "未知";
|
|
37
|
+
const hasMcpConfig = this.provider.mcpPaths.length > 0;
|
|
38
|
+
const hasCallMcpTool = (this.tools ?? []).some((t) => t.function.name === "call_mcp_tool");
|
|
39
|
+
if (hasMcpConfig && !hasCallMcpTool) {
|
|
40
|
+
return `工具 "${toolName}" 不存在。当前有 MCP 服务器配置,但 call_mcp_tool 权限已被禁用,如需使用 MCP 工具请调整权限。`;
|
|
41
|
+
}
|
|
42
|
+
if (hasMcpConfig && hasCallMcpTool) {
|
|
43
|
+
return `工具 "${toolName}" 不存在。如果要调用 MCP 工具,请使用 call_mcp_tool。`;
|
|
44
|
+
}
|
|
45
|
+
return `工具 "${toolName}" 不存在。`;
|
|
46
|
+
};
|
|
32
47
|
/** 已注册的插件列表 */
|
|
33
48
|
_plugins = [];
|
|
34
49
|
constructor(params) {
|
|
@@ -43,7 +58,6 @@ export class SdkAgent extends Agent {
|
|
|
43
58
|
this.provider = params.provider;
|
|
44
59
|
this.definition = params.definition;
|
|
45
60
|
this.permissions = params.permissions;
|
|
46
|
-
this.caps = params.caps;
|
|
47
61
|
}
|
|
48
62
|
/**
|
|
49
63
|
* 注册一个插件。
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { SdkAgent } from "./SdkAgent.js";
|
|
2
2
|
import type { Provider } from "./Provider.js";
|
|
3
3
|
/**
|
|
4
|
-
* 从磁盘创建 Agent
|
|
4
|
+
* 从磁盘创建 Agent。
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* 过滤并实例化工具,产出 SdkAgent。
|
|
6
|
+
* 通过 Provider 获取已发现的能力,读取 Agent 定义,过滤并实例化工具,产出 SdkAgent。
|
|
8
7
|
*
|
|
9
8
|
* ```ts
|
|
10
|
-
* const agent = createAgent(
|
|
9
|
+
* const agent = await createAgent(provider, "my-agent");
|
|
11
10
|
* // agent 是 SdkAgent,可直接注册插件、发送消息
|
|
12
11
|
* ```
|
|
13
12
|
*/
|
|
14
|
-
export declare function createAgent(provider: Provider, agentId: string): SdkAgent
|
|
13
|
+
export declare function createAgent(provider: Provider, agentId: string): Promise<SdkAgent>;
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
import { AgentRepository } from "../crud/AgentRepository.js";
|
|
2
|
-
import { Capabilities } from "../capabilities/Capabilities.js";
|
|
3
2
|
import { SdkAgent } from "./SdkAgent.js";
|
|
4
3
|
import { createModel } from "./createModel.js";
|
|
5
4
|
/**
|
|
6
|
-
* 从磁盘创建 Agent
|
|
5
|
+
* 从磁盘创建 Agent。
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
* 过滤并实例化工具,产出 SdkAgent。
|
|
7
|
+
* 通过 Provider 获取已发现的能力,读取 Agent 定义,过滤并实例化工具,产出 SdkAgent。
|
|
10
8
|
*
|
|
11
9
|
* ```ts
|
|
12
|
-
* const agent = createAgent(
|
|
10
|
+
* const agent = await createAgent(provider, "my-agent");
|
|
13
11
|
* // agent 是 SdkAgent,可直接注册插件、发送消息
|
|
14
12
|
* ```
|
|
15
13
|
*/
|
|
16
|
-
export function createAgent(provider, agentId) {
|
|
17
|
-
const
|
|
18
|
-
const definition = new AgentRepository(provider.agentsDir).read(agentId);
|
|
14
|
+
export async function createAgent(provider, agentId) {
|
|
15
|
+
const definition = await new AgentRepository(provider.agentsDir).read(agentId);
|
|
19
16
|
if (!definition)
|
|
20
17
|
throw new Error(`Agent "${agentId}" 不存在`);
|
|
21
18
|
const modelId = definition.modelId ?? provider.config.defaultModel;
|
|
22
19
|
if (!modelId)
|
|
23
20
|
throw new Error("未指定模型且无默认模型");
|
|
24
|
-
const model = createModel(provider
|
|
25
|
-
const tools =
|
|
21
|
+
const model = createModel(provider, modelId);
|
|
22
|
+
const tools = provider.buildTools(definition.permissions ?? {}, {
|
|
26
23
|
exclude: {
|
|
27
24
|
subagents: definition.function?.name
|
|
28
25
|
? [definition.function.name]
|
|
@@ -36,20 +33,6 @@ export function createAgent(provider, agentId) {
|
|
|
36
33
|
messages: definition.messages,
|
|
37
34
|
tools,
|
|
38
35
|
permissions: definition.permissions,
|
|
39
|
-
caps,
|
|
40
36
|
});
|
|
41
|
-
// 设置 onUnknownTool 钩子:当 LLM 调用不存在的工具时,给出智能提示
|
|
42
|
-
agent.onUnknownTool = (ctx) => {
|
|
43
|
-
const toolName = ctx.toolCall.function?.name ?? "未知";
|
|
44
|
-
const hasMcpConfig = provider.mcpPaths.length > 0;
|
|
45
|
-
const hasCallMcpTool = tools.some((t) => t.function.name === "call_mcp_tool");
|
|
46
|
-
if (hasMcpConfig && !hasCallMcpTool) {
|
|
47
|
-
return `工具 "${toolName}" 不存在。当前有 MCP 服务器配置,但 call_mcp_tool 权限已被禁用,如需使用 MCP 工具请调整权限。`;
|
|
48
|
-
}
|
|
49
|
-
if (hasMcpConfig && hasCallMcpTool) {
|
|
50
|
-
return `工具 "${toolName}" 不存在。如果要调用 MCP 工具,请使用 call_mcp_tool。`;
|
|
51
|
-
}
|
|
52
|
-
return `工具 "${toolName}" 不存在。`;
|
|
53
|
-
};
|
|
54
37
|
return agent;
|
|
55
38
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { ChatCompletionModel } from "@ai-zen/agents-core";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Provider } from "./Provider.js";
|
|
3
3
|
/**
|
|
4
|
-
* 模型工厂 — 根据 modelId 和
|
|
4
|
+
* 模型工厂 — 根据 modelId 和 Provider 构建 Core ChatCompletionModel。
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* 通过 Provider 实例获取 AppConfig 后调用。
|
|
8
|
-
*
|
|
9
|
-
* 改为同步版本,使用 endpoint.chatCompletionSync() 避免不必要的 async。
|
|
6
|
+
* 同步版本,使用 endpoint.chatCompletionSync() 避免不必要的 async。
|
|
10
7
|
*/
|
|
11
|
-
export declare function createModel(
|
|
8
|
+
export declare function createModel(provider: Provider, modelId: string): ChatCompletionModel;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { OpenAI, ChatGPT } from "@ai-zen/agents-core";
|
|
2
2
|
/**
|
|
3
|
-
* 模型工厂 — 根据 modelId 和
|
|
3
|
+
* 模型工厂 — 根据 modelId 和 Provider 构建 Core ChatCompletionModel。
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* 通过 Provider 实例获取 AppConfig 后调用。
|
|
7
|
-
*
|
|
8
|
-
* 改为同步版本,使用 endpoint.chatCompletionSync() 避免不必要的 async。
|
|
5
|
+
* 同步版本,使用 endpoint.chatCompletionSync() 避免不必要的 async。
|
|
9
6
|
*/
|
|
10
|
-
export function createModel(
|
|
7
|
+
export function createModel(provider, modelId) {
|
|
8
|
+
const config = provider.config;
|
|
11
9
|
const modelConfig = config.models.find((m) => m.id === modelId);
|
|
12
10
|
if (!modelConfig)
|
|
13
11
|
throw new Error(`模型 "${modelId}" 不存在`);
|
|
@@ -14,11 +14,11 @@ export declare class EntityRepository<T extends {
|
|
|
14
14
|
/** 获取实体的文件路径 */
|
|
15
15
|
protected path(id: string): string;
|
|
16
16
|
/** 列出目录下所有实体(跳过解析失败的文件) */
|
|
17
|
-
list(): T[]
|
|
17
|
+
list(): Promise<T[]>;
|
|
18
18
|
/** 读取单个实体,不存在返回 null */
|
|
19
|
-
read(id: string): T | null
|
|
19
|
+
read(id: string): Promise<T | null>;
|
|
20
20
|
/** 写入实体(创建或更新) */
|
|
21
|
-
write(entity: T): void
|
|
21
|
+
write(entity: T): Promise<void>;
|
|
22
22
|
/** 删除实体,不存在时不抛异常 */
|
|
23
|
-
delete(id: string): void
|
|
23
|
+
delete(id: string): Promise<void>;
|
|
24
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
/**
|
|
4
4
|
* 通用实体仓储 — 对磁盘 JSON 文件的 CRUD 操作。
|
|
@@ -18,27 +18,36 @@ export class EntityRepository {
|
|
|
18
18
|
return join(this.dir, `${id}.json`);
|
|
19
19
|
}
|
|
20
20
|
/** 列出目录下所有实体(跳过解析失败的文件) */
|
|
21
|
-
list() {
|
|
22
|
-
|
|
21
|
+
async list() {
|
|
22
|
+
try {
|
|
23
|
+
await fs.access(this.dir);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
23
26
|
return [];
|
|
24
|
-
|
|
27
|
+
}
|
|
28
|
+
const entries = await fs.readdir(this.dir);
|
|
29
|
+
const ids = entries
|
|
25
30
|
.filter((f) => f.endsWith(".json"))
|
|
26
31
|
.map((f) => f.replace(/\.json$/, ""));
|
|
27
32
|
const entities = [];
|
|
28
33
|
for (const id of ids) {
|
|
29
|
-
const entity = this.read(id);
|
|
34
|
+
const entity = await this.read(id);
|
|
30
35
|
if (entity)
|
|
31
36
|
entities.push(entity);
|
|
32
37
|
}
|
|
33
38
|
return entities;
|
|
34
39
|
}
|
|
35
40
|
/** 读取单个实体,不存在返回 null */
|
|
36
|
-
read(id) {
|
|
41
|
+
async read(id) {
|
|
37
42
|
const p = this.path(id);
|
|
38
|
-
|
|
43
|
+
try {
|
|
44
|
+
await fs.access(p);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
39
47
|
return null;
|
|
48
|
+
}
|
|
40
49
|
try {
|
|
41
|
-
const raw =
|
|
50
|
+
const raw = await fs.readFile(p, "utf-8");
|
|
42
51
|
return JSON.parse(raw);
|
|
43
52
|
}
|
|
44
53
|
catch {
|
|
@@ -46,17 +55,24 @@ export class EntityRepository {
|
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
/** 写入实体(创建或更新) */
|
|
49
|
-
write(entity) {
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
async write(entity) {
|
|
59
|
+
try {
|
|
60
|
+
await fs.access(this.dir);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
await fs.mkdir(this.dir, { recursive: true });
|
|
52
64
|
}
|
|
53
|
-
|
|
65
|
+
await fs.writeFile(this.path(entity.id), JSON.stringify(entity, null, 2), "utf-8");
|
|
54
66
|
}
|
|
55
67
|
/** 删除实体,不存在时不抛异常 */
|
|
56
|
-
delete(id) {
|
|
68
|
+
async delete(id) {
|
|
57
69
|
const p = this.path(id);
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
try {
|
|
71
|
+
await fs.access(p);
|
|
72
|
+
await fs.unlink(p);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// 文件不存在,忽略
|
|
60
76
|
}
|
|
61
77
|
}
|
|
62
78
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-zen/agents-sdk",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "AI-Zen Agents SDK — shared business logic for CLI and Desktop",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
20
20
|
"dayjs": "^1.11.21",
|
|
21
|
-
"@ai-zen/agents-core": "3.0.
|
|
21
|
+
"@ai-zen/agents-core": "3.0.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^24.12.2",
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import type { Tool } from "@ai-zen/agents-core";
|
|
2
|
-
import type { AgentDefinition, AgentPermissions, McpServerConfig } from "../types/index.js";
|
|
3
|
-
import type { SkillInfo } from "./discovery/skills.js";
|
|
4
|
-
import type { Provider } from "../runtime/Provider.js";
|
|
5
|
-
/**
|
|
6
|
-
* 能力过滤系统的公共类型。
|
|
7
|
-
* FilterOutput 由 Capabilities.filter() 产出,由 Capabilities.instantiate() 消费。
|
|
8
|
-
*/
|
|
9
|
-
export interface FilterOutput {
|
|
10
|
-
tools: string[];
|
|
11
|
-
subagents: string[];
|
|
12
|
-
skills: string[];
|
|
13
|
-
mcps: string[];
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* 排除项黑名单(优先级高于 permissions)。
|
|
17
|
-
* 与 permissions 四维对称,用于安全预过滤。
|
|
18
|
-
*/
|
|
19
|
-
export interface ExcludeOptions {
|
|
20
|
-
tools?: string[];
|
|
21
|
-
skills?: string[];
|
|
22
|
-
mcps?: string[];
|
|
23
|
-
subagents?: string[];
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Capabilities — 全局能力注册表。
|
|
27
|
-
*
|
|
28
|
-
* 职责:
|
|
29
|
-
* 1. 全局发现一次(扫描文件系统,收集所有完整候选)
|
|
30
|
-
* 2. 提供 filter(permissions) 按权限过滤
|
|
31
|
-
* 3. 提供 instantiate(filterOutput) 将过滤后的名称实例化为 Tool[]
|
|
32
|
-
*
|
|
33
|
-
* 设计原则:
|
|
34
|
-
* - 发现结果全局共享,SubAgent 复用同一份候选集
|
|
35
|
-
* - filter 是纯函数(名称匹配),可被任意 Agent 独立调用
|
|
36
|
-
* - instantiate 是纯映射(名称→实例),不含业务逻辑
|
|
37
|
-
* - 通过持有的 Provider 实例获取配置、路径、模型工厂等全局服务
|
|
38
|
-
*/
|
|
39
|
-
export declare class Capabilities {
|
|
40
|
-
/** Provider 全局上下文 */
|
|
41
|
-
readonly provider: Provider;
|
|
42
|
-
builtinInstances: Tool[];
|
|
43
|
-
userInstances: Tool[];
|
|
44
|
-
subagentDefs: AgentDefinition[];
|
|
45
|
-
/** 完整 SkillInfo,含 subAgent 标记,可据此区分枚举 */
|
|
46
|
-
skills: SkillInfo[];
|
|
47
|
-
/** 完整 MCP 服务器配置 */
|
|
48
|
-
mcps: McpServerConfig[];
|
|
49
|
-
constructor(provider: Provider);
|
|
50
|
-
/**
|
|
51
|
-
* 按权限过滤候选集,返回过滤后的名称列表。
|
|
52
|
-
* 纯名称操作(安全预过滤 + 权限过滤),不涉及 Tool 实例化。
|
|
53
|
-
*/
|
|
54
|
-
filter(permissions: AgentPermissions, options?: {
|
|
55
|
-
exclude?: ExcludeOptions;
|
|
56
|
-
}): FilterOutput;
|
|
57
|
-
/**
|
|
58
|
-
* 快捷方法:filter + instantiate 一步完成。
|
|
59
|
-
*/
|
|
60
|
-
buildTools(permissions: AgentPermissions, options?: {
|
|
61
|
-
exclude?: ExcludeOptions;
|
|
62
|
-
}): Tool[];
|
|
63
|
-
/**
|
|
64
|
-
* 将过滤后的名称列表实例化为 Tool 数组。
|
|
65
|
-
*/
|
|
66
|
-
instantiate(filtered: FilterOutput): Tool[];
|
|
67
|
-
/**
|
|
68
|
-
* 重新执行全局发现(重新扫描文件系统)。
|
|
69
|
-
*/
|
|
70
|
-
refresh(options?: {
|
|
71
|
-
silent?: boolean;
|
|
72
|
-
}): void;
|
|
73
|
-
}
|