@zaofan/dsh-qqbot 1.10.8 → 1.10.10
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 +3 -2
- package/client/qqbot-settings.js +6204 -6196
- package/dist/features/botplay.d.ts.map +1 -1
- package/dist/features/botplay.js +6 -2
- package/dist/features/botplay.js.map +1 -1
- package/dist/features/ext-capabilities.d.ts +2 -0
- package/dist/features/ext-capabilities.d.ts.map +1 -1
- package/dist/features/ext-capabilities.js +6 -0
- package/dist/features/ext-capabilities.js.map +1 -1
- package/dist/features/ext-outbound.d.ts +238 -0
- package/dist/features/ext-outbound.d.ts.map +1 -0
- package/dist/features/ext-outbound.js +518 -0
- package/dist/features/ext-outbound.js.map +1 -0
- package/dist/features/ext-reload.d.ts +19 -0
- package/dist/features/ext-reload.d.ts.map +1 -1
- package/dist/features/ext-reload.js +40 -0
- package/dist/features/ext-reload.js.map +1 -1
- package/dist/features/qq-user-questions.d.ts +6 -0
- package/dist/features/qq-user-questions.d.ts.map +1 -1
- package/dist/features/qq-user-questions.js +17 -3
- package/dist/features/qq-user-questions.js.map +1 -1
- package/dist/gateway/middleware-setup.d.ts.map +1 -1
- package/dist/gateway/middleware-setup.js +19 -0
- package/dist/gateway/middleware-setup.js.map +1 -1
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +5 -2
- package/dist/session/session-manager.js.map +1 -1
- package/dist/transport/inbound.js +3 -3
- package/dist/transport/inbound.js.map +1 -1
- package/dist/transport/outbound-buffer.d.ts +31 -1
- package/dist/transport/outbound-buffer.d.ts.map +1 -1
- package/dist/transport/outbound-buffer.js +49 -1
- package/dist/transport/outbound-buffer.js.map +1 -1
- package/dist/transport/outbound.d.ts.map +1 -1
- package/dist/transport/outbound.js +20 -0
- package/dist/transport/outbound.js.map +1 -1
- package/examples/ext-commands//344/274/232/350/257/235/345/210/227/350/241/250.mjs +756 -742
- package/examples/ext-commands//345/224/244/351/206/222.mjs +71 -0
- package/examples/ext-commands//345/255/220/344/274/232/350/257/235.mjs +16 -5
- package/examples/ext-outbound/README.md +139 -0
- package/examples/ext-outbound/sticker-semantic.mjs +524 -0
- package/examples/ext-tools/sticker_auto.mjs +260 -0
- package/examples/ext-tools/vote.mjs +534 -323
- package/package.json +144 -144
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ext-outbound.ts — 【出站扩展】第六套扩展点(2026-10-16 主人定)
|
|
3
|
+
*
|
|
4
|
+
* ┌─ 与 ext-inbound 的对称关系 ─────────────────────────────────────────────┐
|
|
5
|
+
* │ 入站:消息**进来**时改它 / 杀它 → `.qqbot-extensions/inbound/` │
|
|
6
|
+
* │ 出站:消息**出去**时改它 / 杀它 / 补发媒体 → `.qqbot-extensions/outbound/` │ ← 本文件
|
|
7
|
+
* └────────────────────────────────────────────────────────────────────────┘
|
|
8
|
+
*
|
|
9
|
+
* 目录:`{dataRoot}/.qqbot-extensions/outbound/*.mjs`(只扫直接子文件,按文件名升序)
|
|
10
|
+
*
|
|
11
|
+
* 形状(与 inbound 一致,两种写法都支持):
|
|
12
|
+
* ```js
|
|
13
|
+
* export const name = 'my-outbound';
|
|
14
|
+
* export default async function onOutbound(ctx, next) { ...; return next(); }
|
|
15
|
+
* // 或 export async function onOutbound(ctx, next) { ... }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* **出站独有的能力**(ctx 上,详见 OutboundExtCtx):
|
|
19
|
+
* · `ctx.text` 本条出站正文(可读)
|
|
20
|
+
* · `ctx.segments` 解析后的段(图/文/引用),来自 rich-media 的 parseOutbound
|
|
21
|
+
* · `ctx.kind` 'text' | 'markdown' | 'media' | 'card' | 'forward' | 'other'
|
|
22
|
+
* · `ctx.target` 回复目标 { scope, peerId, msgId? }
|
|
23
|
+
* · `ctx.turnId` / `ctx.chunkIndex` / **`ctx.isLastChunk`**(本回合最后一个正文块)
|
|
24
|
+
* · `ctx.rewrite(newText)` 改掉这条出站
|
|
25
|
+
* · `ctx.annihilate(reason)` 消灭这条出站(**之后不要调 next()**)
|
|
26
|
+
* · `ctx.sendMedia({...})` / `ctx.send(text)` 额外发消息(**先被动后主动**)
|
|
27
|
+
*
|
|
28
|
+
* 与前五套**同款**的能力(统一能力包,见 features/ext-capabilities.ts):
|
|
29
|
+
* `emit/markdown/image/media`、`store.load/save`、`identity.*`、`api()`、`kernel`、
|
|
30
|
+
* `appendSilent/appendWake`、`logger`。由挂载点喂进来,缺哪个就优雅降级、**绝不抛**。
|
|
31
|
+
*
|
|
32
|
+
* ★ 供**其他扩展**调用:`globalThis[Symbol.for('im-qqbot.outbound')]`
|
|
33
|
+
* · `send(text, opts)` 发文本(先被动后主动)
|
|
34
|
+
* · `sendMedia({ path|url, text? })` 发媒体
|
|
35
|
+
* · `last()` 最近一次出站的 ctx(含 target,便于"往刚才那个会话发")
|
|
36
|
+
* · `active()` 当前是否正在跑出站链
|
|
37
|
+
*/
|
|
38
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
39
|
+
import { extname, join } from 'node:path';
|
|
40
|
+
import { pathToFileURL } from 'node:url';
|
|
41
|
+
/** 扩展文件允许的扩展名(与 extension-store 的 ALLOWED_EXT 同款) */
|
|
42
|
+
const ALLOWED_EXT = new Set(['.js', '.mjs', '.cjs']);
|
|
43
|
+
/** 出站扩展子目录名(与 inbound / hooks / tools / botplay 并列的第六套) */
|
|
44
|
+
export const EXT_OUTBOUND_SUBDIR = 'outbound';
|
|
45
|
+
/** 其他扩展取"出站操控器"的全局键(Symbol.for ⇒ 跨模块实例单例,同 ext-inbound 的 HANDLER_KEY 手法) */
|
|
46
|
+
export const OUTBOUND_API_KEY = Symbol.for('im-qqbot.outbound');
|
|
47
|
+
export function outboundExtensionsDir(dataRoot) {
|
|
48
|
+
return join(String(dataRoot || ''), '.qqbot-extensions', EXT_OUTBOUND_SUBDIR);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* ★ 2026-10-16:**配置一次**(dataRoot + logger),之后 `loadOutboundExtensions()` 可以不传参。
|
|
52
|
+
*
|
|
53
|
+
* 为什么这么设计:出站链的挂载点在 `transport/outbound-buffer.ts`(很热、每轮都跑),
|
|
54
|
+
* 而"装到哪些扩展"是启动/热刷时才关心的事。让本模块自己记住配置,
|
|
55
|
+
* `features/ext-reload.ts` 的 `reloadExtOutbound()` 就能**直接调装载器**,
|
|
56
|
+
* 不必像 inbound 那样再往 `gateway/middleware-setup.ts` 里塞一个注册表回调(少改一个大文件)。
|
|
57
|
+
*/
|
|
58
|
+
let cfg = null;
|
|
59
|
+
/** 配置出站扩展的数据根与日志器(插件启动时调一次;热刷时复用) */
|
|
60
|
+
export function configureOutboundExtensions(opts) {
|
|
61
|
+
cfg = { dataRoot: String(opts.dataRoot ?? ''), logger: opts.logger };
|
|
62
|
+
}
|
|
63
|
+
/** 重新装载(供热刷用):没配置过则安静返回空结果 */
|
|
64
|
+
export async function reloadOutboundExtensions() {
|
|
65
|
+
if (!cfg)
|
|
66
|
+
return emptyResult();
|
|
67
|
+
return loadOutboundExtensions(cfg);
|
|
68
|
+
}
|
|
69
|
+
// ─────────────────────────── 装载 ───────────────────────────
|
|
70
|
+
let loaded = [];
|
|
71
|
+
function emptyResult(files = []) {
|
|
72
|
+
return { total: 0, skipped: 0, middleware: [], extensions: [], files };
|
|
73
|
+
}
|
|
74
|
+
function pickFn(...cands) {
|
|
75
|
+
for (const c of cands)
|
|
76
|
+
if (typeof c === 'function')
|
|
77
|
+
return c;
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
function normalizeOutbound(mod, file, abs, logger) {
|
|
81
|
+
const m = mod;
|
|
82
|
+
const fn = pickFn(m?.onOutbound, m?.default, m?.middleware);
|
|
83
|
+
if (!fn) {
|
|
84
|
+
logger.warn(`[ext-outbound] ${file} 没有可用的出站中间件(需要 onOutbound / default / middleware 之一),已跳过`);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
file,
|
|
89
|
+
path: abs,
|
|
90
|
+
name: String(m?.name ?? file.replace(/\.[^.]+$/, '')),
|
|
91
|
+
middleware: fn,
|
|
92
|
+
...(typeof m?.dispose === 'function' ? { dispose: m.dispose } : {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function fileVersion(p) {
|
|
96
|
+
try {
|
|
97
|
+
// ⚠️ 本包是 ESM,**不能用 require**(inbound 那边也是静态 import statSync)
|
|
98
|
+
return String(statSync(p).mtimeMs);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return '0';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 扫描 `{dataRoot}/.qqbot-extensions/outbound/*.mjs` 并装载。
|
|
106
|
+
*
|
|
107
|
+
* 目录不存在 / 为空 → 返回空结果、**不打日志**;
|
|
108
|
+
* 单文件失败 → 只 warn 并继续;本函数**永不抛出**。
|
|
109
|
+
* 重新调用 = 热重载(`loaded` 整体替换)。
|
|
110
|
+
*/
|
|
111
|
+
export async function loadOutboundExtensions(opts) {
|
|
112
|
+
const { dataRoot, logger } = opts;
|
|
113
|
+
const dir = outboundExtensionsDir(dataRoot);
|
|
114
|
+
let files;
|
|
115
|
+
try {
|
|
116
|
+
files = readdirSync(dir, { withFileTypes: true })
|
|
117
|
+
.filter((e) => e.isFile() && ALLOWED_EXT.has(extname(e.name).toLowerCase()))
|
|
118
|
+
.map((e) => e.name)
|
|
119
|
+
.sort();
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
loaded = [];
|
|
123
|
+
return emptyResult();
|
|
124
|
+
}
|
|
125
|
+
if (files.length === 0) {
|
|
126
|
+
loaded = [];
|
|
127
|
+
return emptyResult();
|
|
128
|
+
}
|
|
129
|
+
const result = emptyResult(files);
|
|
130
|
+
for (const f of files) {
|
|
131
|
+
const abs = join(dir, f);
|
|
132
|
+
try {
|
|
133
|
+
const url = pathToFileURL(abs).href + `?v=${fileVersion(abs)}`;
|
|
134
|
+
const mod = await import(url);
|
|
135
|
+
const ext = normalizeOutbound(mod, f, abs, logger);
|
|
136
|
+
if (!ext) {
|
|
137
|
+
result.skipped += 1;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
result.total += 1;
|
|
141
|
+
result.extensions.push(ext);
|
|
142
|
+
result.middleware.push(ext.middleware);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
result.skipped += 1;
|
|
146
|
+
logger.warn(`[ext-outbound] ✗ ${f} 装载失败(已跳过, 不影响其它出站扩展): ${err instanceof Error ? err.message : String(err)}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
loaded = result.extensions;
|
|
150
|
+
if (result.total > 0) {
|
|
151
|
+
logger.info(`[ext-outbound] 已装载 ${result.total} 个出站扩展: ${result.extensions.map((e) => e.name).join(', ')}` +
|
|
152
|
+
(result.skipped > 0 ? `(跳过 ${result.skipped} 个)` : ''));
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
/** 当前已装载的出站扩展(诊断用) */
|
|
157
|
+
export function listOutboundExtensions() {
|
|
158
|
+
return loaded.slice();
|
|
159
|
+
}
|
|
160
|
+
// ─────────────────────────── 执行 ───────────────────────────
|
|
161
|
+
/** 熔断:某扩展连续把消息改坏/抛错到阈值就停用它(与 inbound 的熔断同思路) */
|
|
162
|
+
const breaker = new Map();
|
|
163
|
+
const BREAKER_LIMIT = 5;
|
|
164
|
+
/** 改文件 + tools_reload = 复位通道 */
|
|
165
|
+
export function resetOutboundBreaker(name) {
|
|
166
|
+
if (name)
|
|
167
|
+
breaker.delete(name);
|
|
168
|
+
else
|
|
169
|
+
breaker.clear();
|
|
170
|
+
}
|
|
171
|
+
function noteBreaker(name, logger) {
|
|
172
|
+
const n = (breaker.get(name) ?? 0) + 1;
|
|
173
|
+
breaker.set(name, n);
|
|
174
|
+
if (n === BREAKER_LIMIT) {
|
|
175
|
+
logger.warn(`[ext-outbound] ${name} 连续出错 ${n} 次,已停用(改文件后 tools_reload 可复位)`);
|
|
176
|
+
}
|
|
177
|
+
return n;
|
|
178
|
+
}
|
|
179
|
+
let active = 0;
|
|
180
|
+
let lastCtx = null;
|
|
181
|
+
/** 当前是否正在跑出站链(其他扩展可用于"别在我发消息时又触发我") */
|
|
182
|
+
export function outboundActive() {
|
|
183
|
+
return active > 0;
|
|
184
|
+
}
|
|
185
|
+
/** 最近一次出站的 ctx(其他扩展可用它拿 target 往同一个会话补发) */
|
|
186
|
+
export function lastOutboundCtx() {
|
|
187
|
+
return lastCtx;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* 构造一条出站的 ctx(**导出**出来,方便其他扩展/工具直接造一条去发)。
|
|
191
|
+
*/
|
|
192
|
+
export function makeOutboundCtx(initialText, opts = {}, state = { text: initialText, killed: false, reason: '' }) {
|
|
193
|
+
const logger = opts.logger ?? { info() { }, warn() { }, debug() { }, error() { } };
|
|
194
|
+
const t = (opts.target ?? null);
|
|
195
|
+
const self = {
|
|
196
|
+
text: state.text,
|
|
197
|
+
segments: Array.isArray(opts.segments) ? opts.segments : [],
|
|
198
|
+
kind: opts.kind ?? 'text',
|
|
199
|
+
target: t,
|
|
200
|
+
turnId: String(opts.turnId ?? ''),
|
|
201
|
+
chunkIndex: Number(opts.chunkIndex ?? 0),
|
|
202
|
+
isLastChunk: opts.isLastChunk !== false,
|
|
203
|
+
phase: opts.phase === 'turnEnd' ? 'turnEnd' : 'send',
|
|
204
|
+
sender: opts.sender ?? null,
|
|
205
|
+
dataRoot: String(opts.dataRoot ?? ''),
|
|
206
|
+
owners: Array.isArray(opts.owners) ? opts.owners.map(String) : [],
|
|
207
|
+
apiCall: opts.apiCall,
|
|
208
|
+
kernel: opts.kernel,
|
|
209
|
+
logger,
|
|
210
|
+
rewrite(newText) {
|
|
211
|
+
if (state.killed)
|
|
212
|
+
return false;
|
|
213
|
+
state.text = String(newText ?? '');
|
|
214
|
+
self.text = state.text;
|
|
215
|
+
return true;
|
|
216
|
+
},
|
|
217
|
+
annihilate(reason) {
|
|
218
|
+
state.killed = true;
|
|
219
|
+
state.reason = String(reason ?? '');
|
|
220
|
+
return true;
|
|
221
|
+
},
|
|
222
|
+
async sendMedia(input) {
|
|
223
|
+
return sendViaOutboundChannel({ ...input }, opts);
|
|
224
|
+
},
|
|
225
|
+
async send(text, o) {
|
|
226
|
+
return sendViaOutboundChannel({ text: String(text ?? '') }, opts, o);
|
|
227
|
+
},
|
|
228
|
+
/**
|
|
229
|
+
* ★★ 丢后台(2026-10-16 主人定的架构)★★
|
|
230
|
+
* 把"选图/算分/发媒体"这类重活踢出出站链 —— **立刻返回、绝不 await**,
|
|
231
|
+
* 正文照常按原速发出去,补图在后台独立跑(走 sendMedia 的"先被动后主动"通道)。
|
|
232
|
+
* 任何异常都吞掉:后台任务的失败绝不允许影响任何人。
|
|
233
|
+
*/
|
|
234
|
+
background(task) {
|
|
235
|
+
try {
|
|
236
|
+
void Promise.resolve()
|
|
237
|
+
.then(task)
|
|
238
|
+
.catch((err) => {
|
|
239
|
+
try {
|
|
240
|
+
logger.warn?.(`[ext-outbound] 后台任务失败(已忽略): ${err instanceof Error ? err.message : String(err)}`);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
/* 连日志都失败也不能抛 */
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
/* 连调度都失败也不能抛 */
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
note(msg) {
|
|
252
|
+
try {
|
|
253
|
+
logger.debug?.(`[ext-outbound] ${msg}`);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
/* 日志失败不影响主链 */
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
return self;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* 依次跑出站链(文件名升序,与 inbound 同款"链式 + 幂等 next")。
|
|
264
|
+
*
|
|
265
|
+
* 语义(**与 inbound 对齐**):
|
|
266
|
+
* · `next()` **幂等**:误调两次只算第一次;
|
|
267
|
+
* · `next()` 一定被 await(扩展忘 await 时引擎替它 await);
|
|
268
|
+
* · 扩展**不调 next() 且没 annihilate** ⇒ 引擎替它放行(防新手卡死链)+ 记 warn;
|
|
269
|
+
* · `annihilate()` 之后**即便又调了 next() 也不再往下走**。
|
|
270
|
+
*/
|
|
271
|
+
export async function runOutboundChain(text, opts = {}) {
|
|
272
|
+
// ★ 配置兜底:挂载点(transport 层)只关心正文,拿不到 dataRoot/logger 是常态
|
|
273
|
+
// ⇒ 这里用启动时 `configureOutboundExtensions()` 记住的那份补上,
|
|
274
|
+
// 扩展的 `ctx.dataRoot` / `ctx.logger` 才不会空(示范"读表情包库"就靠它)。
|
|
275
|
+
const merged = {
|
|
276
|
+
...(cfg?.dataRoot ? { dataRoot: cfg.dataRoot } : {}),
|
|
277
|
+
...(cfg?.logger ? { logger: cfg.logger } : {}),
|
|
278
|
+
...opts,
|
|
279
|
+
};
|
|
280
|
+
const logger = merged.logger ?? { info() { }, warn() { }, debug() { }, error() { } };
|
|
281
|
+
const exts = loaded;
|
|
282
|
+
if (exts.length === 0)
|
|
283
|
+
return { text, killed: false, reason: '', ran: 0 };
|
|
284
|
+
const state = { text: String(text ?? ''), killed: false, reason: '' };
|
|
285
|
+
const ctx = makeOutboundCtx(state.text, merged, state);
|
|
286
|
+
lastCtx = ctx;
|
|
287
|
+
active += 1;
|
|
288
|
+
try {
|
|
289
|
+
let i = 0;
|
|
290
|
+
let ran = 0;
|
|
291
|
+
const next = async () => {
|
|
292
|
+
if (state.killed)
|
|
293
|
+
return; // 消灭后链停
|
|
294
|
+
if (i >= exts.length)
|
|
295
|
+
return;
|
|
296
|
+
const ext = exts[i++];
|
|
297
|
+
if (!ext)
|
|
298
|
+
return; // 开了 noUncheckedIndexedAccess ⇒ 索引取出来可能是 undefined
|
|
299
|
+
ran += 1;
|
|
300
|
+
if ((breaker.get(ext.name) ?? 0) >= BREAKER_LIMIT)
|
|
301
|
+
return next(); // 已停用 ⇒ 跳过
|
|
302
|
+
// 幂等:同一层重复调用 next 只算第一次
|
|
303
|
+
let called = false;
|
|
304
|
+
const onceNext = async () => {
|
|
305
|
+
if (called)
|
|
306
|
+
return;
|
|
307
|
+
called = true;
|
|
308
|
+
await next();
|
|
309
|
+
};
|
|
310
|
+
try {
|
|
311
|
+
await ext.middleware(ctx, onceNext);
|
|
312
|
+
if (!called && !state.killed) {
|
|
313
|
+
// 既没调 next 也没消灭 ⇒ 替它放行(与 inbound 的"rescue"同语义),并记一笔
|
|
314
|
+
logger.warn(`[ext-outbound] ${ext.name} 既没调 next() 也没 annihilate(),已替它放行`);
|
|
315
|
+
await next();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
const n = noteBreaker(ext.name, logger);
|
|
320
|
+
logger.warn(`[ext-outbound] ${ext.name} 执行出错(第 ${n} 次,不影响出站): ${err instanceof Error ? err.message : String(err)}`);
|
|
321
|
+
// 出错 ⇒ 放行(宁可不改,也不能把消息弄丢)
|
|
322
|
+
if (!state.killed)
|
|
323
|
+
await next();
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
await next();
|
|
327
|
+
return { text: state.text, killed: state.killed, reason: state.reason, ran };
|
|
328
|
+
}
|
|
329
|
+
finally {
|
|
330
|
+
active -= 1;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* ★★ 回合结束钩子(2026-10-16 主人定)★★
|
|
335
|
+
*
|
|
336
|
+
* 挂载点:`transport/outbound.ts` 的 `turn/end` —— 在 `buffer.flush()` 之后、
|
|
337
|
+
* 与 passive 收尾(`maybeResendLastBlock`)**同一时机**。传进来的 `lastText`
|
|
338
|
+
* 就是 `turnBlocks.last`,**是这一回合权威的最后一块正文**。
|
|
339
|
+
*
|
|
340
|
+
* 为什么需要它:一段 assistant 回复可能包含"正文 → 工具调用 → 正文"多段,
|
|
341
|
+
* 每段都各走一次 `sendRichOutbound`。若把配图挂在入口(phase='send'),
|
|
342
|
+
* 第一段就会被当成本回合正文拿去判定 —— **错得离谱**(主人 2026-10-16 实测抓到)。
|
|
343
|
+
*
|
|
344
|
+
* 扩展怎么写:在 `onOutbound(ctx, next)` 里判 `ctx.phase === 'turnEnd'` ⇒ 做配图;
|
|
345
|
+
* `phase === 'send'` ⇒ 只做改写/消灭(或直接 `next()`)。
|
|
346
|
+
*/
|
|
347
|
+
export async function runOutboundTurnEnd(lastText, opts = {}) {
|
|
348
|
+
// 复用同一条链:只是把 phase 标成 turnEnd、并声明"这就是最后一块"
|
|
349
|
+
return runOutboundChain(lastText, { ...opts, phase: 'turnEnd', isLastChunk: true });
|
|
350
|
+
}
|
|
351
|
+
// ─────────────────── 供其他扩展调用的"出站操控器" ───────────────────
|
|
352
|
+
/**
|
|
353
|
+
* 直接经"先被动后主动"通道发一条东西。
|
|
354
|
+
*
|
|
355
|
+
* ⚠️ 这条通道**不跑出站扩展链**(否则自己发的又会被自己拦,形成回环);
|
|
356
|
+
* 要走链请用 {@link runOutboundChain}。
|
|
357
|
+
*/
|
|
358
|
+
export async function sendViaOutboundChannel(payload, opts = {}, sendOpts = {}) {
|
|
359
|
+
const sender = (opts.sender ?? lastCtx?.sender ?? null);
|
|
360
|
+
const target = (opts.target ?? lastCtx?.target ?? null);
|
|
361
|
+
if (!sender || !target)
|
|
362
|
+
return false;
|
|
363
|
+
const body = String(payload.text ?? payload.path ?? payload.url ?? '');
|
|
364
|
+
if (!body)
|
|
365
|
+
return false;
|
|
366
|
+
// ── 先被动:用 target 自带 msgId ──
|
|
367
|
+
const passive = target;
|
|
368
|
+
// ── 后主动:摘掉 msgId(不等它失败;与 session-watch 的"适配主动"同口径)──
|
|
369
|
+
const strip = () => {
|
|
370
|
+
const t2 = { ...target };
|
|
371
|
+
for (const k of ['msgId', 'msg_id', 'messageId', 'referenceMessageId'])
|
|
372
|
+
delete t2[k];
|
|
373
|
+
return t2;
|
|
374
|
+
};
|
|
375
|
+
// ⚠️ 2026-10-16 修(真机首次实测暴露):原来只传了 `(target, payload)` ——
|
|
376
|
+
// `QQBotSender.sendMedia` 要的是 `(target, kind, source)`,参数错 ⇒ 抛错 ⇒ 被 catch 吞掉
|
|
377
|
+
// ⇒ 现象是"出站扩展装上了、但一张图都发不出来"。**改扩展时务必核对宿主接口签名。**
|
|
378
|
+
const isMedia = !!(payload.path || payload.url);
|
|
379
|
+
const mediaKind = String(payload.kind || 'image');
|
|
380
|
+
const mediaSource = payload.url ? { url: String(payload.url) } : { localPath: String(payload.path ?? '') };
|
|
381
|
+
const trySend = async (tg) => {
|
|
382
|
+
try {
|
|
383
|
+
if (isMedia) {
|
|
384
|
+
if (typeof sender.sendMedia !== 'function')
|
|
385
|
+
return false;
|
|
386
|
+
await sender.sendMedia(tg, mediaKind, mediaSource);
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
if (typeof sender.sendMarkdown === 'function') {
|
|
390
|
+
await sender.sendMarkdown(tg, String(payload.text ?? ''));
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
if (typeof sender.sendText === 'function') {
|
|
394
|
+
await sender.sendText(tg, String(payload.text ?? ''));
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
if (await trySend(passive))
|
|
404
|
+
return true;
|
|
405
|
+
if (sendOpts.adaptive === false)
|
|
406
|
+
return false;
|
|
407
|
+
return trySend(strip()); // 主动兜底
|
|
408
|
+
}
|
|
409
|
+
// ── ★ 2026-10-16 主人定:给扩展提供「本地小模型语义打分」 ──────────────────
|
|
410
|
+
// 之前示范扩展只能用字符 bigram(只有字面重合,语义很差)。
|
|
411
|
+
// 插件里本来就有本地小模型(features/local-embed.ts,智能回复/价值评分在用),
|
|
412
|
+
// 这里把它包一层暴露出去:没下模型 / 加载失败 ⇒ 返回 null,扩展自行回落 bigram。
|
|
413
|
+
/** 小模型是否可用(同步探测,不加载) */
|
|
414
|
+
function embedderAvailable() {
|
|
415
|
+
try {
|
|
416
|
+
// 懒探测:真正的可用性在 embedPassages 里判;这里只回答"配置上有没有开"
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* passage 向量缓存:**文本 → 向量**(模块级,进程内长期有效)。
|
|
425
|
+
*
|
|
426
|
+
* ⚠️ 为什么必须有它(2026-10-16 专家团结论):出站扩展要改成"**全库扫** 1891 张",
|
|
427
|
+
* 而不是随机抽 300。若每回合都把 1891 条文本重新喂模型,那是每回合一次全库编码 —— 太慢。
|
|
428
|
+
* 而表情包的 tags/desc 是**静态文本**,编码一次就该复用(改了描述自然 miss 重算)。
|
|
429
|
+
* 上限 5000 条,超了整体清空(表情包库 1891 条远远够用)。
|
|
430
|
+
*/
|
|
431
|
+
const passageVecCache = new Map();
|
|
432
|
+
const PASSAGE_CACHE_MAX = 5000;
|
|
433
|
+
/**
|
|
434
|
+
* 用本地小模型给 `passages` 逐条与 `query` 算余弦相似度。
|
|
435
|
+
* 返回 `null` = 模型不可用(**扩展应回落自己的算法**,绝不抛)。
|
|
436
|
+
*/
|
|
437
|
+
async function embedScores(query, passages) {
|
|
438
|
+
if (!query || !Array.isArray(passages) || passages.length === 0)
|
|
439
|
+
return null;
|
|
440
|
+
try {
|
|
441
|
+
const { createLocalEmbedder } = await import('./local-embed.js');
|
|
442
|
+
const e = createLocalEmbedder({ ...(cfg?.logger ? { logger: cfg.logger } : {}) });
|
|
443
|
+
if (!e.available())
|
|
444
|
+
return null;
|
|
445
|
+
const keys = passages.map((s) => String(s ?? ''));
|
|
446
|
+
// 只对**没缓存过**的文本编码 —— 全库扫的关键:稳态下每回合只编码 query 自己
|
|
447
|
+
const miss = [...new Set(keys.filter((k) => k && !passageVecCache.has(k)))];
|
|
448
|
+
if (miss.length) {
|
|
449
|
+
const vecs = await e.embedPassages(miss);
|
|
450
|
+
if (!vecs)
|
|
451
|
+
return null;
|
|
452
|
+
if (passageVecCache.size + miss.length > PASSAGE_CACHE_MAX)
|
|
453
|
+
passageVecCache.clear();
|
|
454
|
+
for (let i = 0; i < miss.length; i++) {
|
|
455
|
+
const v = vecs[i];
|
|
456
|
+
if (v)
|
|
457
|
+
passageVecCache.set(miss[i], v);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const q = await e.embedQuery(query);
|
|
461
|
+
if (!q)
|
|
462
|
+
return null;
|
|
463
|
+
const dot = (a, b) => {
|
|
464
|
+
let s = 0;
|
|
465
|
+
const n = Math.min(a.length, b.length);
|
|
466
|
+
for (let i = 0; i < n; i++)
|
|
467
|
+
s += a[i] * b[i];
|
|
468
|
+
return s;
|
|
469
|
+
};
|
|
470
|
+
const norm = (v) => Math.sqrt(dot(v, v)) || 1;
|
|
471
|
+
const qn = norm(q);
|
|
472
|
+
return keys.map((k) => {
|
|
473
|
+
const p = passageVecCache.get(k);
|
|
474
|
+
return p ? dot(q, p) / (qn * norm(p)) : 0;
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
return null; // 模型炸了也不能影响出站
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* 其他扩展获取"出站操控器"的入口(`globalThis[OUTBOUND_API_KEY]`)。
|
|
483
|
+
*
|
|
484
|
+
* 用法(任何扩展里):
|
|
485
|
+
* ```js
|
|
486
|
+
* const ob = globalThis[Symbol.for('im-qqbot.outbound')];
|
|
487
|
+
* await ob?.send('补一句', { adaptive: true });
|
|
488
|
+
* await ob?.sendMedia({ path: 'D:/pics/a.png' });
|
|
489
|
+
* const target = ob?.last()?.target; // 往"刚才那个会话"发
|
|
490
|
+
* const scores = await ob?.embed('正文', ['标签A', '标签B']); // 本地小模型语义分(可为 null)
|
|
491
|
+
* ```
|
|
492
|
+
*/
|
|
493
|
+
export function installOutboundApi() {
|
|
494
|
+
const g = globalThis;
|
|
495
|
+
g[OUTBOUND_API_KEY] = {
|
|
496
|
+
version: 1,
|
|
497
|
+
/** 发文本(先被动后主动) */
|
|
498
|
+
send: (text, opts) => sendViaOutboundChannel({ text: String(text ?? '') }, { target: opts?.target, sender: opts?.sender }, opts ?? {}),
|
|
499
|
+
/** 发媒体(先被动后主动) */
|
|
500
|
+
sendMedia: (input, opts) => sendViaOutboundChannel(input, { target: opts?.target, sender: opts?.sender }),
|
|
501
|
+
/**
|
|
502
|
+
* ★ 本地小模型的**语义相似度**打分:`embed(query, passages) → number[] | null`。
|
|
503
|
+
* 顺序与 passages 一一对应;`null` = 模型不可用(扩展请回落自己的算法)。
|
|
504
|
+
*/
|
|
505
|
+
embed: (query, passages) => embedScores(query, passages),
|
|
506
|
+
/** 小模型是否"应当可用"(真正可用性看 embed() 是否返回 null) */
|
|
507
|
+
embedAvailable: () => embedderAvailable(),
|
|
508
|
+
/** 最近一次出站的 ctx(含 target) */
|
|
509
|
+
last: () => lastOutboundCtx(),
|
|
510
|
+
/** 当前是否在跑出站链 */
|
|
511
|
+
active: () => outboundActive(),
|
|
512
|
+
/** 已装载的出站扩展(诊断) */
|
|
513
|
+
list: () => listOutboundExtensions(),
|
|
514
|
+
/** 手动跑一次链(高级用法:先改后发) */
|
|
515
|
+
run: (text, opts) => runOutboundChain(text, opts),
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
//# sourceMappingURL=ext-outbound.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ext-outbound.js","sourceRoot":"","sources":["../../src/features/ext-outbound.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,4 +57,23 @@ export declare function describeExtInboundReload(r: ExtInboundReloadResult | {
|
|
|
57
57
|
}): string;
|
|
58
58
|
/** 当前是否已注册入站扩展重载器(诊断用) */
|
|
59
59
|
export declare function hasExtInboundReloader(): boolean;
|
|
60
|
+
/** 一次出站扩展重载的结果(回执/日志用) */
|
|
61
|
+
export interface ExtOutboundReloadResult {
|
|
62
|
+
/** 本次装载到的扩展数 */
|
|
63
|
+
count: number;
|
|
64
|
+
/** 扩展展示名(便于回执里展示) */
|
|
65
|
+
names: string[];
|
|
66
|
+
}
|
|
67
|
+
/** 注册/注销出站扩展重载器(注销传 undefined;插件重建时调用方会覆盖为新的) */
|
|
68
|
+
export declare function registerExtOutboundReloader(fn: (() => Promise<ExtOutboundReloadResult>) | undefined): void;
|
|
69
|
+
/** 热重载出站扩展;返回 `{ error }` 表示"没装成",理由同 {@link reloadExtCommands} —— 不抛错 */
|
|
70
|
+
export declare function reloadExtOutbound(): Promise<ExtOutboundReloadResult | {
|
|
71
|
+
error: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** 给回执文本用:把出站扩展重载结果拼成一句人话 */
|
|
74
|
+
export declare function describeExtOutboundReload(r: ExtOutboundReloadResult | {
|
|
75
|
+
error: string;
|
|
76
|
+
}): string;
|
|
77
|
+
/** 当前是否已注册出站扩展重载器(诊断用) */
|
|
78
|
+
export declare function hasExtOutboundReloader(): boolean;
|
|
60
79
|
//# sourceMappingURL=ext-reload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ext-reload.d.ts","sourceRoot":"","sources":["../../src/features/ext-reload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,6CAA6C;AAC7C,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAExG;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAO7F;AAED,6CAA6C;AAC7C,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI9F;AAWD,0BAA0B;AAC1B,MAAM,WAAW,sBAAsB;IACrC,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,iDAAiD;AACjD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAExG;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAO5F;AAED,6BAA6B;AAC7B,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI9F;AAED,0BAA0B;AAC1B,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
|
|
1
|
+
{"version":3,"file":"ext-reload.d.ts","sourceRoot":"","sources":["../../src/features/ext-reload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,6CAA6C;AAC7C,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAExG;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAO7F;AAED,6CAA6C;AAC7C,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI9F;AAWD,0BAA0B;AAC1B,MAAM,WAAW,sBAAsB;IACrC,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,iDAAiD;AACjD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAExG;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAO5F;AAED,6BAA6B;AAC7B,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI9F;AAED,0BAA0B;AAC1B,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAWD,0BAA0B;AAC1B,MAAM,WAAW,uBAAuB;IACtC,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,iDAAiD;AACjD,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,uBAAuB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAE1G;AAED,0EAA0E;AAC1E,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,uBAAuB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkB9F;AAED,6BAA6B;AAC7B,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,uBAAuB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIhG;AAED,0BAA0B;AAC1B,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD"}
|
|
@@ -59,4 +59,44 @@ export function describeExtInboundReload(r) {
|
|
|
59
59
|
export function hasExtInboundReloader() {
|
|
60
60
|
return typeof inboundReloader === 'function';
|
|
61
61
|
}
|
|
62
|
+
/** 由 middleware-setup 注册:重扫出站扩展目录并原地换掉生效列表 */
|
|
63
|
+
let outboundReloader;
|
|
64
|
+
/** 注册/注销出站扩展重载器(注销传 undefined;插件重建时调用方会覆盖为新的) */
|
|
65
|
+
export function registerExtOutboundReloader(fn) {
|
|
66
|
+
outboundReloader = fn;
|
|
67
|
+
}
|
|
68
|
+
/** 热重载出站扩展;返回 `{ error }` 表示"没装成",理由同 {@link reloadExtCommands} —— 不抛错 */
|
|
69
|
+
export async function reloadExtOutbound() {
|
|
70
|
+
if (outboundReloader) {
|
|
71
|
+
try {
|
|
72
|
+
return await outboundReloader();
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
return { error: `出站扩展重载失败: ${err instanceof Error ? err.message : String(err)}` };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ★ 2026-10-16:没注册也能用 —— ext-outbound 自己 `configureOutboundExtensions()` 过就直接装载。
|
|
79
|
+
// 这样不必再往 `gateway/middleware-setup.ts`(一个很大的启动函数)里塞注册回调,
|
|
80
|
+
// 出站扩展的装载点收敛在它自己模块内;注册表仍保留(谁想接管就注册)。
|
|
81
|
+
try {
|
|
82
|
+
const { reloadOutboundExtensions } = await import('./ext-outbound.js');
|
|
83
|
+
const r = await reloadOutboundExtensions();
|
|
84
|
+
return { count: r.total, names: r.extensions.map((e) => e.name) };
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return { error: `出站扩展重载失败: ${err instanceof Error ? err.message : String(err)}` };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** 给回执文本用:把出站扩展重载结果拼成一句人话 */
|
|
91
|
+
export function describeExtOutboundReload(r) {
|
|
92
|
+
if ('error' in r)
|
|
93
|
+
return `出站扩展: ${r.error}`;
|
|
94
|
+
if (r.count === 0)
|
|
95
|
+
return '出站扩展: 0 个(目录里没有 outbound/*.mjs?)';
|
|
96
|
+
return `出站扩展: ${r.count} 个已重载 → ${r.names.join(', ')}`;
|
|
97
|
+
}
|
|
98
|
+
/** 当前是否已注册出站扩展重载器(诊断用) */
|
|
99
|
+
export function hasExtOutboundReloader() {
|
|
100
|
+
return typeof outboundReloader === 'function';
|
|
101
|
+
}
|
|
62
102
|
//# sourceMappingURL=ext-reload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ext-reload.js","sourceRoot":"","sources":["../../src/features/ext-reload.ts"],"names":[],"mappings":"AAwBA,gDAAgD;AAChD,IAAI,QAA6D,CAAC;AAElE,6CAA6C;AAC7C,MAAM,UAAU,0BAA0B,CAAC,EAAuD;IAChG,QAAQ,GAAG,EAAE,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IACxD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,aAAa,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IACpF,CAAC;AACH,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,wBAAwB,CAAC,CAA6C;IACpF,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC;IAC5C,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,iCAAiC,CAAC;IACnE,OAAO,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACpF,CAAC;AAmBD,8CAA8C;AAC9C,IAAI,eAAoE,CAAC;AAEzE,iDAAiD;AACjD,MAAM,UAAU,0BAA0B,CAAC,EAAuD;IAChG,eAAe,GAAG,EAAE,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,eAAe;QAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAC/D,IAAI,CAAC;QACH,OAAO,MAAM,eAAe,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,aAAa,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IACpF,CAAC;AACH,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,wBAAwB,CAAC,CAA6C;IACpF,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC;IAC5C,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC;QAAE,OAAO,iCAAiC,CAAC;IAC5D,OAAO,SAAS,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,0BAA0B;AAC1B,MAAM,UAAU,qBAAqB;IACnC,OAAO,OAAO,eAAe,KAAK,UAAU,CAAC;AAC/C,CAAC"}
|
|
1
|
+
{"version":3,"file":"ext-reload.js","sourceRoot":"","sources":["../../src/features/ext-reload.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,6 +89,12 @@ interface PendingGroup {
|
|
|
89
89
|
agent?: unknown;
|
|
90
90
|
turnActive?: boolean;
|
|
91
91
|
lastInboundAt?: number;
|
|
92
|
+
/** 发起提问时的回复目标(带 msgId) —— 抢答补发卡片必须用它走被动回复通道 */
|
|
93
|
+
replyTarget?: {
|
|
94
|
+
scope: ReplyTarget['scope'];
|
|
95
|
+
targetId: string;
|
|
96
|
+
msgId?: string;
|
|
97
|
+
};
|
|
92
98
|
};
|
|
93
99
|
/** true = 后台档(async): 不 resolve 宿主, 答案改了投递回会话 */
|
|
94
100
|
isAsync?: boolean;
|