@ai-zen/agents-sdk 0.2.0-alpha.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.
Files changed (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -0
  3. package/dist/capabilities/Capabilities.d.ts +71 -0
  4. package/dist/capabilities/Capabilities.js +161 -0
  5. package/dist/capabilities/PermissionEvaluator.d.ts +19 -0
  6. package/dist/capabilities/PermissionEvaluator.js +50 -0
  7. package/dist/capabilities/disclosure.d.ts +10 -0
  8. package/dist/capabilities/disclosure.js +17 -0
  9. package/dist/capabilities/discovery/builtin.d.ts +8 -0
  10. package/dist/capabilities/discovery/builtin.js +17 -0
  11. package/dist/capabilities/discovery/mcp.d.ts +7 -0
  12. package/dist/capabilities/discovery/mcp.js +29 -0
  13. package/dist/capabilities/discovery/skills.d.ts +43 -0
  14. package/dist/capabilities/discovery/skills.js +175 -0
  15. package/dist/capabilities/discovery/subagents.d.ts +7 -0
  16. package/dist/capabilities/discovery/subagents.js +39 -0
  17. package/dist/capabilities/discovery/usertools.d.ts +13 -0
  18. package/dist/capabilities/discovery/usertools.js +136 -0
  19. package/dist/capabilities/implements/builtin/batchEdit.d.ts +2 -0
  20. package/dist/capabilities/implements/builtin/batchEdit.js +76 -0
  21. package/dist/capabilities/implements/builtin/copy.d.ts +2 -0
  22. package/dist/capabilities/implements/builtin/copy.js +38 -0
  23. package/dist/capabilities/implements/builtin/cwd.d.ts +2 -0
  24. package/dist/capabilities/implements/builtin/cwd.js +15 -0
  25. package/dist/capabilities/implements/builtin/downloadFile.d.ts +2 -0
  26. package/dist/capabilities/implements/builtin/downloadFile.js +70 -0
  27. package/dist/capabilities/implements/builtin/edit.d.ts +2 -0
  28. package/dist/capabilities/implements/builtin/edit.js +79 -0
  29. package/dist/capabilities/implements/builtin/exec.d.ts +2 -0
  30. package/dist/capabilities/implements/builtin/exec.js +31 -0
  31. package/dist/capabilities/implements/builtin/exist.d.ts +2 -0
  32. package/dist/capabilities/implements/builtin/exist.js +25 -0
  33. package/dist/capabilities/implements/builtin/findText.d.ts +2 -0
  34. package/dist/capabilities/implements/builtin/findText.js +86 -0
  35. package/dist/capabilities/implements/builtin/generateImage.d.ts +9 -0
  36. package/dist/capabilities/implements/builtin/generateImage.js +112 -0
  37. package/dist/capabilities/implements/builtin/glob.d.ts +2 -0
  38. package/dist/capabilities/implements/builtin/glob.js +45 -0
  39. package/dist/capabilities/implements/builtin/index.d.ts +19 -0
  40. package/dist/capabilities/implements/builtin/index.js +34 -0
  41. package/dist/capabilities/implements/builtin/ls.d.ts +2 -0
  42. package/dist/capabilities/implements/builtin/ls.js +28 -0
  43. package/dist/capabilities/implements/builtin/mkdir.d.ts +2 -0
  44. package/dist/capabilities/implements/builtin/mkdir.js +34 -0
  45. package/dist/capabilities/implements/builtin/readFile.d.ts +2 -0
  46. package/dist/capabilities/implements/builtin/readFile.js +31 -0
  47. package/dist/capabilities/implements/builtin/rename.d.ts +2 -0
  48. package/dist/capabilities/implements/builtin/rename.js +32 -0
  49. package/dist/capabilities/implements/builtin/rm.d.ts +2 -0
  50. package/dist/capabilities/implements/builtin/rm.js +34 -0
  51. package/dist/capabilities/implements/builtin/writeFile.d.ts +2 -0
  52. package/dist/capabilities/implements/builtin/writeFile.js +34 -0
  53. package/dist/capabilities/implements/mcpTools.d.ts +20 -0
  54. package/dist/capabilities/implements/mcpTools.js +147 -0
  55. package/dist/capabilities/implements/skillTools.d.ts +15 -0
  56. package/dist/capabilities/implements/skillTools.js +113 -0
  57. package/dist/capabilities/implements/subAgentTools.d.ts +11 -0
  58. package/dist/capabilities/implements/subAgentTools.js +53 -0
  59. package/dist/config/ConfigManager.d.ts +49 -0
  60. package/dist/config/ConfigManager.js +126 -0
  61. package/dist/config/constants.d.ts +20 -0
  62. package/dist/config/constants.js +185 -0
  63. package/dist/crud/AgentRepository.d.ts +9 -0
  64. package/dist/crud/AgentRepository.js +10 -0
  65. package/dist/crud/ConversationRepository.d.ts +9 -0
  66. package/dist/crud/ConversationRepository.js +10 -0
  67. package/dist/crud/DraftRepository.d.ts +15 -0
  68. package/dist/crud/DraftRepository.js +41 -0
  69. package/dist/index.d.ts +40 -0
  70. package/dist/index.js +37 -0
  71. package/dist/plugin/AutoDraftPlugin.d.ts +26 -0
  72. package/dist/plugin/AutoDraftPlugin.js +58 -0
  73. package/dist/plugin/AutoMigratePlugin.d.ts +25 -0
  74. package/dist/plugin/AutoMigratePlugin.js +74 -0
  75. package/dist/plugin/AutoRefreshToolsPlugin.d.ts +12 -0
  76. package/dist/plugin/AutoRefreshToolsPlugin.js +23 -0
  77. package/dist/runtime/McpConnectionManager.d.ts +42 -0
  78. package/dist/runtime/McpConnectionManager.js +238 -0
  79. package/dist/runtime/Provider.d.ts +44 -0
  80. package/dist/runtime/Provider.js +38 -0
  81. package/dist/runtime/SdkAgent.d.ts +100 -0
  82. package/dist/runtime/SdkAgent.js +103 -0
  83. package/dist/runtime/TaskMigrationService.d.ts +24 -0
  84. package/dist/runtime/TaskMigrationService.js +71 -0
  85. package/dist/runtime/createAgent.d.ts +14 -0
  86. package/dist/runtime/createAgent.js +41 -0
  87. package/dist/runtime/createModel.d.ts +11 -0
  88. package/dist/runtime/createModel.js +28 -0
  89. package/dist/shared/EntityRepository.d.ts +24 -0
  90. package/dist/shared/EntityRepository.js +62 -0
  91. package/dist/shared/errors.d.ts +8 -0
  92. package/dist/shared/errors.js +15 -0
  93. package/dist/shared/logger.d.ts +10 -0
  94. package/dist/shared/logger.js +10 -0
  95. package/dist/types/index.d.ts +178 -0
  96. package/dist/types/index.js +5 -0
  97. package/package.json +47 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 LZQCN
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @ai-zen/agents-sdk
2
+
3
+ AI-Zen SDK — 共享业务逻辑层,为 CLI 和 Desktop 提供统一的 Agent 运行时。开箱即用,包含预置厂商配置、默认 Agent 和 SubAgent。
4
+
5
+ ## 真相源
6
+
7
+ **[`docs/sdk-design.md`](./docs/sdk-design.md)** 是本包的唯一设计真相源。所有实现必须与文档一致。
8
+ ## 架构
9
+
10
+ ```
11
+ CLI ──┐
12
+ ├── @ai-zen/sdk ──┐
13
+ Desktop ──┘ │
14
+ LLM API
15
+ ```
16
+
17
+ ## 模块分层
18
+
19
+ ```
20
+ types ← 纯类型,零业务依赖
21
+ config ← 读写 config.json + 迁移 + 内存缓存 + 原子写入
22
+ crud ← 实体 CRUD(Endpoints / Models / Agents / Conversations / Draft)
23
+ capabilities ← 能力发现与装配(内置 + 用户 + MCP + Skill + SubAgent)
24
+ runtime ← Provider + 模型工厂 + Agent 组装 + MCP 连接管理 + 任务迁移
25
+ plugin ← Agent 插件(autoMigrate、autoDraft、autoRefreshTools)
26
+ shared ← 日志、错误
27
+ ```
28
+
29
+ 依赖方向:`plugin → runtime → capabilities → crud → config → types`,上层依赖下层,反之不行。
30
+
31
+ ## 核心概念
32
+
33
+ | 实体 | 说明 |
34
+ |------|------|
35
+ | **Provider** | 全局上下文,持有配置、路径、模型工厂、MCP 管理器 |
36
+ | **Capabilities** | 全局能力注册表(发现 → 过滤 → 实例化) |
37
+ | **SdkAgent** | 继承 Core Agent,携带 SDK 元数据,支持 `use()` 插件注册 |
38
+ | **AgentPlugin** | 插件接口(`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`) |
39
+ | **Endpoint** | API 端点(baseUrl + apiKey) |
40
+ | **Model** | 模型配置,绑定 Endpoint |
41
+ | **SubAgent** | 有 `function` 字段的 Agent,可被其他 Agent 作为工具调用 |
42
+ | **Conversation** | 对话记录 |
43
+ | **Draft** | 当前会话自动保存 |
44
+
45
+ ## 权限模型
46
+
47
+ 四维度各自独立,allow/deny 互斥,无命中即拒绝,权限即披露(deny 掉的项对 LLM 完全不可见)。
48
+
49
+ ```
50
+ Agent.permissions
51
+ ├── tools: { allow: string[] } | { deny: string[] }
52
+ ├── skills: { allow: string[] } | { deny: string[] }
53
+ ├── mcps: { allow: string[] } | { deny: string[] }
54
+ └── subagents: { allow: string[] } | { deny: string[] }
55
+ ```
56
+
57
+ ## 消费模式
58
+
59
+ ```typescript
60
+ const provider = new Provider({ config, ...paths });
61
+ const agent = createAgent(provider, "my-agent");
62
+ agent.use(new AutoMigratePlugin({ maxTokens, migrationAgent, onHandoff }));
63
+ agent.use(new AutoDraftPlugin({ draftsDir, agentId, modelId }));
64
+ agent.use(new AutoRefreshToolsPlugin());
65
+ await agent.init();
66
+ await agent.send("你好");
67
+ ```
68
+
69
+ ## 开发状态
70
+
71
+ | 模块 | 状态 |
72
+ |------|------|
73
+ | `types` | ✅ 已实现 — 核心实体、权限模型、MCP 类型完整 |
74
+ | `config` | ✅ 已实现 — ConfigManager + 出厂默认配置 + 一键 bootstrap |
75
+ | `crud` | ✅ 已实现 — Agent / Conversation / Draft 完整 CRUD |
76
+ | `capabilities` | ✅ 已实现 — 发现 + 权限过滤 + 安全预过滤 + 枚举披露 |
77
+ | `runtime` | ✅ 已实现 — Provider、Capabilities、createAgent、MCP 连接管理、任务迁移 |
78
+ | `plugin` | ✅ 已实现 — AutoMigratePlugin / AutoDraftPlugin / AutoRefreshToolsPlugin |
79
+ | `shared` | ✅ 已实现 — SdkError + 可注入 Logger |
80
+ | 测试 | ✅ 378 个测试,46 个文件,全通过(含真实 API 聊天 e2e) |
81
+
82
+ ## 内置插件
83
+
84
+ | 插件 | 说明 |
85
+ |------|------|
86
+ | `AutoMigratePlugin` | 上下文超限时自动触发任务迁移,生成交接文档,透明替换 Agent |
87
+ | `AutoDraftPlugin` | 每次 `send()` 后自动保存当前消息历史到 draft 文件 |
88
+ | `AutoRefreshToolsPlugin` | 每次 `send()` 前重新扫描文件系统,刷新工具列表 |
89
+
90
+ ## 设计原则
91
+
92
+ 参见项目根 [`GOAL.md`](../../GOAL.md):
93
+
94
+ 1. 逻辑自洽
95
+ 2. 设计为先,文档为准
96
+ 3. 对称、统一
97
+ 4. 去除过度设计
98
+ 5. 奥卡姆剃刀
99
+ 6. 即时重构,保持分层
100
+ 7. 测试是基石
@@ -0,0 +1,71 @@
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(): void;
71
+ }
@@ -0,0 +1,161 @@
1
+ import { PermissionEvaluator } from "./PermissionEvaluator.js";
2
+ import { createLoadSkillTool, createCallSkillSubAgentTool } from "./implements/skillTools.js";
3
+ import { createLoadMcpTool, createCallMcpTool, createReadMcpResourceTool } from "./implements/mcpTools.js";
4
+ import { createSubAgentTool } from "./implements/subAgentTools.js";
5
+ import { discoverBuiltinTools } from "./discovery/builtin.js";
6
+ import { discoverSubAgents } from "./discovery/subagents.js";
7
+ import { discoverSkills } from "./discovery/skills.js";
8
+ import { discoverMcpServers } from "./discovery/mcp.js";
9
+ import { discoverUserTools } from "./discovery/usertools.js";
10
+ /**
11
+ * Capabilities — 全局能力注册表。
12
+ *
13
+ * 职责:
14
+ * 1. 全局发现一次(扫描文件系统,收集所有完整候选)
15
+ * 2. 提供 filter(permissions) 按权限过滤
16
+ * 3. 提供 instantiate(filterOutput) 将过滤后的名称实例化为 Tool[]
17
+ *
18
+ * 设计原则:
19
+ * - 发现结果全局共享,SubAgent 复用同一份候选集
20
+ * - filter 是纯函数(名称匹配),可被任意 Agent 独立调用
21
+ * - instantiate 是纯映射(名称→实例),不含业务逻辑
22
+ * - 通过持有的 Provider 实例获取配置、路径、模型工厂等全局服务
23
+ */
24
+ export class Capabilities {
25
+ /** Provider 全局上下文 */
26
+ provider;
27
+ // ---- 全局候选集(发现一次,全局复用)----
28
+ builtinInstances;
29
+ userInstances;
30
+ subagentDefs;
31
+ /** 完整 SkillInfo,含 subAgent 标记,可据此区分枚举 */
32
+ skills;
33
+ /** 完整 MCP 服务器配置 */
34
+ mcps;
35
+ constructor(provider) {
36
+ this.provider = provider;
37
+ this.builtinInstances = discoverBuiltinTools(provider.config);
38
+ this.userInstances = discoverUserTools(provider.toolsPaths);
39
+ this.subagentDefs = discoverSubAgents(provider.subAgentsPaths);
40
+ this.skills = discoverSkills(provider.skillsPaths);
41
+ this.mcps = discoverMcpServers(provider.mcpPaths);
42
+ }
43
+ /**
44
+ * 按权限过滤候选集,返回过滤后的名称列表。
45
+ * 纯名称操作(安全预过滤 + 权限过滤),不涉及 Tool 实例化。
46
+ */
47
+ filter(permissions, options) {
48
+ const exclude = options?.exclude ?? {};
49
+ const excludeTools = new Set(exclude.tools ?? []);
50
+ const excludeSkills = new Set(exclude.skills ?? []);
51
+ const excludeMcps = new Set(exclude.mcps ?? []);
52
+ const excludeSubAgents = new Set(exclude.subagents ?? []);
53
+ const safeSubagents = excludeSubAgents.size === 0
54
+ ? this.subagentDefs
55
+ : this.subagentDefs.filter((def) => !excludeSubAgents.has(def.function?.name ?? ""));
56
+ const DYNAMIC_TOOL_NAMES = [
57
+ "load_skill",
58
+ "call_skill_sub_agent",
59
+ "load_mcp",
60
+ "call_mcp_tool",
61
+ "read_mcp_resource",
62
+ ];
63
+ const toolNames = [
64
+ ...this.builtinInstances.map((t) => t.function.name),
65
+ ...this.userInstances.map((t) => t.function.name),
66
+ ...DYNAMIC_TOOL_NAMES,
67
+ ].filter((name) => !excludeTools.has(name));
68
+ const evaluator = new PermissionEvaluator(permissions);
69
+ const filtered = evaluator.filter({
70
+ tools: toolNames,
71
+ skills: this.skills
72
+ .filter((s) => !excludeSkills.has(s.id))
73
+ .map((s) => s.id),
74
+ mcps: this.mcps
75
+ .filter((m) => !excludeMcps.has(m.id))
76
+ .map((m) => m.id),
77
+ subagents: safeSubagents.map((d) => d.function.name),
78
+ });
79
+ return {
80
+ tools: filtered.tools,
81
+ subagents: filtered.subagents,
82
+ skills: filtered.skills,
83
+ mcps: filtered.mcps,
84
+ };
85
+ }
86
+ /**
87
+ * 快捷方法:filter + instantiate 一步完成。
88
+ */
89
+ buildTools(permissions, options) {
90
+ return this.instantiate(this.filter(permissions, options));
91
+ }
92
+ /**
93
+ * 将过滤后的名称列表实例化为 Tool 数组。
94
+ */
95
+ instantiate(filtered) {
96
+ const result = [];
97
+ const allowedToolNames = new Set(filtered.tools);
98
+ const provider = this.provider;
99
+ // 1. 内置 + 用户工具
100
+ for (const t of [...this.builtinInstances, ...this.userInstances]) {
101
+ if (allowedToolNames.has(t.function.name)) {
102
+ result.push(t);
103
+ }
104
+ }
105
+ // 2. 筛选候选项(保留完整信息,传给工具函数自行决定如何构建枚举)
106
+ const allowedSkillSet = new Set(filtered.skills);
107
+ const allowedMcpSet = new Set(filtered.mcps);
108
+ const filteredSkills = this.skills.filter((s) => allowedSkillSet.has(s.id));
109
+ const filteredMcps = this.mcps.filter((m) => allowedMcpSet.has(m.id));
110
+ // 3. 动态工具
111
+ if (allowedToolNames.has("load_skill") && filteredSkills.length > 0) {
112
+ result.push(createLoadSkillTool(provider.skillsPaths, filteredSkills));
113
+ }
114
+ // call_skill_sub_agent:只要有支持子 Agent 的 skill 就注册
115
+ const hasSubAgentSkills = filteredSkills.some((s) => s.subAgent);
116
+ if (allowedToolNames.has("call_skill_sub_agent") && hasSubAgentSkills) {
117
+ result.push(createCallSkillSubAgentTool(provider.skillsPaths, filteredSkills, this));
118
+ }
119
+ if (allowedToolNames.has("load_mcp") && provider.mcpManager && provider.mcpConfigs && filteredMcps.length > 0) {
120
+ result.push(createLoadMcpTool(provider.mcpManager, provider.mcpConfigs, filteredMcps));
121
+ }
122
+ if (allowedToolNames.has("call_mcp_tool") && provider.mcpManager) {
123
+ result.push(createCallMcpTool(provider.mcpManager));
124
+ }
125
+ if (allowedToolNames.has("read_mcp_resource") && provider.mcpManager) {
126
+ result.push(createReadMcpResourceTool(provider.mcpManager));
127
+ }
128
+ // 4. SubAgent
129
+ const allowedSubagentSet = new Set(filtered.subagents);
130
+ for (const def of this.subagentDefs) {
131
+ if (!def.function || !allowedSubagentSet.has(def.function.name))
132
+ continue;
133
+ result.push(createSubAgentTool(def, this.provider, this));
134
+ }
135
+ // 5. 去重
136
+ return dedupTools(result);
137
+ }
138
+ /**
139
+ * 重新执行全局发现(重新扫描文件系统)。
140
+ */
141
+ refresh() {
142
+ const provider = this.provider;
143
+ this.builtinInstances = discoverBuiltinTools(provider.config);
144
+ this.userInstances = discoverUserTools(provider.toolsPaths);
145
+ this.subagentDefs = discoverSubAgents(provider.subAgentsPaths);
146
+ this.skills = discoverSkills(provider.skillsPaths);
147
+ this.mcps = discoverMcpServers(provider.mcpPaths);
148
+ }
149
+ }
150
+ function dedupTools(tools) {
151
+ const seen = new Set();
152
+ const result = [];
153
+ for (let i = tools.length - 1; i >= 0; i--) {
154
+ const name = tools[i].function.name;
155
+ if (!seen.has(name)) {
156
+ seen.add(name);
157
+ result.unshift(tools[i]);
158
+ }
159
+ }
160
+ return result;
161
+ }
@@ -0,0 +1,19 @@
1
+ import type { AgentPermissions, PermissionPolicy } from "../types/index.js";
2
+ export interface CandidateSets {
3
+ tools: string[];
4
+ skills: string[];
5
+ mcps: string[];
6
+ subagents: string[];
7
+ }
8
+ /**
9
+ * 权限评估器 — 按四维度权限过滤候选集。
10
+ */
11
+ export declare class PermissionEvaluator {
12
+ private permissions?;
13
+ constructor(permissions?: AgentPermissions);
14
+ filter(candidates: CandidateSets): CandidateSets;
15
+ isAllowed(name: string, dimension: keyof CandidateSets): boolean;
16
+ static match(name: string, policy: PermissionPolicy): boolean;
17
+ private filterDimension;
18
+ private validatePolicy;
19
+ }
@@ -0,0 +1,50 @@
1
+ const DENY_ALL = { deny: ["*"] };
2
+ function matchPermission(name, policy) {
3
+ if ("allow" in policy) {
4
+ return policy.allow.some((p) => p === "*" || p === name);
5
+ }
6
+ return !policy.deny.some((p) => p === "*" || p === name);
7
+ }
8
+ /**
9
+ * 权限评估器 — 按四维度权限过滤候选集。
10
+ */
11
+ export class PermissionEvaluator {
12
+ permissions;
13
+ constructor(permissions) {
14
+ this.permissions = permissions;
15
+ }
16
+ filter(candidates) {
17
+ if (!this.permissions) {
18
+ return { tools: [], skills: [], mcps: [], subagents: [] };
19
+ }
20
+ return {
21
+ tools: this.filterDimension(candidates.tools, this.permissions.tools),
22
+ skills: this.filterDimension(candidates.skills, this.permissions.skills),
23
+ mcps: this.filterDimension(candidates.mcps, this.permissions.mcps),
24
+ subagents: this.filterDimension(candidates.subagents, this.permissions.subagents),
25
+ };
26
+ }
27
+ isAllowed(name, dimension) {
28
+ if (!this.permissions)
29
+ return false;
30
+ const policy = this.permissions[dimension];
31
+ if (!policy)
32
+ return false;
33
+ return matchPermission(name, policy);
34
+ }
35
+ static match(name, policy) {
36
+ return matchPermission(name, policy);
37
+ }
38
+ filterDimension(names, policy) {
39
+ if (!policy) {
40
+ policy = DENY_ALL;
41
+ }
42
+ this.validatePolicy(policy);
43
+ return names.filter((name) => matchPermission(name, policy));
44
+ }
45
+ validatePolicy(policy) {
46
+ if ("allow" in policy && "deny" in policy) {
47
+ throw new Error("权限维度不能同时配置 allow 和 deny");
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,10 @@
1
+ export interface DisclosureParam {
2
+ type: "string";
3
+ description: string;
4
+ enum?: string[];
5
+ }
6
+ /**
7
+ * 创建 load_skill / load_mcp 的参数 schema。
8
+ * 有候选项时生成枚举,无候选项时退化为自由文本并在描述中追加提示。
9
+ */
10
+ export declare function createDisclosureParam(ids: string[], baseDescription: string, emptyHint: string): DisclosureParam;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 创建 load_skill / load_mcp 的参数 schema。
3
+ * 有候选项时生成枚举,无候选项时退化为自由文本并在描述中追加提示。
4
+ */
5
+ export function createDisclosureParam(ids, baseDescription, emptyHint) {
6
+ if (ids.length === 0) {
7
+ return {
8
+ type: "string",
9
+ description: `${baseDescription} ${emptyHint}`,
10
+ };
11
+ }
12
+ return {
13
+ type: "string",
14
+ description: baseDescription,
15
+ enum: ids,
16
+ };
17
+ }
@@ -0,0 +1,8 @@
1
+ import { Tool } from "@ai-zen/agents-core";
2
+ import type { AppConfig } from "../../types/index.js";
3
+ /**
4
+ * 发现内置工具。直接返回 BUILTIN_TOOLS 实例。
5
+ * 如果配置了 defaultImageModel,额外包含 generateImage 工具。
6
+ * 与 discoverUserTools 保持对称:都返回 Tool[]。
7
+ */
8
+ export declare function discoverBuiltinTools(config: AppConfig): Tool[];
@@ -0,0 +1,17 @@
1
+ import { BUILTIN_TOOLS } from "../implements/builtin/index.js";
2
+ import { createGenerateImageTool } from "../implements/builtin/generateImage.js";
3
+ /**
4
+ * 发现内置工具。直接返回 BUILTIN_TOOLS 实例。
5
+ * 如果配置了 defaultImageModel,额外包含 generateImage 工具。
6
+ * 与 discoverUserTools 保持对称:都返回 Tool[]。
7
+ */
8
+ export function discoverBuiltinTools(config) {
9
+ const tools = [...BUILTIN_TOOLS];
10
+ if (config.defaultImageModel) {
11
+ const existingNames = new Set(tools.map((t) => t.function.name));
12
+ if (!existingNames.has("generateImage")) {
13
+ tools.push(createGenerateImageTool(config));
14
+ }
15
+ }
16
+ return tools;
17
+ }
@@ -0,0 +1,7 @@
1
+ import type { McpServerConfig } from "../../types/index.js";
2
+ /**
3
+ * 从 mcp.json 文件列表中发现所有 MCP server 配置。
4
+ * 按优先级从高到低传入路径列表,同名 server 靠前的文件优先(先到先得)。
5
+ * 返回完整配置,不再丢失信息。
6
+ */
7
+ export declare function discoverMcpServers(paths: string[]): McpServerConfig[];
@@ -0,0 +1,29 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ /**
3
+ * 从 mcp.json 文件列表中发现所有 MCP server 配置。
4
+ * 按优先级从高到低传入路径列表,同名 server 靠前的文件优先(先到先得)。
5
+ * 返回完整配置,不再丢失信息。
6
+ */
7
+ export function discoverMcpServers(paths) {
8
+ const seen = new Set();
9
+ const items = [];
10
+ for (const path of paths) {
11
+ if (!existsSync(path))
12
+ continue;
13
+ try {
14
+ const raw = readFileSync(path, "utf-8");
15
+ const config = JSON.parse(raw);
16
+ const servers = config.servers ?? {};
17
+ for (const id of Object.keys(servers)) {
18
+ if (!seen.has(id)) {
19
+ seen.add(id);
20
+ items.push({ id, ...servers[id] });
21
+ }
22
+ }
23
+ }
24
+ catch {
25
+ // 跳过解析失败
26
+ }
27
+ }
28
+ return items;
29
+ }
@@ -0,0 +1,43 @@
1
+ export interface Frontmatter {
2
+ name?: string;
3
+ description?: string;
4
+ license?: string;
5
+ compatibility?: string;
6
+ metadata?: Record<string, string>;
7
+ allowedTools?: string[];
8
+ /** @extension Claude Code 启发:声明此 Skill 可作为子 Agent 运行 */
9
+ subAgent?: boolean;
10
+ }
11
+ export interface SkillValidationError {
12
+ skillId: string;
13
+ field: string;
14
+ message: string;
15
+ }
16
+ /** Skill 完整信息。id = 目录名 = SKILL.md 的 name 字段 */
17
+ export interface SkillInfo {
18
+ id: string;
19
+ name: string;
20
+ description: string;
21
+ subAgent: boolean;
22
+ content: string;
23
+ license?: string;
24
+ compatibility?: string;
25
+ metadata?: Record<string, string>;
26
+ allowedTools?: string[];
27
+ }
28
+ /**
29
+ * 扫描多个目录中发现的所有 Skill(含 SKILL.md 的子目录)。
30
+ * 按优先级从高到低传入路径列表,同名 skill 靠前的路径优先(先到先得)。
31
+ * 解析 YAML frontmatter 中的 name 和 description,同时校验合规。
32
+ */
33
+ export declare function discoverSkills(paths: string[]): SkillInfo[];
34
+ /**
35
+ * 读取单个 Skill 的完整内容与元数据。
36
+ * 按优先级从高到低传入路径列表,靠前的路径优先(先到先得)。
37
+ * 返回 null 如果 skill 在所有目录中都不存在或 SKILL.md 不可读。
38
+ */
39
+ export declare function readSkill(skillDirs: string[], skillId: string): SkillInfo | null;
40
+ /** @internal */
41
+ export declare function parseFrontmatter(content: string): Frontmatter;
42
+ /** @internal */
43
+ export declare function validateSkill(skillId: string, fm: Frontmatter): SkillValidationError[];