@zhin.js/core 1.0.37 → 1.0.39

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 (204) hide show
  1. package/CHANGELOG.md +18 -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/providers/anthropic.d.ts.map +1 -1
  12. package/lib/ai/providers/anthropic.js +2 -0
  13. package/lib/ai/providers/anthropic.js.map +1 -1
  14. package/lib/ai/providers/openai.d.ts.map +1 -1
  15. package/lib/ai/providers/openai.js +8 -0
  16. package/lib/ai/providers/openai.js.map +1 -1
  17. package/lib/ai/types.d.ts +5 -3
  18. package/lib/ai/types.d.ts.map +1 -1
  19. package/lib/built/ai-trigger.js.map +1 -1
  20. package/lib/built/common-adapter-tools.d.ts +55 -0
  21. package/lib/built/common-adapter-tools.d.ts.map +1 -0
  22. package/lib/built/common-adapter-tools.js +158 -0
  23. package/lib/built/common-adapter-tools.js.map +1 -0
  24. package/lib/built/dispatcher.d.ts.map +1 -1
  25. package/lib/built/dispatcher.js +50 -46
  26. package/lib/built/dispatcher.js.map +1 -1
  27. package/lib/built/skill.d.ts.map +1 -1
  28. package/lib/built/skill.js +0 -1
  29. package/lib/built/skill.js.map +1 -1
  30. package/lib/built/tool.d.ts +3 -3
  31. package/lib/built/tool.d.ts.map +1 -1
  32. package/lib/built/tool.js.map +1 -1
  33. package/lib/feature.d.ts +16 -1
  34. package/lib/feature.d.ts.map +1 -1
  35. package/lib/feature.js +41 -2
  36. package/lib/feature.js.map +1 -1
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.d.ts.map +1 -1
  39. package/lib/index.js +2 -0
  40. package/lib/index.js.map +1 -1
  41. package/lib/plugin.d.ts +38 -1
  42. package/lib/plugin.d.ts.map +1 -1
  43. package/lib/plugin.js +73 -22
  44. package/lib/plugin.js.map +1 -1
  45. package/lib/scheduler/scheduler.js +1 -1
  46. package/lib/scheduler/scheduler.js.map +1 -1
  47. package/lib/types.d.ts +43 -28
  48. package/lib/types.d.ts.map +1 -1
  49. package/lib/utils.d.ts +12 -3
  50. package/lib/utils.d.ts.map +1 -1
  51. package/lib/utils.js +64 -54
  52. package/lib/utils.js.map +1 -1
  53. package/package.json +5 -5
  54. package/src/adapter.ts +85 -5
  55. package/src/ai/index.ts +8 -186
  56. package/src/ai/providers/anthropic.ts +1 -0
  57. package/src/ai/providers/openai.ts +5 -1
  58. package/src/ai/types.ts +6 -4
  59. package/src/built/ai-trigger.ts +2 -2
  60. package/src/built/common-adapter-tools.ts +207 -0
  61. package/src/built/dispatcher.ts +51 -52
  62. package/src/built/skill.ts +3 -4
  63. package/src/built/tool.ts +3 -3
  64. package/src/feature.ts +45 -2
  65. package/src/index.ts +2 -0
  66. package/src/plugin.ts +92 -31
  67. package/src/scheduler/scheduler.ts +1 -1
  68. package/src/types.ts +39 -28
  69. package/src/utils.ts +63 -52
  70. package/tests/ai/setup.ts +2 -2
  71. package/tests/utils.test.ts +1 -3
  72. package/lib/ai/agent.d.ts +0 -130
  73. package/lib/ai/agent.d.ts.map +0 -1
  74. package/lib/ai/agent.js +0 -702
  75. package/lib/ai/agent.js.map +0 -1
  76. package/lib/ai/bootstrap.d.ts +0 -91
  77. package/lib/ai/bootstrap.d.ts.map +0 -1
  78. package/lib/ai/bootstrap.js +0 -243
  79. package/lib/ai/bootstrap.js.map +0 -1
  80. package/lib/ai/builtin-tools.d.ts +0 -59
  81. package/lib/ai/builtin-tools.d.ts.map +0 -1
  82. package/lib/ai/builtin-tools.js +0 -777
  83. package/lib/ai/builtin-tools.js.map +0 -1
  84. package/lib/ai/compaction.d.ts +0 -132
  85. package/lib/ai/compaction.d.ts.map +0 -1
  86. package/lib/ai/compaction.js +0 -370
  87. package/lib/ai/compaction.js.map +0 -1
  88. package/lib/ai/context-manager.d.ts +0 -213
  89. package/lib/ai/context-manager.d.ts.map +0 -1
  90. package/lib/ai/context-manager.js +0 -313
  91. package/lib/ai/context-manager.js.map +0 -1
  92. package/lib/ai/conversation-memory.d.ts +0 -181
  93. package/lib/ai/conversation-memory.d.ts.map +0 -1
  94. package/lib/ai/conversation-memory.js +0 -581
  95. package/lib/ai/conversation-memory.js.map +0 -1
  96. package/lib/ai/cron-engine.d.ts +0 -92
  97. package/lib/ai/cron-engine.d.ts.map +0 -1
  98. package/lib/ai/cron-engine.js +0 -278
  99. package/lib/ai/cron-engine.js.map +0 -1
  100. package/lib/ai/follow-up.d.ts +0 -131
  101. package/lib/ai/follow-up.d.ts.map +0 -1
  102. package/lib/ai/follow-up.js +0 -265
  103. package/lib/ai/follow-up.js.map +0 -1
  104. package/lib/ai/hooks.d.ts +0 -143
  105. package/lib/ai/hooks.d.ts.map +0 -1
  106. package/lib/ai/hooks.js +0 -108
  107. package/lib/ai/hooks.js.map +0 -1
  108. package/lib/ai/init.d.ts +0 -30
  109. package/lib/ai/init.d.ts.map +0 -1
  110. package/lib/ai/init.js +0 -686
  111. package/lib/ai/init.js.map +0 -1
  112. package/lib/ai/output.d.ts +0 -93
  113. package/lib/ai/output.d.ts.map +0 -1
  114. package/lib/ai/output.js +0 -176
  115. package/lib/ai/output.js.map +0 -1
  116. package/lib/ai/rate-limiter.d.ts +0 -38
  117. package/lib/ai/rate-limiter.d.ts.map +0 -1
  118. package/lib/ai/rate-limiter.js +0 -86
  119. package/lib/ai/rate-limiter.js.map +0 -1
  120. package/lib/ai/service.d.ts +0 -88
  121. package/lib/ai/service.d.ts.map +0 -1
  122. package/lib/ai/service.js +0 -285
  123. package/lib/ai/service.js.map +0 -1
  124. package/lib/ai/session.d.ts +0 -186
  125. package/lib/ai/session.d.ts.map +0 -1
  126. package/lib/ai/session.js +0 -443
  127. package/lib/ai/session.js.map +0 -1
  128. package/lib/ai/subagent.d.ts +0 -50
  129. package/lib/ai/subagent.d.ts.map +0 -1
  130. package/lib/ai/subagent.js +0 -144
  131. package/lib/ai/subagent.js.map +0 -1
  132. package/lib/ai/tone-detector.d.ts +0 -19
  133. package/lib/ai/tone-detector.d.ts.map +0 -1
  134. package/lib/ai/tone-detector.js +0 -72
  135. package/lib/ai/tone-detector.js.map +0 -1
  136. package/lib/ai/tools.d.ts +0 -45
  137. package/lib/ai/tools.d.ts.map +0 -1
  138. package/lib/ai/tools.js +0 -206
  139. package/lib/ai/tools.js.map +0 -1
  140. package/lib/ai/user-profile.d.ts +0 -56
  141. package/lib/ai/user-profile.d.ts.map +0 -1
  142. package/lib/ai/user-profile.js +0 -130
  143. package/lib/ai/user-profile.js.map +0 -1
  144. package/lib/ai/zhin-agent/builtin-tools.d.ts +0 -17
  145. package/lib/ai/zhin-agent/builtin-tools.d.ts.map +0 -1
  146. package/lib/ai/zhin-agent/builtin-tools.js +0 -220
  147. package/lib/ai/zhin-agent/builtin-tools.js.map +0 -1
  148. package/lib/ai/zhin-agent/config.d.ts +0 -54
  149. package/lib/ai/zhin-agent/config.d.ts.map +0 -1
  150. package/lib/ai/zhin-agent/config.js +0 -76
  151. package/lib/ai/zhin-agent/config.js.map +0 -1
  152. package/lib/ai/zhin-agent/exec-policy.d.ts +0 -20
  153. package/lib/ai/zhin-agent/exec-policy.d.ts.map +0 -1
  154. package/lib/ai/zhin-agent/exec-policy.js +0 -71
  155. package/lib/ai/zhin-agent/exec-policy.js.map +0 -1
  156. package/lib/ai/zhin-agent/index.d.ts +0 -70
  157. package/lib/ai/zhin-agent/index.d.ts.map +0 -1
  158. package/lib/ai/zhin-agent/index.js +0 -404
  159. package/lib/ai/zhin-agent/index.js.map +0 -1
  160. package/lib/ai/zhin-agent/prompt.d.ts +0 -21
  161. package/lib/ai/zhin-agent/prompt.d.ts.map +0 -1
  162. package/lib/ai/zhin-agent/prompt.js +0 -111
  163. package/lib/ai/zhin-agent/prompt.js.map +0 -1
  164. package/lib/ai/zhin-agent/tool-collector.d.ts +0 -22
  165. package/lib/ai/zhin-agent/tool-collector.d.ts.map +0 -1
  166. package/lib/ai/zhin-agent/tool-collector.js +0 -218
  167. package/lib/ai/zhin-agent/tool-collector.js.map +0 -1
  168. package/src/ai/agent.ts +0 -831
  169. package/src/ai/bootstrap.ts +0 -309
  170. package/src/ai/builtin-tools.ts +0 -849
  171. package/src/ai/compaction.ts +0 -529
  172. package/src/ai/context-manager.ts +0 -440
  173. package/src/ai/conversation-memory.ts +0 -774
  174. package/src/ai/cron-engine.ts +0 -337
  175. package/src/ai/follow-up.ts +0 -357
  176. package/src/ai/hooks.ts +0 -223
  177. package/src/ai/init.ts +0 -762
  178. package/src/ai/output.ts +0 -261
  179. package/src/ai/rate-limiter.ts +0 -129
  180. package/src/ai/service.ts +0 -331
  181. package/src/ai/session.ts +0 -544
  182. package/src/ai/subagent.ts +0 -209
  183. package/src/ai/tone-detector.ts +0 -89
  184. package/src/ai/tools.ts +0 -218
  185. package/src/ai/user-profile.ts +0 -181
  186. package/src/ai/zhin-agent/builtin-tools.ts +0 -247
  187. package/src/ai/zhin-agent/config.ts +0 -113
  188. package/src/ai/zhin-agent/exec-policy.ts +0 -78
  189. package/src/ai/zhin-agent/index.ts +0 -512
  190. package/src/ai/zhin-agent/prompt.ts +0 -131
  191. package/src/ai/zhin-agent/tool-collector.ts +0 -243
  192. package/tests/ai/agent.test.ts +0 -614
  193. package/tests/ai/context-manager.test.ts +0 -413
  194. package/tests/ai/conversation-memory.test.ts +0 -128
  195. package/tests/ai/follow-up.test.ts +0 -175
  196. package/tests/ai/integration.test.ts +0 -584
  197. package/tests/ai/output.test.ts +0 -128
  198. package/tests/ai/rate-limiter.test.ts +0 -108
  199. package/tests/ai/session.test.ts +0 -375
  200. package/tests/ai/subagent.test.ts +0 -270
  201. package/tests/ai/tone-detector.test.ts +0 -80
  202. package/tests/ai/tools-builtin.test.ts +0 -346
  203. package/tests/ai/user-profile.test.ts +0 -73
  204. package/tests/ai/zhin-agent.test.ts +0 -177
@@ -1,73 +0,0 @@
1
- /**
2
- * UserProfileStore 测试
3
- */
4
- import { describe, it, expect, beforeEach } from 'vitest';
5
- import { UserProfileStore } from '../../src/ai/user-profile.js';
6
-
7
- describe('UserProfileStore(内存模式)', () => {
8
- let store: UserProfileStore;
9
-
10
- beforeEach(() => {
11
- store = new UserProfileStore();
12
- });
13
-
14
- it('初始 get 应返回 null', async () => {
15
- expect(await store.get('u1', 'name')).toBeNull();
16
- });
17
-
18
- it('set 后应能 get', async () => {
19
- await store.set('u1', 'name', '小明');
20
- expect(await store.get('u1', 'name')).toBe('小明');
21
- });
22
-
23
- it('getAll 应返回所有键值', async () => {
24
- await store.set('u1', 'name', '小明');
25
- await store.set('u1', 'style', '简洁');
26
- const all = await store.getAll('u1');
27
- expect(all).toEqual({ name: '小明', style: '简洁' });
28
- });
29
-
30
- it('getAll 不存在的用户应返回空对象', async () => {
31
- expect(await store.getAll('nonexistent')).toEqual({});
32
- });
33
-
34
- it('delete 已有键应返回 true', async () => {
35
- await store.set('u1', 'name', '小明');
36
- const result = await store.delete('u1', 'name');
37
- expect(result).toBe(true);
38
- expect(await store.get('u1', 'name')).toBeNull();
39
- });
40
-
41
- it('delete 不存在的键应返回 false', async () => {
42
- expect(await store.delete('u1', 'nonexistent')).toBe(false);
43
- });
44
-
45
- it('不同用户数据应隔离', async () => {
46
- await store.set('u1', 'name', '小明');
47
- await store.set('u2', 'name', '小红');
48
- expect(await store.get('u1', 'name')).toBe('小明');
49
- expect(await store.get('u2', 'name')).toBe('小红');
50
- });
51
-
52
- describe('buildProfileSummary', () => {
53
- it('无数据应返回空字符串', async () => {
54
- expect(await store.buildProfileSummary('u1')).toBe('');
55
- });
56
-
57
- it('有数据应生成摘要', async () => {
58
- await store.set('u1', 'name', '小明');
59
- await store.set('u1', 'interests', '编程');
60
- const summary = await store.buildProfileSummary('u1');
61
- expect(summary).toContain('[用户画像]');
62
- expect(summary).toContain('name: 小明');
63
- expect(summary).toContain('interests: 编程');
64
- });
65
- });
66
-
67
- it('dispose 应清理数据', async () => {
68
- await store.set('u1', 'name', '小明');
69
- store.dispose();
70
- // dispose 后重新获取,内存实现应清空
71
- expect(await store.get('u1', 'name')).toBeNull();
72
- });
73
- });
@@ -1,177 +0,0 @@
1
- /**
2
- * ZhinAgent 补全测试
3
- *
4
- * 测试 collectTools 逻辑、handleMessage 端到端流程、会话管理等
5
- */
6
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
- import { ZhinAgent } from '../../src/ai/zhin-agent/index.js';
8
- import { SkillFeature } from '../../src/built/skill.js';
9
- import type { AIProvider, ChatResponse, AgentTool } from '../../src/ai/types.js';
10
- import type { Tool, ToolContext } from '../../src/types.js';
11
-
12
- // Mock AIProvider
13
- function createMockProvider(response: string = '你好!'): AIProvider {
14
- return {
15
- name: 'mock',
16
- models: ['mock-model'],
17
- chat: vi.fn(async () => ({
18
- choices: [{ message: { role: 'assistant' as const, content: response }, finish_reason: 'stop' }],
19
- } as ChatResponse)),
20
- listModels: vi.fn(async () => ['mock-model']),
21
- };
22
- }
23
-
24
- function makeToolContext(overrides: Partial<ToolContext> = {}): ToolContext {
25
- return {
26
- platform: 'test',
27
- botId: 'bot1',
28
- sceneId: 'scene1',
29
- senderId: 'user1',
30
- ...overrides,
31
- };
32
- }
33
-
34
- function makeTool(name: string, desc: string = '', opts: Partial<Tool> = {}): Tool {
35
- return {
36
- name,
37
- description: desc,
38
- parameters: { type: 'object', properties: {} },
39
- execute: vi.fn(async () => `result of ${name}`),
40
- ...opts,
41
- };
42
- }
43
-
44
- describe('ZhinAgent', () => {
45
- let agent: ZhinAgent;
46
- let provider: AIProvider;
47
-
48
- beforeEach(() => {
49
- provider = createMockProvider();
50
- agent = new ZhinAgent(provider, {
51
- persona: '测试助手',
52
- maxIterations: 3,
53
- });
54
- });
55
-
56
- afterEach(() => {
57
- agent.dispose();
58
- });
59
-
60
- describe('构造', () => {
61
- it('应正确初始化', () => {
62
- expect(agent).toBeDefined();
63
- });
64
- });
65
-
66
- describe('依赖注入', () => {
67
- it('setSkillRegistry 应正常工作', () => {
68
- const registry = new SkillFeature();
69
- expect(() => agent.setSkillRegistry(registry)).not.toThrow();
70
- });
71
-
72
- it('registerTool 应添加和移除工具', () => {
73
- const tool: AgentTool = {
74
- name: 'test_tool',
75
- description: '测试',
76
- parameters: { type: 'object', properties: {} },
77
- execute: async () => 'ok',
78
- };
79
-
80
- const dispose = agent.registerTool(tool);
81
- expect(typeof dispose).toBe('function');
82
-
83
- // 移除
84
- dispose();
85
- });
86
- });
87
-
88
- describe('process', () => {
89
- it('应处理简单文本消息并返回 OutputElement[]', async () => {
90
- const context = makeToolContext();
91
-
92
- const result = await agent.process(
93
- '你好',
94
- context,
95
- [],
96
- );
97
-
98
- expect(result).toBeDefined();
99
- expect(Array.isArray(result)).toBe(true);
100
- expect(result.length).toBeGreaterThan(0);
101
- expect(provider.chat).toHaveBeenCalled();
102
- });
103
-
104
- it('应传递工具列表', async () => {
105
- const tools: Tool[] = [makeTool('get_time', '获取时间')];
106
- const context = makeToolContext();
107
-
108
- await agent.process('现在几点', context, tools);
109
-
110
- // provider.chat 应被调用
111
- expect(provider.chat).toHaveBeenCalled();
112
- });
113
-
114
- it('速率限制应生效', async () => {
115
- // 创建一个严格限制的 agent
116
- const strictAgent = new ZhinAgent(provider, {
117
- rateLimit: { maxRequestsPerMinute: 1, cooldownSeconds: 5 },
118
- });
119
-
120
- const context = makeToolContext();
121
-
122
- // 第一次请求
123
- await strictAgent.process('hello', context, []);
124
-
125
- // 第二次应被限制
126
- const result = await strictAgent.process('hello again', context, []);
127
-
128
- // 被限制时应返回友好提示(OutputElement[])
129
- expect(result).toBeDefined();
130
- expect(Array.isArray(result)).toBe(true);
131
-
132
- strictAgent.dispose();
133
- });
134
- });
135
-
136
- describe('collectTools 去重', () => {
137
- it('应优先使用 Skill 中的工具', async () => {
138
- const registry = new SkillFeature();
139
-
140
- // 注册一个 Skill 包含 tool_a
141
- registry.add({
142
- name: 'skill1',
143
- description: '技能1',
144
- tools: [makeTool('tool_a', '来自 skill 的工具', { keywords: ['天气'] })],
145
- keywords: ['天气'],
146
- pluginName: 'p1',
147
- }, 'p1');
148
-
149
- agent.setSkillRegistry(registry);
150
-
151
- // 外部也传入 tool_a(同名)
152
- const externalTools = [makeTool('tool_a', '来自外部的工具')];
153
- const context = makeToolContext();
154
-
155
- // 调用 process,两个同名工具应该只保留一个
156
- await agent.process('查看天气', context, externalTools);
157
-
158
- // provider.chat 应被调用(正常处理)
159
- expect(provider.chat).toHaveBeenCalled();
160
- });
161
- });
162
-
163
- describe('getUserProfiles', () => {
164
- it('应返回 UserProfileStore 实例', () => {
165
- const profiles = agent.getUserProfiles();
166
- expect(profiles).toBeDefined();
167
- expect(typeof profiles.get).toBe('function');
168
- expect(typeof profiles.set).toBe('function');
169
- });
170
- });
171
-
172
- describe('dispose', () => {
173
- it('应正常清理资源', () => {
174
- expect(() => agent.dispose()).not.toThrow();
175
- });
176
- });
177
- });