@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
@@ -1,4 +1,4 @@
1
- import { readFileSync, writeFileSync, existsSync, renameSync, mkdirSync, readdirSync } from "node:fs";
1
+ import { promises as fs } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { DEFAULT_AGENT_ID, DEFAULT_AGENT_DEFINITION, DEFAULT_SUBAGENT_ID, DEFAULT_SUBAGENT_DEFINITION, DEFAULT_APP_CONFIG, CONFIG_SUB_DIRS, } from "./constants.js";
4
4
  /**
@@ -17,21 +17,27 @@ export class ConfigManager {
17
17
  /**
18
18
  * 读取配置。文件不存在时返回出厂默认配置。
19
19
  */
20
- read() {
21
- if (!existsSync(this.configPath)) {
20
+ async read() {
21
+ try {
22
+ await fs.access(this.configPath);
23
+ }
24
+ catch {
22
25
  return { ...DEFAULT_APP_CONFIG };
23
26
  }
24
- const raw = readFileSync(this.configPath, "utf-8");
27
+ const raw = await fs.readFile(this.configPath, "utf-8");
25
28
  return JSON.parse(raw);
26
29
  }
27
- write(config) {
30
+ async write(config) {
28
31
  const dir = dirname(this.configPath);
29
- if (!existsSync(dir)) {
30
- mkdirSync(dir, { recursive: true });
32
+ try {
33
+ await fs.access(dir);
34
+ }
35
+ catch {
36
+ await fs.mkdir(dir, { recursive: true });
31
37
  }
32
38
  const tmpPath = this.configPath + ".tmp";
33
- writeFileSync(tmpPath, JSON.stringify(config, null, 2), "utf-8");
34
- renameSync(tmpPath, this.configPath);
39
+ await fs.writeFile(tmpPath, JSON.stringify(config, null, 2), "utf-8");
40
+ await fs.rename(tmpPath, this.configPath);
35
41
  }
36
42
  // -----------------------------------------------------------------------
37
43
  // 目录 & 默认实体
@@ -40,22 +46,25 @@ export class ConfigManager {
40
46
  * 确保基础目录结构存在。
41
47
  * 创建 basePath 及所有标准共享子目录(agents/、sub-agents/、skills/ 等)。
42
48
  */
43
- ensureDirs() {
44
- mkdirSync(this.basePath, { recursive: true });
49
+ async ensureDirs() {
50
+ await fs.mkdir(this.basePath, { recursive: true });
45
51
  for (const dir of CONFIG_SUB_DIRS) {
46
- mkdirSync(join(this.basePath, dir), { recursive: true });
52
+ await fs.mkdir(join(this.basePath, dir), { recursive: true });
47
53
  }
48
54
  }
49
55
  /**
50
56
  * 确保 config.json 存在。不存在时写入出厂默认配置 DSL。
51
57
  */
52
- ensureDefaultConfig() {
53
- if (existsSync(this.configPath)) {
54
- return this.read();
58
+ async ensureDefaultConfig() {
59
+ try {
60
+ await fs.access(this.configPath);
61
+ return await this.read();
62
+ }
63
+ catch {
64
+ await this.ensureDirs();
65
+ await this.write(DEFAULT_APP_CONFIG);
66
+ return { ...DEFAULT_APP_CONFIG };
55
67
  }
56
- this.ensureDirs();
57
- this.write(DEFAULT_APP_CONFIG);
58
- return { ...DEFAULT_APP_CONFIG };
59
68
  }
60
69
  /**
61
70
  * 确保 basePath/agents/default.json 存在。
@@ -64,14 +73,25 @@ export class ConfigManager {
64
73
  * - agents/ 为空 → 写入默认 Agent
65
74
  * - 已有其他 Agent → 返回 null
66
75
  */
67
- ensureDefaultAgent() {
76
+ async ensureDefaultAgent() {
68
77
  const agentsDir = join(this.basePath, "agents");
69
78
  const defaultPath = join(agentsDir, `${DEFAULT_AGENT_ID}.json`);
70
- if (existsSync(defaultPath)) {
71
- return JSON.parse(readFileSync(defaultPath, "utf-8"));
79
+ try {
80
+ await fs.access(defaultPath);
81
+ return JSON.parse(await fs.readFile(defaultPath, "utf-8"));
82
+ }
83
+ catch {
84
+ // default.json 不存在,继续
85
+ }
86
+ await fs.mkdir(agentsDir, { recursive: true });
87
+ let existing;
88
+ try {
89
+ const allFiles = await fs.readdir(agentsDir);
90
+ existing = allFiles.filter((f) => f.endsWith(".json"));
91
+ }
92
+ catch {
93
+ existing = [];
72
94
  }
73
- mkdirSync(agentsDir, { recursive: true });
74
- const existing = readdirSync(agentsDir).filter((f) => f.endsWith(".json"));
75
95
  if (existing.length > 0) {
76
96
  return null;
77
97
  }
@@ -81,7 +101,7 @@ export class ConfigManager {
81
101
  createdAt: now,
82
102
  updatedAt: now,
83
103
  };
84
- writeFileSync(defaultPath, JSON.stringify(definition, null, 2), "utf-8");
104
+ await fs.writeFile(defaultPath, JSON.stringify(definition, null, 2), "utf-8");
85
105
  return definition;
86
106
  }
87
107
  /**
@@ -91,14 +111,25 @@ export class ConfigManager {
91
111
  * - sub-agents/ 为空 → 写入默认通用助手 SubAgent
92
112
  * - 已有其他 SubAgent → 返回 null
93
113
  */
94
- ensureDefaultSubAgent() {
114
+ async ensureDefaultSubAgent() {
95
115
  const subDir = join(this.basePath, "sub-agents");
96
116
  const defaultPath = join(subDir, `${DEFAULT_SUBAGENT_ID}.json`);
97
- if (existsSync(defaultPath)) {
98
- return JSON.parse(readFileSync(defaultPath, "utf-8"));
117
+ try {
118
+ await fs.access(defaultPath);
119
+ return JSON.parse(await fs.readFile(defaultPath, "utf-8"));
120
+ }
121
+ catch {
122
+ // 文件不存在,继续
123
+ }
124
+ await fs.mkdir(subDir, { recursive: true });
125
+ let existing;
126
+ try {
127
+ const allFiles = await fs.readdir(subDir);
128
+ existing = allFiles.filter((f) => f.endsWith(".json"));
129
+ }
130
+ catch {
131
+ existing = [];
99
132
  }
100
- mkdirSync(subDir, { recursive: true });
101
- const existing = readdirSync(subDir).filter((f) => f.endsWith(".json"));
102
133
  if (existing.length > 0) {
103
134
  return null;
104
135
  }
@@ -108,18 +139,18 @@ export class ConfigManager {
108
139
  createdAt: now,
109
140
  updatedAt: now,
110
141
  };
111
- writeFileSync(defaultPath, JSON.stringify(definition, null, 2), "utf-8");
142
+ await fs.writeFile(defaultPath, JSON.stringify(definition, null, 2), "utf-8");
112
143
  return definition;
113
144
  }
114
145
  /**
115
146
  * 一键初始化:目录 + config.json + 默认 Agent + 默认 SubAgent。
116
147
  * 已有文件不会被覆盖。
117
148
  */
118
- bootstrap() {
119
- this.ensureDirs();
120
- const config = this.ensureDefaultConfig();
121
- const agent = this.ensureDefaultAgent();
122
- const subAgent = this.ensureDefaultSubAgent();
149
+ async bootstrap() {
150
+ await this.ensureDirs();
151
+ const config = await this.ensureDefaultConfig();
152
+ const agent = await this.ensureDefaultAgent();
153
+ const subAgent = await this.ensureDefaultSubAgent();
123
154
  return { config, agent, subAgent };
124
155
  }
125
156
  }
@@ -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,
@@ -9,7 +9,7 @@ export declare class DraftRepository {
9
9
  private dir;
10
10
  constructor(dir: string);
11
11
  private path;
12
- read(conversationId?: string): Draft | null;
13
- write(draft: Draft): void;
14
- delete(conversationId?: string): void;
12
+ read(conversationId?: string): Promise<Draft | null>;
13
+ write(draft: Draft): Promise<void>;
14
+ delete(conversationId?: string): Promise<void>;
15
15
  }
@@ -1,4 +1,4 @@
1
- import { readFileSync, writeFileSync, existsSync, unlinkSync, mkdirSync } from "node:fs";
1
+ import { promises as fs } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  const CURRENT_DRAFT = "_current.json";
4
4
  /**
@@ -15,27 +15,38 @@ export class DraftRepository {
15
15
  path(conversationId) {
16
16
  return join(this.dir, conversationId ? `${conversationId}.json` : CURRENT_DRAFT);
17
17
  }
18
- read(conversationId) {
18
+ async read(conversationId) {
19
19
  const p = this.path(conversationId);
20
- if (!existsSync(p))
20
+ try {
21
+ await fs.access(p);
22
+ }
23
+ catch {
21
24
  return null;
25
+ }
22
26
  try {
23
- return JSON.parse(readFileSync(p, "utf-8"));
27
+ return JSON.parse(await fs.readFile(p, "utf-8"));
24
28
  }
25
29
  catch {
26
30
  return null;
27
31
  }
28
32
  }
29
- write(draft) {
30
- if (!existsSync(this.dir)) {
31
- mkdirSync(this.dir, { recursive: true });
33
+ async write(draft) {
34
+ try {
35
+ await fs.access(this.dir);
32
36
  }
33
- writeFileSync(this.path(draft.conversationId), JSON.stringify(draft, null, 2), "utf-8");
37
+ catch {
38
+ await fs.mkdir(this.dir, { recursive: true });
39
+ }
40
+ await fs.writeFile(this.path(draft.conversationId), JSON.stringify(draft, null, 2), "utf-8");
34
41
  }
35
- delete(conversationId) {
42
+ async delete(conversationId) {
36
43
  const p = this.path(conversationId);
37
- if (existsSync(p)) {
38
- unlinkSync(p);
44
+ try {
45
+ await fs.access(p);
46
+ await fs.unlink(p);
47
+ }
48
+ catch {
49
+ // 文件不存在,忽略
39
50
  }
40
51
  }
41
52
  }
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
  // 发现
@@ -22,5 +22,5 @@ export declare class AutoDraftPlugin implements AgentPlugin {
22
22
  private options;
23
23
  constructor(options: AutoDraftOptions);
24
24
  onInnerLoopEnd(ctx: SendContext): Promise<void>;
25
- static checkDraftForRestore(draftsDir: string): Draft | null;
25
+ static checkDraftForRestore(draftsDir: string): Promise<Draft | null>;
26
26
  }
@@ -1,6 +1,6 @@
1
1
  import { DraftRepository } from "../crud/DraftRepository.js";
2
2
  import { createLogger } from "../shared/logger.js";
3
- import { existsSync } from "node:fs";
3
+ import { promises as fs } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import dayjs from "dayjs";
6
6
  const log = createLogger();
@@ -34,23 +34,27 @@ export class AutoDraftPlugin {
34
34
  updatedAt: new Date().toISOString(),
35
35
  };
36
36
  const repo = new DraftRepository(draftsDir);
37
- repo.write(draft);
37
+ await repo.write(draft);
38
38
  }
39
39
  catch (err) {
40
40
  log.error(`[autoDraft] 保存失败: ${err?.message ?? err}`);
41
41
  }
42
42
  }
43
- static checkDraftForRestore(draftsDir) {
43
+ static async checkDraftForRestore(draftsDir) {
44
44
  const path = join(draftsDir, CURRENT_DRAFT);
45
- if (!existsSync(path))
45
+ try {
46
+ await fs.access(path);
47
+ }
48
+ catch {
46
49
  return null;
50
+ }
47
51
  const repo = new DraftRepository(draftsDir);
48
- const draft = repo.read();
52
+ const draft = await repo.read();
49
53
  if (!draft)
50
54
  return null;
51
55
  const age = dayjs().diff(dayjs(draft.updatedAt), "day");
52
56
  if (age > EXPIRE_DAYS) {
53
- repo.delete();
57
+ await repo.delete();
54
58
  return null;
55
59
  }
56
60
  return draft;
@@ -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]
@@ -1,15 +1,49 @@
1
- import type { AppConfig } from "../types/index.js";
1
+ import type { Tool } from "@ai-zen/agents-core";
2
+ import type { AppConfig, AgentDefinition, AgentPermissions, McpServerConfig } from "../types/index.js";
3
+ import type { SkillInfo } from "../capabilities/discovery/skills.js";
2
4
  import { McpConnectionManager } from "./McpConnectionManager.js";
3
5
  /**
4
- * Provider — 全局上下文实例。
6
+ * 能力过滤系统的公共类型。
7
+ * FilterOutput 由 filter() 产出,由 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
+ * Provider — 全局上下文实例 + 能力注册表。
5
27
  *
6
- * SDK 不是一个模块工具箱(到处 import 散装函数),而是一个实例,
7
- * 持有所有全局状态(配置、路径、MCP 管理器等),各层通过它获取所需。
28
+ * Provider 是 SDK 的全局单例(按需创建),持有:
29
+ * - 应用配置(端点、模型等)
30
+ * - 文件系统路径(Agent 目录、Skill 目录等)
31
+ * - 全局能力注册表(内置工具、用户工具、SubAgent、Skill、MCP)
32
+ * - MCP 连接管理器
33
+ *
34
+ * 创建方式:
35
+ * ```ts
36
+ * // 推荐:一步完成构造 + 能力发现
37
+ * const provider = await Provider.create({ ... });
38
+ *
39
+ * // 仅构造(能力需后续加载)
40
+ * const provider = new Provider({ ... });
41
+ * await provider.init();
42
+ * ```
8
43
  *
9
44
  * 设计原则:
10
- * - Provider 实例一旦创建不可变(路径、配置等不变),refresh 时创建新实例
45
+ * - Provider 实例一旦创建不可变(路径、配置等不变),refresh 时重新发现能力
11
46
  * - 各层不直接 import 散装函数,而是通过 Provider 实例获取
12
- * - Provider 不关心能力的发现/过滤/实例化,那是 Capabilities 的事
13
47
  */
14
48
  export declare class Provider {
15
49
  /** 应用配置(端点、模型等) */
@@ -19,7 +53,14 @@ export declare class Provider {
19
53
  readonly skillsPaths: string[];
20
54
  readonly toolsPaths: string[];
21
55
  readonly mcpPaths: string[];
22
- private _mcpManager?;
56
+ builtinTools: Tool[];
57
+ userTools: Tool[];
58
+ subagents: AgentDefinition[];
59
+ /** 完整 SkillInfo,含 subAgent 标记,可据此区分枚举 */
60
+ skills: SkillInfo[];
61
+ /** 完整 MCP 服务器配置 */
62
+ mcps: McpServerConfig[];
63
+ readonly mcpManager: McpConnectionManager | undefined;
23
64
  constructor(options: {
24
65
  config: AppConfig;
25
66
  agentsDir: string;
@@ -29,8 +70,41 @@ export declare class Provider {
29
70
  mcpPaths?: string[];
30
71
  });
31
72
  /**
32
- * 获取 McpConnectionManager,有 mcpPaths 时延迟创建。
33
- * 首次访问时创建,后续复用同一实例。
73
+ * 异步创建 Provider,一步完成构造 + 全局能力发现。
74
+ */
75
+ static create(options: {
76
+ config: AppConfig;
77
+ agentsDir: string;
78
+ subAgentsPaths?: string[];
79
+ skillsPaths?: string[];
80
+ toolsPaths?: string[];
81
+ mcpPaths?: string[];
82
+ }): Promise<Provider>;
83
+ /**
84
+ * 初始化:执行全局能力发现。
85
+ */
86
+ init(): Promise<void>;
87
+ /**
88
+ * 按权限过滤候选集,返回过滤后的名称列表。
89
+ * 纯名称操作(安全预过滤 + 权限过滤),不涉及 Tool 实例化。
90
+ */
91
+ filter(permissions: AgentPermissions, options?: {
92
+ exclude?: ExcludeOptions;
93
+ }): FilterOutput;
94
+ /**
95
+ * 快捷方法:filter + instantiate 一步完成。
96
+ */
97
+ buildTools(permissions: AgentPermissions, options?: {
98
+ exclude?: ExcludeOptions;
99
+ }): Tool[];
100
+ /**
101
+ * 将过滤后的名称列表实例化为 Tool 数组。
102
+ */
103
+ instantiate(filtered: FilterOutput): Tool[];
104
+ /**
105
+ * 重新执行全局发现(重新扫描文件系统)。
34
106
  */
35
- getMcpManager(): McpConnectionManager | undefined;
107
+ refresh(options?: {
108
+ silent?: boolean;
109
+ }): Promise<void>;
36
110
  }