@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.
Files changed (50) hide show
  1. package/dist/adapter.d.ts +33 -0
  2. package/dist/adapter.js +2 -0
  3. package/dist/adapter.js.map +1 -0
  4. package/dist/adapters/cli.d.ts +16 -0
  5. package/dist/adapters/cli.js +34 -0
  6. package/dist/adapters/cli.js.map +1 -0
  7. package/dist/adapters/dingtalk.d.ts +40 -0
  8. package/dist/adapters/dingtalk.js +93 -0
  9. package/dist/adapters/dingtalk.js.map +1 -0
  10. package/dist/adapters/discord.d.ts +38 -0
  11. package/dist/adapters/discord.js +88 -0
  12. package/dist/adapters/discord.js.map +1 -0
  13. package/dist/adapters/feishu.d.ts +43 -0
  14. package/dist/adapters/feishu.js +107 -0
  15. package/dist/adapters/feishu.js.map +1 -0
  16. package/dist/adapters/slack.d.ts +35 -0
  17. package/dist/adapters/slack.js +83 -0
  18. package/dist/adapters/slack.js.map +1 -0
  19. package/dist/adapters/telegram.d.ts +57 -0
  20. package/dist/adapters/telegram.js +94 -0
  21. package/dist/adapters/telegram.js.map +1 -0
  22. package/dist/adapters/wecom.d.ts +42 -0
  23. package/dist/adapters/wecom.js +177 -0
  24. package/dist/adapters/wecom.js.map +1 -0
  25. package/dist/adapters/whatsapp.d.ts +81 -0
  26. package/dist/adapters/whatsapp.js +193 -0
  27. package/dist/adapters/whatsapp.js.map +1 -0
  28. package/dist/commands.d.ts +18 -0
  29. package/dist/commands.js +29 -0
  30. package/dist/commands.js.map +1 -0
  31. package/dist/config.d.ts +24 -0
  32. package/dist/config.js +73 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/index.d.ts +23 -0
  35. package/dist/index.js +190 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/session.d.ts +10 -0
  38. package/dist/session.js +15 -0
  39. package/dist/session.js.map +1 -0
  40. package/dist/setup.d.ts +1 -0
  41. package/dist/setup.js +265 -0
  42. package/dist/setup.js.map +1 -0
  43. package/dist/status.d.ts +22 -0
  44. package/dist/status.js +47 -0
  45. package/dist/status.js.map +1 -0
  46. package/dist/trajectory.d.ts +10 -0
  47. package/dist/trajectory.js +43 -0
  48. package/dist/trajectory.js.map +1 -0
  49. package/package.json +7 -3
  50. package/src/setup.ts +252 -0
package/dist/setup.js ADDED
@@ -0,0 +1,265 @@
1
+ /**
2
+ * dsh-overdrive setup wizard — 交互式设置向导(hermes setup 风格)
3
+ *
4
+ * 用法:
5
+ * node packages/gateway/dist/setup.js (源码构建后)
6
+ * npx dsh-overdrive-setup (npm 全局/临时)
7
+ *
8
+ * 流程:DeepSeek key → 平台多选 → 逐个收集凭据并联网验证 → 写 .env → 打印下一步。
9
+ * 全程英文为主、中文为辅;验证失败会提示"是否继续"。
10
+ */
11
+ import { createInterface } from 'node:readline/promises';
12
+ import { stdin, stdout } from 'node:process';
13
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ const C = {
16
+ cyan: (t) => `\x1b[36m${t}\x1b[0m`,
17
+ green: (t) => `\x1b[32m${t}\x1b[0m`,
18
+ red: (t) => `\x1b[31m${t}\x1b[0m`,
19
+ dim: (t) => `\x1b[90m${t}\x1b[0m`,
20
+ bold: (t) => `\x1b[1m${t}\x1b[0m`,
21
+ };
22
+ /**
23
+ * 输入层:TTY 用 readline(交互终端);非 TTY 预读全部 stdin(管道/自动化/测试),
24
+ * 逐行分发。输入耗尽时返回 '',由 stopIfClosed 优雅收尾。
25
+ */
26
+ const isTTY = !!stdin.isTTY;
27
+ let ttyRl = null;
28
+ const pipeLines = [];
29
+ if (!isTTY) {
30
+ const chunks = [];
31
+ for await (const chunk of stdin)
32
+ chunks.push(chunk);
33
+ pipeLines.push(...Buffer.concat(chunks).toString('utf8').split(/\r?\n/));
34
+ }
35
+ let inputClosed = !isTTY && pipeLines.length === 0;
36
+ async function promptOnce(question) {
37
+ if (isTTY) {
38
+ ttyRl ??= createInterface({ input: stdin, output: stdout, terminal: true });
39
+ try {
40
+ return await ttyRl.question(question);
41
+ }
42
+ catch {
43
+ inputClosed = true;
44
+ return '';
45
+ }
46
+ }
47
+ const line = pipeLines.shift() ?? '';
48
+ if (line === '' && pipeLines.length === 0)
49
+ inputClosed = true;
50
+ stdout.write(`${question}${line}\n`); // 非 TTY 无回显,手动回显
51
+ return line;
52
+ }
53
+ function closeInput() {
54
+ try {
55
+ ttyRl?.close();
56
+ }
57
+ catch { /* noop */ }
58
+ }
59
+ async function ask(q, hint = '') {
60
+ const answer = await promptOnce(`${C.cyan('?')} ${q} ${C.dim(hint)}\n> `);
61
+ return answer.trim();
62
+ }
63
+ async function confirm(q) {
64
+ const a = (await promptOnce(`${C.cyan('?')} ${q} ${C.dim('[y/N]')}\n> `)).trim().toLowerCase();
65
+ return a === 'y' || a === 'yes';
66
+ }
67
+ function stopIfClosed() {
68
+ if (inputClosed) {
69
+ console.log(C.dim('\n input closed — aborting / 输入已关闭,向导中止'));
70
+ console.log(C.dim(' (run in an interactive terminal / 请在交互式终端中运行)'));
71
+ process.exit(1);
72
+ }
73
+ }
74
+ /** 联网验证辅助:返回 {ok, reason};网络异常按"无法验证"处理(由调用方决定是否继续)。 */
75
+ async function probe(fn, name) {
76
+ try {
77
+ return (await fn()) ? { ok: true, reason: `${name} verified / 验证通过` } : { ok: false, reason: `${name} rejected / 验证失败` };
78
+ }
79
+ catch (error) {
80
+ return { ok: false, reason: `${name} unreachable (network?) / 网络不可达: ${error instanceof Error ? error.message : String(error)}` };
81
+ }
82
+ }
83
+ const PROBES = {
84
+ deepseek: async (v) => {
85
+ const r = await fetch('https://api.deepseek.com/user/balance', { headers: { authorization: `Bearer ${v.DEEPSEEK_API_KEY}` } });
86
+ return r.ok;
87
+ },
88
+ telegram: async (v) => {
89
+ const r = await fetch(`https://api.telegram.org/bot${v.TELEGRAM_BOT_TOKEN}/getMe`);
90
+ const j = (await r.json());
91
+ return j.ok === true;
92
+ },
93
+ discord: async (v) => {
94
+ const r = await fetch('https://discord.com/api/v10/users/@me', { headers: { authorization: `Bot ${v.DISCORD_BOT_TOKEN}` } });
95
+ return r.ok;
96
+ },
97
+ slack: async (v) => {
98
+ const r = await fetch('https://slack.com/api/auth.test', { headers: { authorization: `Bearer ${v.SLACK_BOT_TOKEN}` } });
99
+ const j = (await r.json());
100
+ return j.ok === true;
101
+ },
102
+ feishu: async (v) => {
103
+ const r = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
104
+ method: 'POST', headers: { 'content-type': 'application/json' },
105
+ body: JSON.stringify({ app_id: v.FEISHU_APP_ID, app_secret: v.FEISHU_APP_SECRET }),
106
+ });
107
+ const j = (await r.json());
108
+ return j.code === 0;
109
+ },
110
+ dingtalk: async (v) => {
111
+ const r = await fetch('https://api.dingtalk.com/v1.0/oauth2/accessToken', {
112
+ method: 'POST', headers: { 'content-type': 'application/json' },
113
+ body: JSON.stringify({ appKey: v.DINGTALK_CLIENT_ID, appSecret: v.DINGTALK_CLIENT_SECRET }),
114
+ });
115
+ return r.ok;
116
+ },
117
+ wecom: async (v) => {
118
+ const url = `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${encodeURIComponent(v.WECOM_CORP_ID)}&corpsecret=${encodeURIComponent(v.WECOM_SECRET)}`;
119
+ const j = (await (await fetch(url)).json());
120
+ return j.errcode === 0;
121
+ },
122
+ };
123
+ const PLATFORMS = {
124
+ telegram: {
125
+ label: 'Telegram',
126
+ fields: [['TELEGRAM_BOT_TOKEN', 'Telegram bot token', 'https://t.me/BotFather → /newbot', /^\d+:[A-Za-z0-9_-]{20,}$/]],
127
+ },
128
+ whatsapp: {
129
+ label: 'WhatsApp (no credentials — QR pairing on first start / 无需凭据,首次启动扫码)',
130
+ fields: [],
131
+ },
132
+ discord: {
133
+ label: 'Discord',
134
+ fields: [['DISCORD_BOT_TOKEN', 'Discord bot token', 'Developer Portal → Bot → Token', /^[A-Za-z0-9._-]{20,}$/]],
135
+ },
136
+ slack: {
137
+ label: 'Slack (Socket Mode)',
138
+ fields: [
139
+ ['SLACK_BOT_TOKEN', 'Slack bot token (xoxb-…)', 'App → OAuth & Permissions', /^xoxb-/],
140
+ ['SLACK_APP_TOKEN', 'Slack app-level token (xapp-…)', 'App → Basic Information → App-Level Tokens', /^xapp-/],
141
+ ],
142
+ },
143
+ feishu: {
144
+ label: '飞书 Feishu',
145
+ fields: [
146
+ ['FEISHU_APP_ID', 'Feishu App ID', '开放平台 → 应用凭证', /^cli_/],
147
+ ['FEISHU_APP_SECRET', 'Feishu App Secret', '开放平台 → 应用凭证', /.+/],
148
+ ],
149
+ },
150
+ dingtalk: {
151
+ label: '钉钉 DingTalk',
152
+ fields: [
153
+ ['DINGTALK_CLIENT_ID', 'DingTalk Client ID (AppKey)', '应用开发 → 凭证与基础信息', /.+/],
154
+ ['DINGTALK_CLIENT_SECRET', 'DingTalk Client Secret', '应用开发 → 凭证与基础信息', /.+/],
155
+ ],
156
+ },
157
+ wecom: {
158
+ label: '企业微信 WeCom',
159
+ fields: [
160
+ ['WECOM_CORP_ID', 'WeCom Corp ID', '我的企业 → 企业信息', /.+/],
161
+ ['WECOM_SECRET', 'WeCom Secret', '应用管理 → 应用 → Secret', /.+/],
162
+ ['WECOM_AGENT_ID', 'WeCom Agent ID', '应用管理 → 应用 → AgentId', /^\d+$/],
163
+ ['WECOM_TOKEN', 'WeCom callback Token', '接收消息 → Token(随意填一串)', /.+/],
164
+ ['WECOM_ENCODING_AES_KEY', 'WeCom EncodingAESKey', '接收消息 → EncodingAESKey(43 位)', /^[A-Za-z0-9]{43}$/],
165
+ ],
166
+ },
167
+ };
168
+ /** 读取已有 .env(若存在)合并;返回新内容。 */
169
+ function buildEnv(current, pairs) {
170
+ const map = new Map();
171
+ for (const line of current.split(/\r?\n/)) {
172
+ const m = line.match(/^([A-Z0-9_]+)=(.*)$/);
173
+ if (m)
174
+ map.set(m[1], m[2]);
175
+ }
176
+ for (const [k, v] of pairs)
177
+ map.set(k, v);
178
+ return [...map.entries()].map(([k, v]) => `${k}=${v}`).join('\n') + '\n';
179
+ }
180
+ async function main() {
181
+ console.log('');
182
+ console.log(C.bold(C.cyan('==================================================')));
183
+ console.log(C.bold(C.cyan(' dsh-overdrive setup — the OpenClaw of DeepSeek Harness')));
184
+ console.log(C.bold(C.cyan(' 交互式设置向导(hermes setup 风格)')));
185
+ console.log(C.bold(C.cyan('==================================================')));
186
+ console.log('');
187
+ const pairs = [];
188
+ let platforms = [];
189
+ // 1. DeepSeek API key
190
+ console.log(C.dim(' 1/3 DeepSeek API key — get one: https://platform.deepseek.com/api_keys'));
191
+ for (;;) {
192
+ const key = await ask('Paste your DeepSeek API key (sk-…)', '必填');
193
+ stopIfClosed();
194
+ if (!/^sk-/.test(key)) {
195
+ console.log(C.red(' [x] should start with sk- / 应以 sk- 开头'));
196
+ continue;
197
+ }
198
+ const r = await probe(() => PROBES.deepseek({ DEEPSEEK_API_KEY: key }), 'DeepSeek key');
199
+ console.log(r.ok ? C.green(` [ok] ${r.reason}`) : C.red(` [!] ${r.reason}`));
200
+ if (r.ok || (await confirm('Continue anyway? / 仍然继续?'))) {
201
+ pairs.push(['DEEPSEEK_API_KEY', key]);
202
+ break;
203
+ }
204
+ }
205
+ // 2. platforms
206
+ console.log(C.dim(' 2/3 Platforms — telegram, whatsapp, discord, slack, feishu, dingtalk, wecom'));
207
+ const chosen = await ask('Which platforms? (comma separated, default: telegram)', '逗号分隔,默认 telegram');
208
+ stopIfClosed();
209
+ platforms = (chosen || 'telegram').split(',').map((s) => s.trim().toLowerCase()).filter((s) => PLATFORMS[s]);
210
+ if (platforms.length === 0) {
211
+ console.log(C.red(' [x] no valid platform selected / 未选择有效平台'));
212
+ process.exit(1);
213
+ }
214
+ // 3. per-platform credentials
215
+ console.log(C.dim(' 3/3 Platform credentials (each is verified live) / 平台凭据(逐个实时验证)'));
216
+ for (const p of platforms) {
217
+ console.log(`\n ${C.bold('-- ' + PLATFORMS[p].label)} --`);
218
+ const vals = { ...Object.fromEntries(pairs) };
219
+ for (const [key, prompt, hint, pattern] of PLATFORMS[p].fields) {
220
+ for (;;) {
221
+ const v = await ask(prompt, hint);
222
+ stopIfClosed();
223
+ if (pattern && !pattern.test(v)) {
224
+ console.log(C.red(` [x] format looks wrong / 格式不对(${hint})`));
225
+ continue;
226
+ }
227
+ vals[key] = v;
228
+ break;
229
+ }
230
+ }
231
+ const probeFn = PROBES[p];
232
+ if (probeFn && p !== 'whatsapp') {
233
+ const r = await probe(() => probeFn(vals), PLATFORMS[p].label);
234
+ console.log(r.ok ? C.green(` [ok] ${r.reason}`) : C.red(` [!] ${r.reason}`));
235
+ if (!r.ok && !(await confirm('Continue anyway? / 仍然继续?'))) {
236
+ console.log(C.red(' skipped / 已跳过'));
237
+ continue;
238
+ }
239
+ }
240
+ for (const [k, v] of PLATFORMS[p].fields)
241
+ pairs.push([k, vals[k]]);
242
+ }
243
+ if (platforms.includes('whatsapp'))
244
+ console.log(C.dim(' WhatsApp: no credentials needed — QR shows on first start / 无需凭据,启动时扫码'));
245
+ // 4. write .env
246
+ const envPath = join(process.cwd(), '.env');
247
+ const current = existsSync(envPath) ? readFileSync(envPath, 'utf8') : '';
248
+ const merged = buildEnv(current, [...pairs, ['GATEWAY_ADAPTERS', platforms.join(',')], ['DSH_OVERDRIVE_TOKEN', 'dsh-overdrive-token']]);
249
+ writeFileSync(envPath, merged, 'utf8');
250
+ console.log(`\n ${C.green('[ok]')} .env written → ${C.bold(envPath)}(已合并现有配置)`);
251
+ // 5. next steps
252
+ console.log('');
253
+ console.log(C.bold(C.cyan('==================================================')));
254
+ console.log(C.bold(C.cyan(' Next steps / 下一步')));
255
+ console.log(` ${C.cyan('1)')} Start: docker compose -f deploy/docker-compose.yml up -d --build`);
256
+ console.log(` or: GATEWAY_ADAPTERS=${platforms.join(',')} npx @dsh-overdrive/gateway`);
257
+ console.log(` ${C.cyan('2)')} Console / 控制台: http://localhost:3190/ (含四步引导向导)`);
258
+ console.log(` ${C.cyan('3)')} DSH Web UI (model): http://localhost:3080/`);
259
+ console.log(` ${C.cyan('4)')} In your chat app: send /help`);
260
+ console.log(C.bold(C.cyan('==================================================')));
261
+ console.log('');
262
+ closeInput();
263
+ }
264
+ void main();
265
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type Server } from 'node:http';
2
+ import type { Adapter } from './adapter.js';
3
+ import type { GatewayClient } from '@dsh-overdrive/sdk';
4
+ export interface StatusServerOptions {
5
+ adapters: Adapter[];
6
+ client: GatewayClient;
7
+ version: string;
8
+ }
9
+ /**
10
+ * 健康控制台:GET / 与 /console 返回静态页,GET /api/status 返回 DSH 健康 + 适配器状态。
11
+ *
12
+ * console.html 读取路径说明(与 dist 产物核对过):
13
+ * - src 运行(vitest):import.meta.url = packages/gateway/src/status.ts → ../../web/console.html = packages/web/console.html
14
+ * - dist 运行(node packages/gateway/dist/index.js):import.meta.url = packages/gateway/dist/status.js → ../../web/console.html = packages/web/console.html
15
+ * 两种形态下 `../../web/console.html` 均解析到 packages/web/console.html(plan 中的
16
+ * ../../../web/console.html 会多上一级到仓库根目录,不正确,已修正)。
17
+ */
18
+ export declare function createStatusServer(opts: StatusServerOptions): {
19
+ server: Server;
20
+ listen(port: number): Promise<number>;
21
+ close(): Promise<void>;
22
+ };
package/dist/status.js ADDED
@@ -0,0 +1,47 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { createServer } from 'node:http';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * 健康控制台:GET / 与 /console 返回静态页,GET /api/status 返回 DSH 健康 + 适配器状态。
6
+ *
7
+ * console.html 读取路径说明(与 dist 产物核对过):
8
+ * - src 运行(vitest):import.meta.url = packages/gateway/src/status.ts → ../../web/console.html = packages/web/console.html
9
+ * - dist 运行(node packages/gateway/dist/index.js):import.meta.url = packages/gateway/dist/status.js → ../../web/console.html = packages/web/console.html
10
+ * 两种形态下 `../../web/console.html` 均解析到 packages/web/console.html(plan 中的
11
+ * ../../../web/console.html 会多上一级到仓库根目录,不正确,已修正)。
12
+ */
13
+ export function createStatusServer(opts) {
14
+ const http = createServer(async (req, res) => {
15
+ const url = new URL(req.url ?? '/', 'http://localhost');
16
+ if (url.pathname === '/api/status') {
17
+ let dsh;
18
+ try {
19
+ dsh = await opts.client.health();
20
+ }
21
+ catch (error) {
22
+ dsh = { error: error instanceof Error ? error.message : String(error) };
23
+ }
24
+ const adapters = opts.adapters.map((a) => ({
25
+ id: a.id,
26
+ connected: a.status?.().connected ?? null,
27
+ }));
28
+ res.writeHead(200, { 'content-type': 'application/json' });
29
+ res.end(JSON.stringify({ version: opts.version, dsh, adapters }));
30
+ return;
31
+ }
32
+ if (url.pathname === '/' || url.pathname === '/console') {
33
+ const html = await readFile(fileURLToPath(new URL('../../web/console.html', import.meta.url)), 'utf8').catch(() => '<h1>console.html not found</h1>');
34
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
35
+ res.end(html);
36
+ return;
37
+ }
38
+ res.writeHead(404, { 'content-type': 'text/plain' });
39
+ res.end('not found');
40
+ });
41
+ return {
42
+ server: http,
43
+ listen: (port) => new Promise((resolve) => http.listen(port, '0.0.0.0', () => resolve(http.address().port))),
44
+ close: () => new Promise((resolve) => http.close(() => resolve())),
45
+ };
46
+ }
47
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAUzC;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAyB;IAK1D,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACxD,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YACnC,IAAI,GAA2C,CAAC;YAChD,IAAI,CAAC;gBACH,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1E,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACzC,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI;aAC1C,CAAC,CAAC,CAAC;YACJ,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;YAClE,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CACzB,aAAa,CAAC,IAAI,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACjE,MAAM,CACP,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,iCAAiC,CAAC,CAAC;YACjD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACnE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACd,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;QACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IACH,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CACvB,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE,CAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAE,IAAI,CAAC,OAAO,EAAuB,CAAC,IAAI,CAAC,CAAC,CACvF;QACH,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;KACzE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ServerEvent, TrajectoryStep } from '@dsh-overdrive/sdk';
2
+ /** turn 级轨迹聚合:收集 trajectory.step,turn/end(idle)时产出 trajectory.summary 摘要卡片。 */
3
+ export declare class TrajectoryAggregator {
4
+ private readonly buffer;
5
+ private readonly summaries;
6
+ onEvent(ev: ServerEvent, emit: (ev: ServerEvent) => void): void;
7
+ /** 最近一次 turn 的轨迹摘要文本(/trace 命令用),无则 null。 */
8
+ recentSummary(sessionId: string): string | null;
9
+ }
10
+ export declare function formatTrajectorySummary(steps: TrajectoryStep[]): string;
@@ -0,0 +1,43 @@
1
+ /** turn 级轨迹聚合:收集 trajectory.step,turn/end(idle)时产出 trajectory.summary 摘要卡片。 */
2
+ export class TrajectoryAggregator {
3
+ buffer = new Map();
4
+ summaries = new Map();
5
+ onEvent(ev, emit) {
6
+ if (ev.type === 'agent.status' && ev.status === 'idle') {
7
+ const steps = this.buffer.get(ev.sessionId) ?? [];
8
+ this.buffer.delete(ev.sessionId);
9
+ if (steps.length > 0) {
10
+ this.summaries.set(ev.sessionId, formatTrajectorySummary(steps));
11
+ emit({ type: 'trajectory.summary', sessionId: ev.sessionId, ts: Date.now(), steps });
12
+ }
13
+ emit(ev);
14
+ return;
15
+ }
16
+ if (ev.type === 'agent.status' && ev.status === 'busy') {
17
+ this.buffer.set(ev.sessionId, []);
18
+ emit(ev);
19
+ return;
20
+ }
21
+ if (ev.type === 'trajectory.step') {
22
+ const list = this.buffer.get(ev.sessionId);
23
+ if (list)
24
+ list.push(ev.step);
25
+ else
26
+ this.buffer.set(ev.sessionId, [ev.step]);
27
+ return; // 单步不实时推,等摘要(减少刷屏)
28
+ }
29
+ emit(ev);
30
+ }
31
+ /** 最近一次 turn 的轨迹摘要文本(/trace 命令用),无则 null。 */
32
+ recentSummary(sessionId) {
33
+ return this.summaries.get(sessionId) ?? null;
34
+ }
35
+ }
36
+ export function formatTrajectorySummary(steps) {
37
+ const lines = steps.map((s) => {
38
+ const icon = s.kind === 'tool' ? '🛠️' : s.kind === 'subagent' ? '🤖' : '🧠';
39
+ return `${icon} ${s.label}`;
40
+ });
41
+ return `📋 轨迹(${lines.length} 步)\n${lines.join('\n')}`;
42
+ }
43
+ //# sourceMappingURL=trajectory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trajectory.js","sourceRoot":"","sources":["../src/trajectory.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,MAAM,OAAO,oBAAoB;IACd,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC7C,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvD,OAAO,CAAC,EAAe,EAAE,IAA+B;QACtD,IAAI,EAAE,CAAC,IAAI,KAAK,cAAc,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC;gBACjE,IAAI,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACvF,CAAC;YACD,IAAI,CAAC,EAAE,CAAC,CAAC;YACT,OAAO;QACT,CAAC;QACD,IAAI,EAAE,CAAC,IAAI,KAAK,cAAc,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,CAAC;YACT,OAAO;QACT,CAAC;QACD,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;YAC3C,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;;gBACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,OAAO,CAAC,mBAAmB;QAC7B,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,CAAC;IAED,6CAA6C;IAC7C,aAAa,CAAC,SAAiB;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAuB;IAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7E,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACzD,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@dsh-overdrive/gateway",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc"
7
7
  },
8
+ "bin": {
9
+ "dsh-overdrive-gateway": "dist/index.js",
10
+ "dsh-overdrive-setup": "dist/setup.js"
11
+ },
8
12
  "dependencies": {
9
- "@dsh-overdrive/sdk": "0.1.0",
13
+ "@dsh-overdrive/sdk": "0.1.1",
10
14
  "@larksuiteoapi/node-sdk": "^1.50.0",
11
15
  "@slack/bolt": "^3.0.0",
12
16
  "@whiskeysockets/baileys": "^6.0.1",
@@ -20,7 +24,7 @@
20
24
  "@types/qrcode-terminal": "^0.12.2"
21
25
  },
22
26
  "license": "MIT",
23
- "description": "dsh-overdrive: 多平台消息网关(WhatsApp/Telegram/Discord/Slack/飞书/钉钉/企业微信)",
27
+ "description": "dsh-overdrive: multi-platform messaging gateway for DeepSeek Harness (WhatsApp/Telegram/Discord/Slack/Feishu/DingTalk/WeCom)",
24
28
  "repository": {
25
29
  "type": "git",
26
30
  "url": "https://github.com/temotee2103/dsh-overdrive.git"