@zhin.js/core 1.0.25 → 1.0.26

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 (200) hide show
  1. package/CHANGELOG.md +10 -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 +54 -5
  99. package/lib/built/config.d.ts.map +1 -1
  100. package/lib/built/config.js +76 -10
  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 +4 -4
  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 +238 -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
package/lib/ai/init.js ADDED
@@ -0,0 +1,424 @@
1
+ /**
2
+ * AI 模块初始化
3
+ *
4
+ * 将 AI 服务注册到 Zhin 插件系统中:
5
+ * - AIService context
6
+ * - ZhinAgent 全局大脑
7
+ * - AI 触发处理器 (via MessageDispatcher)
8
+ * - 数据库会话/上下文持久化
9
+ * - 消息记录中间件
10
+ * - AI 管理工具
11
+ */
12
+ import { getPlugin } from '../plugin.js';
13
+ import { ZhinTool, ToolFeature } from '../built/tool.js';
14
+ import { shouldTriggerAI, inferSenderPermissions, parseRichMediaContent, mergeAITriggerConfig, } from '../built/ai-trigger.js';
15
+ import { AIService } from './service.js';
16
+ import { ZhinAgent } from './zhin-agent.js';
17
+ import { SessionManager, createDatabaseSessionManager } from './session.js';
18
+ import { AI_SESSION_MODEL } from './session.js';
19
+ import { createContextManager, CHAT_MESSAGE_MODEL, CONTEXT_SUMMARY_MODEL, } from './context-manager.js';
20
+ import { AI_MESSAGE_MODEL, AI_SUMMARY_MODEL } from './conversation-memory.js';
21
+ import { AI_USER_PROFILE_MODEL } from './user-profile.js';
22
+ import { AI_FOLLOWUP_MODEL } from './follow-up.js';
23
+ // ============================================================================
24
+ // 辅助函数
25
+ // ============================================================================
26
+ /**
27
+ * 从消息中提取图片 URL(支持 XML 标签格式和 raw 对象格式)
28
+ */
29
+ function extractImageUrls(message) {
30
+ const urls = [];
31
+ const raw = typeof message.$raw === 'string' ? message.$raw : JSON.stringify(message.$raw || '');
32
+ // 匹配 <image url="..." /> 格式
33
+ const xmlMatches = raw.match(/<image[^>]+url="([^"]+)"/g);
34
+ if (xmlMatches) {
35
+ for (const m of xmlMatches) {
36
+ const urlMatch = m.match(/url="([^"]+)"/);
37
+ if (urlMatch)
38
+ urls.push(urlMatch[1]);
39
+ }
40
+ }
41
+ // 匹配 [CQ:image,url=...] 格式 (OneBot)
42
+ const cqMatches = raw.match(/\[CQ:image[^\]]*url=([^\],]+)/g);
43
+ if (cqMatches) {
44
+ for (const m of cqMatches) {
45
+ const urlMatch = m.match(/url=([^\],]+)/);
46
+ if (urlMatch)
47
+ urls.push(urlMatch[1]);
48
+ }
49
+ }
50
+ return urls;
51
+ }
52
+ // ============================================================================
53
+ // 初始化函数
54
+ // ============================================================================
55
+ /**
56
+ * 初始化 AI 模块
57
+ *
58
+ * 在 setup.ts 中调用:
59
+ * ```ts
60
+ * import { initAIModule } from '@zhin.js/core';
61
+ * initAIModule();
62
+ * ```
63
+ */
64
+ export function initAIModule() {
65
+ const plugin = getPlugin();
66
+ const { provide, useContext, root, logger } = plugin;
67
+ // ── 工具服务 ──
68
+ provide(new ToolFeature());
69
+ // ── 数据库模型定义 ──
70
+ // provide(defineDatabaseService) 之后 defineModel 即可用,直接在顶层定义
71
+ const defineModel = plugin.defineModel;
72
+ if (typeof defineModel === 'function') {
73
+ defineModel('chat_messages', CHAT_MESSAGE_MODEL);
74
+ defineModel('context_summaries', CONTEXT_SUMMARY_MODEL);
75
+ defineModel('ai_sessions', AI_SESSION_MODEL);
76
+ defineModel('ai_messages', AI_MESSAGE_MODEL);
77
+ defineModel('ai_summaries', AI_SUMMARY_MODEL);
78
+ defineModel('ai_user_profiles', AI_USER_PROFILE_MODEL);
79
+ defineModel('ai_followups', AI_FOLLOWUP_MODEL);
80
+ logger.debug('AI database models registered (7 tables)');
81
+ }
82
+ else {
83
+ logger.debug('defineModel not available, AI will use in-memory storage');
84
+ }
85
+ // ── AI 服务实例 ──
86
+ let aiServiceInstance = null;
87
+ let zhinAgentInstance = null;
88
+ provide({
89
+ name: 'ai',
90
+ description: 'AI Service - Multi-model LLM integration',
91
+ async mounted(p) {
92
+ const configService = root.inject('config');
93
+ const appConfig = configService?.get('zhin.config.yml') || {};
94
+ const config = appConfig.ai || {};
95
+ if (config.enabled === false) {
96
+ logger.info('AI Service is disabled');
97
+ return null;
98
+ }
99
+ const service = new AIService(config);
100
+ aiServiceInstance = service;
101
+ service.setPlugin(root);
102
+ const providers = service.listProviders();
103
+ if (providers.length === 0) {
104
+ logger.warn('No AI providers configured. Please add API keys in zhin.config.yml');
105
+ }
106
+ else {
107
+ logger.info(`AI Service started with providers: ${providers.join(', ')}`);
108
+ }
109
+ return service;
110
+ },
111
+ async dispose(service) {
112
+ if (service) {
113
+ service.dispose();
114
+ aiServiceInstance = null;
115
+ logger.info('AI Service stopped');
116
+ }
117
+ },
118
+ });
119
+ // ── ZhinAgent 全局大脑 ──
120
+ useContext('ai', (ai) => {
121
+ if (!ai.isReady()) {
122
+ logger.warn('AI Service not ready, ZhinAgent not created');
123
+ return;
124
+ }
125
+ const provider = ai.getProvider();
126
+ const agent = new ZhinAgent(provider);
127
+ zhinAgentInstance = agent;
128
+ const skillRegistry = root.inject('skill');
129
+ if (skillRegistry)
130
+ agent.setSkillRegistry(skillRegistry);
131
+ // 注入跟进提醒的发送回调(不依赖数据库,内存模式也能发)
132
+ agent.setFollowUpSender(async (record) => {
133
+ const adapter = root.inject(record.platform);
134
+ if (!adapter || typeof adapter.sendMessage !== 'function') {
135
+ logger.warn(`[跟进提醒] 找不到适配器: ${record.platform}`);
136
+ return;
137
+ }
138
+ const content = `⏰ 定时提醒:${record.message}`;
139
+ await adapter.sendMessage({
140
+ context: record.platform,
141
+ bot: record.bot_id,
142
+ id: record.scene_id,
143
+ type: record.scene_type,
144
+ content,
145
+ });
146
+ });
147
+ logger.debug('ZhinAgent created');
148
+ return () => {
149
+ agent.dispose();
150
+ zhinAgentInstance = null;
151
+ };
152
+ });
153
+ // ── AI 触发处理器 ──
154
+ useContext('ai', (ai) => {
155
+ const rawConfig = ai.getTriggerConfig();
156
+ const triggerConfig = mergeAITriggerConfig(rawConfig);
157
+ if (!triggerConfig.enabled) {
158
+ logger.info('AI Trigger is disabled');
159
+ return;
160
+ }
161
+ const renderOutput = (elements) => {
162
+ const parts = [];
163
+ for (const el of elements) {
164
+ switch (el.type) {
165
+ case 'text':
166
+ if (el.content)
167
+ parts.push(el.content);
168
+ break;
169
+ case 'image':
170
+ parts.push(`<image url="${el.url}"/>`);
171
+ break;
172
+ case 'audio':
173
+ parts.push(`<audio url="${el.url}"/>`);
174
+ break;
175
+ case 'video':
176
+ parts.push(`<video url="${el.url}"/>`);
177
+ break;
178
+ case 'card': {
179
+ const cp = [`📋 ${el.title}`];
180
+ if (el.description)
181
+ cp.push(el.description);
182
+ if (el.fields?.length)
183
+ for (const f of el.fields)
184
+ cp.push(` ${f.label}: ${f.value}`);
185
+ if (el.imageUrl)
186
+ cp.push(`<image url="${el.imageUrl}"/>`);
187
+ parts.push(cp.join('\n'));
188
+ break;
189
+ }
190
+ case 'file':
191
+ parts.push(`📎 ${el.name}: ${el.url}`);
192
+ break;
193
+ }
194
+ }
195
+ return parts.join('\n') || '';
196
+ };
197
+ const handleAIMessage = async (message, content) => {
198
+ const t0 = performance.now();
199
+ if (!ai.isReady())
200
+ return;
201
+ if (triggerConfig.thinkingMessage)
202
+ await message.$reply(triggerConfig.thinkingMessage);
203
+ const permissions = inferSenderPermissions(message, triggerConfig);
204
+ const toolContext = {
205
+ platform: message.$adapter,
206
+ botId: message.$bot,
207
+ sceneId: message.$channel?.id || message.$sender.id,
208
+ senderId: message.$sender.id,
209
+ message,
210
+ scope: permissions.scope,
211
+ senderPermissionLevel: permissions.permissionLevel,
212
+ isGroupAdmin: permissions.isGroupAdmin,
213
+ isGroupOwner: permissions.isGroupOwner,
214
+ isBotAdmin: permissions.isBotAdmin,
215
+ isOwner: permissions.isOwner,
216
+ };
217
+ const tCollect = performance.now();
218
+ const toolService = root.inject('tool');
219
+ let externalTools = [];
220
+ if (toolService) {
221
+ externalTools = toolService.collectAll(root);
222
+ externalTools = toolService.filterByContext(externalTools, toolContext);
223
+ }
224
+ logger.debug(`[AI Handler] 工具收集: ${externalTools.length} 个, ${(performance.now() - tCollect).toFixed(0)}ms`);
225
+ try {
226
+ const timeout = new Promise((_, rej) => setTimeout(() => rej(new Error('AI 响应超时')), triggerConfig.timeout));
227
+ let responseText;
228
+ if (zhinAgentInstance) {
229
+ // 检查消息是否包含图片(多模态路由)
230
+ const imageUrls = extractImageUrls(message);
231
+ let elements;
232
+ if (imageUrls.length > 0) {
233
+ const parts = [];
234
+ if (content)
235
+ parts.push({ type: 'text', text: content });
236
+ for (const url of imageUrls) {
237
+ parts.push({ type: 'image_url', image_url: { url } });
238
+ }
239
+ elements = await Promise.race([
240
+ zhinAgentInstance.processMultimodal(parts, toolContext),
241
+ timeout,
242
+ ]);
243
+ }
244
+ else {
245
+ elements = await Promise.race([
246
+ zhinAgentInstance.process(content, toolContext, externalTools),
247
+ timeout,
248
+ ]);
249
+ }
250
+ responseText = renderOutput(elements);
251
+ }
252
+ else {
253
+ const response = await Promise.race([
254
+ ai.process(content, toolContext, externalTools),
255
+ timeout,
256
+ ]);
257
+ responseText = typeof response === 'string' ? response : '';
258
+ }
259
+ if (responseText)
260
+ await message.$reply(parseRichMediaContent(responseText));
261
+ logger.info(`[AI Handler] 总耗时: ${(performance.now() - t0).toFixed(0)}ms`);
262
+ }
263
+ catch (error) {
264
+ const msg = error instanceof Error ? error.message : String(error);
265
+ logger.warn(`[AI Handler] 失败 (${(performance.now() - t0).toFixed(0)}ms): ${msg}`);
266
+ await message.$reply(triggerConfig.errorTemplate.replace('{error}', msg));
267
+ }
268
+ };
269
+ const dispatcher = root.inject('dispatcher');
270
+ if (dispatcher && typeof dispatcher.setAIHandler === 'function') {
271
+ dispatcher.setAITriggerMatcher((message) => shouldTriggerAI(message, triggerConfig));
272
+ dispatcher.setAIHandler(handleAIMessage);
273
+ logger.debug('AI Handler registered via MessageDispatcher');
274
+ return () => { logger.info('AI Handler unregistered'); };
275
+ }
276
+ // 回退中间件
277
+ const aiMw = async (message, next) => {
278
+ const { triggered, content } = shouldTriggerAI(message, triggerConfig);
279
+ if (!triggered)
280
+ return await next();
281
+ await handleAIMessage(message, content);
282
+ await next();
283
+ };
284
+ const dispose = root.addMiddleware(aiMw);
285
+ logger.debug('AI Trigger middleware registered (fallback mode)');
286
+ return () => { dispose(); };
287
+ });
288
+ // ── 数据库集成(db 就绪后升级各组件到数据库存储)──
289
+ useContext('database', (db) => {
290
+ setTimeout(() => {
291
+ if (!aiServiceInstance)
292
+ return;
293
+ const configService = root.inject('config');
294
+ const appConfig = configService?.get('zhin.config.yml') || {};
295
+ const config = appConfig.ai || {};
296
+ if (config.sessions?.useDatabase === false)
297
+ return;
298
+ try {
299
+ const model = db.models.get('ai_sessions');
300
+ if (!model)
301
+ return;
302
+ const dbSession = createDatabaseSessionManager(model, aiServiceInstance.getSessionConfig());
303
+ aiServiceInstance.setSessionManager(dbSession);
304
+ if (zhinAgentInstance)
305
+ zhinAgentInstance.setSessionManager(dbSession);
306
+ const ctxCfg = aiServiceInstance.getContextConfig();
307
+ if (ctxCfg.enabled !== false) {
308
+ const msgModel = db.models.get('chat_messages');
309
+ const sumModel = db.models.get('context_summaries');
310
+ if (msgModel && sumModel) {
311
+ const ctxMgr = createContextManager(msgModel, sumModel, ctxCfg);
312
+ aiServiceInstance.setContextManager(ctxMgr);
313
+ if (zhinAgentInstance)
314
+ zhinAgentInstance.setContextManager(ctxMgr);
315
+ }
316
+ }
317
+ // ConversationMemory 升级到数据库
318
+ if (zhinAgentInstance) {
319
+ const aiMsgModel = db.models.get('ai_messages');
320
+ const aiSumModel = db.models.get('ai_summaries');
321
+ if (aiMsgModel && aiSumModel) {
322
+ zhinAgentInstance.upgradeMemoryToDatabase(aiMsgModel, aiSumModel);
323
+ }
324
+ // UserProfile 升级到数据库
325
+ const profileModel = db.models.get('ai_user_profiles');
326
+ if (profileModel) {
327
+ zhinAgentInstance.upgradeProfilesToDatabase(profileModel);
328
+ }
329
+ // FollowUp 升级到数据库 + 恢复未完成任务
330
+ const followUpModel = db.models.get('ai_followups');
331
+ if (followUpModel) {
332
+ zhinAgentInstance.upgradeFollowUpsToDatabase(followUpModel);
333
+ // 从数据库恢复未完成的跟进任务
334
+ zhinAgentInstance.restoreFollowUps().catch(e => {
335
+ logger.warn('FollowUp restore failed:', e);
336
+ });
337
+ }
338
+ }
339
+ logger.debug('AI database storage activated (session, memory, profile, followup)');
340
+ }
341
+ catch (e) {
342
+ logger.error('AI Session: database setup failed:', e);
343
+ }
344
+ }, 100);
345
+ });
346
+ // ── 消息记录中间件 ──
347
+ root.addMiddleware(async (message, next) => {
348
+ await next();
349
+ if (aiServiceInstance?.contextManager) {
350
+ const record = {
351
+ platform: message.$adapter,
352
+ scene_id: message.$channel?.id || message.$sender.id,
353
+ scene_type: message.$channel?.type || 'private',
354
+ scene_name: message.$channel?.name || '',
355
+ sender_id: message.$sender.id,
356
+ sender_name: message.$sender.name || message.$sender.id,
357
+ message: typeof message.$raw === 'string'
358
+ ? message.$raw
359
+ : JSON.stringify(message.$raw),
360
+ time: message.$timestamp || Date.now(),
361
+ };
362
+ aiServiceInstance.contextManager.recordMessage(record).catch(() => { });
363
+ }
364
+ });
365
+ // ── AI 管理工具 ──
366
+ useContext('ai', 'tool', (ai, toolService) => {
367
+ if (!ai || !toolService)
368
+ return;
369
+ const listModelsTool = new ZhinTool('ai.models')
370
+ .desc('列出所有可用的 AI 模型')
371
+ .keyword('模型', '可用模型', 'ai模型', 'model', 'models')
372
+ .tag('ai', 'management')
373
+ .execute(async () => {
374
+ const models = await ai.listModels();
375
+ return { providers: models.map(({ provider, models: ml }) => ({ name: provider, models: ml.slice(0, 10), total: ml.length })) };
376
+ })
377
+ .action(async () => {
378
+ const models = await ai.listModels();
379
+ let r = '🤖 可用模型:\n';
380
+ for (const { provider, models: ml } of models) {
381
+ r += `\n【${provider}】\n` + ml.slice(0, 5).map(m => ` • ${m}`).join('\n');
382
+ if (ml.length > 5)
383
+ r += `\n ... 还有 ${ml.length - 5} 个`;
384
+ }
385
+ return r;
386
+ });
387
+ const clearSessionTool = new ZhinTool('ai.clear')
388
+ .desc('清除当前对话的历史记录')
389
+ .keyword('清除', '清空', '重置', 'clear', 'reset')
390
+ .tag('ai', 'session')
391
+ .execute(async (_args, context) => {
392
+ if (!context?.message)
393
+ return { success: false, error: '无消息上下文' };
394
+ const msg = context.message;
395
+ const sid = SessionManager.generateId(msg.$adapter, msg.$sender.id, msg.$channel?.id);
396
+ await ai.sessions.reset(sid);
397
+ return { success: true, message: '对话历史已清除' };
398
+ })
399
+ .action(async (message) => {
400
+ const sid = SessionManager.generateId(message.$adapter, message.$sender.id, message.$channel?.id);
401
+ await ai.sessions.reset(sid);
402
+ return '✅ 对话历史已清除';
403
+ });
404
+ const healthCheckTool = new ZhinTool('ai.health')
405
+ .desc('检查 AI 服务的健康状态')
406
+ .keyword('健康', '状态', '检查', 'health', 'status')
407
+ .tag('ai', 'management')
408
+ .execute(async () => {
409
+ const h = await ai.healthCheck();
410
+ return { providers: Object.entries(h).map(([n, ok]) => ({ name: n, healthy: ok })) };
411
+ })
412
+ .action(async () => {
413
+ const h = await ai.healthCheck();
414
+ return ['🏥 AI 服务健康状态:'].concat(Object.entries(h).map(([p, ok]) => ` ${ok ? '✅' : '❌'} ${p}`)).join('\n');
415
+ });
416
+ const tools = [listModelsTool, clearSessionTool, healthCheckTool];
417
+ const disposers = [];
418
+ for (const tool of tools)
419
+ disposers.push(toolService.addTool(tool, root.name));
420
+ logger.debug(`Registered ${tools.length} AI management tools`);
421
+ return () => disposers.forEach(d => d());
422
+ });
423
+ }
424
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/ai/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @zhin.js/ai - Multi-modal Output Pipeline
3
+ *
4
+ * 统一输出类型系统:AI 回复 → OutputElement[] → Adapter 渲染
5
+ *
6
+ * 支持的输出类型:
7
+ * - text: 纯文本 / markdown
8
+ * - image: 图片 URL 或 base64
9
+ * - audio: 音频 URL 或 base64
10
+ * - video: 视频 URL
11
+ * - card: 结构化卡片 (标题 + 正文 + 字段 + 按钮)
12
+ * - file: 文件附件
13
+ */
14
+ export interface TextElement {
15
+ type: 'text';
16
+ content: string;
17
+ /** markdown / plain */
18
+ format?: 'markdown' | 'plain';
19
+ }
20
+ export interface ImageElement {
21
+ type: 'image';
22
+ url: string;
23
+ /** base64 数据 (url 不可用时的后备) */
24
+ base64?: string;
25
+ alt?: string;
26
+ width?: number;
27
+ height?: number;
28
+ }
29
+ export interface AudioElement {
30
+ type: 'audio';
31
+ url: string;
32
+ base64?: string;
33
+ duration?: number;
34
+ /** 语音转文字的后备文本 */
35
+ fallbackText?: string;
36
+ }
37
+ export interface VideoElement {
38
+ type: 'video';
39
+ url: string;
40
+ coverUrl?: string;
41
+ duration?: number;
42
+ fallbackText?: string;
43
+ }
44
+ export interface CardField {
45
+ label: string;
46
+ value: string;
47
+ inline?: boolean;
48
+ }
49
+ export interface CardButton {
50
+ text: string;
51
+ /** 点击后发送的命令 */
52
+ command?: string;
53
+ /** 点击后打开的 URL */
54
+ url?: string;
55
+ }
56
+ export interface CardElement {
57
+ type: 'card';
58
+ title: string;
59
+ description?: string;
60
+ fields?: CardField[];
61
+ imageUrl?: string;
62
+ buttons?: CardButton[];
63
+ color?: string;
64
+ }
65
+ export interface FileElement {
66
+ type: 'file';
67
+ url: string;
68
+ name: string;
69
+ size?: number;
70
+ mimeType?: string;
71
+ }
72
+ export type OutputElement = TextElement | ImageElement | AudioElement | VideoElement | CardElement | FileElement;
73
+ /**
74
+ * 从 AI 回复文本中解析出结构化的 OutputElement[]
75
+ *
76
+ * 识别规则:
77
+ * - ![alt](url) → ImageElement
78
+ * - [audio](url) → AudioElement
79
+ * - [video](url) → VideoElement
80
+ * - ```card ... ``` → CardElement (JSON)
81
+ * - [file:name](url) → FileElement
82
+ * - 其余文本 → TextElement
83
+ */
84
+ export declare function parseOutput(raw: string): OutputElement[];
85
+ /**
86
+ * 将 OutputElement[] 降级为纯文本(用于不支持富媒体的平台)
87
+ */
88
+ export declare function renderToPlainText(elements: OutputElement[]): string;
89
+ /**
90
+ * 将 OutputElement[] 渲染为 Satori 兼容的 HTML 片段
91
+ */
92
+ export declare function renderToSatori(elements: OutputElement[]): string;
93
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/ai/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,WAAW,GACX,WAAW,CAAC;AAMhB;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CA4ExD;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAyBnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAkChE"}