@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.
Files changed (37) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +6 -7
  3. package/dist/capabilities/discovery/mcp.d.ts +1 -1
  4. package/dist/capabilities/discovery/mcp.js +8 -4
  5. package/dist/capabilities/discovery/skills.d.ts +2 -2
  6. package/dist/capabilities/discovery/skills.js +23 -11
  7. package/dist/capabilities/discovery/subagents.d.ts +1 -1
  8. package/dist/capabilities/discovery/subagents.js +10 -5
  9. package/dist/capabilities/discovery/usertools.d.ts +5 -8
  10. package/dist/capabilities/discovery/usertools.js +42 -68
  11. package/dist/capabilities/implements/skillTools.d.ts +2 -2
  12. package/dist/capabilities/implements/skillTools.js +7 -7
  13. package/dist/capabilities/implements/subAgentTools.d.ts +1 -2
  14. package/dist/capabilities/implements/subAgentTools.js +4 -8
  15. package/dist/config/ConfigManager.d.ts +8 -8
  16. package/dist/config/ConfigManager.js +66 -35
  17. package/dist/config/constants.js +9 -3
  18. package/dist/crud/DraftRepository.d.ts +3 -3
  19. package/dist/crud/DraftRepository.js +22 -11
  20. package/dist/index.d.ts +1 -2
  21. package/dist/index.js +0 -1
  22. package/dist/plugin/AutoDraftPlugin.d.ts +1 -1
  23. package/dist/plugin/AutoDraftPlugin.js +10 -6
  24. package/dist/plugin/AutoRefreshToolsPlugin.js +2 -4
  25. package/dist/runtime/Provider.d.ts +84 -10
  26. package/dist/runtime/Provider.js +172 -12
  27. package/dist/runtime/SdkAgent.d.ts +8 -6
  28. package/dist/runtime/SdkAgent.js +18 -4
  29. package/dist/runtime/createAgent.d.ts +4 -5
  30. package/dist/runtime/createAgent.js +7 -24
  31. package/dist/runtime/createModel.d.ts +4 -7
  32. package/dist/runtime/createModel.js +4 -6
  33. package/dist/shared/EntityRepository.d.ts +4 -4
  34. package/dist/shared/EntityRepository.js +31 -15
  35. package/package.json +2 -2
  36. package/dist/capabilities/Capabilities.d.ts +0 -73
  37. package/dist/capabilities/Capabilities.js +0 -163
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.2] - 2026-07-26
4
+
5
+ ### 💥 破坏性变更
6
+
7
+ - **`EntityRepository` 所有方法改为异步** — `list()`、`read()`、`write()`、`delete()` 现在返回 `Promise`,需 `await`
8
+ - **`DraftRepository` 所有方法改为异步** — `read()`、`write()`、`delete()` 需 `await`
9
+ - **`ConfigManager` 所有方法改为异步** — `read()`、`write()`、`ensureDirs()`、`ensureDefaultAgent()`、`ensureDefaultSubAgent()`、`ensureDefaultConfig()`、`bootstrap()` 均需 `await`
10
+ - **`createAgent()` 恢复为 `async`** — 因底层仓储改为异步,`createAgent(provider, agentId)` 需 `await`
11
+ - **`AutoDraftPlugin.checkDraftForRestore()` 改为异步** — 需 `await`
12
+
13
+ ### 🎯 优化
14
+
15
+ - **全面消除同步文件 IO** — 所有生产代码中的 `existsSync`、`readFileSync`、`writeFileSync`、`readdirSync`、`mkdirSync`、`unlinkSync`、`renameSync` 全部替换为 `fs.promises` 异步 API,避免事件循环阻塞
16
+ - **`skillTools.ts` — 工具回调中的 `readdirSync` 替换为 `fs.promises.readdir`**
17
+
18
+ ### ✅ 测试
19
+
20
+ - 7 个测试文件同步更新为 `async`/`await`,测试辅助函数也使用 `fs.promises`
21
+
22
+ ## [0.3.1] - 2026-07-26
23
+
24
+ ### 💥 破坏性变更
25
+
26
+ - **`Provider` 移至 `runtime`,合并 `Capabilities`** — 删除 `capabilities/Capabilities.ts` 和原 `runtime/Provider.ts`,Provider 直接暴露 `filter()`、`buildTools()`、`instantiate()`、`refresh()`
27
+ - **去除 `getMcpManager()` 方法** — `mcpManager` 从 lazy getter 改为构造时直接 `new McpConnectionManager()`(有 mcpPaths 时),`readonly` 属性
28
+ - **字段重命名** — `builtinInstances` → `builtinTools`,`userInstances` → `userTools`,`subagentDefs` → `subagents`
29
+ - **`createModel` 签名变更** — 从 `createModel(config, modelId)` 改为 `createModel(provider, modelId)`,调用方不再需要 `.config` 解构
30
+ - **`SdkAgent` 去掉 `caps` 字段** — 只保留 `provider`
31
+
32
+ ### 🚀 新功能
33
+
34
+ - **用户工具 ESM 支持** — 移除 `node:vm` 沙箱,统一使用 `import()` 加载 `.js` / `.mjs` 文件,每次 `refresh()` 加时间戳 querystring 防止缓存
35
+ - **`CallbackTool` 替代 `createToolFromObject`** — `{ function, exec }` 格式直接映射为 `CallbackTool`
36
+
37
+ ### 🎯 优化
38
+
39
+ - **默认 Agent 系统提示词更新** — 精简为五条原则:开动脑筋、实事求是、一切行动听指挥、安全第一、能打胜仗
40
+ - **默认 SubAgent `function.description` 优化** — 强调主 Agent 必须提供完整任务上下文
41
+
42
+ ### 🗑 移除
43
+
44
+ - 删除 `capabilities/Provider.ts`(已移回 `runtime/Provider.ts`)
45
+ - 删除 `createToolFromObject` 工具函数
46
+ - 删除 `TODO.md`、`TODO2.md`
47
+ - 测试 fixture 从 `.js` 迁移为 `.mjs`
48
+
3
49
  ## [0.2.6] - 2026-07-20
4
50
 
5
51
  ### 🔧 修复
package/README.md CHANGED
@@ -9,9 +9,9 @@ AI-Zen SDK — 共享业务逻辑层,为 CLI 和 Desktop 提供统一的 Agent
9
9
 
10
10
  ```
11
11
  CLI ──┐
12
- ├── @ai-zen/sdk ──┐
13
- Desktop ──┘ │
14
- LLM API
12
+ ├── @ai-zen/agents-sdk ──┐
13
+ Desktop ──┘ │
14
+ LLM API
15
15
  ```
16
16
 
17
17
  ## 模块分层
@@ -32,8 +32,7 @@ shared ← 日志、错误
32
32
 
33
33
  | 实体 | 说明 |
34
34
  |------|------|
35
- | **Provider** | 全局上下文,持有配置、路径、模型工厂、MCP 管理器 |
36
- | **Capabilities** | 全局能力注册表(发现 → 过滤 → 实例化) |
35
+ | **Provider** | 全局上下文 + 能力注册表,持有配置、路径、模型工厂、MCP 管理器,整合发现 → 过滤 → 实例化 |
37
36
  | **SdkAgent** | 继承 Core Agent,携带 SDK 元数据,支持 `use()` 插件注册 |
38
37
  | **AgentPlugin** | 插件接口(`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`) |
39
38
  | **Endpoint** | API 端点(baseUrl + apiKey) |
@@ -57,7 +56,7 @@ Agent.permissions
57
56
  ## 消费模式
58
57
 
59
58
  ```typescript
60
- const provider = new Provider({ config, ...paths });
59
+ const provider = await Provider.create({ config, ...paths });
61
60
  const agent = createAgent(provider, "my-agent");
62
61
  agent.use(new AutoMigratePlugin({ maxTokens, migrationAgent, onHandoff }));
63
62
  agent.use(new AutoDraftPlugin({ draftsDir, agentId, modelId }));
@@ -77,7 +76,7 @@ await agent.send("你好");
77
76
  | `runtime` | ✅ 已实现 — Provider、Capabilities、createAgent、MCP 连接管理、任务迁移 |
78
77
  | `plugin` | ✅ 已实现 — AutoMigratePlugin / AutoDraftPlugin / AutoRefreshToolsPlugin |
79
78
  | `shared` | ✅ 已实现 — SdkError + 可注入 Logger |
80
- | 测试 | ✅ 359 个测试,45 个文件,全通过(含真实 API 聊天 e2e) |
79
+ | 测试 | ✅ 593 个测试,68 个文件,全通过(含真实 API 聊天 e2e) |
81
80
 
82
81
  ## 内置工具
83
82
 
@@ -9,4 +9,4 @@ import type { McpServerConfig } from "../../types/index.js";
9
9
  *
10
10
  * 按优先级从高到低传入路径列表,同名 server 靠前的文件优先(先到先得)。
11
11
  */
12
- export declare function discoverMcpServers(paths: string[]): McpServerConfig[];
12
+ export declare function discoverMcpServers(paths: string[]): Promise<McpServerConfig[]>;
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from "node:fs";
1
+ import { promises as fs } from "node:fs";
2
2
  /**
3
3
  * 归一化原始 MCP server 配置为内部 McpServerConfig。
4
4
  * 处理业界标准中的字段别名差异。
@@ -51,14 +51,18 @@ function normalizeTransport(type, raw) {
51
51
  *
52
52
  * 按优先级从高到低传入路径列表,同名 server 靠前的文件优先(先到先得)。
53
53
  */
54
- export function discoverMcpServers(paths) {
54
+ export async function discoverMcpServers(paths) {
55
55
  const seen = new Set();
56
56
  const items = [];
57
57
  for (const path of paths) {
58
- if (!existsSync(path))
58
+ try {
59
+ await fs.access(path);
60
+ }
61
+ catch {
59
62
  continue;
63
+ }
60
64
  try {
61
- const raw = readFileSync(path, "utf-8");
65
+ const raw = await fs.readFile(path, "utf-8");
62
66
  const config = JSON.parse(raw);
63
67
  // 业界标准使用 mcpServers 顶层字段
64
68
  const servers = config.mcpServers ?? {};
@@ -34,7 +34,7 @@ export interface SkillInfo {
34
34
  */
35
35
  export declare function discoverSkills(paths: string[], options?: {
36
36
  silent?: boolean;
37
- }): SkillInfo[];
37
+ }): Promise<SkillInfo[]>;
38
38
  /**
39
39
  * 读取单个 Skill 的完整内容与元数据。
40
40
  * 按优先级从高到低传入路径列表,靠前的路径优先(先到先得)。
@@ -42,7 +42,7 @@ export declare function discoverSkills(paths: string[], options?: {
42
42
  */
43
43
  export declare function readSkill(skillDirs: string[], skillId: string, options?: {
44
44
  silent?: boolean;
45
- }): SkillInfo | null;
45
+ }): Promise<SkillInfo | null>;
46
46
  /** @internal */
47
47
  export declare function parseFrontmatter(content: string): Frontmatter;
48
48
  /** @internal */
@@ -1,4 +1,4 @@
1
- import { readdirSync, existsSync, readFileSync } from "node:fs";
1
+ import { promises as fs } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { createLogger } from "../../shared/logger.js";
4
4
  const log = createLogger();
@@ -8,16 +8,20 @@ const log = createLogger();
8
8
  * 按优先级从高到低传入路径列表,同名 skill 靠前的路径优先(先到先得)。
9
9
  * 解析 YAML frontmatter 中的 name 和 description,同时校验合规。
10
10
  */
11
- export function discoverSkills(paths, options) {
11
+ export async function discoverSkills(paths, options) {
12
12
  const silent = options?.silent ?? false;
13
13
  const seen = new Set();
14
14
  const items = [];
15
15
  for (const dir of paths) {
16
- if (!existsSync(dir))
16
+ try {
17
+ await fs.access(dir);
18
+ }
19
+ catch {
17
20
  continue;
21
+ }
18
22
  let entries;
19
23
  try {
20
- entries = readdirSync(dir, { withFileTypes: true });
24
+ entries = await fs.readdir(dir, { withFileTypes: true });
21
25
  }
22
26
  catch {
23
27
  continue;
@@ -28,9 +32,13 @@ export function discoverSkills(paths, options) {
28
32
  if (seen.has(entry.name))
29
33
  continue;
30
34
  const skillMdPath = join(dir, entry.name, "SKILL.md");
31
- if (!existsSync(skillMdPath))
35
+ try {
36
+ await fs.access(skillMdPath);
37
+ }
38
+ catch {
32
39
  continue;
33
- const skill = readSkillFromPath(entry.name, skillMdPath, silent);
40
+ }
41
+ const skill = await readSkillFromPath(entry.name, skillMdPath, silent);
34
42
  if (skill) {
35
43
  seen.add(entry.name);
36
44
  items.push(skill);
@@ -45,20 +53,24 @@ export function discoverSkills(paths, options) {
45
53
  * 按优先级从高到低传入路径列表,靠前的路径优先(先到先得)。
46
54
  * 返回 null 如果 skill 在所有目录中都不存在或 SKILL.md 不可读。
47
55
  */
48
- export function readSkill(skillDirs, skillId, options) {
56
+ export async function readSkill(skillDirs, skillId, options) {
49
57
  const silent = options?.silent ?? false;
50
58
  for (const dir of skillDirs) {
51
59
  const candidate = join(dir, skillId, "SKILL.md");
52
- if (existsSync(candidate)) {
53
- return readSkillFromPath(skillId, candidate, silent);
60
+ try {
61
+ await fs.access(candidate);
62
+ return await readSkillFromPath(skillId, candidate, silent);
63
+ }
64
+ catch {
65
+ continue;
54
66
  }
55
67
  }
56
68
  return null;
57
69
  }
58
70
  // ---- 内部 ----
59
- function readSkillFromPath(skillId, skillMdPath, silent) {
71
+ async function readSkillFromPath(skillId, skillMdPath, silent) {
60
72
  try {
61
- const content = readFileSync(skillMdPath, "utf-8");
73
+ const content = await fs.readFile(skillMdPath, "utf-8");
62
74
  const fm = parseFrontmatter(content);
63
75
  if (!fm.name)
64
76
  return null;
@@ -4,4 +4,4 @@ import type { AgentDefinition } from "../../types/index.js";
4
4
  * 按优先级从高到低传入路径列表,同名 function.name 靠前的路径优先(先到先得)。
5
5
  * 跳过无 function 的普通 Agent 和解析失败的文件。
6
6
  */
7
- export declare function discoverSubAgents(paths: string[]): AgentDefinition[];
7
+ export declare function discoverSubAgents(paths: string[]): Promise<AgentDefinition[]>;
@@ -1,26 +1,31 @@
1
- import { readdirSync, existsSync, readFileSync } from "node:fs";
1
+ import { promises as fs } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  /**
4
4
  * 扫描多个目录中发现的所有 SubAgent 完整定义。
5
5
  * 按优先级从高到低传入路径列表,同名 function.name 靠前的路径优先(先到先得)。
6
6
  * 跳过无 function 的普通 Agent 和解析失败的文件。
7
7
  */
8
- export function discoverSubAgents(paths) {
8
+ export async function discoverSubAgents(paths) {
9
9
  const seen = new Set();
10
10
  const agents = [];
11
11
  for (const dir of paths) {
12
- if (!existsSync(dir))
12
+ try {
13
+ await fs.access(dir);
14
+ }
15
+ catch {
13
16
  continue;
17
+ }
14
18
  let files;
15
19
  try {
16
- files = readdirSync(dir).filter((f) => f.endsWith(".json"));
20
+ const allFiles = await fs.readdir(dir);
21
+ files = allFiles.filter((f) => f.endsWith(".json"));
17
22
  }
18
23
  catch {
19
24
  continue;
20
25
  }
21
26
  for (const file of files) {
22
27
  try {
23
- const raw = readFileSync(join(dir, file), "utf-8");
28
+ const raw = await fs.readFile(join(dir, file), "utf-8");
24
29
  const def = JSON.parse(raw);
25
30
  if (def.function) {
26
31
  const funcName = def.function.name;
@@ -1,15 +1,12 @@
1
1
  import { Tool } from "@ai-zen/agents-core";
2
2
  /**
3
- * 扫描多个 tools/ 目录,发现所有 .js 文件,动态加载为 Tool 实例。
3
+ * 扫描多个 tools/ 目录,发现所有 .js / .mjs 文件,动态加载为 Tool 实例。
4
+ * 使用原生 dynamic import() 加载(在 "type": "module" 下 .js 也是 ESM),
5
+ * 每次添加时间戳 querystring 防止缓存。
6
+ *
4
7
  * 按优先级从高到低传入路径列表,同名工具靠前的路径优先(先到先得)。
5
8
  * 按文件名排序以保证确定性。
6
- *
7
- * 加载方式:
8
- * 1. 使用 vm.compileFunction 创建安全的执行上下文
9
- * 2. 工具文件应通过 module.exports 或 exports.default 导出 Tool 实例
10
- * 3. 支持直接导出 { function, exec } 格式的对象(自动适配为 Tool)
11
- * 4. 支持导出 CallbackTool 兼容的 { function, callback } 格式
12
9
  */
13
10
  export declare function discoverUserTools(paths: string[], options?: {
14
11
  silent?: boolean;
15
- }): Tool[];
12
+ }): Promise<Tool[]>;
@@ -1,35 +1,40 @@
1
- import { readdirSync, existsSync, readFileSync } from "node:fs";
1
+ import { promises as fs } from "node:fs";
2
2
  import { join } from "node:path";
3
- import vm from "node:vm";
3
+ import { pathToFileURL } from "node:url";
4
4
  import { Tool, CallbackTool } from "@ai-zen/agents-core";
5
5
  /**
6
- * 扫描多个 tools/ 目录,发现所有 .js 文件,动态加载为 Tool 实例。
6
+ * 扫描多个 tools/ 目录,发现所有 .js / .mjs 文件,动态加载为 Tool 实例。
7
+ * 使用原生 dynamic import() 加载(在 "type": "module" 下 .js 也是 ESM),
8
+ * 每次添加时间戳 querystring 防止缓存。
9
+ *
7
10
  * 按优先级从高到低传入路径列表,同名工具靠前的路径优先(先到先得)。
8
11
  * 按文件名排序以保证确定性。
9
- *
10
- * 加载方式:
11
- * 1. 使用 vm.compileFunction 创建安全的执行上下文
12
- * 2. 工具文件应通过 module.exports 或 exports.default 导出 Tool 实例
13
- * 3. 支持直接导出 { function, exec } 格式的对象(自动适配为 Tool)
14
- * 4. 支持导出 CallbackTool 兼容的 { function, callback } 格式
15
12
  */
16
- export function discoverUserTools(paths, options) {
13
+ export async function discoverUserTools(paths, options) {
17
14
  const silent = options?.silent ?? false;
18
15
  const seen = new Set();
19
16
  const tools = [];
20
17
  for (const dir of paths) {
21
- if (!existsSync(dir))
18
+ try {
19
+ await fs.access(dir);
20
+ }
21
+ catch {
22
22
  continue;
23
+ }
23
24
  try {
24
- const files = readdirSync(dir)
25
- .filter((f) => f.endsWith(".js"))
26
- .map((f) => f.slice(0, -3))
27
- .sort();
28
- for (const name of files) {
25
+ const allFiles = await fs.readdir(dir);
26
+ const files = allFiles
27
+ .filter((f) => f.endsWith(".js") || f.endsWith(".mjs"))
28
+ .map((f) => {
29
+ const ext = f.endsWith(".mjs") ? ".mjs" : ".js";
30
+ return { name: f.slice(0, -ext.length), ext };
31
+ })
32
+ .sort((a, b) => a.name.localeCompare(b.name));
33
+ for (const { name, ext } of files) {
29
34
  if (!seen.has(name)) {
30
35
  seen.add(name);
31
36
  try {
32
- const tool = loadToolFile(join(dir, name + ".js"), silent);
37
+ const tool = await loadToolFile(join(dir, name + ext), silent);
33
38
  if (tool) {
34
39
  tools.push(tool);
35
40
  }
@@ -46,45 +51,25 @@ export function discoverUserTools(paths, options) {
46
51
  }
47
52
  return tools;
48
53
  }
54
+ // ==================================================================
55
+ // ESM 加载(import())
56
+ // ==================================================================
49
57
  /**
50
- * 从 .js 文件加载 Tool 实例。
58
+ * 从 .js / .mjs 文件加载 Tool 实例。
51
59
  *
52
- * 使用 vm.compileFunction 创建沙箱执行环境,避免污染全局作用域。
53
- * 注入有限的全局 API(console, setTimeout 等),不暴露 process/require。
60
+ * 使用原生 dynamic import() 加载 ESM 模块。每次调用添加时间戳 querystring
61
+ * 防止模块缓存,确保 refresh() 能重新加载。
54
62
  */
55
- function loadToolFile(filepath, silent) {
56
- const code = readFileSync(filepath, "utf-8");
57
- // 构造沙箱上下文
58
- const sandbox = {
59
- // 有限全局 API
60
- console: console,
61
- setTimeout: setTimeout,
62
- clearTimeout: clearTimeout,
63
- setInterval: setInterval,
64
- clearInterval: clearInterval,
65
- Buffer: Buffer,
66
- URL: URL,
67
- URLSearchParams: URLSearchParams,
68
- TextEncoder: TextEncoder,
69
- TextDecoder: TextDecoder,
70
- // 导出的结果存放处
71
- module: { exports: {} },
72
- exports: {},
73
- };
74
- sandbox.global = sandbox;
75
- sandbox.globalThis = sandbox;
76
- const context = vm.createContext(sandbox);
77
- const script = new vm.Script(code, { filename: filepath });
63
+ async function loadToolFile(filepath, silent) {
78
64
  try {
79
- script.runInContext(context, { timeout: 5000 });
80
- // 获取导出结果
81
- const exported = sandbox.module.exports ?? sandbox.exports;
82
- // 空导出
65
+ const url = `${pathToFileURL(filepath).href}?t=${Date.now()}`;
66
+ const mod = await import(url);
67
+ // import() 返回模块命名空间对象,取其 default 导出
68
+ const exported = mod.default ?? mod;
83
69
  if (!exported || (typeof exported === "object" && Object.keys(exported).length === 0)) {
84
70
  return null;
85
71
  }
86
- // 适配不同导出格式
87
- return normalizeToolExport(exported, filepath, silent);
72
+ return normalizeToolExport({ default: exported }, filepath, silent);
88
73
  }
89
74
  catch (err) {
90
75
  if (!silent) {
@@ -93,6 +78,9 @@ function loadToolFile(filepath, silent) {
93
78
  return null;
94
79
  }
95
80
  }
81
+ // ==================================================================
82
+ // 导出格式归一化
83
+ // ==================================================================
96
84
  /**
97
85
  * 统一各种导出格式为 Tool 实例。
98
86
  */
@@ -106,9 +94,12 @@ function normalizeToolExport(exported, filepath, silent) {
106
94
  if (target instanceof Tool) {
107
95
  return target;
108
96
  }
109
- // 情况 3:{ function, exec } 格式 → 适配为 Tool 子类
97
+ // 情况 3:{ function, exec } 格式 → 适配为 CallbackTool
110
98
  if (target && typeof target === "object" && target.function && typeof target.exec === "function") {
111
- return createToolFromObject(target, filepath);
99
+ return new CallbackTool({
100
+ function: target.function,
101
+ callback: target.exec,
102
+ });
112
103
  }
113
104
  // 情况 4:{ function, callback } 格式 → 适配为 CallbackTool
114
105
  if (target && typeof target === "object" && target.function && typeof target.callback === "function") {
@@ -122,20 +113,3 @@ function normalizeToolExport(exported, filepath, silent) {
122
113
  }
123
114
  return null;
124
115
  }
125
- /**
126
- * 将 { function, exec } 对象适配为 Tool 子类实例。
127
- */
128
- function createToolFromObject(obj, filepath) {
129
- return new (class extends Tool {
130
- constructor() {
131
- super({ function: obj.function });
132
- }
133
- async exec(ctx) {
134
- const result = await obj.exec.call(ctx, ctx.parsed_args);
135
- if (typeof result !== "string") {
136
- return JSON.stringify(result) ?? "";
137
- }
138
- return result;
139
- }
140
- })();
141
- }
@@ -1,6 +1,6 @@
1
1
  import { CallbackTool } from "@ai-zen/agents-core";
2
2
  import type { SkillInfo } from "../discovery/skills.js";
3
- import type { Capabilities } from "../Capabilities.js";
3
+ import type { Provider } from "../../runtime/Provider.js";
4
4
  /**
5
5
  * 创建 load_skill 工具。
6
6
  * 枚举所有允许的 skill(不限是否支持子 Agent),由 filteredSkills 提供完整信息。
@@ -12,4 +12,4 @@ export declare function createLoadSkillTool(skillDirs: string[], filteredSkills:
12
12
  *
13
13
  * 回调中创建独立的 Skill 子 Agent,通过 caps 按父 Agent 权限独立解析工具集。
14
14
  */
15
- export declare function createCallSkillSubAgentTool(skillDirs: string[], filteredSkills: SkillInfo[], caps?: Capabilities): CallbackTool;
15
+ export declare function createCallSkillSubAgentTool(skillDirs: string[], filteredSkills: SkillInfo[], provider?: Provider): CallbackTool;
@@ -3,7 +3,7 @@ import { SdkAgent } from "../../runtime/SdkAgent.js";
3
3
  import { createDisclosureParam } from "../disclosure.js";
4
4
  import { readSkill } from "../discovery/skills.js";
5
5
  import { createLogger } from "../../shared/logger.js";
6
- import { readdirSync } from "node:fs";
6
+ import { promises as fs } from "node:fs";
7
7
  const log = createLogger();
8
8
  const EMPTY_HINT = "(当前没有可用的 Skill,请联系用户添加)";
9
9
  /**
@@ -37,14 +37,14 @@ export function createLoadSkillTool(skillDirs, filteredSkills) {
37
37
  },
38
38
  callback: async function (input) {
39
39
  const skillId = input.skill_id;
40
- const skill = readSkill(skillDirs, skillId);
40
+ const skill = await readSkill(skillDirs, skillId);
41
41
  if (!skill) {
42
42
  return `❌ Skill "${skillId}" 不存在,请确认名称是否正确`;
43
43
  }
44
44
  // 扫描 skill 目录下的文件列表
45
45
  let fileList = "";
46
46
  try {
47
- const entries = readdirSync(skill.dirPath, { withFileTypes: true });
47
+ const entries = await fs.readdir(skill.dirPath, { withFileTypes: true });
48
48
  const files = entries.map((e) => {
49
49
  const suffix = e.isDirectory() ? "/" : "";
50
50
  return ` - ${e.name}${suffix}`;
@@ -72,7 +72,7 @@ export function createLoadSkillTool(skillDirs, filteredSkills) {
72
72
  *
73
73
  * 回调中创建独立的 Skill 子 Agent,通过 caps 按父 Agent 权限独立解析工具集。
74
74
  */
75
- export function createCallSkillSubAgentTool(skillDirs, filteredSkills, caps) {
75
+ export function createCallSkillSubAgentTool(skillDirs, filteredSkills, provider) {
76
76
  // 只保留支持子 Agent 模式的 skill
77
77
  const subAgentSkills = filteredSkills.filter((s) => s.subAgent);
78
78
  const ids = subAgentSkills.map((s) => s.id);
@@ -106,7 +106,7 @@ export function createCallSkillSubAgentTool(skillDirs, filteredSkills, caps) {
106
106
  async callback(input) {
107
107
  const skillId = input.skill_id;
108
108
  const task = input.task;
109
- const skill = readSkill(skillDirs, skillId);
109
+ const skill = await readSkill(skillDirs, skillId);
110
110
  if (!skill) {
111
111
  return `❌ Skill "${skillId}" 不存在,请确认名称是否正确`;
112
112
  }
@@ -117,8 +117,8 @@ export function createCallSkillSubAgentTool(skillDirs, filteredSkills, caps) {
117
117
  const parentPermissions = parentAgent instanceof SdkAgent
118
118
  ? parentAgent.permissions
119
119
  : undefined;
120
- const skillTools = caps && parentPermissions
121
- ? caps.buildTools(parentPermissions, {
120
+ const skillTools = provider && parentPermissions
121
+ ? provider.buildTools(parentPermissions, {
122
122
  exclude: { skills: [skillId] },
123
123
  })
124
124
  : [];
@@ -1,11 +1,10 @@
1
1
  import type { Tool } from "@ai-zen/agents-core";
2
2
  import type { AgentDefinition } from "../../types/index.js";
3
3
  import type { Provider } from "../../runtime/Provider.js";
4
- import type { Capabilities } from "../Capabilities.js";
5
4
  /**
6
5
  * 创建 SubAgent 工具(AgentToolLazy)。
7
6
  *
8
7
  * SubAgent 是有 `function` 字段的 Agent,可被其他 Agent 作为工具调用。
9
8
  * 使用延迟构建(AgentToolLazy)避免工具列表构建阶段的递归创建问题。
10
9
  */
11
- export declare function createSubAgentTool(def: AgentDefinition, provider: Provider, caps?: Capabilities): Tool;
10
+ export declare function createSubAgentTool(def: AgentDefinition, provider: Provider): Tool;
@@ -6,7 +6,7 @@ import { createModel } from "../../runtime/createModel.js";
6
6
  * SubAgent 是有 `function` 字段的 Agent,可被其他 Agent 作为工具调用。
7
7
  * 使用延迟构建(AgentToolLazy)避免工具列表构建阶段的递归创建问题。
8
8
  */
9
- export function createSubAgentTool(def, provider, caps) {
9
+ export function createSubAgentTool(def, provider) {
10
10
  if (!def.function) {
11
11
  throw new Error(`Agent "${def.id}" 没有 function 字段,不能作为 SubAgent 工具`);
12
12
  }
@@ -19,14 +19,10 @@ export function createSubAgentTool(def, provider, caps) {
19
19
  },
20
20
  messages: def.messages,
21
21
  buildAgent: function (_parsedArgs) {
22
- if (!caps) {
23
- throw new Error(`SubAgent "${selfName}" 缺少 Capabilities 引用。` +
24
- `请确保 Capabilities.instantiate() 传入了 caps(this)。`);
25
- }
26
22
  // 模型解析:SubAgent 可指定独立模型,否则复用父 Agent 的模型
27
23
  let subModel;
28
24
  if (def.modelId) {
29
- subModel = createModel(provider.config, def.modelId);
25
+ subModel = createModel(provider, def.modelId);
30
26
  }
31
27
  else {
32
28
  const parentModel = this.agent?.model;
@@ -36,12 +32,12 @@ export function createSubAgentTool(def, provider, caps) {
36
32
  subModel = parentModel;
37
33
  }
38
34
  // SubAgent 独立解析自己的工具(排除自身,防止递归)
39
- const subFiltered = caps.filter(def.permissions ?? {}, {
35
+ const subFiltered = provider.filter(def.permissions ?? {}, {
40
36
  exclude: {
41
37
  subagents: def.function?.name ? [def.function.name] : undefined,
42
38
  },
43
39
  });
44
- const tools = caps.instantiate(subFiltered);
40
+ const tools = provider.instantiate(subFiltered);
45
41
  const subAgent = new Agent({
46
42
  model: subModel,
47
43
  tools,
@@ -9,17 +9,17 @@ export declare class ConfigManager {
9
9
  /**
10
10
  * 读取配置。文件不存在时返回出厂默认配置。
11
11
  */
12
- read(): AppConfig;
13
- write(config: AppConfig): void;
12
+ read(): Promise<AppConfig>;
13
+ write(config: AppConfig): Promise<void>;
14
14
  /**
15
15
  * 确保基础目录结构存在。
16
16
  * 创建 basePath 及所有标准共享子目录(agents/、sub-agents/、skills/ 等)。
17
17
  */
18
- ensureDirs(): void;
18
+ ensureDirs(): Promise<void>;
19
19
  /**
20
20
  * 确保 config.json 存在。不存在时写入出厂默认配置 DSL。
21
21
  */
22
- ensureDefaultConfig(): AppConfig;
22
+ ensureDefaultConfig(): Promise<AppConfig>;
23
23
  /**
24
24
  * 确保 basePath/agents/default.json 存在。
25
25
  *
@@ -27,7 +27,7 @@ export declare class ConfigManager {
27
27
  * - agents/ 为空 → 写入默认 Agent
28
28
  * - 已有其他 Agent → 返回 null
29
29
  */
30
- ensureDefaultAgent(): AgentDefinition | null;
30
+ ensureDefaultAgent(): Promise<AgentDefinition | null>;
31
31
  /**
32
32
  * 确保 basePath/sub-agents/{DEFAULT_SUBAGENT_ID}.json 存在。
33
33
  *
@@ -35,15 +35,15 @@ export declare class ConfigManager {
35
35
  * - sub-agents/ 为空 → 写入默认通用助手 SubAgent
36
36
  * - 已有其他 SubAgent → 返回 null
37
37
  */
38
- ensureDefaultSubAgent(): AgentDefinition | null;
38
+ ensureDefaultSubAgent(): Promise<AgentDefinition | null>;
39
39
  /**
40
40
  * 一键初始化:目录 + config.json + 默认 Agent + 默认 SubAgent。
41
41
  * 已有文件不会被覆盖。
42
42
  */
43
- bootstrap(): {
43
+ bootstrap(): Promise<{
44
44
  config: AppConfig;
45
45
  agent: AgentDefinition | null;
46
46
  subAgent: AgentDefinition | null;
47
- };
47
+ }>;
48
48
  }
49
49
  export { DEFAULT_AGENT_ID, DEFAULT_AGENT_DEFINITION, DEFAULT_SUBAGENT_ID, DEFAULT_SUBAGENT_DEFINITION, DEFAULT_APP_CONFIG, CONFIG_SUB_DIRS, } from "./constants.js";