@zaofan/dsh-qqbot 0.6.0
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/LICENSE +21 -0
- package/README.md +308 -0
- package/README_EN.md +273 -0
- package/client/qqbot-settings.js +1463 -0
- package/cordis.patch.yml +36 -0
- package/dist/api/group-admin.d.ts +112 -0
- package/dist/api/group-admin.d.ts.map +1 -0
- package/dist/api/group-admin.js +179 -0
- package/dist/api/group-admin.js.map +1 -0
- package/dist/channel-tools.d.ts +14 -0
- package/dist/channel-tools.d.ts.map +1 -0
- package/dist/channel-tools.js +880 -0
- package/dist/channel-tools.js.map +1 -0
- package/dist/commands/help.d.ts +11 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +21 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/index.d.ts +13 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +29 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/misc.d.ts +14 -0
- package/dist/commands/misc.d.ts.map +1 -0
- package/dist/commands/misc.js +39 -0
- package/dist/commands/misc.js.map +1 -0
- package/dist/commands/model.d.ts +7 -0
- package/dist/commands/model.d.ts.map +1 -0
- package/dist/commands/model.js +58 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/session.d.ts +10 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +26 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +24 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/types.d.ts +12 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/config.d.ts +205 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +203 -0
- package/dist/config.js.map +1 -0
- package/dist/features/chat-ledger.d.ts +53 -0
- package/dist/features/chat-ledger.d.ts.map +1 -0
- package/dist/features/chat-ledger.js +185 -0
- package/dist/features/chat-ledger.js.map +1 -0
- package/dist/features/face-tags.d.ts +17 -0
- package/dist/features/face-tags.d.ts.map +1 -0
- package/dist/features/face-tags.js +79 -0
- package/dist/features/face-tags.js.map +1 -0
- package/dist/features/group-join-request.d.ts +65 -0
- package/dist/features/group-join-request.d.ts.map +1 -0
- package/dist/features/group-join-request.js +190 -0
- package/dist/features/group-join-request.js.map +1 -0
- package/dist/features/history-store.d.ts +8 -0
- package/dist/features/history-store.d.ts.map +1 -0
- package/dist/features/history-store.js +24 -0
- package/dist/features/history-store.js.map +1 -0
- package/dist/features/qq-approval.d.ts +78 -0
- package/dist/features/qq-approval.d.ts.map +1 -0
- package/dist/features/qq-approval.js +165 -0
- package/dist/features/qq-approval.js.map +1 -0
- package/dist/features/schedule-store.d.ts +62 -0
- package/dist/features/schedule-store.d.ts.map +1 -0
- package/dist/features/schedule-store.js +253 -0
- package/dist/features/schedule-store.js.map +1 -0
- package/dist/features/scheduler.d.ts +9 -0
- package/dist/features/scheduler.d.ts.map +1 -0
- package/dist/features/scheduler.js +146 -0
- package/dist/features/scheduler.js.map +1 -0
- package/dist/features/sticker-gate.d.ts +90 -0
- package/dist/features/sticker-gate.d.ts.map +1 -0
- package/dist/features/sticker-gate.js +391 -0
- package/dist/features/sticker-gate.js.map +1 -0
- package/dist/features/sticker-store.d.ts +158 -0
- package/dist/features/sticker-store.d.ts.map +1 -0
- package/dist/features/sticker-store.js +676 -0
- package/dist/features/sticker-store.js.map +1 -0
- package/dist/features/sticker-tagger.d.ts +10 -0
- package/dist/features/sticker-tagger.d.ts.map +1 -0
- package/dist/features/sticker-tagger.js +139 -0
- package/dist/features/sticker-tagger.js.map +1 -0
- package/dist/gateway/bootstrap.d.ts +12 -0
- package/dist/gateway/bootstrap.d.ts.map +1 -0
- package/dist/gateway/bootstrap.js +346 -0
- package/dist/gateway/bootstrap.js.map +1 -0
- package/dist/gateway/debounce.d.ts +40 -0
- package/dist/gateway/debounce.d.ts.map +1 -0
- package/dist/gateway/debounce.js +262 -0
- package/dist/gateway/debounce.js.map +1 -0
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/gateway/index.js +3 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/middleware-setup.d.ts +12 -0
- package/dist/gateway/middleware-setup.d.ts.map +1 -0
- package/dist/gateway/middleware-setup.js +156 -0
- package/dist/gateway/middleware-setup.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +187 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/attachment.d.ts +11 -0
- package/dist/middleware/attachment.d.ts.map +1 -0
- package/dist/middleware/attachment.js +17 -0
- package/dist/middleware/attachment.js.map +1 -0
- package/dist/middleware/media-history.d.ts +30 -0
- package/dist/middleware/media-history.d.ts.map +1 -0
- package/dist/middleware/media-history.js +54 -0
- package/dist/middleware/media-history.js.map +1 -0
- package/dist/middleware/sticker-capture.d.ts +17 -0
- package/dist/middleware/sticker-capture.d.ts.map +1 -0
- package/dist/middleware/sticker-capture.js +97 -0
- package/dist/middleware/sticker-capture.js.map +1 -0
- package/dist/model/index.d.ts +10 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +9 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/model-resolver.d.ts +88 -0
- package/dist/model/model-resolver.d.ts.map +1 -0
- package/dist/model/model-resolver.js +151 -0
- package/dist/model/model-resolver.js.map +1 -0
- package/dist/model/prefs-store.d.ts +24 -0
- package/dist/model/prefs-store.d.ts.map +1 -0
- package/dist/model/prefs-store.js +126 -0
- package/dist/model/prefs-store.js.map +1 -0
- package/dist/model/settings-reader.d.ts +19 -0
- package/dist/model/settings-reader.d.ts.map +1 -0
- package/dist/model/settings-reader.js +76 -0
- package/dist/model/settings-reader.js.map +1 -0
- package/dist/model/types.d.ts +15 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +5 -0
- package/dist/model/types.js.map +1 -0
- package/dist/session/idle-evictor.d.ts +18 -0
- package/dist/session/idle-evictor.d.ts.map +1 -0
- package/dist/session/idle-evictor.js +31 -0
- package/dist/session/idle-evictor.js.map +1 -0
- package/dist/session/index.d.ts +9 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +8 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/session-manager.d.ts +97 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +624 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/types.d.ts +130 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +2 -0
- package/dist/session/types.js.map +1 -0
- package/dist/session/workspace-attach.d.ts +22 -0
- package/dist/session/workspace-attach.d.ts.map +1 -0
- package/dist/session/workspace-attach.js +21 -0
- package/dist/session/workspace-attach.js.map +1 -0
- package/dist/setup.d.ts +25 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +198 -0
- package/dist/setup.js.map +1 -0
- package/dist/shared/index.d.ts +7 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +7 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/scope.d.ts +14 -0
- package/dist/shared/scope.d.ts.map +1 -0
- package/dist/shared/scope.js +12 -0
- package/dist/shared/scope.js.map +1 -0
- package/dist/shared/send-helper.d.ts +11 -0
- package/dist/shared/send-helper.d.ts.map +1 -0
- package/dist/shared/send-helper.js +13 -0
- package/dist/shared/send-helper.js.map +1 -0
- package/dist/shared/utils.d.ts +28 -0
- package/dist/shared/utils.d.ts.map +1 -0
- package/dist/shared/utils.js +143 -0
- package/dist/shared/utils.js.map +1 -0
- package/dist/transport/attachment.d.ts +18 -0
- package/dist/transport/attachment.d.ts.map +1 -0
- package/dist/transport/attachment.js +106 -0
- package/dist/transport/attachment.js.map +1 -0
- package/dist/transport/chunker.d.ts +14 -0
- package/dist/transport/chunker.d.ts.map +1 -0
- package/dist/transport/chunker.js +78 -0
- package/dist/transport/chunker.js.map +1 -0
- package/dist/transport/events.d.ts +80 -0
- package/dist/transport/events.d.ts.map +1 -0
- package/dist/transport/events.js +62 -0
- package/dist/transport/events.js.map +1 -0
- package/dist/transport/inbound.d.ts +8 -0
- package/dist/transport/inbound.d.ts.map +1 -0
- package/dist/transport/inbound.js +292 -0
- package/dist/transport/inbound.js.map +1 -0
- package/dist/transport/index.d.ts +10 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +10 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/inject-rules.d.ts +24 -0
- package/dist/transport/inject-rules.d.ts.map +1 -0
- package/dist/transport/inject-rules.js +72 -0
- package/dist/transport/inject-rules.js.map +1 -0
- package/dist/transport/outbound-buffer.d.ts +56 -0
- package/dist/transport/outbound-buffer.d.ts.map +1 -0
- package/dist/transport/outbound-buffer.js +131 -0
- package/dist/transport/outbound-buffer.js.map +1 -0
- package/dist/transport/outbound.d.ts +30 -0
- package/dist/transport/outbound.d.ts.map +1 -0
- package/dist/transport/outbound.js +139 -0
- package/dist/transport/outbound.js.map +1 -0
- package/dist/transport/rich-media.d.ts +41 -0
- package/dist/transport/rich-media.d.ts.map +1 -0
- package/dist/transport/rich-media.js +104 -0
- package/dist/transport/rich-media.js.map +1 -0
- package/dist/transport/streaming-writer.d.ts +47 -0
- package/dist/transport/streaming-writer.d.ts.map +1 -0
- package/dist/transport/streaming-writer.js +110 -0
- package/dist/transport/streaming-writer.js.map +1 -0
- package/dist/transport/tool-presenter.d.ts +38 -0
- package/dist/transport/tool-presenter.d.ts.map +1 -0
- package/dist/transport/tool-presenter.js +121 -0
- package/dist/transport/tool-presenter.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +106 -0
- package/settings-host.js +927 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* qq-approval.ts — QQ 远程审批: 把 dsh 的权限申请变成 QQ 消息, 由任务发起者在 QQ 里放行/拒绝
|
|
3
|
+
*
|
|
4
|
+
* 思路来源(必须注明):
|
|
5
|
+
* - wang-22-code/dsh-qqbot-bridge 的 src/approval.ts(QqApprovalController 设计)
|
|
6
|
+
* https://github.com/wang-22-code/dsh-qqbot-bridge(README「QQ 权限审批」)
|
|
7
|
+
* - 宿主机制为 dsh 标准事件 ctx.on('approval/request', (request, next) => …),
|
|
8
|
+
* 官方 dsh-acp、dsh-web 审批弹窗同款接线(请求带 request.agent / request.callId,
|
|
9
|
+
* 处理器返回 'allowed-once' | 'rejected' | 'cancelled', 或调用 next() 走宿主默认)。
|
|
10
|
+
*
|
|
11
|
+
* 本实现按本项目结构重写(非拷贝):
|
|
12
|
+
* - 发送走本项目 sender.sendMarkdown(自带 markdown→text→wakeup 降级链与撤回记录);
|
|
13
|
+
* - 会话定位用本项目 SessionManager.findByAgent(带 agent.id 兜底);
|
|
14
|
+
* - 入站拦截挂在本项目 gateway 的 bot.on('message') 最先(消费后不再进 agent)。
|
|
15
|
+
*
|
|
16
|
+
* 流程: 宿主 approval/request → 向"发起者所在会话"推 QQ 审批提示(一次性 CODE)
|
|
17
|
+
* → 入站 /approve|/deny CODE(或 允许/拒绝 CODE)被拦截
|
|
18
|
+
* → 校验"发起者本人 + 同会话" → 结算 allow-once / rejected。
|
|
19
|
+
* 边界: CODE 一次性; approvalTimeoutMs 超时自动拒绝; agent 取消/宿主退出自动取消;
|
|
20
|
+
* 只授权当前这一次操作; 群聊里其他成员看到 CODE 也无法批准(senderId 校验)。
|
|
21
|
+
*/
|
|
22
|
+
import type { ReplyTarget } from '@tencent-connect/qqbot-nodejs';
|
|
23
|
+
import type { QQBotSender } from '../transport/outbound-buffer.js';
|
|
24
|
+
import type { SessionManager } from '../session/index.js';
|
|
25
|
+
import type { Logger } from '../types.js';
|
|
26
|
+
export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';
|
|
27
|
+
/** dsh 宿主 approval/request 事件的请求形状(与本项目实际用到的字段) */
|
|
28
|
+
export interface ApprovalRequestLike {
|
|
29
|
+
agent: unknown;
|
|
30
|
+
toolName?: string;
|
|
31
|
+
reason?: string;
|
|
32
|
+
callId?: string;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
}
|
|
35
|
+
/** 入站消息的最小只读形状(与 transport/inbound.ts 的 msg 同形) */
|
|
36
|
+
interface ApprovableMessage {
|
|
37
|
+
kind?: string;
|
|
38
|
+
senderId?: string;
|
|
39
|
+
content?: string;
|
|
40
|
+
groupOpenid?: string;
|
|
41
|
+
messageId?: string;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
export interface ParsedApprovalCommand {
|
|
45
|
+
outcome: 'allowed-once' | 'rejected';
|
|
46
|
+
code: string;
|
|
47
|
+
}
|
|
48
|
+
/** 只解析显式审批命令; 普通聊天消息原样放行给 agent */
|
|
49
|
+
export declare function parseApprovalCommand(content: string): ParsedApprovalCommand | null;
|
|
50
|
+
/** QQ 载体的一次性审批 answerer(dsh approval/request → QQ 提示 → /approve CODE) */
|
|
51
|
+
export declare class QqApprovalController {
|
|
52
|
+
private readonly manager;
|
|
53
|
+
private readonly sender;
|
|
54
|
+
private readonly logger;
|
|
55
|
+
/** 超时(ms)提供器: 每次 request 现读, 支持 Web 设置热改生效 */
|
|
56
|
+
private readonly timeoutMsProvider;
|
|
57
|
+
private readonly pending;
|
|
58
|
+
constructor(manager: SessionManager, sender: QQBotSender, logger: Logger,
|
|
59
|
+
/** 超时(ms)提供器: 每次 request 现读, 支持 Web 设置热改生效 */
|
|
60
|
+
timeoutMsProvider: () => number);
|
|
61
|
+
/** 宿主 approval/request 处理器: 定位发起者会话并发 QQ 审批提示 */
|
|
62
|
+
request(req: ApprovalRequestLike, next: () => Promise<ApprovalOutcome>): Promise<ApprovalOutcome>;
|
|
63
|
+
/**
|
|
64
|
+
* 入站拦截(挂在 bot.on('message') 最前): 命中 /approve|/deny CODE 则结算并消费消息。
|
|
65
|
+
* @returns true = 消息已被审批逻辑消费(调用方不要再派发给 agent)
|
|
66
|
+
*/
|
|
67
|
+
handleInbound(msg: ApprovableMessage, replyTarget: ReplyTarget): Promise<boolean>;
|
|
68
|
+
/** 结算: 清定时器/中止监听/pending 项并 resolve */
|
|
69
|
+
private settle;
|
|
70
|
+
dispose(): void;
|
|
71
|
+
}
|
|
72
|
+
type ApprovalDispatch = (req: ApprovalRequestLike, next: () => Promise<ApprovalOutcome>) => Promise<ApprovalOutcome>;
|
|
73
|
+
/** bootstrap 注册实际处理器(内含开关闸门 + ownership 由调用方处理); 传 undefined 可卸载 */
|
|
74
|
+
export declare function setApprovalDispatch(fn: ApprovalDispatch | undefined): void;
|
|
75
|
+
/** 生成挂在插件 apply ctx 的审批监听(ACP 模式): 非本 bot agent / 未启用 → next() 快速放行 */
|
|
76
|
+
export declare function makeApprovalListener(): (req: unknown, next: () => Promise<string>) => Promise<string>;
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=qq-approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qq-approval.d.ts","sourceRoot":"","sources":["../../src/features/qq-approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;AAExF,mDAAmD;AACnD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,mDAAmD;AACnD,UAAU,iBAAiB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAWD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,cAAc,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mCAAmC;AACnC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAUlF;AAED,yEAAyE;AACzE,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAPpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;gBAG3C,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM;IAC/B,8CAA8C;IAC7B,iBAAiB,EAAE,MAAM,MAAM;IAGlD,iDAAiD;IAC3C,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IA6CvG;;;OAGG;IACG,aAAa,CAAC,GAAG,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAmDvF,uCAAuC;IACvC,OAAO,CAAC,MAAM;IAWd,OAAO,IAAI,IAAI;CAGhB;AAeD,KAAK,gBAAgB,GAAG,CAAC,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAIrH,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAE1E;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAMrG"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
/** 只解析显式审批命令; 普通聊天消息原样放行给 agent */
|
|
3
|
+
export function parseApprovalCommand(content) {
|
|
4
|
+
const normalized = content.trim();
|
|
5
|
+
const match = normalized.match(/^\/(approve|allow|deny|reject)\s+([A-Z0-9]{6})$/i)
|
|
6
|
+
?? normalized.match(/^(允许|同意|拒绝|不同意)\s+([A-Z0-9]{6})$/i);
|
|
7
|
+
if (!match)
|
|
8
|
+
return null;
|
|
9
|
+
const action = match[1].toLowerCase();
|
|
10
|
+
return {
|
|
11
|
+
outcome: ['approve', 'allow', '允许', '同意'].includes(action) ? 'allowed-once' : 'rejected',
|
|
12
|
+
code: match[2].toUpperCase(),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** QQ 载体的一次性审批 answerer(dsh approval/request → QQ 提示 → /approve CODE) */
|
|
16
|
+
export class QqApprovalController {
|
|
17
|
+
manager;
|
|
18
|
+
sender;
|
|
19
|
+
logger;
|
|
20
|
+
timeoutMsProvider;
|
|
21
|
+
pending = new Map();
|
|
22
|
+
constructor(manager, sender, logger,
|
|
23
|
+
/** 超时(ms)提供器: 每次 request 现读, 支持 Web 设置热改生效 */
|
|
24
|
+
timeoutMsProvider) {
|
|
25
|
+
this.manager = manager;
|
|
26
|
+
this.sender = sender;
|
|
27
|
+
this.logger = logger;
|
|
28
|
+
this.timeoutMsProvider = timeoutMsProvider;
|
|
29
|
+
}
|
|
30
|
+
/** 宿主 approval/request 处理器: 定位发起者会话并发 QQ 审批提示 */
|
|
31
|
+
async request(req, next) {
|
|
32
|
+
const record = this.manager.findByAgent(req.agent);
|
|
33
|
+
if (!record)
|
|
34
|
+
return next();
|
|
35
|
+
if (req.signal?.aborted)
|
|
36
|
+
return 'cancelled';
|
|
37
|
+
const timeoutMs = Math.max(1000, this.timeoutMsProvider() || 120000);
|
|
38
|
+
// 一次性 6 位大写码(与 parseApprovalCommand 正则一致)
|
|
39
|
+
let code = '';
|
|
40
|
+
do {
|
|
41
|
+
code = Array.from({ length: 6 }, () => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'[Math.floor(Math.random() * 36)]).join('');
|
|
42
|
+
} while (this.pending.has(code));
|
|
43
|
+
const outcome = new Promise((resolve) => {
|
|
44
|
+
const timer = setTimeout(() => this.settle(code, 'rejected'), timeoutMs);
|
|
45
|
+
const pending = { record, toolName: String(req.toolName ?? req.callId ?? ''), resolve, timer, signal: req.signal };
|
|
46
|
+
if (req.signal) {
|
|
47
|
+
pending.onAbort = () => this.settle(code, 'cancelled');
|
|
48
|
+
req.signal.addEventListener('abort', pending.onAbort, { once: true });
|
|
49
|
+
}
|
|
50
|
+
this.pending.set(code, pending);
|
|
51
|
+
});
|
|
52
|
+
const reason = String(req.reason ?? '').replace(/[\r\n]+/g, ' ').slice(0, 200);
|
|
53
|
+
const tool = String(req.toolName ?? req.callId ?? '未知工具');
|
|
54
|
+
const seconds = Math.ceil(timeoutMs / 1000);
|
|
55
|
+
const prompt = [
|
|
56
|
+
'⚠️ **DSH 权限申请**',
|
|
57
|
+
`工具:${tool}`,
|
|
58
|
+
reason ? `原因:${reason}` : '',
|
|
59
|
+
'',
|
|
60
|
+
`允许本次操作:\`/approve ${code}\``,
|
|
61
|
+
`拒绝本次操作:\`/deny ${code}\``,
|
|
62
|
+
`仅本次有效,${seconds} 秒后自动拒绝。`,
|
|
63
|
+
].filter(Boolean).join('\n');
|
|
64
|
+
try {
|
|
65
|
+
await this.sender.sendMarkdown(record.replyTarget, prompt);
|
|
66
|
+
this.logger.info(`QQ approval requested: code=${code} tool=${tool}`);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
this.logger.error(`QQ approval prompt failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
70
|
+
this.settle(code, 'unavailable');
|
|
71
|
+
}
|
|
72
|
+
return outcome;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 入站拦截(挂在 bot.on('message') 最前): 命中 /approve|/deny CODE 则结算并消费消息。
|
|
76
|
+
* @returns true = 消息已被审批逻辑消费(调用方不要再派发给 agent)
|
|
77
|
+
*/
|
|
78
|
+
async handleInbound(msg, replyTarget) {
|
|
79
|
+
const command = parseApprovalCommand(msg.content ?? '');
|
|
80
|
+
if (!command)
|
|
81
|
+
return false;
|
|
82
|
+
const pending = this.pending.get(command.code);
|
|
83
|
+
if (!pending) {
|
|
84
|
+
try {
|
|
85
|
+
await this.sender.sendMarkdown(replyTarget, '该权限申请不存在或已过期。');
|
|
86
|
+
}
|
|
87
|
+
catch { /* ignore */ }
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
// 双校验: 必须是"任务发起者本人"且"同一会话"(群聊里其他成员看到 CODE 也不能批)
|
|
91
|
+
const rec = pending.record;
|
|
92
|
+
const sameSender = msg.senderId === rec.senderId;
|
|
93
|
+
const samePeer = rec.scope === 'c2c'
|
|
94
|
+
? msg.kind === 'c2c' && msg.senderId === rec.peerId
|
|
95
|
+
: msg.kind === 'group' && msg.groupOpenid === rec.peerId;
|
|
96
|
+
if (!sameSender || !samePeer) {
|
|
97
|
+
try {
|
|
98
|
+
await this.sender.sendMarkdown(replyTarget, '你无权处理这项权限申请。');
|
|
99
|
+
}
|
|
100
|
+
catch { /* ignore */ }
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
this.settle(command.code, command.outcome);
|
|
104
|
+
// 留痕(不打扰, 正经注入): 用 agent.inject 注入 plugin/notice 消息 —— 不唤醒、排队下个 step
|
|
105
|
+
// 组包(claim 顺序 next-step 先于 next-turn → 排在用户消息前同批进请求); UI 呈现为 context 行,
|
|
106
|
+
// 不再冒充 kind:'user' 发言。宿主无 inject 能力时静默跳过(审计靠 QQ 端 ✅/❌ 回复)。
|
|
107
|
+
const toolName = pending.toolName || '';
|
|
108
|
+
try {
|
|
109
|
+
const agent = pending.record.agent;
|
|
110
|
+
if (agent && typeof agent.inject === 'function') {
|
|
111
|
+
const allowed = command.outcome === 'allowed-once';
|
|
112
|
+
agent.inject(createUserMessage({
|
|
113
|
+
content: [{
|
|
114
|
+
type: 'text',
|
|
115
|
+
text: `主人已在 QQ ${allowed ? '批准' : '拒绝'}一次工具权限申请${toolName ? `(工具: ${toolName})` : ''}。`,
|
|
116
|
+
}],
|
|
117
|
+
source: {
|
|
118
|
+
kind: 'plugin', plugin: 'qqbot-approval', form: 'notice',
|
|
119
|
+
summary: `主人${allowed ? '批准' : '拒绝'}了工具${toolName || ''}的权限申请`,
|
|
120
|
+
},
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch { /* 注入失败不影响裁决 */ }
|
|
125
|
+
try {
|
|
126
|
+
await this.sender.sendMarkdown(replyTarget, command.outcome === 'allowed-once' ? '✅ 已允许本次操作。' : '❌ 已拒绝本次操作。');
|
|
127
|
+
}
|
|
128
|
+
catch { /* ignore */ }
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
/** 结算: 清定时器/中止监听/pending 项并 resolve */
|
|
132
|
+
settle(code, outcome) {
|
|
133
|
+
const pending = this.pending.get(code);
|
|
134
|
+
if (!pending)
|
|
135
|
+
return;
|
|
136
|
+
this.pending.delete(code);
|
|
137
|
+
clearTimeout(pending.timer);
|
|
138
|
+
if (pending.signal && pending.onAbort) {
|
|
139
|
+
try {
|
|
140
|
+
pending.signal.removeEventListener('abort', pending.onAbort);
|
|
141
|
+
}
|
|
142
|
+
catch { /* ignore */ }
|
|
143
|
+
}
|
|
144
|
+
pending.resolve(outcome);
|
|
145
|
+
}
|
|
146
|
+
dispose() {
|
|
147
|
+
for (const code of [...this.pending.keys()])
|
|
148
|
+
this.settle(code, 'cancelled');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
let dispatch;
|
|
152
|
+
/** bootstrap 注册实际处理器(内含开关闸门 + ownership 由调用方处理); 传 undefined 可卸载 */
|
|
153
|
+
export function setApprovalDispatch(fn) {
|
|
154
|
+
dispatch = fn;
|
|
155
|
+
}
|
|
156
|
+
/** 生成挂在插件 apply ctx 的审批监听(ACP 模式): 非本 bot agent / 未启用 → next() 快速放行 */
|
|
157
|
+
export function makeApprovalListener() {
|
|
158
|
+
return ((req, next) => {
|
|
159
|
+
console.log('[qq-approval] ctx listener fired');
|
|
160
|
+
if (!dispatch)
|
|
161
|
+
return next();
|
|
162
|
+
return dispatch(req, next);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=qq-approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qq-approval.js","sourceRoot":"","sources":["../../src/features/qq-approval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Logger } from '../types.js';
|
|
2
|
+
export type TimerKind = 'once' | 'daily';
|
|
3
|
+
export interface TimerJob {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: TimerKind;
|
|
6
|
+
/** 目标会话(scope/peerId 与 qqbot sessionKey 对应) */
|
|
7
|
+
scope: 'group' | 'c2c';
|
|
8
|
+
peerId: string;
|
|
9
|
+
/** 每天触发时刻 HH:MM(daily 必填; once 且用 atTime 时也填) */
|
|
10
|
+
atTime?: string;
|
|
11
|
+
/** 一次性: 绝对触发时间(ms); seconds 相对或 atTime 换算后写入 */
|
|
12
|
+
dueAt?: number;
|
|
13
|
+
/** 到点注入会话的提示内容 */
|
|
14
|
+
prompt: string;
|
|
15
|
+
createdAt: number;
|
|
16
|
+
/** daily 上次触发日期(YYYY-MM-DD), 防同一天重复 */
|
|
17
|
+
lastRunDate?: string;
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface TimerCreateInput {
|
|
21
|
+
kind?: TimerKind;
|
|
22
|
+
scope: 'group' | 'c2c';
|
|
23
|
+
peerId: string;
|
|
24
|
+
/** 相对秒(once; 至少与 atTime 一个) */
|
|
25
|
+
seconds?: number;
|
|
26
|
+
/** 几点几分 HH:MM(24h; daily 必填; once 可选=今天该点, 已过则明天) */
|
|
27
|
+
atTime?: string;
|
|
28
|
+
prompt: string;
|
|
29
|
+
}
|
|
30
|
+
export declare class ScheduleStore {
|
|
31
|
+
private jobs;
|
|
32
|
+
private saveTimer;
|
|
33
|
+
private dirty;
|
|
34
|
+
readonly dataDir: string;
|
|
35
|
+
private logger?;
|
|
36
|
+
constructor(dataDir: string, logger?: Logger);
|
|
37
|
+
private file;
|
|
38
|
+
private load;
|
|
39
|
+
private save;
|
|
40
|
+
flush(): void;
|
|
41
|
+
/** 新建任务; 返回 {ok, id?, error?}。kind 缺省: atTime 且无 seconds→daily, 否则 once */
|
|
42
|
+
add(input: TimerCreateInput): {
|
|
43
|
+
ok: boolean;
|
|
44
|
+
id?: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
};
|
|
47
|
+
get(id: string): TimerJob | undefined;
|
|
48
|
+
/** 下次触发时间戳(用于展示; once=dueAt, daily=今天该点(已过则明天); 禁用/null) */
|
|
49
|
+
nextFireAt(job: TimerJob, now?: number): number | null;
|
|
50
|
+
list(): TimerJob[];
|
|
51
|
+
remove(id: string): boolean;
|
|
52
|
+
/** 当前应触发的任务(由 ticker 调用) */
|
|
53
|
+
due(now?: number): TimerJob[];
|
|
54
|
+
/** 触发后记账: once 删除; daily 记今天 */
|
|
55
|
+
markDone(id: string): void;
|
|
56
|
+
setEnabled(id: string, enabled: boolean): boolean;
|
|
57
|
+
}
|
|
58
|
+
/** 配置定时任务实例(启动早期每账号按自己 dataDir 预初始化; 同目录幂等) */
|
|
59
|
+
export declare function configureScheduleStore(dataDir: string, logger?: Logger): ScheduleStore;
|
|
60
|
+
/** 获取实例。带 dataDir → 按目录取(不在则容错新建); 无参 → primary(主账号, 兼容旧调用)。 */
|
|
61
|
+
export declare function getScheduleStore(dataDir?: string, logger?: Logger): ScheduleStore;
|
|
62
|
+
//# sourceMappingURL=schedule-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-store.d.ts","sourceRoot":"","sources":["../../src/features/schedule-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,OAAO,GAAG,KAAK,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,OAAO,GAAG,KAAK,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,KAAK,CAAS;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAO5C,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,IAAI;IAkBZ,KAAK,IAAI,IAAI;IAOb,2EAA2E;IAC3E,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAsC1E,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIrC,4DAA4D;IAC5D,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,IAAI;IAY1D,IAAI,IAAI,QAAQ,EAAE;IAIlB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ3B,4BAA4B;IAC5B,GAAG,CAAC,GAAG,SAAa,GAAG,QAAQ,EAAE;IAejC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAa1B,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO;CAOlD;AAMD,+CAA+C;AAC/C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAStF;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAoBjF"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* schedule-store.ts — QQ 会话自我定时任务(一次性/每日)存储与调度
|
|
3
|
+
*
|
|
4
|
+
* AI(QQ 会话内)可给自己安排定时提醒/任务: 到点后把 prompt 注入原会话(followup),
|
|
5
|
+
* 她会像收到新消息一样处理并回复到 QQ(带群聊上下文)。
|
|
6
|
+
* 数据落盘 {dataDir}/timers.json, 重启不丢; bootstrap 启动一个 30s ticker 驱动。
|
|
7
|
+
* 类型: once(一次性: seconds 相对秒 或 atTime 今天某时) / daily(每天 HH:MM)。
|
|
8
|
+
*
|
|
9
|
+
* ⚠️ 本地手改功能(fork 新增)。
|
|
10
|
+
*/
|
|
11
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, renameSync } from 'node:fs';
|
|
12
|
+
import { join, resolve } from 'node:path';
|
|
13
|
+
const FILE_NAME = 'timers.json';
|
|
14
|
+
/** 最小相对秒(与 ticker 粒度对齐) */
|
|
15
|
+
const MIN_SECONDS = 30;
|
|
16
|
+
/** 单会话(scope:peer)最多启用的任务数 */
|
|
17
|
+
const MAX_PER_PEER = 20;
|
|
18
|
+
/** 全局任务总数上限 */
|
|
19
|
+
const MAX_GLOBAL = 200;
|
|
20
|
+
/** 解析 HH:MM → 当天该时刻 ms; 已过则明天 */
|
|
21
|
+
function dueAtFromHHMM(hhmm, base = Date.now()) {
|
|
22
|
+
const m = /^(\d{1,2}):(\d{2})$/.exec((hhmm ?? '').trim());
|
|
23
|
+
if (!m)
|
|
24
|
+
return NaN;
|
|
25
|
+
const h = Math.min(23, Number(m[1]));
|
|
26
|
+
const min = Math.min(59, Number(m[2]));
|
|
27
|
+
const d = new Date(base);
|
|
28
|
+
d.setHours(h, min, 0, 0);
|
|
29
|
+
if (d.getTime() <= base)
|
|
30
|
+
d.setDate(d.getDate() + 1); // 已过 → 明天
|
|
31
|
+
return d.getTime();
|
|
32
|
+
}
|
|
33
|
+
export class ScheduleStore {
|
|
34
|
+
jobs = [];
|
|
35
|
+
saveTimer = null;
|
|
36
|
+
dirty = false;
|
|
37
|
+
dataDir;
|
|
38
|
+
logger;
|
|
39
|
+
constructor(dataDir, logger) {
|
|
40
|
+
this.dataDir = dataDir;
|
|
41
|
+
this.logger = logger;
|
|
42
|
+
mkdirSync(dataDir, { recursive: true });
|
|
43
|
+
this.load();
|
|
44
|
+
}
|
|
45
|
+
file() {
|
|
46
|
+
return join(this.dataDir, FILE_NAME);
|
|
47
|
+
}
|
|
48
|
+
load() {
|
|
49
|
+
try {
|
|
50
|
+
const p = this.file();
|
|
51
|
+
if (existsSync(p)) {
|
|
52
|
+
const raw = JSON.parse(readFileSync(p, 'utf8'));
|
|
53
|
+
this.jobs = Array.isArray(raw.jobs) ? raw.jobs : [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
this.jobs = [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
save() {
|
|
61
|
+
this.dirty = true;
|
|
62
|
+
if (this.saveTimer)
|
|
63
|
+
return;
|
|
64
|
+
this.saveTimer = setTimeout(() => {
|
|
65
|
+
this.saveTimer = null;
|
|
66
|
+
if (!this.dirty)
|
|
67
|
+
return;
|
|
68
|
+
this.dirty = false;
|
|
69
|
+
try {
|
|
70
|
+
const p = this.file();
|
|
71
|
+
const tmp = `${p}.tmp`;
|
|
72
|
+
writeFileSync(tmp, JSON.stringify({ version: 1, jobs: this.jobs }, null, 2), 'utf8');
|
|
73
|
+
renameSync(tmp, p);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
this.logger?.warn?.(`[schedule] save failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
77
|
+
}
|
|
78
|
+
}, 300);
|
|
79
|
+
}
|
|
80
|
+
flush() {
|
|
81
|
+
if (this.saveTimer) {
|
|
82
|
+
clearTimeout(this.saveTimer);
|
|
83
|
+
this.saveTimer = null;
|
|
84
|
+
}
|
|
85
|
+
if (!this.dirty)
|
|
86
|
+
return;
|
|
87
|
+
this.dirty = false;
|
|
88
|
+
try {
|
|
89
|
+
writeFileSync(this.file(), JSON.stringify({ version: 1, jobs: this.jobs }, null, 2), 'utf8');
|
|
90
|
+
}
|
|
91
|
+
catch { /* ignore */ }
|
|
92
|
+
}
|
|
93
|
+
/** 新建任务; 返回 {ok, id?, error?}。kind 缺省: atTime 且无 seconds→daily, 否则 once */
|
|
94
|
+
add(input) {
|
|
95
|
+
const kind = input.kind ?? (input.atTime && !input.seconds ? 'daily' : 'once');
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const seconds = Number(input.seconds);
|
|
98
|
+
const hasSec = Number.isFinite(seconds) && seconds > 0;
|
|
99
|
+
const hasAt = /^(\d{1,2}):(\d{2})$/.test((input.atTime ?? '').trim());
|
|
100
|
+
const key = `${input.scope}:${input.peerId}`;
|
|
101
|
+
if (kind === 'once' && hasSec && seconds < MIN_SECONDS)
|
|
102
|
+
return { ok: false, error: `seconds 不能小于 ${MIN_SECONDS} 秒` };
|
|
103
|
+
if (!hasSec && !hasAt)
|
|
104
|
+
return { ok: false, error: 'seconds 与 atTime 至少要给一个' };
|
|
105
|
+
if (kind === 'daily' && !hasAt)
|
|
106
|
+
return { ok: false, error: '每日任务需提供 atTime(几点几分 HH:MM)' };
|
|
107
|
+
if (hasAt && !/^(\d{1,2}):(\d{2})$/.test((input.atTime ?? '').trim()))
|
|
108
|
+
return { ok: false, error: 'atTime 格式应为 HH:MM(如 08:30)' };
|
|
109
|
+
if (kind !== 'once' && kind !== 'daily')
|
|
110
|
+
return { ok: false, error: 'kind 只能为 once 或 daily' };
|
|
111
|
+
// 配额
|
|
112
|
+
const perPeer = this.jobs.filter(j => `${j.scope}:${j.peerId}` === key && j.enabled).length;
|
|
113
|
+
if (perPeer >= MAX_PER_PEER)
|
|
114
|
+
return { ok: false, error: `该会话定时任务已达上限(${MAX_PER_PEER}条)` };
|
|
115
|
+
if (this.jobs.filter(j => j.enabled).length >= MAX_GLOBAL)
|
|
116
|
+
return { ok: false, error: `定时任务总数已达上限(${MAX_GLOBAL}条)` };
|
|
117
|
+
// 去重: 同一会话同一条 daily(同 atTime)不重复建
|
|
118
|
+
if (kind === 'daily') {
|
|
119
|
+
const dup = this.jobs.find(j => j.kind === 'daily' && `${j.scope}:${j.peerId}` === key && j.atTime === input.atTime.trim() && j.enabled);
|
|
120
|
+
if (dup)
|
|
121
|
+
return { ok: false, error: `已存在相同每日任务(每天 ${dup.atTime}), 请删除后再建` };
|
|
122
|
+
}
|
|
123
|
+
const job = {
|
|
124
|
+
id: 't' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6),
|
|
125
|
+
kind,
|
|
126
|
+
scope: input.scope,
|
|
127
|
+
peerId: input.peerId,
|
|
128
|
+
prompt: (input.prompt ?? '').slice(0, 800),
|
|
129
|
+
createdAt: now,
|
|
130
|
+
enabled: true,
|
|
131
|
+
...(hasAt ? { atTime: input.atTime.trim() } : {}),
|
|
132
|
+
...(kind === 'once' ? { dueAt: hasSec && hasAt ? Math.min(now + seconds * 1000, dueAtFromHHMM(input.atTime.trim(), now)) : hasSec ? now + seconds * 1000 : dueAtFromHHMM(input.atTime.trim(), now) } : {}),
|
|
133
|
+
};
|
|
134
|
+
if (!job.prompt)
|
|
135
|
+
return { ok: false, error: 'prompt 不能为空' };
|
|
136
|
+
this.jobs.push(job);
|
|
137
|
+
this.save();
|
|
138
|
+
return { ok: true, id: job.id };
|
|
139
|
+
}
|
|
140
|
+
get(id) {
|
|
141
|
+
return this.jobs.find(j => j.id === id);
|
|
142
|
+
}
|
|
143
|
+
/** 下次触发时间戳(用于展示; once=dueAt, daily=今天该点(已过则明天); 禁用/null) */
|
|
144
|
+
nextFireAt(job, now = Date.now()) {
|
|
145
|
+
if (!job.enabled)
|
|
146
|
+
return null;
|
|
147
|
+
if (job.kind === 'once')
|
|
148
|
+
return job.dueAt ?? null;
|
|
149
|
+
const mm = /^(\d{1,2}):(\d{2})$/.exec(job.atTime ?? '');
|
|
150
|
+
if (!mm)
|
|
151
|
+
return null;
|
|
152
|
+
const d = new Date(now);
|
|
153
|
+
d.setHours(Math.min(23, Number(mm[1])), Math.min(59, Number(mm[2])), 0, 0);
|
|
154
|
+
const today = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
|
|
155
|
+
if (job.lastRunDate === today || d.getTime() <= now)
|
|
156
|
+
d.setDate(d.getDate() + 1);
|
|
157
|
+
return d.getTime();
|
|
158
|
+
}
|
|
159
|
+
list() {
|
|
160
|
+
return this.jobs.slice().sort((a, b) => (a.createdAt - b.createdAt));
|
|
161
|
+
}
|
|
162
|
+
remove(id) {
|
|
163
|
+
const i = this.jobs.findIndex(j => j.id === id);
|
|
164
|
+
if (i < 0)
|
|
165
|
+
return false;
|
|
166
|
+
this.jobs.splice(i, 1);
|
|
167
|
+
this.save();
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
/** 当前应触发的任务(由 ticker 调用) */
|
|
171
|
+
due(now = Date.now()) {
|
|
172
|
+
const today = new Date(now);
|
|
173
|
+
const ymd = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;
|
|
174
|
+
const curMin = today.getHours() * 60 + today.getMinutes();
|
|
175
|
+
return this.jobs.filter(j => {
|
|
176
|
+
if (!j.enabled)
|
|
177
|
+
return false;
|
|
178
|
+
if (j.kind === 'once')
|
|
179
|
+
return j.dueAt !== undefined && j.dueAt <= now;
|
|
180
|
+
// daily: 到 HH:MM 且今天还没跑过
|
|
181
|
+
const mm = /^(\d{1,2}):(\d{2})$/.exec(j.atTime ?? '');
|
|
182
|
+
if (!mm)
|
|
183
|
+
return false;
|
|
184
|
+
const target = Math.min(23, Number(mm[1])) * 60 + Math.min(59, Number(mm[2]));
|
|
185
|
+
return curMin >= target && j.lastRunDate !== ymd;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/** 触发后记账: once 删除; daily 记今天 */
|
|
189
|
+
markDone(id) {
|
|
190
|
+
const j = this.jobs.find(x => x.id === id);
|
|
191
|
+
if (!j)
|
|
192
|
+
return;
|
|
193
|
+
if (j.kind === 'once') {
|
|
194
|
+
const i = this.jobs.indexOf(j);
|
|
195
|
+
if (i >= 0)
|
|
196
|
+
this.jobs.splice(i, 1);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const d = new Date();
|
|
200
|
+
j.lastRunDate = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
|
|
201
|
+
}
|
|
202
|
+
this.save();
|
|
203
|
+
}
|
|
204
|
+
setEnabled(id, enabled) {
|
|
205
|
+
const j = this.jobs.find(x => x.id === id);
|
|
206
|
+
if (!j)
|
|
207
|
+
return false;
|
|
208
|
+
j.enabled = enabled;
|
|
209
|
+
this.save();
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ── 多例注册表(多账号支持, 2026-09-03): 每账号实例一个 dataDir({cwd}/.qqbot) → 各自定时任务。
|
|
214
|
+
const _stores = new Map();
|
|
215
|
+
let _primaryDir;
|
|
216
|
+
/** 配置定时任务实例(启动早期每账号按自己 dataDir 预初始化; 同目录幂等) */
|
|
217
|
+
export function configureScheduleStore(dataDir, logger) {
|
|
218
|
+
const key = resolve(dataDir);
|
|
219
|
+
let s = _stores.get(key);
|
|
220
|
+
if (!s) {
|
|
221
|
+
s = new ScheduleStore(dataDir, logger);
|
|
222
|
+
_stores.set(key, s);
|
|
223
|
+
}
|
|
224
|
+
if (!_primaryDir)
|
|
225
|
+
_primaryDir = key;
|
|
226
|
+
return s;
|
|
227
|
+
}
|
|
228
|
+
/** 获取实例。带 dataDir → 按目录取(不在则容错新建); 无参 → primary(主账号, 兼容旧调用)。 */
|
|
229
|
+
export function getScheduleStore(dataDir, logger) {
|
|
230
|
+
if (dataDir) {
|
|
231
|
+
const key = resolve(dataDir);
|
|
232
|
+
let s = _stores.get(key);
|
|
233
|
+
if (!s) {
|
|
234
|
+
s = new ScheduleStore(dataDir, logger);
|
|
235
|
+
_stores.set(key, s);
|
|
236
|
+
}
|
|
237
|
+
return s;
|
|
238
|
+
}
|
|
239
|
+
if (_primaryDir) {
|
|
240
|
+
const s = _stores.get(_primaryDir);
|
|
241
|
+
if (s)
|
|
242
|
+
return s;
|
|
243
|
+
}
|
|
244
|
+
if (_stores.size === 1)
|
|
245
|
+
return _stores.values().next().value;
|
|
246
|
+
const dir = join(process.cwd(), '.qqbot');
|
|
247
|
+
const s = new ScheduleStore(dir, logger);
|
|
248
|
+
_stores.set(resolve(dir), s);
|
|
249
|
+
if (!_primaryDir)
|
|
250
|
+
_primaryDir = resolve(dir);
|
|
251
|
+
return s;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=schedule-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-store.js","sourceRoot":"","sources":["../../src/features/schedule-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ImQQBotConfig } from '../config.js';
|
|
2
|
+
import type { Logger } from '../types.js';
|
|
3
|
+
import type { SessionManager } from '../session/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* 启动定时调度器。返回 stop():停止轮询并落盘。
|
|
6
|
+
* config 为 live 对象引用(schedule.targets 现读, Web 设置热更新即时生效)。
|
|
7
|
+
*/
|
|
8
|
+
export declare function startScheduler(manager: SessionManager, config: ImQQBotConfig, logger: Logger): () => void;
|
|
9
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/features/scheduler.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,cAAc,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAqB1D;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,GACb,MAAM,IAAI,CA8GZ"}
|