@zhin.js/core 1.0.25 → 1.0.27

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 (202) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +84 -342
  3. package/lib/adapter.d.ts +17 -0
  4. package/lib/adapter.d.ts.map +1 -1
  5. package/lib/adapter.js +84 -2
  6. package/lib/adapter.js.map +1 -1
  7. package/lib/ai/agent.d.ts +126 -0
  8. package/lib/ai/agent.d.ts.map +1 -0
  9. package/lib/ai/agent.js +645 -0
  10. package/lib/ai/agent.js.map +1 -0
  11. package/lib/ai/context-manager.d.ts +213 -0
  12. package/lib/ai/context-manager.d.ts.map +1 -0
  13. package/lib/ai/context-manager.js +313 -0
  14. package/lib/ai/context-manager.js.map +1 -0
  15. package/lib/ai/conversation-memory.d.ts +181 -0
  16. package/lib/ai/conversation-memory.d.ts.map +1 -0
  17. package/lib/ai/conversation-memory.js +581 -0
  18. package/lib/ai/conversation-memory.js.map +1 -0
  19. package/lib/ai/follow-up.d.ts +131 -0
  20. package/lib/ai/follow-up.d.ts.map +1 -0
  21. package/lib/ai/follow-up.js +265 -0
  22. package/lib/ai/follow-up.js.map +1 -0
  23. package/lib/ai/index.d.ts +29 -0
  24. package/lib/ai/index.d.ts.map +1 -0
  25. package/lib/ai/index.js +34 -0
  26. package/lib/ai/index.js.map +1 -0
  27. package/lib/ai/init.d.ts +30 -0
  28. package/lib/ai/init.d.ts.map +1 -0
  29. package/lib/ai/init.js +424 -0
  30. package/lib/ai/init.js.map +1 -0
  31. package/lib/ai/output.d.ts +93 -0
  32. package/lib/ai/output.d.ts.map +1 -0
  33. package/lib/ai/output.js +176 -0
  34. package/lib/ai/output.js.map +1 -0
  35. package/lib/ai/providers/anthropic.d.ts +23 -0
  36. package/lib/ai/providers/anthropic.d.ts.map +1 -0
  37. package/lib/ai/providers/anthropic.js +322 -0
  38. package/lib/ai/providers/anthropic.js.map +1 -0
  39. package/lib/ai/providers/base.d.ts +43 -0
  40. package/lib/ai/providers/base.d.ts.map +1 -0
  41. package/lib/ai/providers/base.js +135 -0
  42. package/lib/ai/providers/base.js.map +1 -0
  43. package/lib/ai/providers/index.d.ts +12 -0
  44. package/lib/ai/providers/index.d.ts.map +1 -0
  45. package/lib/ai/providers/index.js +9 -0
  46. package/lib/ai/providers/index.js.map +1 -0
  47. package/lib/ai/providers/ollama.d.ts +25 -0
  48. package/lib/ai/providers/ollama.d.ts.map +1 -0
  49. package/lib/ai/providers/ollama.js +243 -0
  50. package/lib/ai/providers/ollama.js.map +1 -0
  51. package/lib/ai/providers/openai.d.ts +46 -0
  52. package/lib/ai/providers/openai.d.ts.map +1 -0
  53. package/lib/ai/providers/openai.js +132 -0
  54. package/lib/ai/providers/openai.js.map +1 -0
  55. package/lib/ai/rate-limiter.d.ts +38 -0
  56. package/lib/ai/rate-limiter.d.ts.map +1 -0
  57. package/lib/ai/rate-limiter.js +86 -0
  58. package/lib/ai/rate-limiter.js.map +1 -0
  59. package/lib/ai/service.d.ts +81 -0
  60. package/lib/ai/service.d.ts.map +1 -0
  61. package/lib/ai/service.js +274 -0
  62. package/lib/ai/service.js.map +1 -0
  63. package/lib/ai/session.d.ts +186 -0
  64. package/lib/ai/session.d.ts.map +1 -0
  65. package/lib/ai/session.js +443 -0
  66. package/lib/ai/session.js.map +1 -0
  67. package/lib/ai/tone-detector.d.ts +19 -0
  68. package/lib/ai/tone-detector.d.ts.map +1 -0
  69. package/lib/ai/tone-detector.js +72 -0
  70. package/lib/ai/tone-detector.js.map +1 -0
  71. package/lib/ai/tools.d.ts +45 -0
  72. package/lib/ai/tools.d.ts.map +1 -0
  73. package/lib/ai/tools.js +206 -0
  74. package/lib/ai/tools.js.map +1 -0
  75. package/lib/ai/types.d.ts +264 -0
  76. package/lib/ai/types.d.ts.map +1 -0
  77. package/lib/ai/types.js +6 -0
  78. package/lib/ai/types.js.map +1 -0
  79. package/lib/ai/user-profile.d.ts +56 -0
  80. package/lib/ai/user-profile.d.ts.map +1 -0
  81. package/lib/ai/user-profile.js +130 -0
  82. package/lib/ai/user-profile.js.map +1 -0
  83. package/lib/ai/zhin-agent.d.ts +165 -0
  84. package/lib/ai/zhin-agent.d.ts.map +1 -0
  85. package/lib/ai/zhin-agent.js +707 -0
  86. package/lib/ai/zhin-agent.js.map +1 -0
  87. package/lib/built/ai-trigger.d.ts.map +1 -1
  88. package/lib/built/ai-trigger.js +7 -3
  89. package/lib/built/ai-trigger.js.map +1 -1
  90. package/lib/built/command.d.ts +33 -17
  91. package/lib/built/command.d.ts.map +1 -1
  92. package/lib/built/command.js +71 -44
  93. package/lib/built/command.js.map +1 -1
  94. package/lib/built/component.d.ts +42 -15
  95. package/lib/built/component.d.ts.map +1 -1
  96. package/lib/built/component.js +84 -52
  97. package/lib/built/component.js.map +1 -1
  98. package/lib/built/config.d.ts +64 -5
  99. package/lib/built/config.d.ts.map +1 -1
  100. package/lib/built/config.js +129 -12
  101. package/lib/built/config.js.map +1 -1
  102. package/lib/built/cron.d.ts +41 -18
  103. package/lib/built/cron.d.ts.map +1 -1
  104. package/lib/built/cron.js +106 -63
  105. package/lib/built/cron.js.map +1 -1
  106. package/lib/built/database.d.ts +55 -6
  107. package/lib/built/database.d.ts.map +1 -1
  108. package/lib/built/database.js +93 -22
  109. package/lib/built/database.js.map +1 -1
  110. package/lib/built/dispatcher.d.ts +118 -0
  111. package/lib/built/dispatcher.d.ts.map +1 -0
  112. package/lib/built/dispatcher.js +196 -0
  113. package/lib/built/dispatcher.js.map +1 -0
  114. package/lib/built/permission.d.ts +45 -5
  115. package/lib/built/permission.d.ts.map +1 -1
  116. package/lib/built/permission.js +56 -11
  117. package/lib/built/permission.js.map +1 -1
  118. package/lib/built/skill.d.ts +117 -0
  119. package/lib/built/skill.d.ts.map +1 -0
  120. package/lib/built/skill.js +191 -0
  121. package/lib/built/skill.js.map +1 -0
  122. package/lib/built/tool.d.ts +71 -164
  123. package/lib/built/tool.d.ts.map +1 -1
  124. package/lib/built/tool.js +212 -297
  125. package/lib/built/tool.js.map +1 -1
  126. package/lib/feature.d.ts +75 -0
  127. package/lib/feature.d.ts.map +1 -0
  128. package/lib/feature.js +69 -0
  129. package/lib/feature.js.map +1 -0
  130. package/lib/index.d.ts +4 -0
  131. package/lib/index.d.ts.map +1 -1
  132. package/lib/index.js +7 -0
  133. package/lib/index.js.map +1 -1
  134. package/lib/plugin.d.ts +25 -17
  135. package/lib/plugin.d.ts.map +1 -1
  136. package/lib/plugin.js +180 -20
  137. package/lib/plugin.js.map +1 -1
  138. package/lib/types.d.ts +4 -9
  139. package/lib/types.d.ts.map +1 -1
  140. package/package.json +6 -6
  141. package/src/adapter.ts +101 -2
  142. package/src/ai/agent.ts +772 -0
  143. package/src/ai/context-manager.ts +440 -0
  144. package/src/ai/conversation-memory.ts +774 -0
  145. package/src/ai/follow-up.ts +357 -0
  146. package/src/ai/index.ts +128 -0
  147. package/src/ai/init.ts +502 -0
  148. package/src/ai/output.ts +261 -0
  149. package/src/ai/providers/anthropic.ts +375 -0
  150. package/src/ai/providers/base.ts +173 -0
  151. package/src/ai/providers/index.ts +13 -0
  152. package/src/ai/providers/ollama.ts +292 -0
  153. package/src/ai/providers/openai.ts +167 -0
  154. package/src/ai/rate-limiter.ts +129 -0
  155. package/src/ai/service.ts +319 -0
  156. package/src/ai/session.ts +544 -0
  157. package/src/ai/tone-detector.ts +89 -0
  158. package/src/ai/tools.ts +218 -0
  159. package/src/ai/types.ts +296 -0
  160. package/src/ai/user-profile.ts +181 -0
  161. package/src/ai/zhin-agent.ts +845 -0
  162. package/src/built/ai-trigger.ts +6 -3
  163. package/src/built/command.ts +75 -69
  164. package/src/built/component.ts +94 -76
  165. package/src/built/config.ts +288 -128
  166. package/src/built/cron.ts +117 -101
  167. package/src/built/database.ts +128 -33
  168. package/src/built/dispatcher.ts +332 -0
  169. package/src/built/permission.ts +146 -54
  170. package/src/built/skill.ts +280 -0
  171. package/src/built/tool.ts +245 -366
  172. package/src/feature.ts +113 -0
  173. package/src/index.ts +7 -0
  174. package/src/plugin.ts +198 -33
  175. package/src/types.ts +6 -10
  176. package/tests/adapter.test.ts +153 -1
  177. package/tests/ai/agent.test.ts +614 -0
  178. package/tests/ai/ai-trigger.test.ts +368 -0
  179. package/tests/ai/context-manager.test.ts +413 -0
  180. package/tests/ai/conversation-memory.test.ts +128 -0
  181. package/tests/ai/follow-up.test.ts +175 -0
  182. package/tests/ai/integration.test.ts +584 -0
  183. package/tests/ai/output.test.ts +128 -0
  184. package/tests/ai/providers.integration.test.ts +227 -0
  185. package/tests/ai/rate-limiter.test.ts +108 -0
  186. package/tests/ai/session.test.ts +375 -0
  187. package/tests/ai/setup.ts +308 -0
  188. package/tests/ai/tone-detector.test.ts +80 -0
  189. package/tests/ai/tool.test.ts +800 -0
  190. package/tests/ai/tools-builtin.test.ts +346 -0
  191. package/tests/ai/user-profile.test.ts +73 -0
  192. package/tests/ai/zhin-agent.test.ts +177 -0
  193. package/tests/config.test.ts +46 -0
  194. package/tests/cron.test.ts +94 -5
  195. package/tests/dispatcher.test.ts +146 -0
  196. package/tests/feature.test.ts +145 -0
  197. package/tests/features-builtin.test.ts +191 -0
  198. package/tests/plugin.test.ts +88 -14
  199. package/tests/skill-feature.test.ts +179 -0
  200. package/tests/tool-feature.test.ts +254 -0
  201. package/test/minimal-bot.ts +0 -31
  202. package/test/stress-test.ts +0 -123
@@ -0,0 +1,175 @@
1
+ /**
2
+ * FollowUpManager 测试
3
+ */
4
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
5
+ import { FollowUpManager } from '../../src/ai/follow-up.js';
6
+
7
+ describe('FollowUpManager', () => {
8
+ let manager: FollowUpManager;
9
+
10
+ beforeEach(() => {
11
+ vi.useFakeTimers();
12
+ manager = new FollowUpManager();
13
+ });
14
+
15
+ afterEach(() => {
16
+ manager.dispose();
17
+ vi.useRealTimers();
18
+ });
19
+
20
+ const baseParams = {
21
+ sessionId: 'session1',
22
+ platform: 'qq',
23
+ botId: 'bot1',
24
+ senderId: 'user1',
25
+ sceneId: 'group1',
26
+ sceneType: 'group',
27
+ };
28
+
29
+ describe('schedule', () => {
30
+ it('应创建跟进任务并返回确认文本', async () => {
31
+ const result = await manager.schedule({
32
+ ...baseParams,
33
+ message: '提醒你吃饭',
34
+ delayMinutes: 5,
35
+ });
36
+
37
+ expect(result).toContain('已安排提醒');
38
+ expect(result).toContain('提醒你吃饭');
39
+ });
40
+
41
+ it('应限制最小延迟为 1 分钟', async () => {
42
+ const result = await manager.schedule({
43
+ ...baseParams,
44
+ message: '立即提醒',
45
+ delayMinutes: 0,
46
+ });
47
+ expect(result).toContain('已安排提醒');
48
+ });
49
+
50
+ it('应限制最大延迟为 7 天', async () => {
51
+ const result = await manager.schedule({
52
+ ...baseParams,
53
+ message: '长期提醒',
54
+ delayMinutes: 99999,
55
+ });
56
+ expect(result).toContain('天后');
57
+ });
58
+
59
+ it('同一会话新任务应自动取消旧任务', async () => {
60
+ const sender = vi.fn();
61
+ manager.setSender(sender);
62
+
63
+ await manager.schedule({
64
+ ...baseParams,
65
+ message: '第一个提醒',
66
+ delayMinutes: 10,
67
+ });
68
+
69
+ await manager.schedule({
70
+ ...baseParams,
71
+ message: '第二个提醒',
72
+ delayMinutes: 5,
73
+ });
74
+
75
+ // 推进 11 分钟
76
+ await vi.advanceTimersByTimeAsync(11 * 60 * 1000);
77
+
78
+ // 只有第二个应触发
79
+ expect(sender).toHaveBeenCalledTimes(1);
80
+ expect(sender.mock.calls[0][0].message).toBe('第二个提醒');
81
+ });
82
+ });
83
+
84
+ describe('到期触发', () => {
85
+ it('到期应调用 sender', async () => {
86
+ const sender = vi.fn();
87
+ manager.setSender(sender);
88
+
89
+ await manager.schedule({
90
+ ...baseParams,
91
+ message: '时间到了',
92
+ delayMinutes: 1,
93
+ });
94
+
95
+ // 推进 1 分钟
96
+ await vi.advanceTimersByTimeAsync(60 * 1000);
97
+
98
+ expect(sender).toHaveBeenCalledTimes(1);
99
+ expect(sender.mock.calls[0][0].message).toBe('时间到了');
100
+ });
101
+
102
+ it('无 sender 时不应崩溃', async () => {
103
+ await manager.schedule({
104
+ ...baseParams,
105
+ message: '测试',
106
+ delayMinutes: 1,
107
+ });
108
+
109
+ // 推进 1 分钟 - 不应抛错
110
+ await vi.advanceTimersByTimeAsync(60 * 1000);
111
+ });
112
+ });
113
+
114
+ describe('cancelBySession', () => {
115
+ it('应取消指定会话的所有 pending 任务', async () => {
116
+ const sender = vi.fn();
117
+ manager.setSender(sender);
118
+
119
+ await manager.schedule({
120
+ ...baseParams,
121
+ message: '会被取消',
122
+ delayMinutes: 5,
123
+ });
124
+
125
+ const count = await manager.cancelBySession('session1');
126
+ expect(count).toBe(1);
127
+
128
+ // 推进时间,sender 不应被调用
129
+ await vi.advanceTimersByTimeAsync(10 * 60 * 1000);
130
+ expect(sender).not.toHaveBeenCalled();
131
+ });
132
+
133
+ it('无 pending 时应返回 0', async () => {
134
+ const count = await manager.cancelBySession('nonexistent');
135
+ expect(count).toBe(0);
136
+ });
137
+ });
138
+
139
+ describe('restore', () => {
140
+ it('应恢复未完成的任务', async () => {
141
+ const sender = vi.fn();
142
+ manager.setSender(sender);
143
+
144
+ // 创建一个 5 分钟后的任务
145
+ await manager.schedule({
146
+ ...baseParams,
147
+ message: '恢复测试',
148
+ delayMinutes: 5,
149
+ });
150
+
151
+ // 恢复
152
+ const count = await manager.restore();
153
+ expect(count).toBeGreaterThanOrEqual(0);
154
+ });
155
+ });
156
+
157
+ describe('dispose', () => {
158
+ it('应清理所有定时器和存储', async () => {
159
+ const sender = vi.fn();
160
+ manager.setSender(sender);
161
+
162
+ await manager.schedule({
163
+ ...baseParams,
164
+ message: '测试',
165
+ delayMinutes: 5,
166
+ });
167
+
168
+ manager.dispose();
169
+
170
+ // 推进时间,sender 不应被调用
171
+ await vi.advanceTimersByTimeAsync(10 * 60 * 1000);
172
+ expect(sender).not.toHaveBeenCalled();
173
+ });
174
+ });
175
+ });