@zhin.js/core 1.0.33 → 1.0.34

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 (109) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/lib/ai/agent.d.ts.map +1 -1
  3. package/lib/ai/agent.js +15 -2
  4. package/lib/ai/agent.js.map +1 -1
  5. package/lib/ai/bootstrap.d.ts +11 -2
  6. package/lib/ai/bootstrap.d.ts.map +1 -1
  7. package/lib/ai/bootstrap.js +46 -2
  8. package/lib/ai/bootstrap.js.map +1 -1
  9. package/lib/ai/builtin-tools.d.ts +28 -6
  10. package/lib/ai/builtin-tools.d.ts.map +1 -1
  11. package/lib/ai/builtin-tools.js +265 -76
  12. package/lib/ai/builtin-tools.js.map +1 -1
  13. package/lib/ai/index.d.ts +9 -1
  14. package/lib/ai/index.d.ts.map +1 -1
  15. package/lib/ai/index.js +8 -0
  16. package/lib/ai/index.js.map +1 -1
  17. package/lib/ai/init.d.ts.map +1 -1
  18. package/lib/ai/init.js +84 -3
  19. package/lib/ai/init.js.map +1 -1
  20. package/lib/ai/providers/anthropic.d.ts +7 -0
  21. package/lib/ai/providers/anthropic.d.ts.map +1 -1
  22. package/lib/ai/providers/anthropic.js +3 -0
  23. package/lib/ai/providers/anthropic.js.map +1 -1
  24. package/lib/ai/providers/ollama.d.ts +10 -0
  25. package/lib/ai/providers/ollama.d.ts.map +1 -1
  26. package/lib/ai/providers/ollama.js +11 -3
  27. package/lib/ai/providers/ollama.js.map +1 -1
  28. package/lib/ai/providers/openai.d.ts +7 -0
  29. package/lib/ai/providers/openai.d.ts.map +1 -1
  30. package/lib/ai/providers/openai.js +3 -0
  31. package/lib/ai/providers/openai.js.map +1 -1
  32. package/lib/ai/service.d.ts +4 -0
  33. package/lib/ai/service.d.ts.map +1 -1
  34. package/lib/ai/service.js +7 -0
  35. package/lib/ai/service.js.map +1 -1
  36. package/lib/ai/subagent.d.ts +50 -0
  37. package/lib/ai/subagent.d.ts.map +1 -0
  38. package/lib/ai/subagent.js +144 -0
  39. package/lib/ai/subagent.js.map +1 -0
  40. package/lib/ai/types.d.ts +25 -5
  41. package/lib/ai/types.d.ts.map +1 -1
  42. package/lib/ai/zhin-agent-builtin-tools.d.ts +17 -0
  43. package/lib/ai/zhin-agent-builtin-tools.d.ts.map +1 -0
  44. package/lib/ai/zhin-agent-builtin-tools.js +220 -0
  45. package/lib/ai/zhin-agent-builtin-tools.js.map +1 -0
  46. package/lib/ai/zhin-agent-config.d.ts +54 -0
  47. package/lib/ai/zhin-agent-config.d.ts.map +1 -0
  48. package/lib/ai/zhin-agent-config.js +76 -0
  49. package/lib/ai/zhin-agent-config.js.map +1 -0
  50. package/lib/ai/zhin-agent-exec-policy.d.ts +20 -0
  51. package/lib/ai/zhin-agent-exec-policy.d.ts.map +1 -0
  52. package/lib/ai/zhin-agent-exec-policy.js +71 -0
  53. package/lib/ai/zhin-agent-exec-policy.js.map +1 -0
  54. package/lib/ai/zhin-agent-prompt.d.ts +21 -0
  55. package/lib/ai/zhin-agent-prompt.d.ts.map +1 -0
  56. package/lib/ai/zhin-agent-prompt.js +116 -0
  57. package/lib/ai/zhin-agent-prompt.js.map +1 -0
  58. package/lib/ai/zhin-agent-tool-collector.d.ts +22 -0
  59. package/lib/ai/zhin-agent-tool-collector.d.ts.map +1 -0
  60. package/lib/ai/zhin-agent-tool-collector.js +218 -0
  61. package/lib/ai/zhin-agent-tool-collector.js.map +1 -0
  62. package/lib/ai/zhin-agent.d.ts +11 -155
  63. package/lib/ai/zhin-agent.d.ts.map +1 -1
  64. package/lib/ai/zhin-agent.js +84 -684
  65. package/lib/ai/zhin-agent.js.map +1 -1
  66. package/lib/index.d.ts +1 -0
  67. package/lib/index.d.ts.map +1 -1
  68. package/lib/index.js +1 -0
  69. package/lib/index.js.map +1 -1
  70. package/lib/scheduler/index.d.ts +10 -0
  71. package/lib/scheduler/index.d.ts.map +1 -0
  72. package/lib/scheduler/index.js +12 -0
  73. package/lib/scheduler/index.js.map +1 -0
  74. package/lib/scheduler/scheduler.d.ts +49 -0
  75. package/lib/scheduler/scheduler.d.ts.map +1 -0
  76. package/lib/scheduler/scheduler.js +352 -0
  77. package/lib/scheduler/scheduler.js.map +1 -0
  78. package/lib/scheduler/types.d.ts +71 -0
  79. package/lib/scheduler/types.d.ts.map +1 -0
  80. package/lib/scheduler/types.js +8 -0
  81. package/lib/scheduler/types.js.map +1 -0
  82. package/lib/tool-zod.d.ts +28 -0
  83. package/lib/tool-zod.d.ts.map +1 -0
  84. package/lib/tool-zod.js +98 -0
  85. package/lib/tool-zod.js.map +1 -0
  86. package/package.json +9 -4
  87. package/src/ai/agent.ts +15 -2
  88. package/src/ai/bootstrap.ts +48 -2
  89. package/src/ai/builtin-tools.ts +283 -75
  90. package/src/ai/index.ts +19 -1
  91. package/src/ai/init.ts +85 -3
  92. package/src/ai/providers/anthropic.ts +3 -0
  93. package/src/ai/providers/ollama.ts +13 -3
  94. package/src/ai/providers/openai.ts +3 -0
  95. package/src/ai/service.ts +8 -0
  96. package/src/ai/subagent.ts +209 -0
  97. package/src/ai/types.ts +29 -2
  98. package/src/ai/zhin-agent-builtin-tools.ts +247 -0
  99. package/src/ai/zhin-agent-config.ts +113 -0
  100. package/src/ai/zhin-agent-exec-policy.ts +78 -0
  101. package/src/ai/zhin-agent-prompt.ts +136 -0
  102. package/src/ai/zhin-agent-tool-collector.ts +243 -0
  103. package/src/ai/zhin-agent.ts +113 -791
  104. package/src/index.ts +1 -0
  105. package/src/scheduler/index.ts +28 -0
  106. package/src/scheduler/scheduler.ts +372 -0
  107. package/src/scheduler/types.ts +74 -0
  108. package/src/tool-zod.ts +115 -0
  109. package/tests/ai/subagent.test.ts +270 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Scheduler types
3
+ *
4
+ * 支持三种调度:at(单次指定时间)、every(固定间隔)、cron(表达式)
5
+ * Payload 支持 agent_turn(到点执行 prompt)、heartbeat(读 HEARTBEAT.md)、system_event
6
+ */
7
+ export interface Schedule {
8
+ kind: 'at' | 'every' | 'cron';
9
+ /** 单次执行时间戳(kind=at) */
10
+ atMs?: number;
11
+ /** 间隔毫秒(kind=every) */
12
+ everyMs?: number;
13
+ /** Cron 表达式(kind=cron) */
14
+ expr?: string;
15
+ /** 时区(kind=cron 可选) */
16
+ tz?: string;
17
+ }
18
+ export interface JobPayload {
19
+ kind: 'system_event' | 'agent_turn' | 'heartbeat';
20
+ /** 触发时发给 AI 的 prompt(agent_turn)或 heartbeat 说明 */
21
+ message: string;
22
+ /** 是否投递到指定 channel/user */
23
+ deliver: boolean;
24
+ channel?: string;
25
+ to?: string;
26
+ }
27
+ export interface JobState {
28
+ nextRunAtMs?: number;
29
+ lastRunAtMs?: number;
30
+ lastStatus?: 'ok' | 'error' | 'skipped';
31
+ lastError?: string;
32
+ }
33
+ export interface ScheduledJob {
34
+ id: string;
35
+ name: string;
36
+ enabled: boolean;
37
+ schedule: Schedule;
38
+ payload: JobPayload;
39
+ state: JobState;
40
+ createdAtMs: number;
41
+ updatedAtMs: number;
42
+ /** 单次任务执行后是否删除 */
43
+ deleteAfterRun: boolean;
44
+ }
45
+ export interface JobStore {
46
+ version: number;
47
+ jobs: ScheduledJob[];
48
+ }
49
+ export type JobCallback = (job: ScheduledJob) => Promise<void>;
50
+ export interface AddJobOptions {
51
+ name: string;
52
+ schedule: Schedule;
53
+ payload: JobPayload;
54
+ enabled?: boolean;
55
+ deleteAfterRun?: boolean;
56
+ }
57
+ export interface IScheduler {
58
+ start(): Promise<void>;
59
+ stop(): void;
60
+ addJob(options: AddJobOptions): ScheduledJob;
61
+ removeJob(jobId: string): boolean;
62
+ enableJob(jobId: string, enabled: boolean): boolean;
63
+ runJob(jobId: string): Promise<void>;
64
+ listJobs(): ScheduledJob[];
65
+ status(): {
66
+ running: boolean;
67
+ jobCount: number;
68
+ nextWakeAt?: number;
69
+ };
70
+ }
71
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scheduler/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC;IAC9B,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC;IAClD,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB;IAClB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,YAAY,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAAC;IAC7C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IACpD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,IAAI,YAAY,EAAE,CAAC;IAC3B,MAAM,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvE"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Scheduler types
3
+ *
4
+ * 支持三种调度:at(单次指定时间)、every(固定间隔)、cron(表达式)
5
+ * Payload 支持 agent_turn(到点执行 prompt)、heartbeat(读 HEARTBEAT.md)、system_event
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scheduler/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Zod 工具适配层(可选)
3
+ *
4
+ * 使用 Zod 定义工具参数时可获得类型推断与校验。需安装 zod:
5
+ * pnpm add zod
6
+ *
7
+ * 用法:
8
+ * import { createToolFromZod } from '@zhin.js/core/tool-zod';
9
+ * import { z } from 'zod';
10
+ * const tool = createToolFromZod('my_tool', '描述', z.object({ id: z.string() }), async (args) => { ... });
11
+ * plugin.addTool(tool);
12
+ */
13
+ import type { Tool, ToolContext } from './types.js';
14
+ type MaybePromise<T> = T | Promise<T>;
15
+ export interface CreateToolFromZodOptions {
16
+ tags?: string[];
17
+ keywords?: string[];
18
+ source?: string;
19
+ hidden?: boolean;
20
+ kind?: string;
21
+ }
22
+ /**
23
+ * 从 Zod 模式创建 Tool,便于类型安全与校验。
24
+ * 需要安装 zod:pnpm add zod。传入的 schema 应为 z.object({ ... })。
25
+ */
26
+ export declare function createToolFromZod<T extends Record<string, any>>(name: string, description: string, schema: any, execute: (args: T, context?: ToolContext) => MaybePromise<any>, options?: CreateToolFromZodOptions): Tool;
27
+ export {};
28
+ //# sourceMappingURL=tool-zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-zod.d.ts","sourceRoot":"","sources":["../src/tool-zod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AAE1E,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAyDtC,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7D,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,YAAY,CAAC,GAAG,CAAC,EAC9D,OAAO,CAAC,EAAE,wBAAwB,GACjC,IAAI,CAuBN"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Zod 工具适配层(可选)
3
+ *
4
+ * 使用 Zod 定义工具参数时可获得类型推断与校验。需安装 zod:
5
+ * pnpm add zod
6
+ *
7
+ * 用法:
8
+ * import { createToolFromZod } from '@zhin.js/core/tool-zod';
9
+ * import { z } from 'zod';
10
+ * const tool = createToolFromZod('my_tool', '描述', z.object({ id: z.string() }), async (args) => { ... });
11
+ * plugin.addTool(tool);
12
+ */
13
+ function zodFieldToJsonSchema(z) {
14
+ if (!z || !z._def)
15
+ return { type: 'string' };
16
+ const def = z._def;
17
+ const typeName = def.typeName;
18
+ if (typeName === 'ZodOptional' || typeName === 'ZodDefault') {
19
+ const inner = def.innerType ?? def.type;
20
+ return zodFieldToJsonSchema(inner);
21
+ }
22
+ if (typeName === 'ZodString') {
23
+ const out = { type: 'string' };
24
+ if (def.description)
25
+ out.description = def.description;
26
+ return out;
27
+ }
28
+ if (typeName === 'ZodNumber') {
29
+ const out = { type: 'number' };
30
+ if (def.description)
31
+ out.description = def.description;
32
+ return out;
33
+ }
34
+ if (typeName === 'ZodBoolean') {
35
+ const out = { type: 'boolean' };
36
+ if (def.description)
37
+ out.description = def.description;
38
+ return out;
39
+ }
40
+ if (typeName === 'ZodEnum') {
41
+ return { type: 'string', enum: def.values };
42
+ }
43
+ if (typeName === 'ZodArray') {
44
+ return { type: 'array', items: zodFieldToJsonSchema(def.type ?? def.element) };
45
+ }
46
+ return { type: 'string' };
47
+ }
48
+ function zodToJsonSchema(schema) {
49
+ const result = {
50
+ type: 'object',
51
+ properties: {},
52
+ required: [],
53
+ };
54
+ if (!schema || !schema.shape)
55
+ return result;
56
+ const shape = schema.shape;
57
+ const properties = result.properties;
58
+ const required = [];
59
+ for (const [key, value] of Object.entries(shape)) {
60
+ const zodValue = value;
61
+ properties[key] = zodFieldToJsonSchema(zodValue);
62
+ const typeName = zodValue?._def?.typeName;
63
+ if (typeName !== 'ZodOptional' && typeName !== 'ZodDefault') {
64
+ required.push(key);
65
+ }
66
+ }
67
+ result.required = required.length > 0 ? required : undefined;
68
+ return result;
69
+ }
70
+ /**
71
+ * 从 Zod 模式创建 Tool,便于类型安全与校验。
72
+ * 需要安装 zod:pnpm add zod。传入的 schema 应为 z.object({ ... })。
73
+ */
74
+ export function createToolFromZod(name, description, schema, execute, options) {
75
+ if (!schema?.safeParse) {
76
+ throw new Error('createToolFromZod: schema must be a Zod object schema (e.g. z.object({ ... })). Install zod: pnpm add zod');
77
+ }
78
+ const parameters = zodToJsonSchema(schema);
79
+ return {
80
+ name,
81
+ description,
82
+ parameters,
83
+ execute: async (args, context) => {
84
+ const parsed = schema.safeParse(args);
85
+ if (!parsed.success) {
86
+ const msg = parsed.error.errors?.map((e) => `${e.path?.join('.') ?? 'root'}: ${e.message}`).join('; ') ?? 'Invalid arguments';
87
+ return `Error: ${msg}`;
88
+ }
89
+ return execute(parsed.data, context);
90
+ },
91
+ tags: options?.tags,
92
+ keywords: options?.keywords,
93
+ source: options?.source,
94
+ hidden: options?.hidden,
95
+ kind: options?.kind,
96
+ };
97
+ }
98
+ //# sourceMappingURL=tool-zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-zod.js","sourceRoot":"","sources":["../src/tool-zod.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/core",
3
- "version": "1.0.33",
3
+ "version": "1.0.34",
4
4
  "description": "Zhin机器人核心框架",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -11,6 +11,11 @@
11
11
  "development": "./src/index.ts",
12
12
  "import": "./lib/index.js"
13
13
  },
14
+ "./tool-zod": {
15
+ "types": "./lib/tool-zod.d.ts",
16
+ "development": "./src/tool-zod.ts",
17
+ "import": "./lib/tool-zod.js"
18
+ },
14
19
  "./jsx": {
15
20
  "types": "./lib/jsx.d.ts",
16
21
  "development": "./src/jsx.ts",
@@ -32,9 +37,9 @@
32
37
  "segment-matcher": "latest",
33
38
  "smol-toml": "^1.6.0",
34
39
  "yaml": "^2.3.4",
35
- "@zhin.js/database": "1.0.20",
36
- "@zhin.js/logger": "0.1.17",
37
- "@zhin.js/schema": "1.0.17"
40
+ "@zhin.js/database": "1.0.21",
41
+ "@zhin.js/logger": "0.1.18",
42
+ "@zhin.js/schema": "1.0.18"
38
43
  },
39
44
  "devDependencies": {
40
45
  "@types/node": "^24.3.0",
package/src/ai/agent.ts CHANGED
@@ -32,6 +32,7 @@ export function formatToolTitle(name: string, args?: Record<string, any>): strin
32
32
  case 'read_file': return a.file_path != null ? `read_file: ${a.file_path}` : name;
33
33
  case 'write_file': return a.file_path != null ? `write_file: ${a.file_path}` : name;
34
34
  case 'edit_file': return a.file_path != null ? `edit_file: ${a.file_path}` : name;
35
+ case 'list_dir': return a.path != null ? `list_dir: ${a.path}` : name;
35
36
  case 'web_search': return a.query != null ? `web_search: ${String(a.query).slice(0, 40)}` : name;
36
37
  case 'web_fetch': return a.url != null ? `web_fetch: ${String(a.url).slice(0, 50)}` : name;
37
38
  default: {
@@ -286,10 +287,21 @@ export class Agent {
286
287
  });
287
288
  }
288
289
 
290
+ let args: Record<string, unknown>;
289
291
  try {
290
- const args = JSON.parse(toolCall.function.arguments);
291
- this.emit('tool_call', tool.name, args);
292
+ args = JSON.parse(toolCall.function.arguments);
293
+ } catch {
294
+ return JSON.stringify({
295
+ error: 'Invalid tool arguments JSON',
296
+ tool: toolCall.function.name,
297
+ hint: '请检查工具参数格式后重试。',
298
+ });
299
+ }
300
+
301
+ logger.debug({ tool: toolCall.function.name, params: args }, 'Executing tool');
302
+ this.emit('tool_call', tool.name, args);
292
303
 
304
+ try {
293
305
  // 带超时的工具执行
294
306
  const result = await Promise.race([
295
307
  tool.execute(args),
@@ -303,6 +315,7 @@ export class Agent {
303
315
  } catch (error) {
304
316
  const errorMsg = error instanceof Error ? error.message : String(error);
305
317
  logger.warn(`工具 ${toolCall.function.name} 执行失败: ${errorMsg}`);
318
+ logger.error({ tool: toolCall.function.name, params: args, err: error }, 'Tool execution failed');
306
319
  // 向 AI 提供结构化的错误信息和恢复提示
307
320
  return JSON.stringify({
308
321
  error: errorMsg,
@@ -24,10 +24,10 @@ const logger = new Logger(null, 'Bootstrap');
24
24
  // 常量
25
25
  // ============================================================================
26
26
 
27
- /** 支持的引导文件名 */
27
+ /** 支持的引导文件名(顺序:SOUL → AGENTS → TOOLS) */
28
28
  export const BOOTSTRAP_FILENAMES = [
29
- 'AGENTS.md',
30
29
  'SOUL.md',
30
+ 'AGENTS.md',
31
31
  'TOOLS.md',
32
32
  ] as const;
33
33
 
@@ -104,6 +104,52 @@ function getDataDir(workspaceDir?: string): string {
104
104
  return path.join(cwd, 'data');
105
105
  }
106
106
 
107
+ /**
108
+ * 获取文件制长期记忆目录(data/memory),不存在则创建
109
+ */
110
+ export function getMemoryDir(workspaceDir?: string): string {
111
+ const dir = path.join(getDataDir(workspaceDir), 'memory');
112
+ if (!fs.existsSync(dir)) {
113
+ fs.mkdirSync(dir, { recursive: true });
114
+ }
115
+ return dir;
116
+ }
117
+
118
+ function todayDate(): string {
119
+ return new Date().toISOString().split('T')[0];
120
+ }
121
+
122
+ /**
123
+ * 读取文件制长期记忆 + 当日笔记,拼成注入 system prompt 的字符串(与 miniclawd 一致)
124
+ * 同步读取,供 buildRichSystemPrompt 等同步调用
125
+ */
126
+ export function getFileMemoryContext(workspaceDir?: string): string {
127
+ const memoryDir = getMemoryDir(workspaceDir);
128
+ const parts: string[] = [];
129
+
130
+ const memoryFile = path.join(memoryDir, 'MEMORY.md');
131
+ if (fs.existsSync(memoryFile)) {
132
+ try {
133
+ const longTerm = fs.readFileSync(memoryFile, 'utf-8').trim();
134
+ if (longTerm) parts.push('## Long-term Memory\n' + longTerm);
135
+ } catch {
136
+ // ignore read errors
137
+ }
138
+ }
139
+
140
+ const todayFile = path.join(memoryDir, `${todayDate()}.md`);
141
+ if (fs.existsSync(todayFile)) {
142
+ try {
143
+ const today = fs.readFileSync(todayFile, 'utf-8').trim();
144
+ if (today) parts.push("## Today's Notes\n" + today);
145
+ } catch {
146
+ // ignore read errors
147
+ }
148
+ }
149
+
150
+ return parts.length > 0 ? parts.join('\n\n') : '';
151
+ }
152
+
107
153
  /**
108
154
  * 加载工作区引导文件
109
155
  *