@ai-zen/agents-sdk 0.2.0-alpha.3 → 0.2.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.
@@ -67,5 +67,7 @@ export declare class Capabilities {
67
67
  /**
68
68
  * 重新执行全局发现(重新扫描文件系统)。
69
69
  */
70
- refresh(): void;
70
+ refresh(options?: {
71
+ silent?: boolean;
72
+ }): void;
71
73
  }
@@ -138,12 +138,13 @@ export class Capabilities {
138
138
  /**
139
139
  * 重新执行全局发现(重新扫描文件系统)。
140
140
  */
141
- refresh() {
141
+ refresh(options) {
142
+ const silent = options?.silent ?? false;
142
143
  const provider = this.provider;
143
144
  this.builtinInstances = discoverBuiltinTools(provider.config);
144
- this.userInstances = discoverUserTools(provider.toolsPaths);
145
+ this.userInstances = discoverUserTools(provider.toolsPaths, { silent });
145
146
  this.subagentDefs = discoverSubAgents(provider.subAgentsPaths);
146
- this.skills = discoverSkills(provider.skillsPaths);
147
+ this.skills = discoverSkills(provider.skillsPaths, { silent });
147
148
  this.mcps = discoverMcpServers(provider.mcpPaths);
148
149
  }
149
150
  }
@@ -30,13 +30,17 @@ export interface SkillInfo {
30
30
  * 按优先级从高到低传入路径列表,同名 skill 靠前的路径优先(先到先得)。
31
31
  * 解析 YAML frontmatter 中的 name 和 description,同时校验合规。
32
32
  */
33
- export declare function discoverSkills(paths: string[]): SkillInfo[];
33
+ export declare function discoverSkills(paths: string[], options?: {
34
+ silent?: boolean;
35
+ }): SkillInfo[];
34
36
  /**
35
37
  * 读取单个 Skill 的完整内容与元数据。
36
38
  * 按优先级从高到低传入路径列表,靠前的路径优先(先到先得)。
37
39
  * 返回 null 如果 skill 在所有目录中都不存在或 SKILL.md 不可读。
38
40
  */
39
- export declare function readSkill(skillDirs: string[], skillId: string): SkillInfo | null;
41
+ export declare function readSkill(skillDirs: string[], skillId: string, options?: {
42
+ silent?: boolean;
43
+ }): SkillInfo | null;
40
44
  /** @internal */
41
45
  export declare function parseFrontmatter(content: string): Frontmatter;
42
46
  /** @internal */
@@ -8,7 +8,8 @@ const log = createLogger();
8
8
  * 按优先级从高到低传入路径列表,同名 skill 靠前的路径优先(先到先得)。
9
9
  * 解析 YAML frontmatter 中的 name 和 description,同时校验合规。
10
10
  */
11
- export function discoverSkills(paths) {
11
+ export function discoverSkills(paths, options) {
12
+ const silent = options?.silent ?? false;
12
13
  const seen = new Set();
13
14
  const items = [];
14
15
  for (const dir of paths) {
@@ -29,7 +30,7 @@ export function discoverSkills(paths) {
29
30
  const skillMdPath = join(dir, entry.name, "SKILL.md");
30
31
  if (!existsSync(skillMdPath))
31
32
  continue;
32
- const skill = readSkillFromPath(entry.name, skillMdPath);
33
+ const skill = readSkillFromPath(entry.name, skillMdPath, silent);
33
34
  if (skill) {
34
35
  seen.add(entry.name);
35
36
  items.push(skill);
@@ -44,26 +45,29 @@ export function discoverSkills(paths) {
44
45
  * 按优先级从高到低传入路径列表,靠前的路径优先(先到先得)。
45
46
  * 返回 null 如果 skill 在所有目录中都不存在或 SKILL.md 不可读。
46
47
  */
47
- export function readSkill(skillDirs, skillId) {
48
+ export function readSkill(skillDirs, skillId, options) {
49
+ const silent = options?.silent ?? false;
48
50
  for (const dir of skillDirs) {
49
51
  const candidate = join(dir, skillId, "SKILL.md");
50
52
  if (existsSync(candidate)) {
51
- return readSkillFromPath(skillId, candidate);
53
+ return readSkillFromPath(skillId, candidate, silent);
52
54
  }
53
55
  }
54
56
  return null;
55
57
  }
56
58
  // ---- 内部 ----
57
- function readSkillFromPath(skillId, skillMdPath) {
59
+ function readSkillFromPath(skillId, skillMdPath, silent) {
58
60
  try {
59
61
  const content = readFileSync(skillMdPath, "utf-8");
60
62
  const fm = parseFrontmatter(content);
61
63
  if (!fm.name)
62
64
  return null;
63
65
  // 规范合规校验
64
- const errors = validateSkill(skillId, fm);
65
- for (const err of errors) {
66
- log.warn(`[skills] ${err.skillId}: ${err.field} — ${err.message}`);
66
+ if (!silent) {
67
+ const errors = validateSkill(skillId, fm);
68
+ for (const err of errors) {
69
+ log.warn(`[skills] ${err.skillId}: ${err.field} — ${err.message}`);
70
+ }
67
71
  }
68
72
  return {
69
73
  id: skillId,
@@ -10,4 +10,6 @@ import { Tool } from "@ai-zen/agents-core";
10
10
  * 3. 支持直接导出 { function, exec } 格式的对象(自动适配为 Tool)
11
11
  * 4. 支持导出 CallbackTool 兼容的 { function, callback } 格式
12
12
  */
13
- export declare function discoverUserTools(paths: string[]): Tool[];
13
+ export declare function discoverUserTools(paths: string[], options?: {
14
+ silent?: boolean;
15
+ }): Tool[];
@@ -13,7 +13,8 @@ import { Tool, CallbackTool } from "@ai-zen/agents-core";
13
13
  * 3. 支持直接导出 { function, exec } 格式的对象(自动适配为 Tool)
14
14
  * 4. 支持导出 CallbackTool 兼容的 { function, callback } 格式
15
15
  */
16
- export function discoverUserTools(paths) {
16
+ export function discoverUserTools(paths, options) {
17
+ const silent = options?.silent ?? false;
17
18
  const seen = new Set();
18
19
  const tools = [];
19
20
  for (const dir of paths) {
@@ -28,7 +29,7 @@ export function discoverUserTools(paths) {
28
29
  if (!seen.has(name)) {
29
30
  seen.add(name);
30
31
  try {
31
- const tool = loadToolFile(join(dir, name + ".js"));
32
+ const tool = loadToolFile(join(dir, name + ".js"), silent);
32
33
  if (tool) {
33
34
  tools.push(tool);
34
35
  }
@@ -51,7 +52,7 @@ export function discoverUserTools(paths) {
51
52
  * 使用 vm.compileFunction 创建沙箱执行环境,避免污染全局作用域。
52
53
  * 注入有限的全局 API(console, setTimeout 等),不暴露 process/require。
53
54
  */
54
- function loadToolFile(filepath) {
55
+ function loadToolFile(filepath, silent) {
55
56
  const code = readFileSync(filepath, "utf-8");
56
57
  // 构造沙箱上下文
57
58
  const sandbox = {
@@ -83,17 +84,19 @@ function loadToolFile(filepath) {
83
84
  return null;
84
85
  }
85
86
  // 适配不同导出格式
86
- return normalizeToolExport(exported, filepath);
87
+ return normalizeToolExport(exported, filepath, silent);
87
88
  }
88
89
  catch (err) {
89
- console.error(`[usertools] 加载工具文件失败: ${filepath} — ${err?.message ?? err}`);
90
+ if (!silent) {
91
+ console.error(`[usertools] 加载工具文件失败: ${filepath} — ${err?.message ?? err}`);
92
+ }
90
93
  return null;
91
94
  }
92
95
  }
93
96
  /**
94
97
  * 统一各种导出格式为 Tool 实例。
95
98
  */
96
- function normalizeToolExport(exported, filepath) {
99
+ function normalizeToolExport(exported, filepath, silent) {
97
100
  // 情况 1:直接是 Tool 实例
98
101
  if (exported instanceof Tool) {
99
102
  return exported;
@@ -114,7 +117,9 @@ function normalizeToolExport(exported, filepath) {
114
117
  callback: target.callback,
115
118
  });
116
119
  }
117
- console.error(`[usertools] 无法识别的工具格式: ${filepath}`);
120
+ if (!silent) {
121
+ console.error(`[usertools] 无法识别的工具格式: ${filepath}`);
122
+ }
118
123
  return null;
119
124
  }
120
125
  /**
@@ -94,7 +94,7 @@ export const execAsyncTool = new CallbackTool({
94
94
  resolve(JSON.stringify({
95
95
  success: false,
96
96
  pid: null,
97
- error: `启动失败: ${err.message}`,
97
+ message: `启动失败: ${err.message}`,
98
98
  }));
99
99
  });
100
100
  child.on("spawn", () => {
@@ -12,6 +12,11 @@ const EMPTY_HINT = "(当前没有可用的 Skill,请联系用户添加)";
12
12
  export function createLoadSkillTool(skillDirs, filteredSkills) {
13
13
  const ids = filteredSkills.map((s) => s.id);
14
14
  const param = createDisclosureParam(ids, "选择一个 Skill", EMPTY_HINT);
15
+ // 拼接各 skill 的描述供 LLM 参考
16
+ const skillDescriptions = filteredSkills
17
+ .map((s) => ` - ${s.id}: ${s.description || "无描述"}`)
18
+ .join("\n");
19
+ const skillIdDescription = `${param.description}\n\n各 Skill 说明:\n${skillDescriptions || " 无可用 Skill"}`;
15
20
  return new CallbackTool({
16
21
  function: {
17
22
  name: "load_skill",
@@ -21,7 +26,7 @@ export function createLoadSkillTool(skillDirs, filteredSkills) {
21
26
  properties: {
22
27
  skill_id: {
23
28
  type: "string",
24
- description: param.description,
29
+ description: skillIdDescription,
25
30
  ...(param.enum ? { enum: param.enum } : {}),
26
31
  },
27
32
  },
@@ -57,6 +62,11 @@ export function createCallSkillSubAgentTool(skillDirs, filteredSkills, caps) {
57
62
  const subAgentSkills = filteredSkills.filter((s) => s.subAgent);
58
63
  const ids = subAgentSkills.map((s) => s.id);
59
64
  const param = createDisclosureParam(ids, "选择一个 Skill(支持子 Agent)", EMPTY_HINT);
65
+ // 拼接各 skill 的描述供 LLM 参考
66
+ const skillDescriptions = subAgentSkills
67
+ .map((s) => ` - ${s.id}: ${s.description || "无描述"}`)
68
+ .join("\n");
69
+ const skillIdDescription = `${param.description}\n\n各 Skill 说明:\n${skillDescriptions || " 无可用 Skill"}`;
60
70
  return new CallbackTool({
61
71
  function: {
62
72
  name: "call_skill_sub_agent",
@@ -66,7 +76,7 @@ export function createCallSkillSubAgentTool(skillDirs, filteredSkills, caps) {
66
76
  properties: {
67
77
  skill_id: {
68
78
  type: "string",
69
- description: param.description,
79
+ description: skillIdDescription,
70
80
  ...(param.enum ? { enum: param.enum } : {}),
71
81
  },
72
82
  task: {
@@ -11,7 +11,7 @@ export class AutoRefreshToolsPlugin {
11
11
  const { agent } = ctx;
12
12
  if (!agent.caps)
13
13
  return;
14
- agent.caps.refresh();
14
+ agent.caps.refresh({ silent: true });
15
15
  agent.tools = agent.caps.buildTools(agent.permissions ?? {}, {
16
16
  exclude: {
17
17
  subagents: agent.definition.function?.name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-zen/agents-sdk",
3
- "version": "0.2.0-alpha.3",
3
+ "version": "0.2.1",
4
4
  "description": "AI-Zen Agents SDK — shared business logic for CLI and Desktop",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",