@cloudbase/agent-adapter-wx 0.0.18
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/README.md +221 -0
- package/dist/index.d.mts +700 -0
- package/dist/index.d.ts +700 -0
- package/dist/index.js +1257 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1199 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +62 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import { AbstractAgent, AgentConfig, BaseEvent, RunAgentInput } from '@ag-ui/client';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { WxSendMessageInput, aitools } from '@cloudbase/aiagent-framework';
|
|
5
|
+
import { Logger } from '@cloudbase/agent-shared';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WeChat platform types
|
|
9
|
+
*/
|
|
10
|
+
declare enum WeChatPlatform {
|
|
11
|
+
/** 企业微信客服 */
|
|
12
|
+
CUSTOM_SERVICE = "WXCustomerService",
|
|
13
|
+
/** 微信小程序 */
|
|
14
|
+
MINI_APP = "WXMiniapp",
|
|
15
|
+
/** 微信服务号 */
|
|
16
|
+
SERVICE = "WXService",
|
|
17
|
+
/** 微信订阅号 */
|
|
18
|
+
SUBSCRIPTION = "WXSubscription"
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Message types
|
|
22
|
+
*/
|
|
23
|
+
declare enum MessageType {
|
|
24
|
+
TEXT = "text",
|
|
25
|
+
IMAGE = "image",
|
|
26
|
+
EVENT = "event",
|
|
27
|
+
VOICE = "voice"
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* WeChat send mode
|
|
31
|
+
*/
|
|
32
|
+
declare enum WeChatSendMode {
|
|
33
|
+
/** Use local WeChatSender (for local development) */
|
|
34
|
+
LOCAL = "local",
|
|
35
|
+
/** Use aitools SDK (for cloud function environment) */
|
|
36
|
+
AITOOLS = "aitools"
|
|
37
|
+
}
|
|
38
|
+
interface WeChatConfig {
|
|
39
|
+
platform: WeChatPlatform;
|
|
40
|
+
appId: string;
|
|
41
|
+
appSecret: string;
|
|
42
|
+
openKfId?: string;
|
|
43
|
+
tokenCacheTTL?: number;
|
|
44
|
+
sendMode?: WeChatSendMode;
|
|
45
|
+
context?: any;
|
|
46
|
+
}
|
|
47
|
+
interface MessageContent {
|
|
48
|
+
content: string;
|
|
49
|
+
type: MessageType;
|
|
50
|
+
imageUrl?: string;
|
|
51
|
+
}
|
|
52
|
+
interface SendMessageOptions {
|
|
53
|
+
toUser: string;
|
|
54
|
+
message: MessageContent;
|
|
55
|
+
recommendQuestions?: string[];
|
|
56
|
+
msgId?: string;
|
|
57
|
+
}
|
|
58
|
+
interface AccessTokenResponse {
|
|
59
|
+
access_token: string;
|
|
60
|
+
expires_in: number;
|
|
61
|
+
errcode?: number;
|
|
62
|
+
errmsg?: string;
|
|
63
|
+
}
|
|
64
|
+
interface WeChatAPIResponse {
|
|
65
|
+
errcode: number;
|
|
66
|
+
errmsg: string;
|
|
67
|
+
[key: string]: any;
|
|
68
|
+
}
|
|
69
|
+
interface TokenCacheEntry {
|
|
70
|
+
accessToken: string;
|
|
71
|
+
expiresAt: number;
|
|
72
|
+
}
|
|
73
|
+
interface WeChatMessage {
|
|
74
|
+
touser: string;
|
|
75
|
+
msgtype: string;
|
|
76
|
+
text?: {
|
|
77
|
+
content: string;
|
|
78
|
+
};
|
|
79
|
+
image?: {
|
|
80
|
+
media_id?: string;
|
|
81
|
+
pic_url?: string;
|
|
82
|
+
};
|
|
83
|
+
open_kfid?: string;
|
|
84
|
+
msgid?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* WeChat Message Handler - 微信消息处理工具
|
|
89
|
+
*
|
|
90
|
+
* 处理调用模型之前的所有逻辑:
|
|
91
|
+
* - 消息类型校验
|
|
92
|
+
* - 内容提取
|
|
93
|
+
* - 消息数据生成
|
|
94
|
+
* - 发送者/会话提取
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* WeChat message input - 微信公众号/服务号/小程序消息
|
|
99
|
+
*/
|
|
100
|
+
interface WeChatCommonInput {
|
|
101
|
+
toUserName: string;
|
|
102
|
+
fromUserName: string;
|
|
103
|
+
createTime: number;
|
|
104
|
+
msgType: string;
|
|
105
|
+
msgId: string;
|
|
106
|
+
content?: string;
|
|
107
|
+
mediaId?: string;
|
|
108
|
+
recognition?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* WeChat Work customer service message input - 企业微信客服消息
|
|
112
|
+
*/
|
|
113
|
+
interface WeChatWorkCommonInput {
|
|
114
|
+
toUserName?: string;
|
|
115
|
+
externalUserId: string;
|
|
116
|
+
openKfId: string;
|
|
117
|
+
msgType: string;
|
|
118
|
+
msgId: string;
|
|
119
|
+
sendTime: number;
|
|
120
|
+
text?: {
|
|
121
|
+
content: string;
|
|
122
|
+
};
|
|
123
|
+
voice?: {
|
|
124
|
+
mediaId: string;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Supported trigger sources - 支持的触发源
|
|
129
|
+
*/
|
|
130
|
+
type WeChatTriggerSrc = WeChatPlatform.SUBSCRIPTION | WeChatPlatform.SERVICE | WeChatPlatform.MINI_APP | WeChatPlatform.CUSTOM_SERVICE;
|
|
131
|
+
/**
|
|
132
|
+
* Supported message types - 支持的消息类型
|
|
133
|
+
*/
|
|
134
|
+
declare const SUPPORTED_MSG_TYPES: readonly ["text", "voice"];
|
|
135
|
+
type SupportedMsgType = (typeof SUPPORTED_MSG_TYPES)[number];
|
|
136
|
+
/**
|
|
137
|
+
* Chat history record - 聊天历史记录
|
|
138
|
+
*/
|
|
139
|
+
interface ChatHistoryRecord {
|
|
140
|
+
recordId: string;
|
|
141
|
+
botId: string;
|
|
142
|
+
conversation: string;
|
|
143
|
+
role: "user" | "assistant";
|
|
144
|
+
content: string;
|
|
145
|
+
type: string;
|
|
146
|
+
triggerSrc: string;
|
|
147
|
+
sender: string;
|
|
148
|
+
needAsyncReply: boolean;
|
|
149
|
+
reply: string;
|
|
150
|
+
originMsg: string;
|
|
151
|
+
recommendQuestions: string[];
|
|
152
|
+
createdAt: number;
|
|
153
|
+
image?: string;
|
|
154
|
+
status?: string;
|
|
155
|
+
traceId?: string;
|
|
156
|
+
asyncReply?: string;
|
|
157
|
+
replyTo?: string;
|
|
158
|
+
event?: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Processed message data - 处理后的消息数据
|
|
162
|
+
*/
|
|
163
|
+
interface ProcessedMsgData {
|
|
164
|
+
msgData: ChatHistoryRecord;
|
|
165
|
+
replyMsgData: ChatHistoryRecord;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Message validation result - 消息校验结果
|
|
169
|
+
*/
|
|
170
|
+
interface MessageValidationResult {
|
|
171
|
+
isValid: boolean;
|
|
172
|
+
skipAI: boolean;
|
|
173
|
+
errorMessage?: string;
|
|
174
|
+
userErrorMessage?: string;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Voice message handler type - 语音消息处理器类型
|
|
178
|
+
*/
|
|
179
|
+
type VoiceMessageHandler = (botId: string, triggerSrc: string, mediaId: string) => Promise<{
|
|
180
|
+
content: string;
|
|
181
|
+
} | null>;
|
|
182
|
+
/**
|
|
183
|
+
* Validate message type - 校验消息类型
|
|
184
|
+
*/
|
|
185
|
+
declare function validateMessageType(msgType: string): MessageValidationResult;
|
|
186
|
+
/**
|
|
187
|
+
* Extract message type from origin message - 从原始消息提取消息类型
|
|
188
|
+
*/
|
|
189
|
+
declare function extractMsgType(originMsg: any): string;
|
|
190
|
+
/**
|
|
191
|
+
* Extract trigger source from origin message - 从原始消息提取触发源
|
|
192
|
+
*/
|
|
193
|
+
declare function extractTriggerSrc(originMsg: any, defaultSrc?: WeChatTriggerSrc): WeChatTriggerSrc;
|
|
194
|
+
/**
|
|
195
|
+
* Extract text content from WeChat message - 从微信消息提取文本内容
|
|
196
|
+
*/
|
|
197
|
+
declare function extractTextContent(originMsg: any, triggerSrc: WeChatTriggerSrc): string;
|
|
198
|
+
/**
|
|
199
|
+
* Extract voice media ID from WeChat message - 从微信消息提取语音媒体ID
|
|
200
|
+
*/
|
|
201
|
+
declare function extractVoiceMediaId(originMsg: any, triggerSrc: WeChatTriggerSrc): string;
|
|
202
|
+
/**
|
|
203
|
+
* Get content from WeChat message (text or voice) - 获取微信消息内容
|
|
204
|
+
*/
|
|
205
|
+
declare function getWxChatContent(originMsg: any, triggerSrc: WeChatTriggerSrc, voiceMessageHandler?: VoiceMessageHandler, botId?: string): Promise<string>;
|
|
206
|
+
/**
|
|
207
|
+
* Extract sender from origin message - 从原始消息提取发送者
|
|
208
|
+
*/
|
|
209
|
+
declare function extractSender(originMsg: any, triggerSrc: WeChatTriggerSrc): string;
|
|
210
|
+
/**
|
|
211
|
+
* Extract conversation ID from origin message - 从原始消息提取会话ID
|
|
212
|
+
*/
|
|
213
|
+
declare function extractConversation(originMsg: any, triggerSrc: WeChatTriggerSrc): string;
|
|
214
|
+
/**
|
|
215
|
+
* Generate record ID - 生成记录ID
|
|
216
|
+
*/
|
|
217
|
+
declare function generateRecordId(triggerSrc: WeChatTriggerSrc, msgId: string, timestamp: number): string;
|
|
218
|
+
/**
|
|
219
|
+
* Extract message ID from origin message - 从原始消息提取消息ID
|
|
220
|
+
*/
|
|
221
|
+
declare function extractMsgId(originMsg: any): string;
|
|
222
|
+
/**
|
|
223
|
+
* Extract timestamp from origin message - 从原始消息提取时间戳
|
|
224
|
+
*/
|
|
225
|
+
declare function extractTimestamp(originMsg: any, triggerSrc: WeChatTriggerSrc): number;
|
|
226
|
+
/**
|
|
227
|
+
* Determine if async reply is needed - 判断是否需要异步回复
|
|
228
|
+
*/
|
|
229
|
+
declare function needAsyncReply(triggerSrc: WeChatTriggerSrc, wxVerify: boolean): boolean;
|
|
230
|
+
/**
|
|
231
|
+
* WeChat reply message structure
|
|
232
|
+
*/
|
|
233
|
+
interface WeChatReplyMessage {
|
|
234
|
+
toUserName: string;
|
|
235
|
+
fromUserName: string;
|
|
236
|
+
createTime: number;
|
|
237
|
+
msgType: string;
|
|
238
|
+
content: string;
|
|
239
|
+
msgId: string;
|
|
240
|
+
openKfId?: string;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Format reply message for WeChat
|
|
244
|
+
* Used for both sync HTTP response and async aitools sending
|
|
245
|
+
*/
|
|
246
|
+
declare function formatWeChatReplyMessage(callbackData: any, triggerSrc: string, content: string): WeChatReplyMessage;
|
|
247
|
+
/**
|
|
248
|
+
* Deal message data - 处理微信消息,生成 msgData 和 replyMsgData
|
|
249
|
+
* 完整实现原 chat_wx.service.ts 中的 dealMsgData 逻辑
|
|
250
|
+
*/
|
|
251
|
+
declare function dealMsgData(originMsg: WxSendMessageInput["callbackData"], triggerSrc: WeChatTriggerSrc, wxVerify: boolean, botId: string): ProcessedMsgData;
|
|
252
|
+
/**
|
|
253
|
+
* Handle WeChat retry for unverified accounts (11-second rule)
|
|
254
|
+
* 处理未认证账号的微信重试逻辑(11秒规则)
|
|
255
|
+
*/
|
|
256
|
+
declare function handleWeChatRetry(previousReply: HistoryEntry | null, originMsg: any, triggerSrc: WeChatTriggerSrc): Promise<{
|
|
257
|
+
shouldSkip: boolean;
|
|
258
|
+
content?: string;
|
|
259
|
+
}>;
|
|
260
|
+
/**
|
|
261
|
+
* Check if "继续" command is within 5-minute timeout
|
|
262
|
+
* 检查"继续"命令是否在5分钟超时内
|
|
263
|
+
*/
|
|
264
|
+
declare function isContinueCommandValid(previousReply: HistoryEntry | null): boolean;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* WeChat Chat History Manager
|
|
268
|
+
* Manages chat history for "continue" command and retry logic
|
|
269
|
+
* Uses CloudBase database storage
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Message role type
|
|
274
|
+
*/
|
|
275
|
+
type MessageRole = "user" | "assistant" | "system";
|
|
276
|
+
/**
|
|
277
|
+
* Metadata for history entry (stored in metadata field)
|
|
278
|
+
*/
|
|
279
|
+
interface HistoryEntryMetadata {
|
|
280
|
+
/** Sender identifier */
|
|
281
|
+
sender?: string;
|
|
282
|
+
/** Trigger source (WXSubscription, WXService, etc.) */
|
|
283
|
+
triggerSrc?: string;
|
|
284
|
+
/** Original message data */
|
|
285
|
+
originMsg?: string;
|
|
286
|
+
/** Reply to message ID */
|
|
287
|
+
replyTo?: string;
|
|
288
|
+
/** Reply message ID */
|
|
289
|
+
reply?: string;
|
|
290
|
+
/** Image URL if applicable */
|
|
291
|
+
image?: string;
|
|
292
|
+
/** Recommended questions */
|
|
293
|
+
recommendQuestions?: string[];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* History entry for storage
|
|
297
|
+
* Contains message info plus optional metadata
|
|
298
|
+
*/
|
|
299
|
+
interface HistoryEntry {
|
|
300
|
+
id?: string;
|
|
301
|
+
/** Unique message ID (record_id in database) */
|
|
302
|
+
messageId: string;
|
|
303
|
+
/** Message role: user, assistant, or system */
|
|
304
|
+
role: MessageRole;
|
|
305
|
+
/** Message content */
|
|
306
|
+
content?: string;
|
|
307
|
+
/** Thread/Conversation ID */
|
|
308
|
+
threadId: string;
|
|
309
|
+
/** Creation timestamp */
|
|
310
|
+
createdAt: number;
|
|
311
|
+
/** Bot ID */
|
|
312
|
+
botId?: string;
|
|
313
|
+
/** Run ID for tracking agent runs */
|
|
314
|
+
runId?: string;
|
|
315
|
+
/** Whether async reply is needed (WeChat specific) */
|
|
316
|
+
needAsyncReply?: boolean;
|
|
317
|
+
/** Message status: pending, done, error, cancel */
|
|
318
|
+
status?: string;
|
|
319
|
+
/** Message type */
|
|
320
|
+
type?: string;
|
|
321
|
+
/** Additional metadata */
|
|
322
|
+
metadata?: HistoryEntryMetadata;
|
|
323
|
+
}
|
|
324
|
+
interface HistoryManagerConfig {
|
|
325
|
+
/** CloudBase environment ID */
|
|
326
|
+
envId?: string;
|
|
327
|
+
/** CloudBase secret ID */
|
|
328
|
+
secretId?: string;
|
|
329
|
+
/** CloudBase secret key */
|
|
330
|
+
secretKey?: string;
|
|
331
|
+
/** CloudBase session token */
|
|
332
|
+
token?: string;
|
|
333
|
+
/** Collection name, default: wx_chat_history */
|
|
334
|
+
collectionName?: string;
|
|
335
|
+
/** Bot ID for filtering */
|
|
336
|
+
botId?: string;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* WeChat History Manager
|
|
340
|
+
* Uses CloudBase database storage
|
|
341
|
+
* Singleton pattern for shared history across adapter and controller
|
|
342
|
+
*/
|
|
343
|
+
declare class WeChatHistoryManager {
|
|
344
|
+
private static instance;
|
|
345
|
+
private tcbClient;
|
|
346
|
+
private collectionName;
|
|
347
|
+
private botId;
|
|
348
|
+
private collectionReady;
|
|
349
|
+
private constructor();
|
|
350
|
+
static getInstance(config?: HistoryManagerConfig): WeChatHistoryManager;
|
|
351
|
+
/**
|
|
352
|
+
* Ensure collection exists, create if not
|
|
353
|
+
*/
|
|
354
|
+
private ensureCollection;
|
|
355
|
+
/**
|
|
356
|
+
* Get previous reply from history
|
|
357
|
+
*/
|
|
358
|
+
getPreviousReply(threadId: string, messageId?: string | null): Promise<HistoryEntry | null>;
|
|
359
|
+
/**
|
|
360
|
+
* Save record to history
|
|
361
|
+
*/
|
|
362
|
+
saveToHistory(record: HistoryEntry): Promise<void>;
|
|
363
|
+
/**
|
|
364
|
+
* Update record content by messageId
|
|
365
|
+
*/
|
|
366
|
+
updateContent(_threadId: string, messageId: string, content: string): Promise<void>;
|
|
367
|
+
}
|
|
368
|
+
declare const getHistoryManager: typeof WeChatHistoryManager.getInstance;
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Configuration for WeChat Agent Adapter
|
|
372
|
+
*/
|
|
373
|
+
interface WeChatAgentConfig extends AgentConfig {
|
|
374
|
+
/**
|
|
375
|
+
* The underlying agent to wrap
|
|
376
|
+
*/
|
|
377
|
+
agent: AbstractAgent;
|
|
378
|
+
/**
|
|
379
|
+
* WeChat configuration
|
|
380
|
+
*/
|
|
381
|
+
wechatConfig: WeChatConfig;
|
|
382
|
+
/**
|
|
383
|
+
* Optional: Custom message formatter
|
|
384
|
+
* Converts agent output to WeChat message format
|
|
385
|
+
*/
|
|
386
|
+
messageFormatter?: (content: string, event: BaseEvent) => SendMessageOptions;
|
|
387
|
+
/**
|
|
388
|
+
* Optional: Filter which events should trigger WeChat messages
|
|
389
|
+
* Default: only TEXT_MESSAGE_CONTENT events
|
|
390
|
+
*/
|
|
391
|
+
eventFilter?: (event: BaseEvent) => boolean;
|
|
392
|
+
/**
|
|
393
|
+
* Optional: Recommended questions to show after reply
|
|
394
|
+
*/
|
|
395
|
+
recommendQuestions?: string[];
|
|
396
|
+
/**
|
|
397
|
+
* Optional: History manager for saving chat history
|
|
398
|
+
* If not provided, will use singleton instance
|
|
399
|
+
*/
|
|
400
|
+
historyManager?: WeChatHistoryManager;
|
|
401
|
+
}
|
|
402
|
+
interface IWxRunAgentInput extends RunAgentInput {
|
|
403
|
+
forwardedProps: {
|
|
404
|
+
wxSendmessageInput: WxSendMessageInput;
|
|
405
|
+
/** Full user message data from dealMsgData */
|
|
406
|
+
msgData?: {
|
|
407
|
+
recordId: string;
|
|
408
|
+
botId: string;
|
|
409
|
+
conversation: string;
|
|
410
|
+
role: "user" | "assistant";
|
|
411
|
+
content: string;
|
|
412
|
+
type: string;
|
|
413
|
+
triggerSrc: string;
|
|
414
|
+
sender: string;
|
|
415
|
+
needAsyncReply: boolean;
|
|
416
|
+
reply: string;
|
|
417
|
+
originMsg: string;
|
|
418
|
+
recommendQuestions: string[];
|
|
419
|
+
createdAt: number;
|
|
420
|
+
};
|
|
421
|
+
/** Reply metadata for assistant message */
|
|
422
|
+
replay: {
|
|
423
|
+
id: string;
|
|
424
|
+
botId: string;
|
|
425
|
+
conversation: string;
|
|
426
|
+
role: "user" | "assistant";
|
|
427
|
+
content: string;
|
|
428
|
+
type: string;
|
|
429
|
+
triggerSrc: string;
|
|
430
|
+
sender: string;
|
|
431
|
+
needAsyncReply: boolean;
|
|
432
|
+
reply: string;
|
|
433
|
+
originMsg: string;
|
|
434
|
+
recommendQuestions: string[];
|
|
435
|
+
createdAt: number;
|
|
436
|
+
};
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* WeChat Agent Adapter
|
|
441
|
+
*
|
|
442
|
+
* Wraps any AbstractAgent and automatically sends its output to WeChat.
|
|
443
|
+
* All methods are proxied to the underlying agent, with the run() method
|
|
444
|
+
* enhanced to capture messages and send them via WeChat.
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```typescript
|
|
448
|
+
* const myAgent = new SomeAgent({ ... });
|
|
449
|
+
* const wechatAgent = new WeChatAgentAdapter({
|
|
450
|
+
* agent: myAgent,
|
|
451
|
+
* wechatConfig: {
|
|
452
|
+
* platform: 'work',
|
|
453
|
+
* corpId: 'xxx',
|
|
454
|
+
* corpSecret: 'xxx'
|
|
455
|
+
* }
|
|
456
|
+
* });
|
|
457
|
+
*
|
|
458
|
+
* // Use it like any other agent
|
|
459
|
+
* wechatAgent.run(input).subscribe(event => {
|
|
460
|
+
* // Events are emitted normally
|
|
461
|
+
* // AND automatically sent to WeChat
|
|
462
|
+
* });
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
declare class WeChatAgent extends AbstractAgent {
|
|
466
|
+
private wrappedAgent;
|
|
467
|
+
private wechatSender?;
|
|
468
|
+
private wechatConfig;
|
|
469
|
+
private _historyManager;
|
|
470
|
+
private messageFormatter;
|
|
471
|
+
private eventFilter;
|
|
472
|
+
private messageBuffer;
|
|
473
|
+
private recommendQuestions?;
|
|
474
|
+
aitools?: aitools.AITools;
|
|
475
|
+
constructor(config: WeChatAgentConfig);
|
|
476
|
+
/**
|
|
477
|
+
* Last assembled reply content after run() completes
|
|
478
|
+
* Controller can read this instead of re-assembling from events
|
|
479
|
+
*/
|
|
480
|
+
lastReply: string;
|
|
481
|
+
/**
|
|
482
|
+
* Whether last run had an error
|
|
483
|
+
*/
|
|
484
|
+
lastRunHadError: boolean;
|
|
485
|
+
/**
|
|
486
|
+
* Get previous reply from history
|
|
487
|
+
* Used for: retry detection, "继续" command
|
|
488
|
+
*/
|
|
489
|
+
getPreviousReply(conversation: string, recordId?: string | null): Promise<HistoryEntry | null>;
|
|
490
|
+
/**
|
|
491
|
+
* Update message content in history
|
|
492
|
+
*/
|
|
493
|
+
updateHistoryContent(messageId: string, content: string, threadId: string): Promise<void>;
|
|
494
|
+
/**
|
|
495
|
+
* Handle unverified account logic (WXSubscription/WXService)
|
|
496
|
+
* Handles "继续" command and 11-second retry
|
|
497
|
+
* Uses existing functions from wechat-message-handler.ts
|
|
498
|
+
* @returns { needSkipAI, replyContent, isEnd }
|
|
499
|
+
*/
|
|
500
|
+
handleUnverifiedChat(params: {
|
|
501
|
+
content: string;
|
|
502
|
+
conversation: string;
|
|
503
|
+
previousReply: HistoryEntry | null;
|
|
504
|
+
callbackData: WxSendMessageInput;
|
|
505
|
+
triggerSrc: string;
|
|
506
|
+
}): Promise<{
|
|
507
|
+
needSkipAI: boolean;
|
|
508
|
+
replyContent: string;
|
|
509
|
+
isEnd: boolean;
|
|
510
|
+
}>;
|
|
511
|
+
/**
|
|
512
|
+
* Run method with WeChat integration
|
|
513
|
+
* Wraps the underlying agent's run() and sends messages to WeChat
|
|
514
|
+
*/
|
|
515
|
+
run(input: IWxRunAgentInput): Observable<BaseEvent>;
|
|
516
|
+
/**
|
|
517
|
+
* Save input message to history at the start of run()
|
|
518
|
+
* Only saves if the last message is from user role
|
|
519
|
+
* Uses msgData from forwardedProps for complete data (similar to dealMsgData)
|
|
520
|
+
*/
|
|
521
|
+
private saveInputToHistory;
|
|
522
|
+
/**
|
|
523
|
+
* Handle WeChat message sending based on events
|
|
524
|
+
*/
|
|
525
|
+
private handleWeChatSending;
|
|
526
|
+
/**
|
|
527
|
+
* Send message to WeChat and save to history
|
|
528
|
+
* Only sends in async mode (needAsyncReply=true)
|
|
529
|
+
* For sync mode, message is returned via HTTP response by controller
|
|
530
|
+
*/
|
|
531
|
+
private sendToWeChat;
|
|
532
|
+
/**
|
|
533
|
+
* Save reply content to history
|
|
534
|
+
* Uses replay metadata from forwardedProps for complete data (similar to dealMsgData)
|
|
535
|
+
*/
|
|
536
|
+
private saveReplyToHistory;
|
|
537
|
+
/**
|
|
538
|
+
* Send message via aitools SDK (for cloud function environment)
|
|
539
|
+
*/
|
|
540
|
+
private sendViaAITools;
|
|
541
|
+
/**
|
|
542
|
+
* Format reply message for WeChat HTTP response (sync mode)
|
|
543
|
+
* Public method for controller to use
|
|
544
|
+
*/
|
|
545
|
+
formatReplyMessage(callbackData: any, triggerSrc: string, content: string): WeChatReplyMessage;
|
|
546
|
+
/**
|
|
547
|
+
* Process reply message to get correct format for different WeChat platforms
|
|
548
|
+
* Based on chat_wx.service.ts processReplyMsg implementation
|
|
549
|
+
*/
|
|
550
|
+
private processReplyMsg;
|
|
551
|
+
/**
|
|
552
|
+
* Send message via local WeChatSender (for local development)
|
|
553
|
+
*/
|
|
554
|
+
private sendViaLocalSender;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* WeChat Message Controller
|
|
559
|
+
* Using @cloudbase/agent-adapter-wx for message processing
|
|
560
|
+
* Directly using sendMessageAGUI handler from @cloudbase/agent-server
|
|
561
|
+
*/
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Agent creator function return type
|
|
565
|
+
*/
|
|
566
|
+
interface AgentCreatorResult {
|
|
567
|
+
agent: AbstractAgent | WeChatAgent | {
|
|
568
|
+
toAGUIAgent(): AbstractAgent;
|
|
569
|
+
};
|
|
570
|
+
cleanup?: () => void;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Agent creator function type
|
|
574
|
+
*/
|
|
575
|
+
type AgentCreator = (params: {
|
|
576
|
+
request: Request;
|
|
577
|
+
options?: {
|
|
578
|
+
agentId: string;
|
|
579
|
+
};
|
|
580
|
+
}) => AgentCreatorResult | Promise<AgentCreatorResult>;
|
|
581
|
+
/**
|
|
582
|
+
* Handler options
|
|
583
|
+
*/
|
|
584
|
+
interface WxMessageHandlerOptions {
|
|
585
|
+
logger?: Logger;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Create WeChat message handler
|
|
589
|
+
* Directly using sendMessageAGUI.handler from @cloudbase/agent-server
|
|
590
|
+
* Aligned with chat_wx_v2.service.ts logic
|
|
591
|
+
*
|
|
592
|
+
* @param createAgent - Function to create agent instance (returns { agent, cleanup?})
|
|
593
|
+
* @param options - Handler options
|
|
594
|
+
* @returns Express route handler
|
|
595
|
+
*/
|
|
596
|
+
declare function createWxMessageHandler(createAgent: AgentCreator, options?: WxMessageHandlerOptions): (req: Request, res: Response) => Promise<Response>;
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Main WeChat sender class
|
|
600
|
+
* Provides a simple API to send LLM messages to WeChat platforms
|
|
601
|
+
*/
|
|
602
|
+
declare class WeChatSender {
|
|
603
|
+
private config;
|
|
604
|
+
private tokenManager;
|
|
605
|
+
private messageFormatter;
|
|
606
|
+
private platformRouter;
|
|
607
|
+
constructor(config: WeChatConfig);
|
|
608
|
+
/**
|
|
609
|
+
* Send a message to WeChat
|
|
610
|
+
*/
|
|
611
|
+
send(options: SendMessageOptions, originMsg?: any): Promise<WeChatAPIResponse>;
|
|
612
|
+
/**
|
|
613
|
+
* Send multiple messages in batch
|
|
614
|
+
*/
|
|
615
|
+
sendBatch(messages: SendMessageOptions[]): Promise<WeChatAPIResponse[]>;
|
|
616
|
+
/**
|
|
617
|
+
* Send message asynchronously (fire and forget)
|
|
618
|
+
*/
|
|
619
|
+
sendAsync(options: SendMessageOptions, originMsg?: any): Promise<void>;
|
|
620
|
+
/**
|
|
621
|
+
* Clear token cache
|
|
622
|
+
*/
|
|
623
|
+
clearCache(): void;
|
|
624
|
+
/**
|
|
625
|
+
* Get current configuration
|
|
626
|
+
*/
|
|
627
|
+
getConfig(): WeChatConfig;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Token manager for WeChat access tokens
|
|
632
|
+
* Handles token caching and automatic refresh
|
|
633
|
+
*/
|
|
634
|
+
declare class TokenManager {
|
|
635
|
+
private cache;
|
|
636
|
+
/**
|
|
637
|
+
* Get access token (with caching)
|
|
638
|
+
*/
|
|
639
|
+
getAccessToken(config: WeChatConfig): Promise<string>;
|
|
640
|
+
/**
|
|
641
|
+
* Fetch access token from WeChat API
|
|
642
|
+
*/
|
|
643
|
+
private fetchAccessToken;
|
|
644
|
+
/**
|
|
645
|
+
* Get token URL based on platform
|
|
646
|
+
*/
|
|
647
|
+
private getTokenUrl;
|
|
648
|
+
/**
|
|
649
|
+
* Generate cache key
|
|
650
|
+
*/
|
|
651
|
+
private getCacheKey;
|
|
652
|
+
/**
|
|
653
|
+
* Clear token cache
|
|
654
|
+
*/
|
|
655
|
+
clearCache(config?: WeChatConfig): void;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Message formatter for different WeChat platforms
|
|
660
|
+
*/
|
|
661
|
+
declare class MessageFormatter {
|
|
662
|
+
/**
|
|
663
|
+
* Format message for WeChat API
|
|
664
|
+
*/
|
|
665
|
+
formatMessage(options: SendMessageOptions, platform: WeChatPlatform, originMsg?: any): WeChatMessage;
|
|
666
|
+
/**
|
|
667
|
+
* Append recommended questions to content
|
|
668
|
+
*/
|
|
669
|
+
private withRecommendQuestions;
|
|
670
|
+
/**
|
|
671
|
+
* Split long message into chunks
|
|
672
|
+
*/
|
|
673
|
+
splitLongMessage(content: string, maxLength?: number): string[];
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Platform router for sending messages to different WeChat platforms
|
|
678
|
+
*/
|
|
679
|
+
declare class PlatformRouter {
|
|
680
|
+
private tokenManager;
|
|
681
|
+
constructor(tokenManager: TokenManager);
|
|
682
|
+
/**
|
|
683
|
+
* Send message to WeChat platform
|
|
684
|
+
*/
|
|
685
|
+
send(message: WeChatMessage, config: WeChatConfig): Promise<WeChatAPIResponse>;
|
|
686
|
+
/**
|
|
687
|
+
* Send to Enterprise WeChat Customer Service
|
|
688
|
+
*/
|
|
689
|
+
private sendToCustomService;
|
|
690
|
+
/**
|
|
691
|
+
* Send to WeChat Mini Program
|
|
692
|
+
*/
|
|
693
|
+
private sendToMiniApp;
|
|
694
|
+
/**
|
|
695
|
+
* Send to WeChat Official Account (Service/Subscription)
|
|
696
|
+
*/
|
|
697
|
+
private sendToOfficialAccount;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export { type AccessTokenResponse, type ChatHistoryRecord, type HistoryEntry, type HistoryManagerConfig, type MessageContent, MessageFormatter, MessageType, type MessageValidationResult, PlatformRouter, type ProcessedMsgData, SUPPORTED_MSG_TYPES, type SendMessageOptions, type SupportedMsgType, type TokenCacheEntry, TokenManager, type VoiceMessageHandler, type WeChatAPIResponse, WeChatAgent, type WeChatAgentConfig, type WeChatCommonInput, type WeChatConfig, WeChatHistoryManager, type WeChatMessage, WeChatPlatform, type WeChatReplyMessage, WeChatSendMode, WeChatSender, type WeChatTriggerSrc, type WeChatWorkCommonInput, createWxMessageHandler, dealMsgData, extractConversation, extractMsgId, extractMsgType, extractSender, extractTextContent, extractTimestamp, extractTriggerSrc, extractVoiceMediaId, formatWeChatReplyMessage, generateRecordId, getHistoryManager, getWxChatContent, handleWeChatRetry, isContinueCommandValid, needAsyncReply, validateMessageType };
|