@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.
- package/CHANGELOG.md +10 -0
- package/README.md +84 -342
- package/lib/adapter.d.ts +17 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +84 -2
- package/lib/adapter.js.map +1 -1
- package/lib/ai/agent.d.ts +126 -0
- package/lib/ai/agent.d.ts.map +1 -0
- package/lib/ai/agent.js +645 -0
- package/lib/ai/agent.js.map +1 -0
- package/lib/ai/context-manager.d.ts +213 -0
- package/lib/ai/context-manager.d.ts.map +1 -0
- package/lib/ai/context-manager.js +313 -0
- package/lib/ai/context-manager.js.map +1 -0
- package/lib/ai/conversation-memory.d.ts +181 -0
- package/lib/ai/conversation-memory.d.ts.map +1 -0
- package/lib/ai/conversation-memory.js +581 -0
- package/lib/ai/conversation-memory.js.map +1 -0
- package/lib/ai/follow-up.d.ts +131 -0
- package/lib/ai/follow-up.d.ts.map +1 -0
- package/lib/ai/follow-up.js +265 -0
- package/lib/ai/follow-up.js.map +1 -0
- package/lib/ai/index.d.ts +29 -0
- package/lib/ai/index.d.ts.map +1 -0
- package/lib/ai/index.js +34 -0
- package/lib/ai/index.js.map +1 -0
- package/lib/ai/init.d.ts +30 -0
- package/lib/ai/init.d.ts.map +1 -0
- package/lib/ai/init.js +424 -0
- package/lib/ai/init.js.map +1 -0
- package/lib/ai/output.d.ts +93 -0
- package/lib/ai/output.d.ts.map +1 -0
- package/lib/ai/output.js +176 -0
- package/lib/ai/output.js.map +1 -0
- package/lib/ai/providers/anthropic.d.ts +23 -0
- package/lib/ai/providers/anthropic.d.ts.map +1 -0
- package/lib/ai/providers/anthropic.js +322 -0
- package/lib/ai/providers/anthropic.js.map +1 -0
- package/lib/ai/providers/base.d.ts +43 -0
- package/lib/ai/providers/base.d.ts.map +1 -0
- package/lib/ai/providers/base.js +135 -0
- package/lib/ai/providers/base.js.map +1 -0
- package/lib/ai/providers/index.d.ts +12 -0
- package/lib/ai/providers/index.d.ts.map +1 -0
- package/lib/ai/providers/index.js +9 -0
- package/lib/ai/providers/index.js.map +1 -0
- package/lib/ai/providers/ollama.d.ts +25 -0
- package/lib/ai/providers/ollama.d.ts.map +1 -0
- package/lib/ai/providers/ollama.js +243 -0
- package/lib/ai/providers/ollama.js.map +1 -0
- package/lib/ai/providers/openai.d.ts +46 -0
- package/lib/ai/providers/openai.d.ts.map +1 -0
- package/lib/ai/providers/openai.js +132 -0
- package/lib/ai/providers/openai.js.map +1 -0
- package/lib/ai/rate-limiter.d.ts +38 -0
- package/lib/ai/rate-limiter.d.ts.map +1 -0
- package/lib/ai/rate-limiter.js +86 -0
- package/lib/ai/rate-limiter.js.map +1 -0
- package/lib/ai/service.d.ts +81 -0
- package/lib/ai/service.d.ts.map +1 -0
- package/lib/ai/service.js +274 -0
- package/lib/ai/service.js.map +1 -0
- package/lib/ai/session.d.ts +186 -0
- package/lib/ai/session.d.ts.map +1 -0
- package/lib/ai/session.js +443 -0
- package/lib/ai/session.js.map +1 -0
- package/lib/ai/tone-detector.d.ts +19 -0
- package/lib/ai/tone-detector.d.ts.map +1 -0
- package/lib/ai/tone-detector.js +72 -0
- package/lib/ai/tone-detector.js.map +1 -0
- package/lib/ai/tools.d.ts +45 -0
- package/lib/ai/tools.d.ts.map +1 -0
- package/lib/ai/tools.js +206 -0
- package/lib/ai/tools.js.map +1 -0
- package/lib/ai/types.d.ts +264 -0
- package/lib/ai/types.d.ts.map +1 -0
- package/lib/ai/types.js +6 -0
- package/lib/ai/types.js.map +1 -0
- package/lib/ai/user-profile.d.ts +56 -0
- package/lib/ai/user-profile.d.ts.map +1 -0
- package/lib/ai/user-profile.js +130 -0
- package/lib/ai/user-profile.js.map +1 -0
- package/lib/ai/zhin-agent.d.ts +165 -0
- package/lib/ai/zhin-agent.d.ts.map +1 -0
- package/lib/ai/zhin-agent.js +707 -0
- package/lib/ai/zhin-agent.js.map +1 -0
- package/lib/built/ai-trigger.d.ts.map +1 -1
- package/lib/built/ai-trigger.js +7 -3
- package/lib/built/ai-trigger.js.map +1 -1
- package/lib/built/command.d.ts +33 -17
- package/lib/built/command.d.ts.map +1 -1
- package/lib/built/command.js +71 -44
- package/lib/built/command.js.map +1 -1
- package/lib/built/component.d.ts +42 -15
- package/lib/built/component.d.ts.map +1 -1
- package/lib/built/component.js +84 -52
- package/lib/built/component.js.map +1 -1
- package/lib/built/config.d.ts +54 -5
- package/lib/built/config.d.ts.map +1 -1
- package/lib/built/config.js +76 -10
- package/lib/built/config.js.map +1 -1
- package/lib/built/cron.d.ts +41 -18
- package/lib/built/cron.d.ts.map +1 -1
- package/lib/built/cron.js +106 -63
- package/lib/built/cron.js.map +1 -1
- package/lib/built/database.d.ts +55 -6
- package/lib/built/database.d.ts.map +1 -1
- package/lib/built/database.js +93 -22
- package/lib/built/database.js.map +1 -1
- package/lib/built/dispatcher.d.ts +118 -0
- package/lib/built/dispatcher.d.ts.map +1 -0
- package/lib/built/dispatcher.js +196 -0
- package/lib/built/dispatcher.js.map +1 -0
- package/lib/built/permission.d.ts +45 -5
- package/lib/built/permission.d.ts.map +1 -1
- package/lib/built/permission.js +56 -11
- package/lib/built/permission.js.map +1 -1
- package/lib/built/skill.d.ts +117 -0
- package/lib/built/skill.d.ts.map +1 -0
- package/lib/built/skill.js +191 -0
- package/lib/built/skill.js.map +1 -0
- package/lib/built/tool.d.ts +71 -164
- package/lib/built/tool.d.ts.map +1 -1
- package/lib/built/tool.js +212 -297
- package/lib/built/tool.js.map +1 -1
- package/lib/feature.d.ts +75 -0
- package/lib/feature.d.ts.map +1 -0
- package/lib/feature.js +69 -0
- package/lib/feature.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -1
- package/lib/plugin.d.ts +25 -17
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +180 -20
- package/lib/plugin.js.map +1 -1
- package/lib/types.d.ts +4 -9
- package/lib/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/adapter.ts +101 -2
- package/src/ai/agent.ts +772 -0
- package/src/ai/context-manager.ts +440 -0
- package/src/ai/conversation-memory.ts +774 -0
- package/src/ai/follow-up.ts +357 -0
- package/src/ai/index.ts +128 -0
- package/src/ai/init.ts +502 -0
- package/src/ai/output.ts +261 -0
- package/src/ai/providers/anthropic.ts +375 -0
- package/src/ai/providers/base.ts +173 -0
- package/src/ai/providers/index.ts +13 -0
- package/src/ai/providers/ollama.ts +292 -0
- package/src/ai/providers/openai.ts +167 -0
- package/src/ai/rate-limiter.ts +129 -0
- package/src/ai/service.ts +319 -0
- package/src/ai/session.ts +544 -0
- package/src/ai/tone-detector.ts +89 -0
- package/src/ai/tools.ts +218 -0
- package/src/ai/types.ts +296 -0
- package/src/ai/user-profile.ts +181 -0
- package/src/ai/zhin-agent.ts +845 -0
- package/src/built/ai-trigger.ts +6 -3
- package/src/built/command.ts +75 -69
- package/src/built/component.ts +94 -76
- package/src/built/config.ts +238 -128
- package/src/built/cron.ts +117 -101
- package/src/built/database.ts +128 -33
- package/src/built/dispatcher.ts +332 -0
- package/src/built/permission.ts +146 -54
- package/src/built/skill.ts +280 -0
- package/src/built/tool.ts +245 -366
- package/src/feature.ts +113 -0
- package/src/index.ts +7 -0
- package/src/plugin.ts +198 -33
- package/src/types.ts +6 -10
- package/tests/adapter.test.ts +153 -1
- package/tests/ai/agent.test.ts +614 -0
- package/tests/ai/ai-trigger.test.ts +368 -0
- package/tests/ai/context-manager.test.ts +413 -0
- package/tests/ai/conversation-memory.test.ts +128 -0
- package/tests/ai/follow-up.test.ts +175 -0
- package/tests/ai/integration.test.ts +584 -0
- package/tests/ai/output.test.ts +128 -0
- package/tests/ai/providers.integration.test.ts +227 -0
- package/tests/ai/rate-limiter.test.ts +108 -0
- package/tests/ai/session.test.ts +375 -0
- package/tests/ai/setup.ts +308 -0
- package/tests/ai/tone-detector.test.ts +80 -0
- package/tests/ai/tool.test.ts +800 -0
- package/tests/ai/tools-builtin.test.ts +346 -0
- package/tests/ai/user-profile.test.ts +73 -0
- package/tests/ai/zhin-agent.test.ts +177 -0
- package/tests/config.test.ts +46 -0
- package/tests/cron.test.ts +94 -5
- package/tests/dispatcher.test.ts +146 -0
- package/tests/feature.test.ts +145 -0
- package/tests/features-builtin.test.ts +191 -0
- package/tests/plugin.test.ts +88 -14
- package/tests/skill-feature.test.ts +179 -0
- 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":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AAItD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,GAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAgBnD,+EAA+E;AAC/E,OAAO;AACP,+EAA+E;AAE/E;;GAEG;AACH,SAAS,gBAAgB,CAAC,OAAqB;IAC7C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAEjG,4BAA4B;IAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC1D,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC1C,IAAI,QAAQ;gBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC9D,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC1C,IAAI,QAAQ;gBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACrD,aAAa;IACb,OAAO,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC;IAE3B,gBAAgB;IAChB,4DAA4D;IAC5D,MAAM,WAAW,GAAI,MAAc,CAAC,WAEvB,CAAC;IACd,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;QACtC,WAAW,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;QACjD,WAAW,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC;QACxD,WAAW,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;QAC7C,WAAW,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;QAC7C,WAAW,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QAC9C,WAAW,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;QACvD,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC3E,CAAC;IAED,gBAAgB;IAChB,IAAI,iBAAiB,GAAqB,IAAI,CAAC;IAC/C,IAAI,iBAAiB,GAAqB,IAAI,CAAC;IAE/C,OAAO,CAAC;QACN,IAAI,EAAE,IAAW;QACjB,WAAW,EAAE,0CAA0C;QACvD,KAAK,CAAC,OAAO,CAAC,CAAS;YACrB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,SAAS,GACb,aAAa,EAAE,GAAG,CAAoB,iBAAiB,CAAC,IAAI,EAAE,CAAC;YACjE,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;YAElC,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;gBACtC,OAAO,IAAW,CAAC;YACrB,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;YACtC,iBAAiB,GAAG,OAAO,CAAC;YAC5B,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAExB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,CACT,oEAAoE,CACrE,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CACT,sCAAsC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7D,CAAC;YACJ,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAyB;YACrC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,iBAAiB,GAAG,IAAI,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,uBAAuB;IACvB,UAAU,CAAC,IAAW,EAAE,CAAC,EAAa,EAAE,EAAE;QACxC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;QACtC,iBAAiB,GAAG,KAAK,CAAC;QAE1B,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,OAAc,CAEnC,CAAC;QACd,IAAI,aAAa;YAAE,KAAK,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAEzD,8BAA8B;QAC9B,KAAK,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAe,CAAQ,CAAC;YAC3D,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;gBAC1D,MAAM,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,MAAM,OAAO,GAAG,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,OAAO,CAAC,WAAW,CAAC;gBACxB,OAAO,EAAE,MAAM,CAAC,QAAQ;gBACxB,GAAG,EAAE,MAAM,CAAC,MAAM;gBAClB,EAAE,EAAE,MAAM,CAAC,QAAQ;gBACnB,IAAI,EAAE,MAAM,CAAC,UAAiB;gBAC9B,OAAO;aACR,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE;YACV,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,iBAAiB,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,iBAAiB;IACjB,UAAU,CAAC,IAAW,EAAE,CAAC,EAAa,EAAE,EAAE;QACxC,MAAM,SAAS,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACxC,MAAM,aAAa,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,CAAC,QAAyB,EAAU,EAAE;YACzD,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC1B,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;oBAChB,KAAK,MAAM;wBACT,IAAI,EAAE,CAAC,OAAO;4BAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;wBACvC,MAAM;oBACR,KAAK,OAAO;wBACV,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;wBACvC,MAAM;oBACR,KAAK,OAAO;wBACV,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;wBACvC,MAAM;oBACR,KAAK,OAAO;wBACV,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;wBACvC,MAAM;oBACR,KAAK,MAAM,CAAC,CAAC,CAAC;wBACZ,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;wBAC9B,IAAI,EAAE,CAAC,WAAW;4BAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;wBAC5C,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM;4BACnB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM;gCAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;wBACjE,IAAI,EAAE,CAAC,QAAQ;4BAAE,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC;wBAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;wBAC1B,MAAM;oBACR,CAAC;oBACD,KAAK,MAAM;wBACT,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;wBACvC,MAAM;gBACV,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,KAAK,EAC3B,OAAqB,EACrB,OAAe,EACf,EAAE;YACF,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE;gBAAE,OAAO;YAC1B,IAAI,aAAa,CAAC,eAAe;gBAC/B,MAAM,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;YAEtD,MAAM,WAAW,GAAG,sBAAsB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACnE,MAAM,WAAW,GAAgB;gBAC/B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK,EAAE,OAAO,CAAC,IAAI;gBACnB,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;gBACnD,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;gBAC5B,OAAO;gBACP,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,qBAAqB,EAAE,WAAW,CAAC,eAAe;gBAClD,YAAY,EAAE,WAAW,CAAC,YAAY;gBACtC,YAAY,EAAE,WAAW,CAAC,YAAY;gBACtC,UAAU,EAAE,WAAW,CAAC,UAAU;gBAClC,OAAO,EAAE,WAAW,CAAC,OAAO;aAC7B,CAAC;YAEF,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACnC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxC,IAAI,aAAa,GAAW,EAAE,CAAC;YAC/B,IAAI,WAAW,EAAE,CAAC;gBAChB,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC7C,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;YAC1E,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,sBAAsB,aAAa,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAE7G,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAC5C,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CACnE,CAAC;gBAEF,IAAI,YAAoB,CAAC;gBACzB,IAAI,iBAAiB,EAAE,CAAC;oBACtB,oBAAoB;oBACpB,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;oBAC5C,IAAI,QAAyB,CAAC;oBAC9B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACzB,MAAM,KAAK,GAAkB,EAAE,CAAC;wBAChC,IAAI,OAAO;4BAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;wBACzD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;4BAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;wBACxD,CAAC;wBACD,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;4BAC5B,iBAAiB,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC;4BACvD,OAAO;yBACR,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;4BAC5B,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC;4BAC9D,OAAO;yBACR,CAAC,CAAC;oBACL,CAAC;oBACD,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACxC,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;wBAClC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC;wBAC/C,OAAO;qBACR,CAAC,CAAC;oBACH,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9D,CAAC;gBAED,IAAI,YAAY;oBAAE,MAAM,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC;gBAC5E,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACnE,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;gBAClF,MAAM,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAmB,CAErC,CAAC;QAEd,IAAI,UAAU,IAAI,OAAO,UAAU,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YAChE,UAAU,CAAC,mBAAmB,CAAC,CAAC,OAAqB,EAAE,EAAE,CACvD,eAAe,CAAC,OAAO,EAAE,aAAa,CAAC,CACxC,CAAC;YACF,UAAU,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC5D,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,QAAQ;QACR,MAAM,IAAI,GAAG,KAAK,EAChB,OAAqB,EACrB,IAAyB,EACzB,EAAE;YACF,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACvE,IAAI,CAAC,SAAS;gBAAE,OAAO,MAAM,IAAI,EAAE,CAAC;YACpC,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,IAAI,EAAE,CAAC;QACf,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACjE,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,gCAAgC;IAChC,UAAU,CAAC,UAAiB,EAAE,CAAC,EAAO,EAAE,EAAE;QACxC,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,iBAAiB;gBAAE,OAAO;YAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,SAAS,GACb,aAAa,EAAE,GAAG,CAAoB,iBAAiB,CAAC,IAAI,EAAE,CAAC;YACjE,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;YAElC,IAAI,MAAM,CAAC,QAAQ,EAAE,WAAW,KAAK,KAAK;gBAAE,OAAO;YAEnD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBAC3C,IAAI,CAAC,KAAK;oBAAE,OAAO;gBAEnB,MAAM,SAAS,GAAG,4BAA4B,CAC5C,KAAK,EACL,iBAAiB,CAAC,gBAAgB,EAAE,CACrC,CAAC;gBACF,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAC/C,IAAI,iBAAiB;oBAAE,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAEtE,MAAM,MAAM,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;gBACpD,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;oBAC7B,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;oBAChD,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;oBACpD,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;wBACzB,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;wBAChE,iBAAiB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;wBAC5C,IAAI,iBAAiB;4BAAE,iBAAiB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;oBACrE,CAAC;gBACH,CAAC;gBAED,4BAA4B;gBAC5B,IAAI,iBAAiB,EAAE,CAAC;oBACtB,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBAChD,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;oBACjD,IAAI,UAAU,IAAI,UAAU,EAAE,CAAC;wBAC7B,iBAAiB,CAAC,uBAAuB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;oBACpE,CAAC;oBAED,qBAAqB;oBACrB,MAAM,YAAY,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBACvD,IAAI,YAAY,EAAE,CAAC;wBACjB,iBAAiB,CAAC,yBAAyB,CAAC,YAAY,CAAC,CAAC;oBAC5D,CAAC;oBAED,4BAA4B;oBAC5B,MAAM,aAAa,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;oBACpD,IAAI,aAAa,EAAE,CAAC;wBAClB,iBAAiB,CAAC,0BAA0B,CAAC,aAAa,CAAC,CAAC;wBAE5D,iBAAiB;wBACjB,iBAAiB,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;4BAC7C,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;wBAC7C,CAAC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,MAAM,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACrF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAgB,EAAE,IAAyB,EAAE,EAAE;QACvE,MAAM,IAAI,EAAE,CAAC;QACb,IAAI,iBAAiB,EAAE,cAAc,EAAE,CAAC;YACtC,MAAM,MAAM,GAAkB;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;gBACpD,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,SAAS;gBAC/C,UAAU,EAAG,OAAO,CAAC,QAAgB,EAAE,IAAI,IAAI,EAAE;gBACjD,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;gBAC7B,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;gBACvD,OAAO,EACL,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;oBAC9B,CAAC,CAAC,OAAO,CAAC,IAAI;oBACd,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;gBAClC,IAAI,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE;aACvC,CAAC;YACF,iBAAiB,CAAC,cAAc,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,UAAU,CAAC,IAAW,EAAE,MAAa,EAAE,CAAC,EAAyB,EAAE,WAAgB,EAAE,EAAE;QACrF,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW;YAAE,OAAO;QAEhC,MAAM,cAAc,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC;aAC7C,IAAI,CAAC,eAAe,CAAC;aACrB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;aAChD,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;aACvB,OAAO,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;YACrC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;QAClI,CAAC,CAAC;aACD,MAAM,CAAC,KAAK,IAAI,EAAE;YACjB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,YAAY,CAAC;YACrB,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC;gBAC9C,CAAC,IAAI,MAAM,QAAQ,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1E,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;oBAAE,CAAC,IAAI,cAAc,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC;YAC1D,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QAEL,MAAM,gBAAgB,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC;aAC9C,IAAI,CAAC,aAAa,CAAC;aACnB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC;aAC3C,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC;aACpB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAChC,IAAI,CAAC,OAAO,EAAE,OAAO;gBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YAClE,MAAM,GAAG,GAAG,OAAO,CAAC,OAAkB,CAAC;YACvC,MAAM,GAAG,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACtF,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC/C,CAAC,CAAC;aACD,MAAM,CAAC,KAAK,EAAE,OAAgB,EAAE,EAAE;YACjC,MAAM,GAAG,GAAG,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAClG,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC,CAAC;QAEL,MAAM,eAAe,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC;aAC9C,IAAI,CAAC,eAAe,CAAC;aACrB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC;aAC7C,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;aACvB,OAAO,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;YACjC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;QACvF,CAAC,CAAC;aACD,MAAM,CAAC,KAAK,IAAI,EAAE;YACjB,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;YACjC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAC7B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAC/D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEL,MAAM,KAAK,GAAG,CAAC,cAAc,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC;QAClE,MAAM,SAAS,GAAmB,EAAE,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,MAAM,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,MAAM,sBAAsB,CAAC,CAAC;QAC/D,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -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
|
+
* -  → 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"}
|