fix(ask): prototype 拦截器替代 waterfall hook + TG 原生按钮作答
根因:dsh 0.1.5-rc.1 把 'user-questions/request' waterfall 分发到 per-fiber events 注册表,其他 fiber 的 ctx.on 监听(含本插件)永远收不到 分发(实测 root/global/agent 作用域监听全部落空)。 修复:包装 UserQuestionService.prototype.ask(类跨实例共享),无论哪个 fiber/实例发起的 ask 都能拦截到 agent+questions;TG 答案与原 ask 竞速, 保留 dual-path 语义;stop 时恢复原型,热重载不叠加。 功能(应用户要求): - 提问前显式发送预告文本消息 - 选项改用 TG 原生 inline keyboard 按钮(单选即点即答,多选带提交键) - 文本作答保留并与按钮作答合并,逐题累计、齐题自动提交 - 附带修复:Telegram API 调用加 15s 客户端超时(代理挂死会卡死通知队列) Co-authored-by: Shirobana Agent Bot <tg-bridge>
This commit is contained in:
co-authored by
Shirobana Agent Bot <tg-bridge>
parent
4039dec03c
commit
da06485d64
Vendored
+15
-15
@@ -43,8 +43,9 @@ export declare class TelegramBridge {
|
||||
private hookTimer;
|
||||
private readonly pendingApprovalsTG;
|
||||
private disposeApprovalHook;
|
||||
/** dsh 0.1.5 起 ask 走 'user-questions/request' waterfall(不再有 userQuestions.provider)。 */
|
||||
private disposeUserQuestionHook;
|
||||
/** Prototype-ask interceptor state (see installAskInterceptor). */
|
||||
private askInstalled;
|
||||
private askRestore;
|
||||
/** callId → tool name (tool/result failure notices) */
|
||||
private readonly callNames;
|
||||
/** sessionId → latest todo snapshot (/mission) */
|
||||
@@ -117,10 +118,10 @@ export declare class TelegramBridge {
|
||||
/** Retry an outbound call with capped linear backoff (500ms, 1s, 2s… max 4s). */
|
||||
private withRetry;
|
||||
/**
|
||||
* Send a notice; a leading `> ` keeps the quote look via a plain-text `> `
|
||||
* prefix. NB: NOT `<blockquote>` HTML — older Telegram clients cannot render
|
||||
* the blockquote entity at all and show the whole message as “not supported”.
|
||||
* Falls back to plain text when the send fails — a notice is never lost.
|
||||
* Send a notice; a leading `> ` marks the body for quote rendering as a real
|
||||
* `<blockquote>` (parse_mode HTML) — every current Telegram client draws the
|
||||
* accent-colored left bar. Old-client compatibility is no longer required,
|
||||
* but a failed HTML send still falls back to plain text — a notice is never lost.
|
||||
*/
|
||||
private deliverNotice;
|
||||
/** Serialized per-chat notice chain — bursts can't race into Telegram 429s. */
|
||||
@@ -128,18 +129,17 @@ export declare class TelegramBridge {
|
||||
private startTypingHeartbeat;
|
||||
private stopTypingHeartbeat;
|
||||
private stopAllHeartbeats;
|
||||
private userQuestions;
|
||||
/**
|
||||
* dsh 0.1.5 移除了 `userQuestions.provider`:ask 现在走 'user-questions/request'
|
||||
* waterfall(与 approval/request 同形),启动时注册一次即可,无需轮询 provider。
|
||||
* 让 TG 答案与 next()(UI 转发)赛跑;未绑定聊天时 TG promise 永不 settle,
|
||||
* 于是 race 完全跟随 next()。
|
||||
*/
|
||||
private onUserQuestionRequest;
|
||||
private installAskInterceptor;
|
||||
private aroundUserQuestionAsk;
|
||||
private registerTgAsk;
|
||||
/** Announce the incoming question, then one message per question (options as native inline-keyboard buttons). */
|
||||
private deliverAskPrompt;
|
||||
/** Resolve the pending ask once EVERY question has an answer (keyboard and/or text). */
|
||||
private finalizeAskIfComplete;
|
||||
private settleGuiSide;
|
||||
private formatAskPending;
|
||||
private handleTgAnswer;
|
||||
/** Inline-keyboard tap on an ask message: toggle/record the choice, resolve when every question is answered. */
|
||||
private handleAskCallback;
|
||||
private onApprovalRequest;
|
||||
private handleTgApproval;
|
||||
private stopBound;
|
||||
|
||||
Reference in New Issue
Block a user