@dsh-overdrive/gateway 0.1.0 → 0.1.2
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/dist/adapter.d.ts +33 -0
- package/dist/adapter.js +2 -0
- package/dist/adapter.js.map +1 -0
- package/dist/adapters/cli.d.ts +16 -0
- package/dist/adapters/cli.js +34 -0
- package/dist/adapters/cli.js.map +1 -0
- package/dist/adapters/dingtalk.d.ts +40 -0
- package/dist/adapters/dingtalk.js +93 -0
- package/dist/adapters/dingtalk.js.map +1 -0
- package/dist/adapters/discord.d.ts +38 -0
- package/dist/adapters/discord.js +88 -0
- package/dist/adapters/discord.js.map +1 -0
- package/dist/adapters/feishu.d.ts +43 -0
- package/dist/adapters/feishu.js +107 -0
- package/dist/adapters/feishu.js.map +1 -0
- package/dist/adapters/slack.d.ts +35 -0
- package/dist/adapters/slack.js +83 -0
- package/dist/adapters/slack.js.map +1 -0
- package/dist/adapters/telegram.d.ts +57 -0
- package/dist/adapters/telegram.js +94 -0
- package/dist/adapters/telegram.js.map +1 -0
- package/dist/adapters/wecom.d.ts +42 -0
- package/dist/adapters/wecom.js +177 -0
- package/dist/adapters/wecom.js.map +1 -0
- package/dist/adapters/whatsapp.d.ts +81 -0
- package/dist/adapters/whatsapp.js +193 -0
- package/dist/adapters/whatsapp.js.map +1 -0
- package/dist/commands.d.ts +18 -0
- package/dist/commands.js +29 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +190 -0
- package/dist/index.js.map +1 -0
- package/dist/session.d.ts +10 -0
- package/dist/session.js +15 -0
- package/dist/session.js.map +1 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +265 -0
- package/dist/setup.js.map +1 -0
- package/dist/status.d.ts +22 -0
- package/dist/status.js +47 -0
- package/dist/status.js.map +1 -0
- package/dist/trajectory.d.ts +10 -0
- package/dist/trajectory.js +43 -0
- package/dist/trajectory.js.map +1 -0
- package/package.json +7 -3
- package/src/setup.ts +252 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import makeWASocket, { useMultiFileAuthState, DisconnectReason, generateWAMessageFromContent, } from '@whiskeysockets/baileys';
|
|
2
|
+
import * as qrcode from 'qrcode-terminal';
|
|
3
|
+
import pino from 'pino';
|
|
4
|
+
export function extractWhatsAppText(raw) {
|
|
5
|
+
const msg = raw.message;
|
|
6
|
+
if (!msg)
|
|
7
|
+
return null;
|
|
8
|
+
if (typeof msg.conversation === 'string' && msg.conversation)
|
|
9
|
+
return msg.conversation;
|
|
10
|
+
if (msg.extendedTextMessage && typeof msg.extendedTextMessage.text === 'string')
|
|
11
|
+
return msg.extendedTextMessage.text;
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
/** 纯函数:imageMessage 的下载 URL(Baileys 已解析的 url 优先,退 directPath);无图返回 undefined。 */
|
|
15
|
+
export function whatsappImageUrl(raw) {
|
|
16
|
+
const img = raw.message?.imageMessage;
|
|
17
|
+
return img?.url ?? img?.directPath ?? undefined;
|
|
18
|
+
}
|
|
19
|
+
function waMediaUrl(m) {
|
|
20
|
+
return m?.url ?? m?.directPath ?? undefined;
|
|
21
|
+
}
|
|
22
|
+
/** 媒体消息 → media 引用(kind + url):image/voice/video/file;无 url 视为无法透传,返回 undefined。 */
|
|
23
|
+
function whatsappMedia(raw) {
|
|
24
|
+
const msg = raw.message;
|
|
25
|
+
if (!msg)
|
|
26
|
+
return undefined;
|
|
27
|
+
if (msg.imageMessage) {
|
|
28
|
+
const url = whatsappImageUrl(raw);
|
|
29
|
+
return url ? { kind: 'image', url } : undefined;
|
|
30
|
+
}
|
|
31
|
+
if (msg.audioMessage) {
|
|
32
|
+
const url = waMediaUrl(msg.audioMessage);
|
|
33
|
+
return url ? { kind: 'voice', url } : undefined;
|
|
34
|
+
}
|
|
35
|
+
if (msg.videoMessage) {
|
|
36
|
+
const url = waMediaUrl(msg.videoMessage);
|
|
37
|
+
return url ? { kind: 'video', url } : undefined;
|
|
38
|
+
}
|
|
39
|
+
if (msg.documentMessage) {
|
|
40
|
+
const url = waMediaUrl(msg.documentMessage);
|
|
41
|
+
return url ? { kind: 'file', url } : undefined;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
export function normalizeWhatsAppMessage(raw) {
|
|
46
|
+
if (raw.key?.fromMe)
|
|
47
|
+
return null;
|
|
48
|
+
const media = whatsappMedia(raw);
|
|
49
|
+
const text = extractWhatsAppText(raw) ?? raw.message?.imageMessage?.caption ?? '';
|
|
50
|
+
if (!text && !media)
|
|
51
|
+
return null;
|
|
52
|
+
const remoteJid = raw.key?.remoteJid;
|
|
53
|
+
if (!remoteJid)
|
|
54
|
+
return null;
|
|
55
|
+
const userId = raw.key?.participant ?? remoteJid;
|
|
56
|
+
const msg = { chatId: remoteJid, userId, text };
|
|
57
|
+
if (media)
|
|
58
|
+
msg.media = media;
|
|
59
|
+
return { kind: 'message', msg };
|
|
60
|
+
}
|
|
61
|
+
export function buildNumberedReply(text, buttons) {
|
|
62
|
+
const options = buttons.map((b, i) => `${i + 1}) ${b.label}`).join('\n');
|
|
63
|
+
return `${text}\n\n${options}\n\n回复数字选择。`;
|
|
64
|
+
}
|
|
65
|
+
export function matchNumberedReply(text, buttons) {
|
|
66
|
+
const n = Number(text.trim());
|
|
67
|
+
if (!Number.isInteger(n) || n < 1 || n > buttons.length)
|
|
68
|
+
return undefined;
|
|
69
|
+
return buttons[n - 1];
|
|
70
|
+
}
|
|
71
|
+
/** WhatsApp 原生交互按钮:nativeFlowMessage.buttons 数组({ name: 'quick_reply', buttonParamsJson: JSON({id, display_text}) })。 */
|
|
72
|
+
export function buildNativeFlowButtons(buttons) {
|
|
73
|
+
return buttons.map((b) => ({
|
|
74
|
+
name: 'quick_reply',
|
|
75
|
+
buttonParamsJson: JSON.stringify({ id: b.id, display_text: b.label }),
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
/** 解析原生按钮响应:interactiveResponseMessage.nativeFlowResponseMessage.paramsJson 中的 id;非交互/非法 JSON/缺 id 返回 null。 */
|
|
79
|
+
export function parseNativeButtonResponse(raw) {
|
|
80
|
+
const params = raw.message?.interactiveResponseMessage?.nativeFlowResponseMessage?.paramsJson;
|
|
81
|
+
if (!params)
|
|
82
|
+
return null;
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(params);
|
|
85
|
+
return parsed.id ?? null;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export class WhatsAppAdapter {
|
|
92
|
+
opts;
|
|
93
|
+
id = 'whatsapp';
|
|
94
|
+
sock;
|
|
95
|
+
connected = false;
|
|
96
|
+
messageCb;
|
|
97
|
+
replyCb;
|
|
98
|
+
/** chatId → 当前 pending 按钮(编号回复 → 按钮 id) */
|
|
99
|
+
pendingButtons = new Map();
|
|
100
|
+
constructor(opts) {
|
|
101
|
+
this.opts = opts;
|
|
102
|
+
}
|
|
103
|
+
async connect() {
|
|
104
|
+
const { state, saveCreds } = await useMultiFileAuthState(this.opts.authDir);
|
|
105
|
+
const sock = makeWASocket({
|
|
106
|
+
auth: state,
|
|
107
|
+
printQRInTerminal: false,
|
|
108
|
+
logger: pino({ level: 'silent' }),
|
|
109
|
+
browser: ['dsh-overdrive', 'Chrome', '120.0.0.0'],
|
|
110
|
+
});
|
|
111
|
+
this.sock = sock;
|
|
112
|
+
sock.ev.on('creds.update', saveCreds);
|
|
113
|
+
sock.ev.on('connection.update', (update) => {
|
|
114
|
+
if (update.qr) {
|
|
115
|
+
qrcode.generate(update.qr, { small: true });
|
|
116
|
+
console.log('[whatsapp] 请用 WhatsApp 扫上方二维码完成配对(重启应用可重新生成)');
|
|
117
|
+
}
|
|
118
|
+
if (update.connection === 'open') {
|
|
119
|
+
this.connected = true;
|
|
120
|
+
console.log('[whatsapp] 已连接 WhatsApp');
|
|
121
|
+
}
|
|
122
|
+
if (update.connection === 'close') {
|
|
123
|
+
this.connected = false;
|
|
124
|
+
const status = update.lastDisconnect?.error?.output?.statusCode;
|
|
125
|
+
if (status === DisconnectReason.loggedOut) {
|
|
126
|
+
console.error('[whatsapp] 已登出:删除 data/whatsapp 目录后重启可重新扫码');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
console.warn('[whatsapp] 连接断开,3s 后重连…');
|
|
130
|
+
setTimeout(() => void this.connect().catch((e) => console.error('[whatsapp] 重连失败:', e)), 3000);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
134
|
+
for (const raw of messages) {
|
|
135
|
+
const waRaw = raw;
|
|
136
|
+
// 原生交互按钮响应:interactiveResponseMessage → 按钮 id(优先于编号回复兜底)
|
|
137
|
+
const buttonId = parseNativeButtonResponse(waRaw);
|
|
138
|
+
if (buttonId) {
|
|
139
|
+
const chatId = waRaw.key?.remoteJid;
|
|
140
|
+
if (chatId)
|
|
141
|
+
this.pendingButtons.delete(chatId);
|
|
142
|
+
this.replyCb?.(buttonId);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const normalized = normalizeWhatsAppMessage(waRaw);
|
|
146
|
+
if (!normalized)
|
|
147
|
+
continue;
|
|
148
|
+
// 编号回复兜底:若该 chat 有 pending 按钮且消息是数字,转成按钮点击
|
|
149
|
+
const pending = this.pendingButtons.get(normalized.msg.chatId);
|
|
150
|
+
if (pending) {
|
|
151
|
+
const button = matchNumberedReply(normalized.msg.text, pending);
|
|
152
|
+
if (button) {
|
|
153
|
+
this.pendingButtons.delete(normalized.msg.chatId);
|
|
154
|
+
this.replyCb?.(button.id);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
this.messageCb?.(normalized.msg);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async send(chatId, payload) {
|
|
163
|
+
if (!this.sock)
|
|
164
|
+
return;
|
|
165
|
+
if (payload.buttons?.length) {
|
|
166
|
+
this.pendingButtons.set(chatId, payload.buttons);
|
|
167
|
+
// 原生交互按钮优先:Baileys 6.x 的 AnyMessageContent 无 interactive 键,
|
|
168
|
+
// 以 proto.IMessage(interactiveMessage.nativeFlowMessage)+ relayMessage 发送。
|
|
169
|
+
const userJid = this.sock.user?.id;
|
|
170
|
+
if (userJid) {
|
|
171
|
+
const waMsg = generateWAMessageFromContent(chatId, {
|
|
172
|
+
interactiveMessage: {
|
|
173
|
+
body: { text: payload.text },
|
|
174
|
+
nativeFlowMessage: { buttons: buildNativeFlowButtons(payload.buttons) },
|
|
175
|
+
},
|
|
176
|
+
}, { userJid });
|
|
177
|
+
if (waMsg.message) {
|
|
178
|
+
await this.sock.relayMessage(chatId, waMsg.message, { messageId: waMsg.key.id ?? undefined });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// 兜底:连接未就绪(无 userJid)或生成失败时退回编号文本方案
|
|
183
|
+
const text = buildNumberedReply(payload.text, payload.buttons);
|
|
184
|
+
await this.sock.sendMessage(chatId, { text });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
await this.sock.sendMessage(chatId, { text: payload.text });
|
|
188
|
+
}
|
|
189
|
+
onMessage(cb) { this.messageCb = cb; }
|
|
190
|
+
onReply(cb) { this.replyCb = cb; }
|
|
191
|
+
status() { return { connected: this.connected }; }
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=whatsapp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/adapters/whatsapp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ParsedCommand = {
|
|
2
|
+
kind: 'trace';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'new';
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'agents';
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'help';
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'task';
|
|
11
|
+
prompt: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'cron';
|
|
14
|
+
schedule: string;
|
|
15
|
+
prompt: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function parseCommand(text: string): ParsedCommand | null;
|
|
18
|
+
export declare const HELP_TEXT: string;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// cron 语法:/cron <分 时 日 月 周> <需求>(schedule 为 5 个空白分隔字段)
|
|
2
|
+
const CRON_RE = /^\/cron\s+(\S+\s+\S+\s+\S+\s+\S+\s+\S+)\s+(.+)$/;
|
|
3
|
+
export function parseCommand(text) {
|
|
4
|
+
const trimmed = text.trim();
|
|
5
|
+
if (trimmed === '/trace')
|
|
6
|
+
return { kind: 'trace' };
|
|
7
|
+
if (trimmed === '/new')
|
|
8
|
+
return { kind: 'new' };
|
|
9
|
+
if (trimmed === '/agents')
|
|
10
|
+
return { kind: 'agents' };
|
|
11
|
+
if (trimmed === '/help')
|
|
12
|
+
return { kind: 'help' };
|
|
13
|
+
const task = trimmed.match(/^\/task\s+(.+)$/);
|
|
14
|
+
if (task)
|
|
15
|
+
return { kind: 'task', prompt: task[1] };
|
|
16
|
+
const cron = trimmed.match(CRON_RE);
|
|
17
|
+
if (cron)
|
|
18
|
+
return { kind: 'cron', schedule: cron[1], prompt: cron[2] };
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
export const HELP_TEXT = [
|
|
22
|
+
'/help — 帮助',
|
|
23
|
+
'/trace — 查看最近一轮轨迹',
|
|
24
|
+
'/task <需求> — 派子任务',
|
|
25
|
+
'/cron <分 时 日 月 周> <需求> — 定时任务',
|
|
26
|
+
'/agents — 查看子任务状态',
|
|
27
|
+
'/new — 重置会话',
|
|
28
|
+
].join('\n');
|
|
29
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAQA,uDAAuD;AACvD,MAAM,OAAO,GAAG,iDAAiD,CAAC;AAElE,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACnD,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/C,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IACrD,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC9C,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,YAAY;IACZ,mBAAmB;IACnB,mBAAmB;IACnB,+BAA+B;IAC/B,mBAAmB;IACnB,aAAa;CACd,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Adapter } from './adapter.js';
|
|
2
|
+
/** 平台适配器需要的全部环境变量(缺省为 undefined = 不启用该平台)。 */
|
|
3
|
+
export interface AdapterEnv {
|
|
4
|
+
whatsappDataDir?: string;
|
|
5
|
+
telegramBotToken?: string;
|
|
6
|
+
discordBotToken?: string;
|
|
7
|
+
slackBotToken?: string;
|
|
8
|
+
slackAppToken?: string;
|
|
9
|
+
feishuAppId?: string;
|
|
10
|
+
feishuAppSecret?: string;
|
|
11
|
+
dingtalkClientId?: string;
|
|
12
|
+
dingtalkClientSecret?: string;
|
|
13
|
+
wecomCorpId?: string;
|
|
14
|
+
wecomSecret?: string;
|
|
15
|
+
wecomAgentId?: string;
|
|
16
|
+
wecomToken?: string;
|
|
17
|
+
wecomEncodingAESKey?: string;
|
|
18
|
+
wecomCallbackPort?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function parseAdapterIds(raw: string): string[];
|
|
21
|
+
/** 按 id 创建适配器实例;依赖注入 env 便于测试。 */
|
|
22
|
+
export declare function createAdapter(id: string, env: AdapterEnv): Adapter;
|
|
23
|
+
/** 从 process.env 读适配器配置。 */
|
|
24
|
+
export declare function adapterEnvFromProcess(env?: NodeJS.ProcessEnv): AdapterEnv;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CliAdapter } from './adapters/cli.js';
|
|
2
|
+
import { WhatsAppAdapter } from './adapters/whatsapp.js';
|
|
3
|
+
import { TelegramAdapter } from './adapters/telegram.js';
|
|
4
|
+
import { DiscordAdapter } from './adapters/discord.js';
|
|
5
|
+
import { SlackAdapter } from './adapters/slack.js';
|
|
6
|
+
import { FeishuAdapter } from './adapters/feishu.js';
|
|
7
|
+
import { DingTalkAdapter } from './adapters/dingtalk.js';
|
|
8
|
+
import { WeComAdapter } from './adapters/wecom.js';
|
|
9
|
+
export function parseAdapterIds(raw) {
|
|
10
|
+
const ids = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
|
11
|
+
return ids.length > 0 ? ids : ['cli'];
|
|
12
|
+
}
|
|
13
|
+
/** 按 id 创建适配器实例;依赖注入 env 便于测试。 */
|
|
14
|
+
export function createAdapter(id, env) {
|
|
15
|
+
switch (id) {
|
|
16
|
+
case 'cli':
|
|
17
|
+
return new CliAdapter();
|
|
18
|
+
case 'whatsapp':
|
|
19
|
+
return new WhatsAppAdapter({ authDir: env.whatsappDataDir ?? 'data/whatsapp' });
|
|
20
|
+
case 'telegram':
|
|
21
|
+
if (!env.telegramBotToken)
|
|
22
|
+
throw new Error('telegram 适配器需要 TELEGRAM_BOT_TOKEN');
|
|
23
|
+
return new TelegramAdapter({ token: env.telegramBotToken });
|
|
24
|
+
case 'discord':
|
|
25
|
+
if (!env.discordBotToken)
|
|
26
|
+
throw new Error('discord 适配器需要 DISCORD_BOT_TOKEN');
|
|
27
|
+
return new DiscordAdapter({ token: env.discordBotToken });
|
|
28
|
+
case 'slack':
|
|
29
|
+
if (!env.slackBotToken || !env.slackAppToken)
|
|
30
|
+
throw new Error('slack 适配器需要 SLACK_BOT_TOKEN 与 SLACK_APP_TOKEN');
|
|
31
|
+
return new SlackAdapter({ botToken: env.slackBotToken, appToken: env.slackAppToken });
|
|
32
|
+
case 'feishu':
|
|
33
|
+
if (!env.feishuAppId || !env.feishuAppSecret)
|
|
34
|
+
throw new Error('feishu 适配器需要 FEISHU_APP_ID / FEISHU_APP_SECRET');
|
|
35
|
+
return new FeishuAdapter({ appId: env.feishuAppId, appSecret: env.feishuAppSecret });
|
|
36
|
+
case 'dingtalk':
|
|
37
|
+
if (!env.dingtalkClientId || !env.dingtalkClientSecret)
|
|
38
|
+
throw new Error('dingtalk 适配器需要 DINGTALK_CLIENT_ID / DINGTALK_CLIENT_SECRET');
|
|
39
|
+
return new DingTalkAdapter({ clientId: env.dingtalkClientId, clientSecret: env.dingtalkClientSecret });
|
|
40
|
+
case 'wecom':
|
|
41
|
+
if (!env.wecomCorpId || !env.wecomSecret || !env.wecomAgentId || !env.wecomToken || !env.wecomEncodingAESKey) {
|
|
42
|
+
throw new Error('wecom 适配器需要 WECOM_CORP_ID / WECOM_SECRET / WECOM_AGENT_ID / WECOM_TOKEN / WECOM_ENCODING_AES_KEY');
|
|
43
|
+
}
|
|
44
|
+
return new WeComAdapter({
|
|
45
|
+
corpId: env.wecomCorpId, secret: env.wecomSecret, agentId: env.wecomAgentId,
|
|
46
|
+
token: env.wecomToken, encodingAESKey: env.wecomEncodingAESKey,
|
|
47
|
+
callbackPort: Number(env.wecomCallbackPort ?? 3193),
|
|
48
|
+
});
|
|
49
|
+
default:
|
|
50
|
+
throw new Error(`unknown adapter: ${id}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** 从 process.env 读适配器配置。 */
|
|
54
|
+
export function adapterEnvFromProcess(env = process.env) {
|
|
55
|
+
return {
|
|
56
|
+
whatsappDataDir: env.WHATSAPP_DATA_DIR,
|
|
57
|
+
telegramBotToken: env.TELEGRAM_BOT_TOKEN,
|
|
58
|
+
discordBotToken: env.DISCORD_BOT_TOKEN,
|
|
59
|
+
slackBotToken: env.SLACK_BOT_TOKEN,
|
|
60
|
+
slackAppToken: env.SLACK_APP_TOKEN,
|
|
61
|
+
feishuAppId: env.FEISHU_APP_ID,
|
|
62
|
+
feishuAppSecret: env.FEISHU_APP_SECRET,
|
|
63
|
+
dingtalkClientId: env.DINGTALK_CLIENT_ID,
|
|
64
|
+
dingtalkClientSecret: env.DINGTALK_CLIENT_SECRET,
|
|
65
|
+
wecomCorpId: env.WECOM_CORP_ID,
|
|
66
|
+
wecomSecret: env.WECOM_SECRET,
|
|
67
|
+
wecomAgentId: env.WECOM_AGENT_ID,
|
|
68
|
+
wecomToken: env.WECOM_TOKEN,
|
|
69
|
+
wecomEncodingAESKey: env.WECOM_ENCODING_AES_KEY,
|
|
70
|
+
wecomCallbackPort: env.WECOM_CALLBACK_PORT,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { GatewayClient, type ServerEvent } from '@dsh-overdrive/sdk';
|
|
2
|
+
import type { Adapter, OutboundPayload } from './adapter.js';
|
|
3
|
+
import { CliAdapter } from './adapters/cli.js';
|
|
4
|
+
/**
|
|
5
|
+
* message.delta → 打字指示去重:同一 turn 内首个 delta 触发一次 typing,
|
|
6
|
+
* complete 后复位,下一 turn 可再次触发。纯逻辑,便于单测。
|
|
7
|
+
*/
|
|
8
|
+
export declare class DeltaTracker {
|
|
9
|
+
private readonly fired;
|
|
10
|
+
onDelta(sessionId: string, fireTyping: () => void): void;
|
|
11
|
+
/** turn 结束(message.complete / error)时复位,允许下一 turn 再次触发 typing。 */
|
|
12
|
+
onComplete(sessionId: string): void;
|
|
13
|
+
}
|
|
14
|
+
/** 事件 → 平台输出。纯函数,便于单测。返回 null 表示该事件不产出消息。 */
|
|
15
|
+
export declare function planOutbound(ev: ServerEvent): {
|
|
16
|
+
payload: OutboundPayload;
|
|
17
|
+
} | null;
|
|
18
|
+
export interface WireOptions {
|
|
19
|
+
allowlist: string[];
|
|
20
|
+
}
|
|
21
|
+
/** 单个适配器的接线:白名单 → 命令面/upsert → sendMessage;按钮 → resolveApproval;事件流经轨迹聚合。 */
|
|
22
|
+
export declare function wireAdapter(adapter: Adapter, client: GatewayClient, opts: WireOptions): Promise<void>;
|
|
23
|
+
export { CliAdapter };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { GatewayClient } from '@dsh-overdrive/sdk';
|
|
2
|
+
import { Allowlist, buildSessionKey } from './session.js';
|
|
3
|
+
import { adapterEnvFromProcess, createAdapter, parseAdapterIds } from './config.js';
|
|
4
|
+
import { CliAdapter } from './adapters/cli.js';
|
|
5
|
+
import { parseCommand, HELP_TEXT } from './commands.js';
|
|
6
|
+
import { TrajectoryAggregator, formatTrajectorySummary } from './trajectory.js';
|
|
7
|
+
import { createStatusServer } from './status.js';
|
|
8
|
+
/**
|
|
9
|
+
* message.delta → 打字指示去重:同一 turn 内首个 delta 触发一次 typing,
|
|
10
|
+
* complete 后复位,下一 turn 可再次触发。纯逻辑,便于单测。
|
|
11
|
+
*/
|
|
12
|
+
export class DeltaTracker {
|
|
13
|
+
fired = new Set();
|
|
14
|
+
onDelta(sessionId, fireTyping) {
|
|
15
|
+
if (this.fired.has(sessionId))
|
|
16
|
+
return;
|
|
17
|
+
this.fired.add(sessionId);
|
|
18
|
+
fireTyping();
|
|
19
|
+
}
|
|
20
|
+
/** turn 结束(message.complete / error)时复位,允许下一 turn 再次触发 typing。 */
|
|
21
|
+
onComplete(sessionId) {
|
|
22
|
+
this.fired.delete(sessionId);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** 事件 → 平台输出。纯函数,便于单测。返回 null 表示该事件不产出消息。 */
|
|
26
|
+
export function planOutbound(ev) {
|
|
27
|
+
switch (ev.type) {
|
|
28
|
+
case 'message.complete':
|
|
29
|
+
return { payload: { text: ev.text } };
|
|
30
|
+
case 'message.delta':
|
|
31
|
+
return null; // 流式渲染走 sendTyping(见 wireAdapter),不产出文本
|
|
32
|
+
case 'trajectory.step': {
|
|
33
|
+
const icon = ev.step.kind === 'tool' ? '🛠️' : ev.step.kind === 'subagent' ? '🤖' : '🧠';
|
|
34
|
+
return { payload: { text: `${icon} ${ev.step.label}` } };
|
|
35
|
+
}
|
|
36
|
+
case 'trajectory.summary':
|
|
37
|
+
return { payload: { text: formatTrajectorySummary(ev.steps) } };
|
|
38
|
+
case 'approval.request':
|
|
39
|
+
return {
|
|
40
|
+
payload: {
|
|
41
|
+
text: `⚠️ 需要批准:${ev.summary}(${Math.round(ev.timeoutMs / 1000)}s 内有效)`,
|
|
42
|
+
buttons: [
|
|
43
|
+
{ id: `approve:${ev.reqId}`, label: '✅ 同意' },
|
|
44
|
+
{ id: `reject:${ev.reqId}`, label: '🚫 拒绝' },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
case 'agent.status':
|
|
49
|
+
return ev.status === 'subagent-spawned'
|
|
50
|
+
? { payload: { text: '🤖 派生子任务…' } }
|
|
51
|
+
: null;
|
|
52
|
+
case 'task.done':
|
|
53
|
+
return { payload: { text: ev.ok ? `✅ 任务完成 ${ev.taskId}` : `❌ 任务失败 ${ev.taskId}` } };
|
|
54
|
+
case 'error':
|
|
55
|
+
return { payload: { text: `❌ 出错了:${ev.message}` } };
|
|
56
|
+
default:
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** 命令面分发:/trace /new /task /cron /agents /help(M4)。 */
|
|
61
|
+
async function handleCommand(adapter, client, command, sessionId, chatId, aggregator) {
|
|
62
|
+
switch (command.kind) {
|
|
63
|
+
case 'trace': {
|
|
64
|
+
const summary = aggregator.recentSummary(sessionId);
|
|
65
|
+
await adapter.send(chatId, { text: summary ?? '暂无轨迹(尚未运行或已重置)。' });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
case 'new': {
|
|
69
|
+
await client.resetSession(sessionId);
|
|
70
|
+
await adapter.send(chatId, { text: '🆕 会话已重置' });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
case 'task': {
|
|
74
|
+
await client.createTask({ sessionId, kind: 'subagent', prompt: command.prompt });
|
|
75
|
+
await adapter.send(chatId, { text: '🤖 子任务已派出' });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
case 'cron': {
|
|
79
|
+
await client.createTask({ sessionId, kind: 'cron', prompt: command.prompt, schedule: command.schedule });
|
|
80
|
+
await adapter.send(chatId, { text: '⏰ 定时任务已注册' });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
case 'agents': {
|
|
84
|
+
await adapter.send(chatId, { text: '(M4 简化)子任务状态由 agent 汇报,/task 派发' });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
case 'help': {
|
|
88
|
+
await adapter.send(chatId, { text: HELP_TEXT });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** 单个适配器的接线:白名单 → 命令面/upsert → sendMessage;按钮 → resolveApproval;事件流经轨迹聚合。 */
|
|
94
|
+
export async function wireAdapter(adapter, client, opts) {
|
|
95
|
+
const allow = new Allowlist(opts.allowlist);
|
|
96
|
+
const chatIds = new Map();
|
|
97
|
+
const aggregator = new TrajectoryAggregator();
|
|
98
|
+
const deltas = new DeltaTracker();
|
|
99
|
+
adapter.onMessage(async (msg) => {
|
|
100
|
+
const key = buildSessionKey(adapter.id, msg);
|
|
101
|
+
console.log(`[gateway][${adapter.id}] 收到消息 chat=${msg.chatId} user=${msg.userId} text="${msg.text.slice(0, 40)}"`);
|
|
102
|
+
try {
|
|
103
|
+
if (!allow.allows(key)) {
|
|
104
|
+
await adapter.send(msg.chatId, { text: '⛔ 你不在白名单里。' });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
chatIds.set(key, msg.chatId);
|
|
108
|
+
const command = parseCommand(msg.text);
|
|
109
|
+
if (command) {
|
|
110
|
+
console.log(`[gateway][${adapter.id}] 命令: ${JSON.stringify(command)}`);
|
|
111
|
+
await handleCommand(adapter, client, command, key, msg.chatId, aggregator);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
await client.upsertSession({ platform: adapter.id, channel: msg.chatId, user: msg.userId });
|
|
115
|
+
console.log(`[gateway][${adapter.id}] upsertSession OK -> ${key}`);
|
|
116
|
+
await client.sendMessage(key, { text: msg.text, media: msg.media });
|
|
117
|
+
console.log(`[gateway][${adapter.id}] sendMessage OK`);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
121
|
+
console.error(`[gateway][${adapter.id}] 处理失败: ${message}`);
|
|
122
|
+
await adapter.send(msg.chatId, { text: `❌ 出错了:${message}` }).catch(() => undefined);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
adapter.onReply(async (buttonId) => {
|
|
126
|
+
try {
|
|
127
|
+
const idx = buttonId.indexOf(':');
|
|
128
|
+
if (idx < 0)
|
|
129
|
+
return;
|
|
130
|
+
const action = buttonId.slice(0, idx);
|
|
131
|
+
const reqId = buttonId.slice(idx + 1);
|
|
132
|
+
if ((action === 'approve' || action === 'reject') && reqId) {
|
|
133
|
+
await client.resolveApproval(reqId, action);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error(`[gateway] resolveApproval 失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
const chatIdFor = (sessionId) => {
|
|
141
|
+
const known = chatIds.get(sessionId);
|
|
142
|
+
if (known)
|
|
143
|
+
return known;
|
|
144
|
+
return sessionId.split(':')[1] ?? sessionId;
|
|
145
|
+
};
|
|
146
|
+
await client.connect((ev) => {
|
|
147
|
+
// 流式渲染:delta → 打字指示(去重),complete/error → 复位(下一 turn 可再触发)
|
|
148
|
+
if (ev.type === 'message.delta') {
|
|
149
|
+
deltas.onDelta(ev.sessionId, () => void adapter.sendTyping?.(chatIdFor(ev.sessionId)));
|
|
150
|
+
}
|
|
151
|
+
else if (ev.type === 'message.complete' || ev.type === 'error') {
|
|
152
|
+
deltas.onComplete(ev.sessionId);
|
|
153
|
+
}
|
|
154
|
+
// 轨迹聚合:trajectory.step 攒批,idle 时产出 trajectory.summary(减少刷屏)
|
|
155
|
+
aggregator.onEvent(ev, (out) => {
|
|
156
|
+
const planned = planOutbound(out);
|
|
157
|
+
if (!planned)
|
|
158
|
+
return;
|
|
159
|
+
const chatId = chatIdFor(out.sessionId);
|
|
160
|
+
console.log(`[gateway][${adapter.id}] 事件 ${out.type} -> 发送到 ${chatId}`);
|
|
161
|
+
void adapter.send(chatId, planned.payload).then(() => console.log(`[gateway][${adapter.id}] 已发送 ${out.type} 到 ${chatId}`), (error) => console.error(`[gateway][${adapter.id}] 发送失败 ${out.type}: ${error instanceof Error ? error.message : String(error)}`));
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
async function main() {
|
|
166
|
+
const dshBaseUrl = process.env.DSH_BASE_URL ?? 'http://127.0.0.1:3191';
|
|
167
|
+
const dshToken = process.env.DSH_TOKEN ?? 'dev-token';
|
|
168
|
+
const allowlist = (process.env.ALLOWLIST ?? '')
|
|
169
|
+
.split(',').map((s) => s.trim()).filter(Boolean);
|
|
170
|
+
const adapterIds = parseAdapterIds(process.env.GATEWAY_ADAPTERS ?? 'cli');
|
|
171
|
+
const env = adapterEnvFromProcess();
|
|
172
|
+
const client = new GatewayClient(dshBaseUrl, dshToken);
|
|
173
|
+
await client.health(); // 确认 DSH 侧(或 mock)活着
|
|
174
|
+
const adapters = adapterIds.map((id) => createAdapter(id, env));
|
|
175
|
+
for (const adapter of adapters) {
|
|
176
|
+
await adapter.connect();
|
|
177
|
+
await wireAdapter(adapter, client, { allowlist });
|
|
178
|
+
console.log(`[gateway] ${adapter.id} 适配器已就绪`);
|
|
179
|
+
}
|
|
180
|
+
const consolePort = Number(process.env.GATEWAY_CONSOLE_PORT ?? 3190);
|
|
181
|
+
const status = createStatusServer({ adapters, client, version: '0.1.0' });
|
|
182
|
+
await status.listen(consolePort);
|
|
183
|
+
console.log(`[gateway] 控制台 http://0.0.0.0:${consolePort}/`);
|
|
184
|
+
process.stdout.write(`[gateway] 就绪(适配器: ${adapterIds.join(', ')})。Ctrl+C 退出。\n`);
|
|
185
|
+
}
|
|
186
|
+
if (process.argv[1]?.endsWith('index.js'))
|
|
187
|
+
void main();
|
|
188
|
+
// 保留 CLI 的直接导入(E2E 用)
|
|
189
|
+
export { CliAdapter };
|
|
190
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function buildSessionKey(adapterId: string, msg: {
|
|
2
|
+
chatId: string;
|
|
3
|
+
userId: string;
|
|
4
|
+
}): string;
|
|
5
|
+
/** 空列表 = 开发模式放行所有;生产环境必须显式配置。 */
|
|
6
|
+
export declare class Allowlist {
|
|
7
|
+
private readonly entries;
|
|
8
|
+
constructor(entries: string[]);
|
|
9
|
+
allows(key: string): boolean;
|
|
10
|
+
}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { sessionKey } from '@dsh-overdrive/sdk';
|
|
2
|
+
export function buildSessionKey(adapterId, msg) {
|
|
3
|
+
return sessionKey(adapterId, msg.chatId, msg.userId);
|
|
4
|
+
}
|
|
5
|
+
/** 空列表 = 开发模式放行所有;生产环境必须显式配置。 */
|
|
6
|
+
export class Allowlist {
|
|
7
|
+
entries;
|
|
8
|
+
constructor(entries) {
|
|
9
|
+
this.entries = entries;
|
|
10
|
+
}
|
|
11
|
+
allows(key) {
|
|
12
|
+
return this.entries.length === 0 || this.entries.includes(key);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,GAAuC;IAEvC,OAAO,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,iCAAiC;AACjC,MAAM,OAAO,SAAS;IACS;IAA7B,YAA6B,OAAiB;QAAjB,YAAO,GAAP,OAAO,CAAU;IAAG,CAAC;IAElD,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACjE,CAAC;CACF"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|