@zhin.js/core 1.0.37 → 1.0.38

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 (196) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +57 -3
  3. package/lib/adapter.d.ts +11 -0
  4. package/lib/adapter.d.ts.map +1 -1
  5. package/lib/adapter.js +61 -0
  6. package/lib/adapter.js.map +1 -1
  7. package/lib/ai/index.d.ts +3 -39
  8. package/lib/ai/index.d.ts.map +1 -1
  9. package/lib/ai/index.js +2 -44
  10. package/lib/ai/index.js.map +1 -1
  11. package/lib/ai/types.d.ts +4 -3
  12. package/lib/ai/types.d.ts.map +1 -1
  13. package/lib/built/ai-trigger.js.map +1 -1
  14. package/lib/built/common-adapter-tools.d.ts +55 -0
  15. package/lib/built/common-adapter-tools.d.ts.map +1 -0
  16. package/lib/built/common-adapter-tools.js +158 -0
  17. package/lib/built/common-adapter-tools.js.map +1 -0
  18. package/lib/built/dispatcher.d.ts.map +1 -1
  19. package/lib/built/dispatcher.js +50 -46
  20. package/lib/built/dispatcher.js.map +1 -1
  21. package/lib/built/skill.d.ts.map +1 -1
  22. package/lib/built/skill.js +0 -1
  23. package/lib/built/skill.js.map +1 -1
  24. package/lib/built/tool.d.ts +3 -3
  25. package/lib/built/tool.d.ts.map +1 -1
  26. package/lib/built/tool.js.map +1 -1
  27. package/lib/feature.d.ts +16 -1
  28. package/lib/feature.d.ts.map +1 -1
  29. package/lib/feature.js +41 -2
  30. package/lib/feature.js.map +1 -1
  31. package/lib/index.d.ts +1 -0
  32. package/lib/index.d.ts.map +1 -1
  33. package/lib/index.js +2 -0
  34. package/lib/index.js.map +1 -1
  35. package/lib/plugin.d.ts +38 -1
  36. package/lib/plugin.d.ts.map +1 -1
  37. package/lib/plugin.js +73 -22
  38. package/lib/plugin.js.map +1 -1
  39. package/lib/scheduler/scheduler.js +1 -1
  40. package/lib/scheduler/scheduler.js.map +1 -1
  41. package/lib/types.d.ts +43 -28
  42. package/lib/types.d.ts.map +1 -1
  43. package/lib/utils.d.ts +12 -3
  44. package/lib/utils.d.ts.map +1 -1
  45. package/lib/utils.js +64 -54
  46. package/lib/utils.js.map +1 -1
  47. package/package.json +5 -5
  48. package/src/adapter.ts +85 -5
  49. package/src/ai/index.ts +8 -186
  50. package/src/ai/types.ts +5 -4
  51. package/src/built/ai-trigger.ts +2 -2
  52. package/src/built/common-adapter-tools.ts +207 -0
  53. package/src/built/dispatcher.ts +51 -52
  54. package/src/built/skill.ts +3 -4
  55. package/src/built/tool.ts +3 -3
  56. package/src/feature.ts +45 -2
  57. package/src/index.ts +2 -0
  58. package/src/plugin.ts +92 -31
  59. package/src/scheduler/scheduler.ts +1 -1
  60. package/src/types.ts +39 -28
  61. package/src/utils.ts +63 -52
  62. package/tests/ai/setup.ts +2 -2
  63. package/tests/utils.test.ts +1 -3
  64. package/lib/ai/agent.d.ts +0 -130
  65. package/lib/ai/agent.d.ts.map +0 -1
  66. package/lib/ai/agent.js +0 -702
  67. package/lib/ai/agent.js.map +0 -1
  68. package/lib/ai/bootstrap.d.ts +0 -91
  69. package/lib/ai/bootstrap.d.ts.map +0 -1
  70. package/lib/ai/bootstrap.js +0 -243
  71. package/lib/ai/bootstrap.js.map +0 -1
  72. package/lib/ai/builtin-tools.d.ts +0 -59
  73. package/lib/ai/builtin-tools.d.ts.map +0 -1
  74. package/lib/ai/builtin-tools.js +0 -777
  75. package/lib/ai/builtin-tools.js.map +0 -1
  76. package/lib/ai/compaction.d.ts +0 -132
  77. package/lib/ai/compaction.d.ts.map +0 -1
  78. package/lib/ai/compaction.js +0 -370
  79. package/lib/ai/compaction.js.map +0 -1
  80. package/lib/ai/context-manager.d.ts +0 -213
  81. package/lib/ai/context-manager.d.ts.map +0 -1
  82. package/lib/ai/context-manager.js +0 -313
  83. package/lib/ai/context-manager.js.map +0 -1
  84. package/lib/ai/conversation-memory.d.ts +0 -181
  85. package/lib/ai/conversation-memory.d.ts.map +0 -1
  86. package/lib/ai/conversation-memory.js +0 -581
  87. package/lib/ai/conversation-memory.js.map +0 -1
  88. package/lib/ai/cron-engine.d.ts +0 -92
  89. package/lib/ai/cron-engine.d.ts.map +0 -1
  90. package/lib/ai/cron-engine.js +0 -278
  91. package/lib/ai/cron-engine.js.map +0 -1
  92. package/lib/ai/follow-up.d.ts +0 -131
  93. package/lib/ai/follow-up.d.ts.map +0 -1
  94. package/lib/ai/follow-up.js +0 -265
  95. package/lib/ai/follow-up.js.map +0 -1
  96. package/lib/ai/hooks.d.ts +0 -143
  97. package/lib/ai/hooks.d.ts.map +0 -1
  98. package/lib/ai/hooks.js +0 -108
  99. package/lib/ai/hooks.js.map +0 -1
  100. package/lib/ai/init.d.ts +0 -30
  101. package/lib/ai/init.d.ts.map +0 -1
  102. package/lib/ai/init.js +0 -686
  103. package/lib/ai/init.js.map +0 -1
  104. package/lib/ai/output.d.ts +0 -93
  105. package/lib/ai/output.d.ts.map +0 -1
  106. package/lib/ai/output.js +0 -176
  107. package/lib/ai/output.js.map +0 -1
  108. package/lib/ai/rate-limiter.d.ts +0 -38
  109. package/lib/ai/rate-limiter.d.ts.map +0 -1
  110. package/lib/ai/rate-limiter.js +0 -86
  111. package/lib/ai/rate-limiter.js.map +0 -1
  112. package/lib/ai/service.d.ts +0 -88
  113. package/lib/ai/service.d.ts.map +0 -1
  114. package/lib/ai/service.js +0 -285
  115. package/lib/ai/service.js.map +0 -1
  116. package/lib/ai/session.d.ts +0 -186
  117. package/lib/ai/session.d.ts.map +0 -1
  118. package/lib/ai/session.js +0 -443
  119. package/lib/ai/session.js.map +0 -1
  120. package/lib/ai/subagent.d.ts +0 -50
  121. package/lib/ai/subagent.d.ts.map +0 -1
  122. package/lib/ai/subagent.js +0 -144
  123. package/lib/ai/subagent.js.map +0 -1
  124. package/lib/ai/tone-detector.d.ts +0 -19
  125. package/lib/ai/tone-detector.d.ts.map +0 -1
  126. package/lib/ai/tone-detector.js +0 -72
  127. package/lib/ai/tone-detector.js.map +0 -1
  128. package/lib/ai/tools.d.ts +0 -45
  129. package/lib/ai/tools.d.ts.map +0 -1
  130. package/lib/ai/tools.js +0 -206
  131. package/lib/ai/tools.js.map +0 -1
  132. package/lib/ai/user-profile.d.ts +0 -56
  133. package/lib/ai/user-profile.d.ts.map +0 -1
  134. package/lib/ai/user-profile.js +0 -130
  135. package/lib/ai/user-profile.js.map +0 -1
  136. package/lib/ai/zhin-agent/builtin-tools.d.ts +0 -17
  137. package/lib/ai/zhin-agent/builtin-tools.d.ts.map +0 -1
  138. package/lib/ai/zhin-agent/builtin-tools.js +0 -220
  139. package/lib/ai/zhin-agent/builtin-tools.js.map +0 -1
  140. package/lib/ai/zhin-agent/config.d.ts +0 -54
  141. package/lib/ai/zhin-agent/config.d.ts.map +0 -1
  142. package/lib/ai/zhin-agent/config.js +0 -76
  143. package/lib/ai/zhin-agent/config.js.map +0 -1
  144. package/lib/ai/zhin-agent/exec-policy.d.ts +0 -20
  145. package/lib/ai/zhin-agent/exec-policy.d.ts.map +0 -1
  146. package/lib/ai/zhin-agent/exec-policy.js +0 -71
  147. package/lib/ai/zhin-agent/exec-policy.js.map +0 -1
  148. package/lib/ai/zhin-agent/index.d.ts +0 -70
  149. package/lib/ai/zhin-agent/index.d.ts.map +0 -1
  150. package/lib/ai/zhin-agent/index.js +0 -404
  151. package/lib/ai/zhin-agent/index.js.map +0 -1
  152. package/lib/ai/zhin-agent/prompt.d.ts +0 -21
  153. package/lib/ai/zhin-agent/prompt.d.ts.map +0 -1
  154. package/lib/ai/zhin-agent/prompt.js +0 -111
  155. package/lib/ai/zhin-agent/prompt.js.map +0 -1
  156. package/lib/ai/zhin-agent/tool-collector.d.ts +0 -22
  157. package/lib/ai/zhin-agent/tool-collector.d.ts.map +0 -1
  158. package/lib/ai/zhin-agent/tool-collector.js +0 -218
  159. package/lib/ai/zhin-agent/tool-collector.js.map +0 -1
  160. package/src/ai/agent.ts +0 -831
  161. package/src/ai/bootstrap.ts +0 -309
  162. package/src/ai/builtin-tools.ts +0 -849
  163. package/src/ai/compaction.ts +0 -529
  164. package/src/ai/context-manager.ts +0 -440
  165. package/src/ai/conversation-memory.ts +0 -774
  166. package/src/ai/cron-engine.ts +0 -337
  167. package/src/ai/follow-up.ts +0 -357
  168. package/src/ai/hooks.ts +0 -223
  169. package/src/ai/init.ts +0 -762
  170. package/src/ai/output.ts +0 -261
  171. package/src/ai/rate-limiter.ts +0 -129
  172. package/src/ai/service.ts +0 -331
  173. package/src/ai/session.ts +0 -544
  174. package/src/ai/subagent.ts +0 -209
  175. package/src/ai/tone-detector.ts +0 -89
  176. package/src/ai/tools.ts +0 -218
  177. package/src/ai/user-profile.ts +0 -181
  178. package/src/ai/zhin-agent/builtin-tools.ts +0 -247
  179. package/src/ai/zhin-agent/config.ts +0 -113
  180. package/src/ai/zhin-agent/exec-policy.ts +0 -78
  181. package/src/ai/zhin-agent/index.ts +0 -512
  182. package/src/ai/zhin-agent/prompt.ts +0 -131
  183. package/src/ai/zhin-agent/tool-collector.ts +0 -243
  184. package/tests/ai/agent.test.ts +0 -614
  185. package/tests/ai/context-manager.test.ts +0 -413
  186. package/tests/ai/conversation-memory.test.ts +0 -128
  187. package/tests/ai/follow-up.test.ts +0 -175
  188. package/tests/ai/integration.test.ts +0 -584
  189. package/tests/ai/output.test.ts +0 -128
  190. package/tests/ai/rate-limiter.test.ts +0 -108
  191. package/tests/ai/session.test.ts +0 -375
  192. package/tests/ai/subagent.test.ts +0 -270
  193. package/tests/ai/tone-detector.test.ts +0 -80
  194. package/tests/ai/tools-builtin.test.ts +0 -346
  195. package/tests/ai/user-profile.test.ts +0 -73
  196. package/tests/ai/zhin-agent.test.ts +0 -177
package/src/types.ts CHANGED
@@ -14,7 +14,7 @@ export interface Models extends Record<string,object>{
14
14
  SystemLog: SystemLog
15
15
  User: User,
16
16
  }
17
- export type MaybePromise<T> = T extends Promise<infer U> ? T|U : T|Promise<T>;
17
+ export type MaybePromise<T> = [T] extends [Promise<infer U>] ? T|U : T|Promise<T>;
18
18
  export interface RegisteredAdapters {
19
19
  process: ProcessAdapter;
20
20
  }
@@ -71,6 +71,8 @@ export interface MessageSender{
71
71
  id: string;
72
72
  name?: string;
73
73
  permissions?:string[]
74
+ /** 平台侧角色标识(owner / admin / member 等) */
75
+ role?: string;
74
76
  }
75
77
  /**
76
78
  * 通用字典类型
@@ -305,25 +307,52 @@ export type ToolScope = 'private' | 'group' | 'channel';
305
307
  */
306
308
  export type ToolPermissionLevel = 'user' | 'group_admin' | 'group_owner' | 'bot_admin' | 'owner';
307
309
 
308
- export interface Tool {
310
+ /**
311
+ * 标准化工具返回类型。
312
+ * execute 可返回以下任一形式:
313
+ * - string: 直接作为文本回复
314
+ * - { text: string }: 结构化文本
315
+ * - { data: unknown; format?: string }: 结构化数据
316
+ * - void/null/undefined: 无回复
317
+ * - Record / Array: 自动 JSON.stringify
318
+ */
319
+ export type ToolResult = string | void | null | undefined | { text: string } | { data: unknown; format?: string } | Record<string, unknown> | unknown[];
320
+
321
+ /**
322
+ * 统一的 Tool 定义(支持泛型参数类型推断)。
323
+ *
324
+ * @template TArgs 参数类型,默认 Record<string, any>
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * // 无泛型 — 兼容旧代码
329
+ * const tool: Tool = { name: 'ping', ... };
330
+ *
331
+ * // 有泛型 — 通过 defineTool 获得类型安全
332
+ * const tool = defineTool<{ city: string }>({
333
+ * name: 'weather',
334
+ * parameters: { type: 'object', properties: { city: { type: 'string', description: '城市' } }, required: ['city'] },
335
+ * execute: async (args) => args.city, // args.city 有类型提示
336
+ * });
337
+ * ```
338
+ */
339
+ export interface Tool<TArgs extends Record<string, any> = Record<string, any>> {
309
340
  /** 工具名称(唯一标识,建议使用 snake_case) */
310
341
  name: string;
311
342
 
312
343
  /** 工具描述(供 AI 和帮助系统使用) */
313
344
  description: string;
314
345
 
315
- /**
316
- * 参数定义(JSON Schema 格式)
317
- */
318
- parameters: ToolParametersSchema;
346
+ /** 参数定义(JSON Schema 格式) */
347
+ parameters: ToolParametersSchema<TArgs>;
319
348
 
320
349
  /**
321
350
  * 工具执行函数
322
351
  * @param args 解析后的参数
323
352
  * @param context 执行上下文(包含消息、发送者等信息)
324
- * @returns 执行结果(字符串会直接作为回复,对象会被 JSON 序列化)
353
+ * @returns 执行结果
325
354
  */
326
- execute: (args: Record<string, any>, context?: ToolContext) => MaybePromise<any>;
355
+ execute: (args: TArgs, context?: ToolContext) => MaybePromise<ToolResult>;
327
356
 
328
357
  /** 工具来源标识(自动填充:adapter:xxx / plugin:xxx) */
329
358
  source?: string;
@@ -386,27 +415,9 @@ export interface Tool {
386
415
  }
387
416
 
388
417
  /**
389
- * 类型安全的 Tool 定义(用于 defineTool)
390
- * 提供泛型参数以获得 execute 函数的类型推断
418
+ * @deprecated 使用 `Tool<TArgs>` 替代。Tool 已原生支持泛型。
391
419
  */
392
- export interface ToolDefinition<TArgs extends Record<string, any> = Record<string, any>> {
393
- name: string;
394
- description: string;
395
- parameters: ToolParametersSchema<TArgs>;
396
- execute: (args: TArgs, context?: ToolContext) => MaybePromise<any>;
397
- source?: string;
398
- tags?: string[];
399
- keywords?: string[];
400
- command?: Tool.CommandConfig | false;
401
- permissions?: string[];
402
- /** 支持的平台列表(不填则支持所有平台) */
403
- platforms?: string[];
404
- /** 支持的场景列表(不填则支持所有场景) */
405
- scopes?: ToolScope[];
406
- /** 调用所需的最低权限级别(默认 'user') */
407
- permissionLevel?: ToolPermissionLevel;
408
- hidden?: boolean;
409
- }
420
+ export type ToolDefinition<TArgs extends Record<string, any> = Record<string, any>> = Tool<TArgs>;
410
421
 
411
422
  export namespace Tool {
412
423
  /**
package/src/utils.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as path from "path";
2
2
  import * as fs from "fs";
3
+ import * as vm from "vm";
3
4
  import {
4
5
  AdapterMessage,
5
6
  Dict,
@@ -11,15 +12,21 @@ import {
11
12
  import { Message } from "./message.js";
12
13
 
13
14
  export function getValueWithRuntime(template: string, ctx: Dict) {
14
- const result = evaluate(template, ctx);
15
- if (result === `return(${template})`) return undefined;
16
- return result;
15
+ return evaluate(template, ctx);
17
16
  }
18
- export const evaluate = <S, T = any>(exp: string, context: S) => {
19
- const result = execute<S, T>(`return(${exp})`, context);
20
- // 如果结果是原始表达式,说明访问被阻止,返回 undefined
21
- if (result === `return(${exp})`) return undefined;
22
- return result;
17
+ /**
18
+ * Evaluate a single expression in a sandboxed vm context.
19
+ * Unlike `execute`, does NOT wrap in IIFE — the expression value is returned directly.
20
+ */
21
+ export const evaluate = <S extends Record<string, unknown>, T = unknown>(exp: string, context: S): T | undefined => {
22
+ const script = getOrCompileScript(exp);
23
+ if (!script) return undefined;
24
+
25
+ try {
26
+ return script.runInNewContext(buildSandbox(context), { timeout: 200 }) as T;
27
+ } catch {
28
+ return undefined;
29
+ }
23
30
  };
24
31
  /**
25
32
  * 组合中间件,洋葱模型
@@ -74,25 +81,28 @@ export function compose<P extends RegisteredAdapter=RegisteredAdapter>(
74
81
  return dispatch(0);
75
82
  };
76
83
  }
77
- // 使用 LRU 缓存限制大小,防止内存泄漏
84
+ // LRU cache for compiled vm.Script instances
78
85
  const MAX_EVAL_CACHE_SIZE = 1000;
79
- const evalCache: Record<string, Function> = Object.create(null);
80
- const evalCacheKeys: string[] = [];
86
+ const scriptCache = new Map<string, vm.Script>();
81
87
 
82
- export const execute = <S, T = any>(exp: string, context: S): T => {
83
- let fn = evalCache[exp];
84
-
85
- if (!fn) {
86
- // 如果缓存已满,删除最旧的条目(LRU)
87
- if (evalCacheKeys.length >= MAX_EVAL_CACHE_SIZE) {
88
- const oldest = evalCacheKeys.shift()!;
89
- delete evalCache[oldest];
90
- }
91
-
92
- fn = evalCache[exp] = toFunction(exp);
93
- evalCacheKeys.push(exp);
88
+ function getOrCompileScript(code: string): vm.Script | null {
89
+ let script = scriptCache.get(code);
90
+ if (script) return script;
91
+ try {
92
+ script = new vm.Script(code);
93
+ } catch {
94
+ return null;
94
95
  }
95
- context = {
96
+ if (scriptCache.size >= MAX_EVAL_CACHE_SIZE) {
97
+ const oldest = scriptCache.keys().next().value;
98
+ if (oldest !== undefined) scriptCache.delete(oldest);
99
+ }
100
+ scriptCache.set(code, script);
101
+ return script;
102
+ }
103
+
104
+ function buildSandbox<S extends Record<string, unknown>>(context: S): Record<string, unknown> {
105
+ return {
96
106
  ...context,
97
107
  process: {
98
108
  version: process.version,
@@ -106,48 +116,48 @@ export const execute = <S, T = any>(exp: string, context: S): T => {
106
116
  pid: process.pid,
107
117
  ppid: process.ppid,
108
118
  },
109
- Bun: "你想干嘛",
110
119
  global: undefined,
120
+ globalThis: undefined,
111
121
  Buffer: undefined,
112
122
  crypto: undefined,
123
+ require: undefined,
124
+ import: undefined,
125
+ __dirname: undefined,
126
+ __filename: undefined,
127
+ Bun: undefined,
128
+ Deno: undefined,
113
129
  };
114
- try {
115
- return fn.apply(context, [context]);
116
- } catch {
117
- return exp as T;
118
- }
119
- };
130
+ }
120
131
 
121
- const toFunction = (exp: string): Function => {
122
- try {
123
- return new Function(`$data`, `with($data){${exp}}`);
124
- } catch {
125
- return () => { };
126
- }
132
+ /**
133
+ * Execute a code block in a sandboxed vm context.
134
+ * Supports `return` statements by wrapping in an IIFE.
135
+ * Throws on compilation or runtime errors.
136
+ */
137
+ export const execute = <S extends Record<string, unknown>, T = unknown>(code: string, context: S): T => {
138
+ const wrapped = `(function(){${code}})()`;
139
+ const script = getOrCompileScript(wrapped);
140
+ if (!script) throw new SyntaxError(`Failed to compile: ${code.slice(0, 80)}`);
141
+
142
+ return script.runInNewContext(buildSandbox(context), { timeout: 200 }) as T;
127
143
  };
128
144
 
129
- // 清理 evalCache(用于内存调试)
130
145
  export function clearEvalCache(): void {
131
- Object.keys(evalCache).forEach(key => {
132
- delete evalCache[key];
133
- });
134
- evalCacheKeys.length = 0;
146
+ scriptCache.clear();
135
147
  }
136
148
 
137
- // 获取 evalCache 统计信息(用于内存调试)
138
149
  export function getEvalCacheStats(): { size: number; maxSize: number } {
139
150
  return {
140
- size: evalCacheKeys.length,
141
- maxSize: MAX_EVAL_CACHE_SIZE
151
+ size: scriptCache.size,
152
+ maxSize: MAX_EVAL_CACHE_SIZE,
142
153
  };
143
154
  }
144
155
  export function compiler(template: string, ctx: Dict) {
145
156
  const matched = [...template.matchAll(/\${([^}]*?)}/g)];
146
157
  for (const item of matched) {
147
158
  const tpl = item[1];
148
- let value = getValueWithRuntime(tpl, ctx);
149
- if (value === tpl) continue;
150
- if (typeof value !== "string") value = JSON.stringify(value, null, 2);
159
+ const raw = getValueWithRuntime(tpl, ctx);
160
+ const value = typeof raw === 'string' ? raw : (raw == null ? 'undefined' : JSON.stringify(raw, null, 2));
151
161
  template = template.replace(`\${${item[1]}}`, value);
152
162
  }
153
163
  return template;
@@ -394,14 +404,15 @@ export namespace Time {
394
404
 
395
405
  export function parseDate(date: string) {
396
406
  const parsed = parseTime(date);
407
+ let dateInput: string | number = date;
397
408
  if (parsed) {
398
- date = (Date.now() + parsed) as any;
409
+ dateInput = Date.now() + parsed;
399
410
  } else if (/^\d{1,2}(:\d{1,2}){1,2}$/.test(date)) {
400
- date = `${new Date().toLocaleDateString()}-${date}`;
411
+ dateInput = `${new Date().toLocaleDateString()}-${date}`;
401
412
  } else if (/^\d{1,2}-\d{1,2}-\d{1,2}(:\d{1,2}){1,2}$/.test(date)) {
402
- date = `${new Date().getFullYear()}-${date}`;
413
+ dateInput = `${new Date().getFullYear()}-${date}`;
403
414
  }
404
- return date ? new Date(date) : new Date();
415
+ return dateInput ? new Date(dateInput) : new Date();
405
416
  }
406
417
 
407
418
  export function formatTimeShort(ms: number) {
package/tests/ai/setup.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { vi } from 'vitest';
10
10
  import type { Message, MessageElement, Tool, ToolContext } from '@zhin.js/core';
11
- import type { AIConfig, AIProviderConfig, ChatMessage } from '../../src/ai/types.js';
11
+ import type { AIConfig, ChatMessage } from '@zhin.js/core';
12
12
 
13
13
  // ============================================================================
14
14
  // Logger Mock
@@ -226,7 +226,7 @@ export const createMockAIConfig = (overrides: Partial<AIConfig> = {}): AIConfig
226
226
  defaultProvider: 'mock',
227
227
  sessions: {
228
228
  maxHistory: 10,
229
- timeout: 300000,
229
+ expireMs: 300000,
230
230
  },
231
231
  context: {
232
232
  enabled: false,
@@ -140,9 +140,7 @@ describe('evaluate and execute', () => {
140
140
  })
141
141
 
142
142
  it('should handle invalid expressions gracefully', () => {
143
- const result = execute('invalid syntax here !!!', {})
144
- // 无效表达式会被 try-catch 捕获,返回 undefined
145
- expect(result).toBeUndefined()
143
+ expect(() => execute('invalid syntax here !!!', {})).toThrow()
146
144
  })
147
145
 
148
146
  it('should provide safe process context', () => {
package/lib/ai/agent.d.ts DELETED
@@ -1,130 +0,0 @@
1
- /**
2
- * @zhin.js/ai - Agent System
3
- * AI Agent 实现,支持工具调用和多轮对话
4
- */
5
- import type { AIProvider, AgentConfig, AgentTool, AgentResult, ChatMessage, ToolFilterOptions, Usage } from './types.js';
6
- /**
7
- * 根据工具名和参数生成简短标题(用于日志、TOOLS.md 等)
8
- */
9
- export declare function formatToolTitle(name: string, args?: Record<string, any>): string;
10
- /**
11
- * Agent 执行状态
12
- */
13
- export interface AgentState {
14
- messages: ChatMessage[];
15
- toolCalls: {
16
- tool: string;
17
- args: Record<string, any>;
18
- result: any;
19
- }[];
20
- usage: Usage;
21
- iterations: number;
22
- }
23
- /**
24
- * Agent 事件
25
- */
26
- export interface AgentEvents {
27
- 'thinking': (message: string) => void;
28
- 'tool_call': (tool: string, args: Record<string, any>) => void;
29
- 'tool_result': (tool: string, result: any) => void;
30
- 'streaming': (content: string) => void;
31
- 'complete': (result: AgentResult) => void;
32
- 'error': (error: Error) => void;
33
- }
34
- /**
35
- * AI Agent 类
36
- * 支持工具调用、多轮对话、流式输出
37
- */
38
- export declare class Agent {
39
- private provider;
40
- private config;
41
- private tools;
42
- private eventHandlers;
43
- constructor(provider: AIProvider, config: AgentConfig);
44
- /**
45
- * 默认系统提示词
46
- */
47
- private getDefaultSystemPrompt;
48
- /**
49
- * 注册事件处理器
50
- */
51
- on<K extends keyof AgentEvents>(event: K, handler: AgentEvents[K]): () => void;
52
- /**
53
- * 触发事件
54
- */
55
- private emit;
56
- /**
57
- * 添加工具
58
- */
59
- addTool(tool: AgentTool): void;
60
- /**
61
- * 移除工具
62
- */
63
- removeTool(name: string): void;
64
- /**
65
- * 获取工具定义(缓存在第一次调用后保持不变)
66
- */
67
- private getToolDefinitions;
68
- /**
69
- * 生成工具调用的去重 key(规范化参数以避免 "" vs "{}" 等差异)
70
- */
71
- private static toolCallKey;
72
- /**
73
- * 安全解析 JSON,失败则返回原始字符串
74
- */
75
- private static safeParse;
76
- /**
77
- * 程序化工具过滤 —— 替代 AI 意图分析的高效方案
78
- *
79
- * 评分规则(按权重从高到低):
80
- * 1. keywords 精确匹配: +1.0 per hit —— 工具声明的触发关键词
81
- * 2. tags 匹配: +0.5 per hit —— 工具分类标签
82
- * 3. 工具名 token 匹配: +0.3 per hit —— 工具名按 `.` `_` `-` 拆词
83
- * 4. description 关键词: +0.15 per hit —— 描述中的词/短语
84
- *
85
- * 权限过滤发生在评分之前,直接跳过无权使用的工具。
86
- *
87
- * @param message 用户消息原文
88
- * @param tools 候选工具列表
89
- * @param options 过滤选项
90
- * @returns 按相关性降序排列的工具子集
91
- */
92
- static filterTools(message: string, tools: AgentTool[], options?: ToolFilterOptions): AgentTool[];
93
- /**
94
- * 执行单个工具调用(带超时保护)
95
- */
96
- private executeToolCall;
97
- /**
98
- * 并行执行多个工具调用(跳过重复的)
99
- * @returns 新执行的工具调用结果列表;如果全部重复则返回空数组
100
- */
101
- private executeToolCalls;
102
- /**
103
- * 累加 token 用量
104
- */
105
- private static addUsage;
106
- /**
107
- * 运行 Agent
108
- *
109
- * @param userMessage 用户消息
110
- * @param context 对话上下文
111
- * @param filterOptions 工具过滤选项 —— 启用后在 AI 调用之前程序化筛选工具,省去额外的 AI 意图分析往返
112
- */
113
- run(userMessage: string, context?: ChatMessage[], filterOptions?: ToolFilterOptions): Promise<AgentResult>;
114
- /**
115
- * 流式运行 Agent
116
- *
117
- * @param userMessage 用户消息
118
- * @param context 对话上下文
119
- * @param filterOptions 工具过滤选项 —— 启用后在 AI 调用之前程序化筛选工具
120
- */
121
- runStream(userMessage: string, context?: ChatMessage[], filterOptions?: ToolFilterOptions): AsyncIterable<{
122
- type: 'content' | 'tool_call' | 'tool_result' | 'done';
123
- data: any;
124
- }>;
125
- }
126
- /**
127
- * 创建 Agent 实例
128
- */
129
- export declare function createAgent(provider: AIProvider, config: Omit<AgentConfig, 'provider'>): Agent;
130
- //# sourceMappingURL=agent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/ai/agent.ts"],"names":[],"mappings":"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"}