@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.
- package/CHANGELOG.md +9 -0
- package/lib/ai/agent.d.ts.map +1 -1
- package/lib/ai/agent.js +15 -2
- package/lib/ai/agent.js.map +1 -1
- package/lib/ai/bootstrap.d.ts +11 -2
- package/lib/ai/bootstrap.d.ts.map +1 -1
- package/lib/ai/bootstrap.js +46 -2
- package/lib/ai/bootstrap.js.map +1 -1
- package/lib/ai/builtin-tools.d.ts +28 -6
- package/lib/ai/builtin-tools.d.ts.map +1 -1
- package/lib/ai/builtin-tools.js +265 -76
- package/lib/ai/builtin-tools.js.map +1 -1
- package/lib/ai/index.d.ts +9 -1
- package/lib/ai/index.d.ts.map +1 -1
- package/lib/ai/index.js +8 -0
- package/lib/ai/index.js.map +1 -1
- package/lib/ai/init.d.ts.map +1 -1
- package/lib/ai/init.js +84 -3
- package/lib/ai/init.js.map +1 -1
- package/lib/ai/providers/anthropic.d.ts +7 -0
- package/lib/ai/providers/anthropic.d.ts.map +1 -1
- package/lib/ai/providers/anthropic.js +3 -0
- package/lib/ai/providers/anthropic.js.map +1 -1
- package/lib/ai/providers/ollama.d.ts +10 -0
- package/lib/ai/providers/ollama.d.ts.map +1 -1
- package/lib/ai/providers/ollama.js +11 -3
- package/lib/ai/providers/ollama.js.map +1 -1
- package/lib/ai/providers/openai.d.ts +7 -0
- package/lib/ai/providers/openai.d.ts.map +1 -1
- package/lib/ai/providers/openai.js +3 -0
- package/lib/ai/providers/openai.js.map +1 -1
- package/lib/ai/service.d.ts +4 -0
- package/lib/ai/service.d.ts.map +1 -1
- package/lib/ai/service.js +7 -0
- package/lib/ai/service.js.map +1 -1
- package/lib/ai/subagent.d.ts +50 -0
- package/lib/ai/subagent.d.ts.map +1 -0
- package/lib/ai/subagent.js +144 -0
- package/lib/ai/subagent.js.map +1 -0
- package/lib/ai/types.d.ts +25 -5
- package/lib/ai/types.d.ts.map +1 -1
- package/lib/ai/zhin-agent-builtin-tools.d.ts +17 -0
- package/lib/ai/zhin-agent-builtin-tools.d.ts.map +1 -0
- package/lib/ai/zhin-agent-builtin-tools.js +220 -0
- package/lib/ai/zhin-agent-builtin-tools.js.map +1 -0
- package/lib/ai/zhin-agent-config.d.ts +54 -0
- package/lib/ai/zhin-agent-config.d.ts.map +1 -0
- package/lib/ai/zhin-agent-config.js +76 -0
- package/lib/ai/zhin-agent-config.js.map +1 -0
- package/lib/ai/zhin-agent-exec-policy.d.ts +20 -0
- package/lib/ai/zhin-agent-exec-policy.d.ts.map +1 -0
- package/lib/ai/zhin-agent-exec-policy.js +71 -0
- package/lib/ai/zhin-agent-exec-policy.js.map +1 -0
- package/lib/ai/zhin-agent-prompt.d.ts +21 -0
- package/lib/ai/zhin-agent-prompt.d.ts.map +1 -0
- package/lib/ai/zhin-agent-prompt.js +116 -0
- package/lib/ai/zhin-agent-prompt.js.map +1 -0
- package/lib/ai/zhin-agent-tool-collector.d.ts +22 -0
- package/lib/ai/zhin-agent-tool-collector.d.ts.map +1 -0
- package/lib/ai/zhin-agent-tool-collector.js +218 -0
- package/lib/ai/zhin-agent-tool-collector.js.map +1 -0
- package/lib/ai/zhin-agent.d.ts +11 -155
- package/lib/ai/zhin-agent.d.ts.map +1 -1
- package/lib/ai/zhin-agent.js +84 -684
- package/lib/ai/zhin-agent.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/scheduler/index.d.ts +10 -0
- package/lib/scheduler/index.d.ts.map +1 -0
- package/lib/scheduler/index.js +12 -0
- package/lib/scheduler/index.js.map +1 -0
- package/lib/scheduler/scheduler.d.ts +49 -0
- package/lib/scheduler/scheduler.d.ts.map +1 -0
- package/lib/scheduler/scheduler.js +352 -0
- package/lib/scheduler/scheduler.js.map +1 -0
- package/lib/scheduler/types.d.ts +71 -0
- package/lib/scheduler/types.d.ts.map +1 -0
- package/lib/scheduler/types.js +8 -0
- package/lib/scheduler/types.js.map +1 -0
- package/lib/tool-zod.d.ts +28 -0
- package/lib/tool-zod.d.ts.map +1 -0
- package/lib/tool-zod.js +98 -0
- package/lib/tool-zod.js.map +1 -0
- package/package.json +9 -4
- package/src/ai/agent.ts +15 -2
- package/src/ai/bootstrap.ts +48 -2
- package/src/ai/builtin-tools.ts +283 -75
- package/src/ai/index.ts +19 -1
- package/src/ai/init.ts +85 -3
- package/src/ai/providers/anthropic.ts +3 -0
- package/src/ai/providers/ollama.ts +13 -3
- package/src/ai/providers/openai.ts +3 -0
- package/src/ai/service.ts +8 -0
- package/src/ai/subagent.ts +209 -0
- package/src/ai/types.ts +29 -2
- package/src/ai/zhin-agent-builtin-tools.ts +247 -0
- package/src/ai/zhin-agent-config.ts +113 -0
- package/src/ai/zhin-agent-exec-policy.ts +78 -0
- package/src/ai/zhin-agent-prompt.ts +136 -0
- package/src/ai/zhin-agent-tool-collector.ts +243 -0
- package/src/ai/zhin-agent.ts +113 -791
- package/src/index.ts +1 -0
- package/src/scheduler/index.ts +28 -0
- package/src/scheduler/scheduler.ts +372 -0
- package/src/scheduler/types.ts +74 -0
- package/src/tool-zod.ts +115 -0
- 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 @@
|
|
|
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"}
|
package/lib/tool-zod.js
ADDED
|
@@ -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.
|
|
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.
|
|
36
|
-
"@zhin.js/logger": "0.1.
|
|
37
|
-
"@zhin.js/schema": "1.0.
|
|
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
|
-
|
|
291
|
-
|
|
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,
|
package/src/ai/bootstrap.ts
CHANGED
|
@@ -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
|
*
|