@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
@@ -0,0 +1,147 @@
1
+ import { CallbackTool } from "@ai-zen/agents-core";
2
+ import { createDisclosureParam } from "../disclosure.js";
3
+ const EMPTY_HINT = "(当前没有可用的 MCP 服务器,请联系用户添加)";
4
+ /**
5
+ * 创建 load_mcp 工具。
6
+ * server 枚举由 filteredMcps (完整 McpServerConfig[])自动推导。
7
+ */
8
+ export function createLoadMcpTool(mcpManager, mcpConfigs, filteredMcps) {
9
+ const ids = filteredMcps.map((s) => s.id);
10
+ const param = createDisclosureParam(ids, "选择一个 MCP 服务器", EMPTY_HINT);
11
+ return new CallbackTool({
12
+ function: {
13
+ name: "load_mcp",
14
+ description: "连接到指定 MCP 服务器,获取其可用工具和资源列表。",
15
+ parameters: {
16
+ type: "object",
17
+ properties: {
18
+ server: {
19
+ type: "string",
20
+ description: param.description,
21
+ ...(param.enum ? { enum: param.enum } : {}),
22
+ },
23
+ },
24
+ required: ["server"],
25
+ additionalProperties: false,
26
+ },
27
+ },
28
+ callback: async (input) => {
29
+ const serverName = input.server;
30
+ const serverConfig = mcpConfigs.get(serverName);
31
+ if (!serverConfig) {
32
+ return `❌ MCP 服务器 "${serverName}" 不存在`;
33
+ }
34
+ const existingManifest = mcpManager.getManifest(serverName);
35
+ if (existingManifest && mcpManager.getState(serverName) === "connected") {
36
+ mcpManager.touch(serverName);
37
+ const toolList = existingManifest.tools.map((t) => `- ${t.name}: ${t.description}`).join("\n");
38
+ return `✅ MCP 服务器 "${serverName}" 已连接 (${existingManifest.tools.length} 个工具):\n${toolList}`;
39
+ }
40
+ try {
41
+ const manifest = await mcpManager.connect(serverName, serverConfig.config);
42
+ const toolList = manifest.tools.map((t) => `- ${t.name}: ${t.description}`).join("\n");
43
+ return `✅ MCP 服务器 "${serverName}" 已连接 (${manifest.tools.length} 个工具):\n${toolList}`;
44
+ }
45
+ catch (error) {
46
+ return `无法连接到 "${serverName}": ${error?.message ?? error}`;
47
+ }
48
+ },
49
+ });
50
+ }
51
+ /**
52
+ * 创建 call_mcp_tool 工具。
53
+ * 通过官方 Client.callTool() API 调用 MCP 服务器上的工具。
54
+ */
55
+ export function createCallMcpTool(mcpManager) {
56
+ return new CallbackTool({
57
+ function: {
58
+ name: "call_mcp_tool",
59
+ description: "调用已连接 MCP 服务器上的指定工具。需先通过 load_mcp 连接服务器。",
60
+ parameters: {
61
+ type: "object",
62
+ properties: {
63
+ server: { type: "string", description: "MCP 服务器名称" },
64
+ tool: { type: "string", description: "工具名称" },
65
+ arguments: { type: "object", description: "工具参数" },
66
+ },
67
+ required: ["server", "tool", "arguments"],
68
+ additionalProperties: false,
69
+ },
70
+ },
71
+ callback: async (input) => {
72
+ const serverName = input.server;
73
+ const state = mcpManager.getState(serverName);
74
+ if (state !== "connected") {
75
+ return `请先使用 load_mcp 连接 "${serverName}"`;
76
+ }
77
+ const client = mcpManager.getClient(serverName);
78
+ if (!client) {
79
+ return `MCP 服务器 "${serverName}" 的客户端不可用`;
80
+ }
81
+ try {
82
+ mcpManager.touch(serverName);
83
+ const result = await client.callTool({
84
+ name: input.tool,
85
+ arguments: input.arguments,
86
+ });
87
+ const contents = result.content ?? [];
88
+ const textParts = contents
89
+ .filter((c) => c.type === "text")
90
+ .map((c) => c.text);
91
+ const text = textParts.join("\n");
92
+ if (result.isError) {
93
+ return `❌ 工具执行出错:\n${text || JSON.stringify(result)}`;
94
+ }
95
+ return text || JSON.stringify(result);
96
+ }
97
+ catch (error) {
98
+ return `❌ 调用 "${input.tool}" 失败: ${error?.message ?? error}`;
99
+ }
100
+ },
101
+ });
102
+ }
103
+ /**
104
+ * 创建 read_mcp_resource 工具。
105
+ */
106
+ export function createReadMcpResourceTool(mcpManager) {
107
+ return new CallbackTool({
108
+ function: {
109
+ name: "read_mcp_resource",
110
+ description: "读取已连接 MCP 服务器上的指定资源(文档、数据等)。",
111
+ parameters: {
112
+ type: "object",
113
+ properties: {
114
+ server: { type: "string", description: "MCP 服务器名称" },
115
+ uri: { type: "string", description: "资源 URI" },
116
+ },
117
+ required: ["server", "uri"],
118
+ additionalProperties: false,
119
+ },
120
+ },
121
+ callback: async (input) => {
122
+ const serverName = input.server;
123
+ const state = mcpManager.getState(serverName);
124
+ if (state !== "connected") {
125
+ return `请先使用 load_mcp 连接 "${serverName}"`;
126
+ }
127
+ const client = mcpManager.getClient(serverName);
128
+ if (!client) {
129
+ return `MCP 服务器 "${serverName}" 的客户端不可用`;
130
+ }
131
+ try {
132
+ mcpManager.touch(serverName);
133
+ const result = await client.readResource({
134
+ uri: input.uri,
135
+ });
136
+ const contents = result?.contents ?? [];
137
+ const textParts = contents
138
+ .filter((c) => c.text)
139
+ .map((c) => c.text);
140
+ return textParts.join("\n") || JSON.stringify(result);
141
+ }
142
+ catch (error) {
143
+ return `❌ 读取资源 "${input.uri}" 失败: ${error?.message ?? error}`;
144
+ }
145
+ },
146
+ });
147
+ }
@@ -0,0 +1,15 @@
1
+ import { CallbackTool } from "@ai-zen/agents-core";
2
+ import type { SkillInfo } from "../discovery/skills.js";
3
+ import type { Capabilities } from "../Capabilities.js";
4
+ /**
5
+ * 创建 load_skill 工具。
6
+ * 枚举所有允许的 skill(不限是否支持子 Agent),由 filteredSkills 提供完整信息。
7
+ */
8
+ export declare function createLoadSkillTool(skillDirs: string[], filteredSkills: SkillInfo[]): CallbackTool;
9
+ /**
10
+ * 创建 call_skill_sub_agent 工具。
11
+ * 只展示 subAgent: true 的 Skill,枚举中自动排除不支持子 Agent 模式的 skill。
12
+ *
13
+ * 回调中创建独立的 Skill 子 Agent,通过 caps 按父 Agent 权限独立解析工具集。
14
+ */
15
+ export declare function createCallSkillSubAgentTool(skillDirs: string[], filteredSkills: SkillInfo[], caps?: Capabilities): CallbackTool;
@@ -0,0 +1,113 @@
1
+ import { CallbackTool, Agent, Message } from "@ai-zen/agents-core";
2
+ import { SdkAgent } from "../../runtime/SdkAgent.js";
3
+ import { createDisclosureParam } from "../disclosure.js";
4
+ import { readSkill } from "../discovery/skills.js";
5
+ import { createLogger } from "../../shared/logger.js";
6
+ const log = createLogger();
7
+ const EMPTY_HINT = "(当前没有可用的 Skill,请联系用户添加)";
8
+ /**
9
+ * 创建 load_skill 工具。
10
+ * 枚举所有允许的 skill(不限是否支持子 Agent),由 filteredSkills 提供完整信息。
11
+ */
12
+ export function createLoadSkillTool(skillDirs, filteredSkills) {
13
+ const ids = filteredSkills.map((s) => s.id);
14
+ const param = createDisclosureParam(ids, "选择一个 Skill", EMPTY_HINT);
15
+ return new CallbackTool({
16
+ function: {
17
+ name: "load_skill",
18
+ description: "加载指定 Skill 的完整指导文档。Skill 是预制的专业指导,加载后展开到上下文中。",
19
+ parameters: {
20
+ type: "object",
21
+ properties: {
22
+ skill_id: {
23
+ type: "string",
24
+ description: param.description,
25
+ ...(param.enum ? { enum: param.enum } : {}),
26
+ },
27
+ },
28
+ required: ["skill_id"],
29
+ additionalProperties: false,
30
+ },
31
+ },
32
+ callback: async function (input) {
33
+ const skillId = input.skill_id;
34
+ const skill = readSkill(skillDirs, skillId);
35
+ if (!skill) {
36
+ return `❌ Skill "${skillId}" 不存在,请确认名称是否正确`;
37
+ }
38
+ const alreadyLoaded = this.agent?.messages?.some((m) => String(m.content ?? "").includes(`Skill "${skillId}" 已加载`));
39
+ if (alreadyLoaded) {
40
+ return `Skill "${skillId}" 已加载`;
41
+ }
42
+ if (this.agent) {
43
+ this.agent.messages.push(Message.System(`以下是 Skill "${skillId}" 的内容,请按照其中的指导完成任务:\n\n${skill.content}`));
44
+ }
45
+ return `✅ Skill "${skillId}" 已加载,内容已附加到当前对话中`;
46
+ },
47
+ });
48
+ }
49
+ /**
50
+ * 创建 call_skill_sub_agent 工具。
51
+ * 只展示 subAgent: true 的 Skill,枚举中自动排除不支持子 Agent 模式的 skill。
52
+ *
53
+ * 回调中创建独立的 Skill 子 Agent,通过 caps 按父 Agent 权限独立解析工具集。
54
+ */
55
+ export function createCallSkillSubAgentTool(skillDirs, filteredSkills, caps) {
56
+ // 只保留支持子 Agent 模式的 skill
57
+ const subAgentSkills = filteredSkills.filter((s) => s.subAgent);
58
+ const ids = subAgentSkills.map((s) => s.id);
59
+ const param = createDisclosureParam(ids, "选择一个 Skill(支持子 Agent)", EMPTY_HINT);
60
+ return new CallbackTool({
61
+ function: {
62
+ name: "call_skill_sub_agent",
63
+ description: "将任务委派给指定的 Skill 子 Agent,由其独立完成并返回结果。",
64
+ parameters: {
65
+ type: "object",
66
+ properties: {
67
+ skill_id: {
68
+ type: "string",
69
+ description: param.description,
70
+ ...(param.enum ? { enum: param.enum } : {}),
71
+ },
72
+ task: {
73
+ type: "string",
74
+ description: "要委派给子 Agent 完成的任务描述",
75
+ },
76
+ },
77
+ required: ["skill_id", "task"],
78
+ additionalProperties: false,
79
+ },
80
+ },
81
+ async callback(input) {
82
+ const skillId = input.skill_id;
83
+ const task = input.task;
84
+ const skill = readSkill(skillDirs, skillId);
85
+ if (!skill) {
86
+ return `❌ Skill "${skillId}" 不存在,请确认名称是否正确`;
87
+ }
88
+ if (!skill.subAgent) {
89
+ return `Skill "${skillId}" 不支持子 Agent 模式,请使用 load_skill 加载指导后自行处理`;
90
+ }
91
+ const parentAgent = (this).agent;
92
+ const parentPermissions = parentAgent instanceof SdkAgent
93
+ ? parentAgent.permissions
94
+ : undefined;
95
+ const skillTools = caps && parentPermissions
96
+ ? caps.buildTools(parentPermissions, {
97
+ exclude: { skills: [skillId] },
98
+ })
99
+ : [];
100
+ const subAgent = new Agent({
101
+ model: parentAgent.model,
102
+ messages: [
103
+ Message.System(skill.content),
104
+ Message.User(task),
105
+ ],
106
+ tools: skillTools,
107
+ });
108
+ await subAgent.run();
109
+ const lastMsg = subAgent.messages.at(-1);
110
+ return typeof lastMsg?.content === "string" ? lastMsg.content : "";
111
+ },
112
+ });
113
+ }
@@ -0,0 +1,11 @@
1
+ import type { Tool } from "@ai-zen/agents-core";
2
+ import type { AgentDefinition } from "../../types/index.js";
3
+ import type { Provider } from "../../runtime/Provider.js";
4
+ import type { Capabilities } from "../Capabilities.js";
5
+ /**
6
+ * 创建 SubAgent 工具(AgentToolLazy)。
7
+ *
8
+ * SubAgent 是有 `function` 字段的 Agent,可被其他 Agent 作为工具调用。
9
+ * 使用延迟构建(AgentToolLazy)避免工具列表构建阶段的递归创建问题。
10
+ */
11
+ export declare function createSubAgentTool(def: AgentDefinition, provider: Provider, caps?: Capabilities): Tool;
@@ -0,0 +1,53 @@
1
+ import { Agent, AgentToolLazy } from "@ai-zen/agents-core";
2
+ import { createModel } from "../../runtime/createModel.js";
3
+ /**
4
+ * 创建 SubAgent 工具(AgentToolLazy)。
5
+ *
6
+ * SubAgent 是有 `function` 字段的 Agent,可被其他 Agent 作为工具调用。
7
+ * 使用延迟构建(AgentToolLazy)避免工具列表构建阶段的递归创建问题。
8
+ */
9
+ export function createSubAgentTool(def, provider, caps) {
10
+ if (!def.function) {
11
+ throw new Error(`Agent "${def.id}" 没有 function 字段,不能作为 SubAgent 工具`);
12
+ }
13
+ const selfName = def.function.name;
14
+ const lazy = new AgentToolLazy({
15
+ function: {
16
+ name: selfName,
17
+ description: def.function.description || def.description || def.name,
18
+ parameters: def.function.parameters,
19
+ },
20
+ messages: def.messages,
21
+ buildAgent: function (_parsedArgs) {
22
+ if (!caps) {
23
+ throw new Error(`SubAgent "${selfName}" 缺少 Capabilities 引用。` +
24
+ `请确保 Capabilities.instantiate() 传入了 caps(this)。`);
25
+ }
26
+ // 模型解析:SubAgent 可指定独立模型,否则复用父 Agent 的模型
27
+ let subModel;
28
+ if (def.modelId) {
29
+ subModel = createModel(provider.config, def.modelId);
30
+ }
31
+ else {
32
+ const parentModel = this.agent?.model;
33
+ if (!parentModel) {
34
+ throw new Error(`SubAgent "${selfName}" 未指定 modelId,且父 Agent 没有可复用的模型`);
35
+ }
36
+ subModel = parentModel;
37
+ }
38
+ // SubAgent 独立解析自己的工具(排除自身,防止递归)
39
+ const subFiltered = caps.filter(def.permissions ?? {}, {
40
+ exclude: {
41
+ subagents: def.function?.name ? [def.function.name] : undefined,
42
+ },
43
+ });
44
+ const tools = caps.instantiate(subFiltered);
45
+ const subAgent = new Agent({
46
+ model: subModel,
47
+ tools,
48
+ });
49
+ return subAgent;
50
+ },
51
+ });
52
+ return lazy;
53
+ }
@@ -0,0 +1,49 @@
1
+ import type { AppConfig, AgentDefinition } from "../types/index.js";
2
+ /**
3
+ * 配置管理器 — 负责配置文件的读写、目录初始化、默认实体创建。
4
+ */
5
+ export declare class ConfigManager {
6
+ readonly configPath: string;
7
+ readonly basePath: string;
8
+ constructor(configPath: string);
9
+ /**
10
+ * 读取配置。文件不存在时返回出厂默认配置。
11
+ */
12
+ read(): AppConfig;
13
+ write(config: AppConfig): void;
14
+ /**
15
+ * 确保基础目录结构存在。
16
+ * 创建 basePath 及所有标准共享子目录(agents/、sub-agents/、skills/ 等)。
17
+ */
18
+ ensureDirs(): void;
19
+ /**
20
+ * 确保 config.json 存在。不存在时写入出厂默认配置 DSL。
21
+ */
22
+ ensureDefaultConfig(): AppConfig;
23
+ /**
24
+ * 确保 basePath/agents/default.json 存在。
25
+ *
26
+ * - default.json 已存在 → 返回已有定义,不覆盖
27
+ * - agents/ 为空 → 写入默认 Agent
28
+ * - 已有其他 Agent → 返回 null
29
+ */
30
+ ensureDefaultAgent(): AgentDefinition | null;
31
+ /**
32
+ * 确保 basePath/sub-agents/{DEFAULT_SUBAGENT_ID}.json 存在。
33
+ *
34
+ * - 文件已存在 → 返回已有定义,不覆盖
35
+ * - sub-agents/ 为空 → 写入默认通用助手 SubAgent
36
+ * - 已有其他 SubAgent → 返回 null
37
+ */
38
+ ensureDefaultSubAgent(): AgentDefinition | null;
39
+ /**
40
+ * 一键初始化:目录 + config.json + 默认 Agent + 默认 SubAgent。
41
+ * 已有文件不会被覆盖。
42
+ */
43
+ bootstrap(): {
44
+ config: AppConfig;
45
+ agent: AgentDefinition | null;
46
+ subAgent: AgentDefinition | null;
47
+ };
48
+ }
49
+ export { DEFAULT_AGENT_ID, DEFAULT_AGENT_DEFINITION, DEFAULT_SUBAGENT_ID, DEFAULT_SUBAGENT_DEFINITION, DEFAULT_APP_CONFIG, CONFIG_SUB_DIRS, } from "./constants.js";
@@ -0,0 +1,126 @@
1
+ import { readFileSync, writeFileSync, existsSync, renameSync, mkdirSync, readdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { DEFAULT_AGENT_ID, DEFAULT_AGENT_DEFINITION, DEFAULT_SUBAGENT_ID, DEFAULT_SUBAGENT_DEFINITION, DEFAULT_APP_CONFIG, CONFIG_SUB_DIRS, } from "./constants.js";
4
+ /**
5
+ * 配置管理器 — 负责配置文件的读写、目录初始化、默认实体创建。
6
+ */
7
+ export class ConfigManager {
8
+ configPath;
9
+ basePath;
10
+ constructor(configPath) {
11
+ this.configPath = configPath;
12
+ this.basePath = dirname(configPath);
13
+ }
14
+ // -----------------------------------------------------------------------
15
+ // config.json
16
+ // -----------------------------------------------------------------------
17
+ /**
18
+ * 读取配置。文件不存在时返回出厂默认配置。
19
+ */
20
+ read() {
21
+ if (!existsSync(this.configPath)) {
22
+ return { ...DEFAULT_APP_CONFIG };
23
+ }
24
+ const raw = readFileSync(this.configPath, "utf-8");
25
+ return JSON.parse(raw);
26
+ }
27
+ write(config) {
28
+ const dir = dirname(this.configPath);
29
+ if (!existsSync(dir)) {
30
+ mkdirSync(dir, { recursive: true });
31
+ }
32
+ const tmpPath = this.configPath + ".tmp";
33
+ writeFileSync(tmpPath, JSON.stringify(config, null, 2), "utf-8");
34
+ renameSync(tmpPath, this.configPath);
35
+ }
36
+ // -----------------------------------------------------------------------
37
+ // 目录 & 默认实体
38
+ // -----------------------------------------------------------------------
39
+ /**
40
+ * 确保基础目录结构存在。
41
+ * 创建 basePath 及所有标准共享子目录(agents/、sub-agents/、skills/ 等)。
42
+ */
43
+ ensureDirs() {
44
+ mkdirSync(this.basePath, { recursive: true });
45
+ for (const dir of CONFIG_SUB_DIRS) {
46
+ mkdirSync(join(this.basePath, dir), { recursive: true });
47
+ }
48
+ }
49
+ /**
50
+ * 确保 config.json 存在。不存在时写入出厂默认配置 DSL。
51
+ */
52
+ ensureDefaultConfig() {
53
+ if (existsSync(this.configPath)) {
54
+ return this.read();
55
+ }
56
+ this.ensureDirs();
57
+ this.write(DEFAULT_APP_CONFIG);
58
+ return { ...DEFAULT_APP_CONFIG };
59
+ }
60
+ /**
61
+ * 确保 basePath/agents/default.json 存在。
62
+ *
63
+ * - default.json 已存在 → 返回已有定义,不覆盖
64
+ * - agents/ 为空 → 写入默认 Agent
65
+ * - 已有其他 Agent → 返回 null
66
+ */
67
+ ensureDefaultAgent() {
68
+ const agentsDir = join(this.basePath, "agents");
69
+ const defaultPath = join(agentsDir, `${DEFAULT_AGENT_ID}.json`);
70
+ if (existsSync(defaultPath)) {
71
+ return JSON.parse(readFileSync(defaultPath, "utf-8"));
72
+ }
73
+ mkdirSync(agentsDir, { recursive: true });
74
+ const existing = readdirSync(agentsDir).filter((f) => f.endsWith(".json"));
75
+ if (existing.length > 0) {
76
+ return null;
77
+ }
78
+ const now = new Date().toISOString();
79
+ const definition = {
80
+ ...DEFAULT_AGENT_DEFINITION,
81
+ createdAt: now,
82
+ updatedAt: now,
83
+ };
84
+ writeFileSync(defaultPath, JSON.stringify(definition, null, 2), "utf-8");
85
+ return definition;
86
+ }
87
+ /**
88
+ * 确保 basePath/sub-agents/{DEFAULT_SUBAGENT_ID}.json 存在。
89
+ *
90
+ * - 文件已存在 → 返回已有定义,不覆盖
91
+ * - sub-agents/ 为空 → 写入默认通用助手 SubAgent
92
+ * - 已有其他 SubAgent → 返回 null
93
+ */
94
+ ensureDefaultSubAgent() {
95
+ const subDir = join(this.basePath, "sub-agents");
96
+ const defaultPath = join(subDir, `${DEFAULT_SUBAGENT_ID}.json`);
97
+ if (existsSync(defaultPath)) {
98
+ return JSON.parse(readFileSync(defaultPath, "utf-8"));
99
+ }
100
+ mkdirSync(subDir, { recursive: true });
101
+ const existing = readdirSync(subDir).filter((f) => f.endsWith(".json"));
102
+ if (existing.length > 0) {
103
+ return null;
104
+ }
105
+ const now = new Date().toISOString();
106
+ const definition = {
107
+ ...DEFAULT_SUBAGENT_DEFINITION,
108
+ createdAt: now,
109
+ updatedAt: now,
110
+ };
111
+ writeFileSync(defaultPath, JSON.stringify(definition, null, 2), "utf-8");
112
+ return definition;
113
+ }
114
+ /**
115
+ * 一键初始化:目录 + config.json + 默认 Agent + 默认 SubAgent。
116
+ * 已有文件不会被覆盖。
117
+ */
118
+ bootstrap() {
119
+ this.ensureDirs();
120
+ const config = this.ensureDefaultConfig();
121
+ const agent = this.ensureDefaultAgent();
122
+ const subAgent = this.ensureDefaultSubAgent();
123
+ return { config, agent, subAgent };
124
+ }
125
+ }
126
+ export { DEFAULT_AGENT_ID, DEFAULT_AGENT_DEFINITION, DEFAULT_SUBAGENT_ID, DEFAULT_SUBAGENT_DEFINITION, DEFAULT_APP_CONFIG, CONFIG_SUB_DIRS, } from "./constants.js";
@@ -0,0 +1,20 @@
1
+ import type { AgentDefinition, AppConfig } from "../types/index.js";
2
+ /** 默认 Agent ID */
3
+ export declare const DEFAULT_AGENT_ID = "default";
4
+ /** 默认 Agent 定义(不含时间戳) */
5
+ export declare const DEFAULT_AGENT_DEFINITION: Omit<AgentDefinition, "createdAt" | "updatedAt">;
6
+ /** 默认 SubAgent ID */
7
+ export declare const DEFAULT_SUBAGENT_ID = "general-assistant";
8
+ /** 默认 SubAgent 定义(不含时间戳) */
9
+ export declare const DEFAULT_SUBAGENT_DEFINITION: Omit<AgentDefinition, "createdAt" | "updatedAt">;
10
+ /** SDK 出厂默认 AppConfig。CLI/Desktop 首次初始化时使用。 */
11
+ export declare const DEFAULT_APP_CONFIG: AppConfig;
12
+ /**
13
+ * 标准共享子目录列表(不包含运行时目录)。
14
+ *
15
+ * 各客户端(CLI/Desktop)的运行时数据(config.json、conversations/、drafts/)
16
+ * 由客户端自行在各自目录下管理:
17
+ * ~/.ai-zen/cli/ ← CLI 运行时
18
+ * ~/.ai-zen/desktop/ ← Desktop 运行时(未来)
19
+ */
20
+ export declare const CONFIG_SUB_DIRS: readonly ["agents", "sub-agents", "skills", "tools", "mcp-oauth"];