@ai-zen/agents-sdk 0.2.8 → 0.3.1

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 CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.1] - 2026-07-26
4
+
5
+ ### 💥 破坏性变更
6
+
7
+ - **`Provider` 移至 `runtime`,合并 `Capabilities`** — 删除 `capabilities/Capabilities.ts` 和原 `runtime/Provider.ts`,Provider 直接暴露 `filter()`、`buildTools()`、`instantiate()`、`refresh()`
8
+ - **去除 `getMcpManager()` 方法** — `mcpManager` 从 lazy getter 改为构造时直接 `new McpConnectionManager()`(有 mcpPaths 时),`readonly` 属性
9
+ - **字段重命名** — `builtinInstances` → `builtinTools`,`userInstances` → `userTools`,`subagentDefs` → `subagents`
10
+ - **`createModel` 签名变更** — 从 `createModel(config, modelId)` 改为 `createModel(provider, modelId)`,调用方不再需要 `.config` 解构
11
+ - **`SdkAgent` 去掉 `caps` 字段** — 只保留 `provider`
12
+
13
+ ### 🚀 新功能
14
+
15
+ - **用户工具 ESM 支持** — 移除 `node:vm` 沙箱,统一使用 `import()` 加载 `.js` / `.mjs` 文件,每次 `refresh()` 加时间戳 querystring 防止缓存
16
+ - **`CallbackTool` 替代 `createToolFromObject`** — `{ function, exec }` 格式直接映射为 `CallbackTool`
17
+
18
+ ### 🎯 优化
19
+
20
+ - **默认 Agent 系统提示词更新** — 精简为五条原则:开动脑筋、实事求是、一切行动听指挥、安全第一、能打胜仗
21
+ - **默认 SubAgent `function.description` 优化** — 强调主 Agent 必须提供完整任务上下文
22
+
23
+ ### 🗑 移除
24
+
25
+ - 删除 `capabilities/Provider.ts`(已移回 `runtime/Provider.ts`)
26
+ - 删除 `createToolFromObject` 工具函数
27
+ - 删除 `TODO.md`、`TODO2.md`
28
+ - 测试 fixture 从 `.js` 迁移为 `.mjs`
29
+
3
30
  ## [0.2.6] - 2026-07-20
4
31
 
5
32
  ### 🔧 修复
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;
@@ -37,7 +37,7 @@ 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
  }
@@ -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,
@@ -12,7 +12,13 @@ export const DEFAULT_AGENT_DEFINITION = {
12
12
  messages: [
13
13
  {
14
14
  role: AgentNS.Role.System,
15
- content: "你是一个AI助手,专门帮助用户回答问题和执行任务。请用中文回复。",
15
+ content: `你是一个严谨可靠的智能助手。请用中文回复,说话风格参照官方文件。
16
+
17
+ - 开动脑筋 — 主动思考、灵活运用工具,而不是机械执行
18
+ - 实事求是 — 知之为知之,不知为不知,而不是凭空编造
19
+ - 一切行动听指挥 — 严格遵循用户指令,而不是自作主张
20
+ - 安全第一 — 风险操作先告知确认,而不是盲目执行
21
+ - 能打胜仗 — 写优秀的代码,而不是只限于能用的代码`,
16
22
  },
17
23
  ],
18
24
  permissions: {
@@ -47,11 +53,11 @@ export const DEFAULT_SUBAGENT_DEFINITION = {
47
53
  },
48
54
  function: {
49
55
  name: "sub_agent_default",
50
- description: "通用子 Agent,可独立完成各类任务。将任务委派给它后,它会自主调用自身工具(文件读写、代码执行、搜索等)来完成任务并返回结果。适合处理需要多步骤执行、工具调用的复杂任务。",
56
+ description: "通用子 Agent,可独立完成各类任务。委派任务时必须提供完整的任务上下文,包括所有必要的背景信息、文件路径、具体要求和约束条件,确保子 Agent 无需追问即可独立执行。",
51
57
  parameters: {
52
58
  type: "object",
53
59
  properties: {
54
- task: { type: "string", description: "任务描述" },
60
+ task: { type: "string", description: "完整的任务描述,必须包含所有必要的背景、目标、约束条件和上下文信息" },
55
61
  },
56
62
  required: ["task"],
57
63
  additionalProperties: false,
package/dist/index.d.ts CHANGED
@@ -1,10 +1,8 @@
1
1
  export type { PermissionPolicy, AgentPermissions, Endpoint, Model, ImageModel, AgentDefinition, Conversation, Draft, AppConfig, McpIcon, McpAnnotations, McpToolDef, McpResourceDef, McpPromptDef, McpServerManifest, McpServerConfig, McpConnectionState, } from "./types/index.js";
2
- export { Capabilities } from "./capabilities/Capabilities.js";
3
2
  export { PermissionEvaluator } from "./capabilities/PermissionEvaluator.js";
4
3
  export type { CandidateSets } from "./capabilities/PermissionEvaluator.js";
5
4
  export { createDisclosureParam } from "./capabilities/disclosure.js";
6
5
  export type { DisclosureParam } from "./capabilities/disclosure.js";
7
- export type { FilterOutput, ExcludeOptions } from "./capabilities/Capabilities.js";
8
6
  export { discoverBuiltinTools } from "./capabilities/discovery/builtin.js";
9
7
  export { discoverSubAgents } from "./capabilities/discovery/subagents.js";
10
8
  export { discoverSkills, readSkill } from "./capabilities/discovery/skills.js";
@@ -17,6 +15,7 @@ export { AgentRepository } from "./crud/AgentRepository.js";
17
15
  export { ConversationRepository } from "./crud/ConversationRepository.js";
18
16
  export { DraftRepository } from "./crud/DraftRepository.js";
19
17
  export { Provider } from "./runtime/Provider.js";
18
+ export type { FilterOutput, ExcludeOptions } from "./runtime/Provider.js";
20
19
  export { createModel } from "./runtime/createModel.js";
21
20
  export { SdkAgent } from "./runtime/SdkAgent.js";
22
21
  export type { AgentPlugin, SendContext } from "./runtime/SdkAgent.js";
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  // 能力管线
2
- export { Capabilities } from "./capabilities/Capabilities.js";
3
2
  export { PermissionEvaluator } from "./capabilities/PermissionEvaluator.js";
4
3
  export { createDisclosureParam } from "./capabilities/disclosure.js";
5
4
  // 发现
@@ -9,10 +9,8 @@
9
9
  export class AutoRefreshToolsPlugin {
10
10
  async onBeforeSend(ctx) {
11
11
  const { agent } = ctx;
12
- if (!agent.caps)
13
- return;
14
- agent.caps.refresh({ silent: true });
15
- agent.tools = agent.caps.buildTools(agent.permissions ?? {}, {
12
+ await agent.provider.refresh({ silent: true });
13
+ agent.tools = agent.provider.buildTools(agent.permissions ?? {}, {
16
14
  exclude: {
17
15
  subagents: agent.definition.function?.name
18
16
  ? [agent.definition.function.name]