@ai-setting/roy-agent-core 1.7.77 → 1.7.85

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 (66) hide show
  1. package/dist/config/config-protection.d.ts +89 -0
  2. package/dist/config/index.d.ts +1 -0
  3. package/dist/config/index.js +16 -0
  4. package/dist/env/agent/agent-component.d.ts +42 -21
  5. package/dist/env/agent/agent-component.js +2 -2
  6. package/dist/env/agent/index.js +2 -2
  7. package/dist/env/agent/types.d.ts +32 -12
  8. package/dist/env/error-reply.d.ts +6 -0
  9. package/dist/env/error-reply.js +1 -1
  10. package/dist/env/event-source/bounty-im-handler.d.ts +8 -0
  11. package/dist/env/event-source/es-command.d.ts +39 -0
  12. package/dist/env/event-source/es-plugins.d.ts +68 -0
  13. package/dist/env/event-source/event-source-component.d.ts +15 -0
  14. package/dist/env/event-source/event-source-handlers.d.ts +68 -0
  15. package/dist/env/event-source/event-source-handlers.js +20 -8
  16. package/dist/env/event-source/index.d.ts +5 -1
  17. package/dist/env/event-source/index.js +57 -8
  18. package/dist/env/event-source/types.d.ts +101 -1
  19. package/dist/env/event-source/wecom-card-action-handler.d.ts +141 -0
  20. package/dist/env/event-source/wecom-card-builder.d.ts +220 -0
  21. package/dist/env/event-source/wecom-cli-handler.d.ts +266 -0
  22. package/dist/env/event-source/wecom-cli-sender.d.ts +88 -0
  23. package/dist/env/event-source/wecom-media.d.ts +130 -0
  24. package/dist/env/event-source/wecom-respond-registry.d.ts +151 -0
  25. package/dist/env/event-source/wecom-ws-bridge.d.ts +213 -0
  26. package/dist/env/index.js +16 -14
  27. package/dist/env/task/delegate/delegate-tool.d.ts +62 -2
  28. package/dist/env/task/delegate/delegate-tool.js +3 -1
  29. package/dist/env/task/delegate/index.js +1 -1
  30. package/dist/env/task/index.js +2 -2
  31. package/dist/env/task/plugins/index.d.ts +2 -0
  32. package/dist/env/task/plugins/index.js +23 -2
  33. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +41 -2
  34. package/dist/env/task/plugins/lark-card-patch-notifier.js +1 -1
  35. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +16 -0
  36. package/dist/env/task/plugins/wecom-card-state-store.d.ts +121 -0
  37. package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +224 -0
  38. package/dist/env/tool/built-in/index.d.ts +2 -0
  39. package/dist/env/tool/built-in/index.js +6 -1
  40. package/dist/env/tool/index.js +3 -2
  41. package/dist/env/workflow/index.js +3 -3
  42. package/dist/env/workflow/plugins/index.js +2 -2
  43. package/dist/env/workflow/tools/index.js +2 -2
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.js +68 -17
  46. package/dist/shared/@ai-setting/{roy-agent-core-v87njmq7.js → roy-agent-core-0dh8npnz.js} +1 -1
  47. package/dist/shared/@ai-setting/roy-agent-core-2stt4rp5.js +134 -0
  48. package/dist/shared/@ai-setting/{roy-agent-core-mww0mnd9.js → roy-agent-core-7bpj859q.js} +1 -1
  49. package/dist/shared/@ai-setting/{roy-agent-core-w0qjeq2v.js → roy-agent-core-7dd0s3xb.js} +14 -4
  50. package/dist/shared/@ai-setting/{roy-agent-core-rsn44n9y.js → roy-agent-core-b31v3qpv.js} +851 -46
  51. package/dist/shared/@ai-setting/{roy-agent-core-0v27y99n.js → roy-agent-core-begm7ytz.js} +63 -2
  52. package/dist/shared/@ai-setting/{roy-agent-core-aa2j7bk9.js → roy-agent-core-cha0jc7n.js} +40 -26
  53. package/dist/shared/@ai-setting/{roy-agent-core-hd3n57zs.js → roy-agent-core-d1n4jbza.js} +1 -1
  54. package/dist/shared/@ai-setting/{roy-agent-core-9vhq7fvv.js → roy-agent-core-dkrvmjsh.js} +12 -74
  55. package/dist/shared/@ai-setting/{roy-agent-core-99nwgj84.js → roy-agent-core-fzw9xzm1.js} +1 -1
  56. package/dist/shared/@ai-setting/roy-agent-core-m3vjepzz.js +544 -0
  57. package/dist/shared/@ai-setting/{roy-agent-core-ew6qb5yx.js → roy-agent-core-p6ks90tb.js} +1 -1
  58. package/dist/shared/@ai-setting/{roy-agent-core-rhtdspx6.js → roy-agent-core-qk9hd89p.js} +1 -1
  59. package/dist/shared/@ai-setting/{roy-agent-core-6cy43nss.js → roy-agent-core-rykf7c04.js} +49 -9
  60. package/dist/shared/@ai-setting/{roy-agent-core-8ez6mccb.js → roy-agent-core-tk98f92b.js} +4 -0
  61. package/dist/shared/@ai-setting/{roy-agent-core-bxkjk7zx.js → roy-agent-core-vx8zc847.js} +4 -1
  62. package/dist/shared/@ai-setting/roy-agent-core-vyr6svt6.js +31 -0
  63. package/dist/shared/@ai-setting/{roy-agent-core-3gpygqcx.js → roy-agent-core-xf6z96qy.js} +2086 -163
  64. package/package.json +10 -1
  65. /package/dist/shared/@ai-setting/{roy-agent-core-b4x6x4k2.js → roy-agent-core-m1fgtnrc.js} +0 -0
  66. /package/dist/shared/@ai-setting/{roy-agent-core-v85n42ve.js → roy-agent-core-ze5cqpf2.js} +0 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * @fileoverview Task #5165 — 企微长连接 WebSocket 桥
3
+ *
4
+ * ## 为什么自实现(不用 @wecom/aibot-node-sdk)
5
+ *
6
+ * 1. core 已依赖 `ws@^8.16.0`(bounty-im-handler 同款用法),
7
+ * 不新增任何 npm 依赖(npm 官方 registry 挂,见 Task #5142);
8
+ * 2. 协议极简(4 种帧),SDK 的认证/心跳/重连语义已全部吃透
9
+ * (读 SDK dist/index.cjs.js 源码取证,Task #5142);
10
+ * 3. 避免第三方依赖供应链风险。
11
+ *
12
+ * ## 协议(官方文档 101463 + SDK 源码取证)
13
+ *
14
+ * - 认证帧:`{cmd:"aibot_subscribe", headers:{req_id}, body:{bot_id, secret}}`
15
+ * 响应:无 cmd,`headers.req_id` 前缀 `aibot_subscribe_`,`errcode==0` 成功
16
+ * - 心跳:`{cmd:"ping", headers:{req_id}}`,响应 req_id 前缀 `ping_`,建议 30s
17
+ * - 消息:`{cmd:"aibot_msg_callback", headers:{req_id}, body:{msgid,...}}`
18
+ * - 事件:`{cmd:"aibot_event_callback", headers:{req_id}, body:{...}}`
19
+ * - 回复:`{cmd:"aibot_respond_msg", headers:{req_id:原样透传}, body:{...}}`
20
+ * - 断线重连:指数退避;认证失败与断线**独立计数**
21
+ * - ⚠️ 每机器人同一时刻只允许 1 条长连接(新连接踢旧连接)
22
+ *
23
+ * @see packages/core/src/env/event-source/wecom-ws-bridge.test.ts
24
+ * @see docs/research/2026-11-07-wecom-cli-and-roy-agent-es.md
25
+ */
26
+ import type { WebSocket } from "ws";
27
+ /** 企微长连接默认地址(官方文档 101463) */
28
+ export declare const WECOM_WS_URL = "wss://openws.work.weixin.qq.com";
29
+ /** 心跳间隔(官方建议 30s) */
30
+ export declare const WECOM_HEARTBEAT_INTERVAL_MS = 30000;
31
+ /** 重连基础延迟(指数退避起点) */
32
+ export declare const WECOM_RECONNECT_BASE_DELAY_MS = 1000;
33
+ /** 重连最大延迟(指数退避封顶) */
34
+ export declare const WECOM_RECONNECT_MAX_DELAY_MS = 60000;
35
+ /** 默认最大重连次数(断线场景) */
36
+ export declare const WECOM_MAX_RECONNECT_ATTEMPTS = 10;
37
+ /** 默认最大认证失败次数(凭据错误重试无用) */
38
+ export declare const WECOM_MAX_AUTH_FAILURE_ATTEMPTS = 5;
39
+ /** 生成 `<prefix>_<timestamp>_<random>` 形态的 req_id(对齐官方 SDK) */
40
+ export declare function generateWecomReqId(prefix: string): string;
41
+ /** 通用帧形状(收发共用) */
42
+ export interface WecomFrame {
43
+ cmd?: string;
44
+ headers?: {
45
+ req_id?: string;
46
+ };
47
+ body?: Record<string, unknown>;
48
+ errcode?: number;
49
+ errmsg?: string;
50
+ }
51
+ /** 构造认证帧(aibot_subscribe) */
52
+ export declare function buildWecomAuthFrame(botId: string, secret: string): WecomFrame & {
53
+ cmd: string;
54
+ body: Record<string, unknown>;
55
+ };
56
+ /** 构造心跳帧(ping) */
57
+ export declare function buildWecomHeartbeatFrame(): WecomFrame & {
58
+ cmd: string;
59
+ };
60
+ /**
61
+ * 构造回复帧(aibot_respond_msg,Task #5174)。
62
+ *
63
+ * ★ 协议硬约束(官方文档 101463 + SDK 源码取证):
64
+ * - `headers.req_id` 必须**原样透传**原消息帧的 req_id
65
+ * (服务端靠它把回复关联到原消息/会话);
66
+ * - body 是消息体(msgtype: text / markdown / image / ...);
67
+ * - 收到回调后 24h 内可回复;限频 30 条/分钟。
68
+ *
69
+ * @param reqId 原消息帧的 req_id(空则抛错 —— 关联缺失等于发不出去)
70
+ * @param body 消息体(如 `{msgtype:"text", text:{content:"..."}}`)
71
+ */
72
+ export declare function buildWecomRespondFrame(reqId: string, body: Record<string, unknown>): WecomFrame & {
73
+ cmd: string;
74
+ body: Record<string, unknown>;
75
+ };
76
+ /** 便捷构造:text 回复帧 */
77
+ export declare function buildWecomRespondTextFrame(reqId: string, content: string): WecomFrame & {
78
+ cmd: string;
79
+ body: Record<string, unknown>;
80
+ };
81
+ /** 判定是否认证响应(req_id 前缀 `aibot_subscribe_`,无论成败) */
82
+ export declare function isWecomAuthResponse(frame: WecomFrame): boolean;
83
+ /** 判定是否心跳响应(req_id 前缀 `ping_`) */
84
+ export declare function isWecomHeartbeatResponse(frame: WecomFrame): boolean;
85
+ /**
86
+ * 判定是否「服务端踢线」事件帧(Task #5203)。
87
+ *
88
+ * ## 为什么需要它(真网根因)
89
+ *
90
+ * 企微「每机器人同一时刻只允许 1 条长连接」——新连接建起来会把旧连接踢掉。
91
+ * 踢线时服务端**只发一个事件帧** `disconnected_event`,
92
+ * **TCP 连接并不关闭**(socket 仍 ESTAB,心跳 ping/pong 仍正常往返)。
93
+ *
94
+ * ⇒ 原实现只在 `ws.on("close")` 时重连 ⇒ 被踢线的 bridge **永远不重连**,
95
+ * 变成「心跳正常但业务流量全丢」的僵尸连接(真网现象:用户点卡片按钮,
96
+ * 回调送不达 ES,app.log 里只有 disconnected_event,没有 template_card_event)。
97
+ *
98
+ * @see https://developer.work.weixin.qq.com/document/path/101463(长连接规范)
99
+ */
100
+ export declare function isWecomDisconnectedEvent(frame: unknown): boolean;
101
+ /**
102
+ * 清洗帧中的 secret 字段(DS review B1,Task #5165)。
103
+ *
104
+ * 浅拷贝 + 删除顶层与 body 层的 `secret` —— 服务端 echo 请求体时
105
+ * 防止认证 secret 经 onMessage → rawEvent 泄漏给 LLM。
106
+ */
107
+ export declare function sanitizeWecomFrame(frame: WecomFrame): WecomFrame;
108
+ /** WsBridge 配置 */
109
+ export interface WecomWsBridgeOptions {
110
+ botId: string;
111
+ secret: string;
112
+ /** 覆盖默认 ws 地址(测试 / 内网代理用) */
113
+ wsUrl?: string;
114
+ /** WebSocket 工厂(测试注入 mock;生产用 `new (await import('ws')).WebSocket`) */
115
+ wsFactory?: (url: string) => WebSocket;
116
+ heartbeatIntervalMs?: number;
117
+ reconnectBaseDelayMs?: number;
118
+ reconnectMaxDelayMs?: number;
119
+ maxReconnectAttempts?: number;
120
+ maxAuthFailureAttempts?: number;
121
+ }
122
+ /**
123
+ * 企微长连接桥(对齐官方 SDK 语义,自实现于 ws)。
124
+ *
125
+ * 状态机:
126
+ * connect() → open → 发认证帧 → 认证响应
127
+ * ├─ errcode==0 → authenticated → 启动心跳
128
+ * └─ errcode!=0 → auth 失败计数 → 指数退避重连
129
+ * close/error → 断线计数 → 指数退避重连
130
+ * stop() → 手动关闭,不再重连
131
+ *
132
+ * ⚠️ 每机器人同一时刻只允许 1 条长连接(新连接踢旧连接)。
133
+ */
134
+ export declare class WecomWsBridge {
135
+ private opts;
136
+ private readonly botId;
137
+ private readonly secret;
138
+ private wsFactory;
139
+ private wsUrl;
140
+ private ws?;
141
+ private heartbeatTimer?;
142
+ private reconnectTimer?;
143
+ private reconnectAttempts;
144
+ private authFailureAttempts;
145
+ private manualClose;
146
+ private lastCloseWasAuthFailure;
147
+ private stopped;
148
+ private onMessageCb?;
149
+ private onAuthenticatedCb?;
150
+ private onReconnectingCb?;
151
+ private onErrorCb?;
152
+ constructor(opts: WecomWsBridgeOptions);
153
+ onMessage(cb: (frame: WecomFrame) => void): void;
154
+ onAuthenticated(cb: () => void): void;
155
+ onReconnecting(cb: (attempt: number) => void): void;
156
+ onError(cb: (err: Error) => void): void;
157
+ /** 建立连接(open 后自动发认证帧) */
158
+ connect(): void;
159
+ private optsBotId;
160
+ private optsSecret;
161
+ /** 处理服务端帧(认证响应 / 心跳响应 / 消息 / 事件) */
162
+ private handleFrame;
163
+ private sendFrame;
164
+ /**
165
+ * 发送回复帧(aibot_respond_msg,Task #5174)。
166
+ *
167
+ * best-effort 语义:返回错误而不抛 —— 调用方(handler)在
168
+ * 事件回调里,抛错会打断事件处理链。
169
+ *
170
+ * @param reqId 原消息帧的 req_id(原样透传)
171
+ * @param body 消息体
172
+ * @returns 发送失败时返回 Error;成功返回 undefined
173
+ */
174
+ respond(reqId: string, body: Record<string, unknown>): Error | undefined;
175
+ /**
176
+ * 主动推送帧(Task #5203:aibot_send_msg 直发 template_card)。
177
+ *
178
+ * 与 respond 的区别:respond 必须关联原消息 req_id(被动回复),
179
+ * sendCmd 是**主动推送**(req_id 由开发者自行生成,用于关联
180
+ * 请求与响应)—— 不依赖用户消息触发。
181
+ *
182
+ * best-effort 语义同 respond:返回错误而不抛。
183
+ *
184
+ * @param cmd 命令类型(如 "aibot_send_msg")
185
+ * @param body 消息体
186
+ */
187
+ sendCmd(cmd: string, body: Record<string, unknown>): Error | undefined;
188
+ /**
189
+ * 发送自定义帧(req_id 由调用方透传,Task #5203 回归修复)。
190
+ *
191
+ * ★ 为什么需要:卡片更新(aibot_respond_update_msg)必须
192
+ * **原样透传** template_card_event 回调帧的 req_id
193
+ * (5 秒窗口关联),而 sendCmd 自己生成 req_id、
194
+ * respond() 硬包成 aibot_respond_msg —— 两者都不满足。
195
+ *
196
+ * best-effort 语义同 respond/sendCmd:返回错误而不抛。
197
+ *
198
+ * @param frame 完整帧(cmd + headers.req_id + body)
199
+ */
200
+ sendFrameWithReqId(frame: {
201
+ cmd: string;
202
+ headers: {
203
+ req_id: string;
204
+ };
205
+ body: Record<string, unknown>;
206
+ }): Error | undefined;
207
+ private startHeartbeat;
208
+ private stopHeartbeat;
209
+ /** 指数退避重连(认证失败与断线独立计数) */
210
+ private scheduleReconnect;
211
+ /** 手动停止(不再重连) */
212
+ stop(): void;
213
+ }
package/dist/env/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  BaseEnvironment
3
- } from "../shared/@ai-setting/roy-agent-core-ew6qb5yx.js";
3
+ } from "../shared/@ai-setting/roy-agent-core-p6ks90tb.js";
4
4
  import {
5
5
  TaskComponent
6
- } from "../shared/@ai-setting/roy-agent-core-rhtdspx6.js";
6
+ } from "../shared/@ai-setting/roy-agent-core-qk9hd89p.js";
7
7
  import"../shared/@ai-setting/roy-agent-core-2akfd64z.js";
8
8
  import"../shared/@ai-setting/roy-agent-core-jm136jzh.js";
9
- import"../shared/@ai-setting/roy-agent-core-aa2j7bk9.js";
9
+ import"../shared/@ai-setting/roy-agent-core-cha0jc7n.js";
10
10
  import"../shared/@ai-setting/roy-agent-core-fttgm52a.js";
11
11
  import"../shared/@ai-setting/roy-agent-core-q813vafd.js";
12
12
  import"../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
@@ -14,21 +14,23 @@ import"../shared/@ai-setting/roy-agent-core-vffccgf6.js";
14
14
  import"../shared/@ai-setting/roy-agent-core-p5cz9m8v.js";
15
15
  import {
16
16
  EventSourceComponent
17
- } from "../shared/@ai-setting/roy-agent-core-0v27y99n.js";
17
+ } from "../shared/@ai-setting/roy-agent-core-begm7ytz.js";
18
18
  import {
19
19
  builtInHandlers,
20
20
  larkCliHandler
21
- } from "../shared/@ai-setting/roy-agent-core-3gpygqcx.js";
21
+ } from "../shared/@ai-setting/roy-agent-core-xf6z96qy.js";
22
22
  import {
23
23
  EventSourceInitHooks,
24
24
  getDefaultConfigForType,
25
25
  isBuiltInEventSourceType,
26
26
  isValidEventSourceType,
27
27
  validateEventSourceConfig
28
- } from "../shared/@ai-setting/roy-agent-core-bxkjk7zx.js";
28
+ } from "../shared/@ai-setting/roy-agent-core-vx8zc847.js";
29
29
  import"../shared/@ai-setting/roy-agent-core-v0hf14bj.js";
30
30
  import"../shared/@ai-setting/roy-agent-core-tm1mxttk.js";
31
- import"../shared/@ai-setting/roy-agent-core-rsn44n9y.js";
31
+ import"../shared/@ai-setting/roy-agent-core-2stt4rp5.js";
32
+ import"../shared/@ai-setting/roy-agent-core-b31v3qpv.js";
33
+ import"../shared/@ai-setting/roy-agent-core-m3vjepzz.js";
32
34
  import"../shared/@ai-setting/roy-agent-core-na18zwj0.js";
33
35
  import"../shared/@ai-setting/roy-agent-core-9vxh6f8h.js";
34
36
  import"../shared/@ai-setting/roy-agent-core-ezvpreqz.js";
@@ -36,20 +38,20 @@ import"../shared/@ai-setting/roy-agent-core-1pg0fepg.js";
36
38
  import"../shared/@ai-setting/roy-agent-core-tr3ep81v.js";
37
39
  import"../shared/@ai-setting/roy-agent-core-m46fe3x4.js";
38
40
  import"../shared/@ai-setting/roy-agent-core-4rtg69cn.js";
39
- import"../shared/@ai-setting/roy-agent-core-hd3n57zs.js";
40
- import"../shared/@ai-setting/roy-agent-core-w0qjeq2v.js";
41
+ import"../shared/@ai-setting/roy-agent-core-d1n4jbza.js";
42
+ import"../shared/@ai-setting/roy-agent-core-7dd0s3xb.js";
41
43
  import {
42
44
  WorkflowComponent
43
- } from "../shared/@ai-setting/roy-agent-core-v87njmq7.js";
45
+ } from "../shared/@ai-setting/roy-agent-core-0dh8npnz.js";
44
46
  import"../shared/@ai-setting/roy-agent-core-es203w7p.js";
45
47
  import"../shared/@ai-setting/roy-agent-core-h0x19xgn.js";
46
48
  import"../shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
47
- import"../shared/@ai-setting/roy-agent-core-mww0mnd9.js";
49
+ import"../shared/@ai-setting/roy-agent-core-7bpj859q.js";
48
50
  import"../shared/@ai-setting/roy-agent-core-ddyk1rc0.js";
49
51
  import"../shared/@ai-setting/roy-agent-core-0qyrk5k0.js";
50
52
  import"../shared/@ai-setting/roy-agent-core-hhrg314p.js";
51
53
  import"../shared/@ai-setting/roy-agent-core-12n08pg5.js";
52
- import"../shared/@ai-setting/roy-agent-core-6cy43nss.js";
54
+ import"../shared/@ai-setting/roy-agent-core-rykf7c04.js";
53
55
  import"../shared/@ai-setting/roy-agent-core-6rh8k6ba.js";
54
56
  import"../shared/@ai-setting/roy-agent-core-6atd905e.js";
55
57
  import"../shared/@ai-setting/roy-agent-core-dqxec05w.js";
@@ -68,8 +70,8 @@ import"../shared/@ai-setting/roy-agent-core-jagkferh.js";
68
70
  import {
69
71
  AgentComponent,
70
72
  AgentComponentConfigSchema
71
- } from "../shared/@ai-setting/roy-agent-core-9vhq7fvv.js";
72
- import"../shared/@ai-setting/roy-agent-core-v85n42ve.js";
73
+ } from "../shared/@ai-setting/roy-agent-core-dkrvmjsh.js";
74
+ import"../shared/@ai-setting/roy-agent-core-ze5cqpf2.js";
73
75
  import"../shared/@ai-setting/roy-agent-core-jvv2h3d6.js";
74
76
  import"../shared/@ai-setting/roy-agent-core-ed233k5z.js";
75
77
  import {
@@ -236,6 +236,16 @@ export interface BackgroundTask {
236
236
  * 顺序 = 优先级(主模型失败后逐个尝试)。
237
237
  */
238
238
  fallbackModels?: string[];
239
+ /**
240
+ * ★ Task #5217 fix 2 — 父 agent 本次 run 的 channel systemPrompt
241
+ * (context.metadata.systemPrompt,如 lean lark 渠道 prompt)。
242
+ * 透传给 sub-agent 的 AgentContext.metadata.systemPrompt,
243
+ * 使 AgentComponent._run 把它追加到 sub-agent 的 LLM system message。
244
+ *
245
+ * 注意:与 model 一样**不写进 sub-agent 的注册配置** —— per-run
246
+ * 透传天然每次都是最新值(channel prompt 是 per-event 的)。
247
+ */
248
+ systemPrompt?: string;
239
249
  /**
240
250
  * ★ Task #4552 (A1):本任务被允许的运行时长(毫秒,createTask 时确定)。
241
251
  *
@@ -280,6 +290,16 @@ export interface BackgroundTask {
280
290
  profile?: string;
281
291
  params?: Record<string, unknown>;
282
292
  };
293
+ /**
294
+ * ★ Task #5265 — delegate 时刻的 pluginEnabled 快照。
295
+ *
296
+ * 后台任务通知轮(task.background.* 合成 envEvent)此前
297
+ * pluginEnabled={}(空)→ WecomTaskNotifyPlugin 等 ES 插件的
298
+ * pluginEnabled 守卫拦截 → 不发卡(用户只见纯文本)。
299
+ * createTask 时快照 parent EnvContext.pluginEnabled,
300
+ * publishBackgroundEvent 时写进 event.metadata.pluginEnabled。
301
+ */
302
+ pluginEnabledSnapshot?: Record<string, boolean>;
283
303
  }
284
304
  /**
285
305
  * Task #4794 — BackgroundTaskManager.dispose() 的行为选项。
@@ -347,6 +367,12 @@ export interface CreateBackgroundTaskOptions {
347
367
  * Task #4724 — 父 agent 的兜底模型**有序列表**,透传给 sub-agent。
348
368
  */
349
369
  fallbackModels?: string[];
370
+ /**
371
+ * ★ Task #5217 fix 2 — 父 agent 本次 run 的 channel systemPrompt
372
+ * (context.metadata.systemPrompt,如 lean lark 渠道 prompt)。
373
+ * 透传给 sub-agent 的 AgentContext.metadata.systemPrompt。
374
+ */
375
+ systemPrompt?: string;
350
376
  }
351
377
  /**
352
378
  * 构建 entry-agent 调度的 prompt 包装 (Task #2164 beta-compare divergence #2)
@@ -578,7 +604,7 @@ export declare class BackgroundTaskManager {
578
604
  *
579
605
  * @internal 测试 / 集成用,普通调用方走 publishBackgroundEvent 私有方法
580
606
  */
581
- publishBackgroundEventWithTrigger<T>(type: string, payload: T, parentSessionId: string | undefined, triggerEventId: string, replyChannel?: BackgroundTask["replyChannel"]): void;
607
+ publishBackgroundEventWithTrigger<T>(type: string, payload: T, parentSessionId: string | undefined, triggerEventId: string, replyChannel?: BackgroundTask["replyChannel"], pluginEnabledSnapshot?: Record<string, boolean>): void;
582
608
  /**
583
609
  * Task #3xxx — 解析 AskUserError 信息
584
610
  *
@@ -782,6 +808,34 @@ declare function _captureReplyChannelSnapshot(): BackgroundTask["replyChannel"]
782
808
  * traced 版 captureReplyChannelSnapshot(供 debug trace 观测 task 的回复目标快照)。
783
809
  */
784
810
  export declare const captureReplyChannelSnapshot: typeof _captureReplyChannelSnapshot;
811
+ /**
812
+ * ★ Task #5265 — 把当前 EnvContext.pluginEnabled 拍成不可变快照。
813
+ *
814
+ * ## 为什么需要(生产故障 2026-11-10 12:45)
815
+ *
816
+ * 后台任务完成通知链路(task.background.completed → 通知会话)的
817
+ * 合成 envEvent **pluginEnabled={}(空)** →
818
+ * WecomTaskNotifyPlugin.execute 的 pluginEnabled 守卫
819
+ * (key=wecom-bot-2:WecomTaskNotifyPlugin)不通过 → 插件直接 return
820
+ * 不发卡(用户只看到纯文本)。
821
+ *
822
+ * 主会话(事件轮直发)pluginEnabled 由 event-source-handlers 构建
823
+ * (有 key)→ 有卡。合成事件(publishBackgroundEvent)此前不携带
824
+ * pluginEnabled,dispatcher 的重建逻辑依赖 metadata.plugins(也为空)
825
+ * → 守卫拦截。
826
+ *
827
+ * 修复:delegate 时刻快照 pluginEnabled,随 task 存
828
+ * `BackgroundTask.pluginEnabledSnapshot`,publishBackgroundEvent 时
829
+ * 写进 event.metadata.pluginEnabled —— 通知轮合成 envEvent 自带,
830
+ * dispatcher / buildRunEnvContext 透传 → 守卫放行。
831
+ *
832
+ * 返回 undefined 当没有 EnvContext / 没有 pluginEnabled(向后兼容)。
833
+ */
834
+ declare function _capturePluginEnabledSnapshot(): Record<string, boolean> | undefined;
835
+ /**
836
+ * traced 版 capturePluginEnabledSnapshot(供 debug trace 观测快照结果)。
837
+ */
838
+ export declare const capturePluginEnabledSnapshot: typeof _capturePluginEnabledSnapshot;
785
839
  declare function handleBackgroundTask(backgroundTaskManager: BackgroundTaskManager, parentSessionId: string, description: string, prompt: string, subagentType: string, timeout?: number, similarTaskIds?: number[],
786
840
  /**
787
841
  * ★ 2026-07-10 新增(Task #1752 subSessionId 复用机制)
@@ -804,5 +858,11 @@ model?: string, fallbackModel?: string,
804
858
  * Task #4724 — 父 agent 本次 run 的兜底模型**有序列表**。
805
859
  * 透传给 createTask → sub-agent 的 AgentContext(顺序 = 优先级)。
806
860
  */
807
- fallbackModels?: string[]): Promise<ToolResult>;
861
+ fallbackModels?: string[],
862
+ /**
863
+ * ★ Task #5217 fix 2 — 父 agent 本次 run 的 channel systemPrompt
864
+ * (ToolContext.metadata.systemPrompt,per-event)。
865
+ * 透传给 createTask → sub-agent 的 AgentContext.metadata.systemPrompt。
866
+ */
867
+ systemPrompt?: string): Promise<ToolResult>;
808
868
  export { handleBackgroundTask };
@@ -7,12 +7,13 @@ import {
7
7
  WORKFLOW_COMPAT_ALIASES,
8
8
  buildEntryAgentPrompt,
9
9
  builtInSubAgents,
10
+ capturePluginEnabledSnapshot,
10
11
  captureReplyChannelSnapshot,
11
12
  createDelegateTool,
12
13
  deriveTriggerEventIdFromEnvContext,
13
14
  getSubAgentSpec,
14
15
  handleBackgroundTask
15
- } from "../../../shared/@ai-setting/roy-agent-core-aa2j7bk9.js";
16
+ } from "../../../shared/@ai-setting/roy-agent-core-cha0jc7n.js";
16
17
  import"../../../shared/@ai-setting/roy-agent-core-fttgm52a.js";
17
18
  import"../../../shared/@ai-setting/roy-agent-core-na18zwj0.js";
18
19
  import"../../../shared/@ai-setting/roy-agent-core-9vxh6f8h.js";
@@ -35,6 +36,7 @@ export {
35
36
  deriveTriggerEventIdFromEnvContext,
36
37
  createDelegateTool,
37
38
  captureReplyChannelSnapshot,
39
+ capturePluginEnabledSnapshot,
38
40
  builtInSubAgents,
39
41
  buildEntryAgentPrompt,
40
42
  WORKFLOW_COMPAT_ALIASES,
@@ -5,7 +5,7 @@ import {
5
5
  BackgroundTaskEventTypes,
6
6
  BackgroundTaskManager,
7
7
  createDelegateTool
8
- } from "../../../shared/@ai-setting/roy-agent-core-aa2j7bk9.js";
8
+ } from "../../../shared/@ai-setting/roy-agent-core-cha0jc7n.js";
9
9
  import"../../../shared/@ai-setting/roy-agent-core-fttgm52a.js";
10
10
  import"../../../shared/@ai-setting/roy-agent-core-na18zwj0.js";
11
11
  import"../../../shared/@ai-setting/roy-agent-core-9vxh6f8h.js";
@@ -5,10 +5,10 @@ import {
5
5
  TaskPriorityEnum,
6
6
  TaskStatusEnum,
7
7
  TaskTypeEnum
8
- } from "../../shared/@ai-setting/roy-agent-core-rhtdspx6.js";
8
+ } from "../../shared/@ai-setting/roy-agent-core-qk9hd89p.js";
9
9
  import"../../shared/@ai-setting/roy-agent-core-2akfd64z.js";
10
10
  import"../../shared/@ai-setting/roy-agent-core-jm136jzh.js";
11
- import"../../shared/@ai-setting/roy-agent-core-aa2j7bk9.js";
11
+ import"../../shared/@ai-setting/roy-agent-core-cha0jc7n.js";
12
12
  import"../../shared/@ai-setting/roy-agent-core-fttgm52a.js";
13
13
  import"../../shared/@ai-setting/roy-agent-core-q813vafd.js";
14
14
  import {
@@ -10,6 +10,8 @@ export { TASK_COMPLETION_HINT_ANCHOR, TASK_COMPLETE_ITEM_BY_ITEM, TASK_COMPLETE_
10
10
  export type { DecisionPort, DecisionRequest, DecisionAnswer, DecisionResponse, } from "./decision-port";
11
11
  export { WORKFLOW_EXTRACTOR_PROMPT, formatExtractorInput, formatExtractorInputFromDescription, parseExtractorOutput, } from "./workflow-extractor-agent";
12
12
  export { LarkCliTaskNotifyHook, createLarkCliTaskNotifyHook, type TaskNotifyConfig, NotifyType, } from "./lark-cli-task-notify-plugin";
13
+ export { WecomTaskNotifyHook, createWecomTaskNotifyHook, extractWecomFields, buildWecomTaskCard, WecomNotifyType, type WecomTaskNotifyConfig, type WecomMilestone, } from "./wecom-task-notify-plugin";
14
+ export { createWecomCardStateStore, createMemoryWecomCardStore, MemoryWecomCardStateStore, SqliteWecomCardStateStore, getDefaultWecomCardDbPath, type WecomCardState, type WecomCardStateStore, } from "./wecom-card-state-store";
13
15
  export { PerTaskGroupChatPlugin, createPerTaskGroupChatPlugin, type PerTaskGroupConfig, } from "./per-task-group-chat-plugin";
14
16
  export { LarkCardPatchNotifier, type LarkCardPatchNotifierOptions, buildTaskCard, buildWorkflowCard, renderProgressBar, renderMilestones, renderProcessSteps, renderTaskInfoLines, renderContextAsLines, renderWorkflowInfoLines, formatTimestampForDisplay, formatDateTimeForDisplay, formatDurationMs, sanitizeInlineText, humanizeValue, resolveTaskTitleForDisplay, buildChatAppLink, DEFAULT_APP_LINK_BASE, type CardStatus, type WorkflowCardStatus, type Milestone, type ProcessStep, type TaskMeta, type WorkflowMeta, type CardPayload, type StartTaskOptions, type UpdateTaskOptions, type FinishTaskOptions, type StartTaskResult, type StartWorkflowOptions, type UpdateWorkflowOptions, type FinishWorkflowOptions, } from "./lark-card-patch-notifier";
15
17
  export { createLarkCardStateStore, getDefaultLarkCardDbPath, MemoryLarkCardStateStore, SqliteLarkCardStateStore, type LarkCardState, type LarkCardRecordStatus, type LarkCardStateStore, } from "./lark-card-state-store";
@@ -5,26 +5,37 @@ import {
5
5
  LayaCompletionPlugin,
6
6
  LayaDecisionPlugin,
7
7
  MemoryLarkCardStateStore,
8
+ MemoryWecomCardStateStore,
8
9
  NotifyType,
9
10
  PerTaskGroupChatPlugin,
10
11
  SqliteLarkCardStateStore,
12
+ SqliteWecomCardStateStore,
11
13
  TaskTagPlugin,
12
14
  WORKFLOW_EXTRACTOR_PROMPT,
15
+ WecomNotifyType,
16
+ WecomTaskNotifyHook,
13
17
  buildCompletionHint,
14
18
  buildCompletionQuestion,
19
+ buildWecomTaskCard,
15
20
  createAutoTaskPlugin,
16
21
  createLarkCardStateStore,
17
22
  createLarkCliTaskNotifyHook,
18
23
  createLayaCompletionPlugin,
19
24
  createLayaDecisionPlugin,
25
+ createMemoryWecomCardStore,
20
26
  createPerTaskGroupChatPlugin,
27
+ createWecomCardStateStore,
28
+ createWecomTaskNotifyHook,
29
+ extractWecomFields,
21
30
  formatExtractorInput,
22
31
  formatExtractorInputFromDescription,
23
32
  getDefaultLarkCardDbPath,
33
+ getDefaultWecomCardDbPath,
24
34
  parseExtractorOutput,
25
35
  registerLayaCompletionTaskHook,
26
36
  renderCompletionState
27
- } from "../../../shared/@ai-setting/roy-agent-core-rsn44n9y.js";
37
+ } from "../../../shared/@ai-setting/roy-agent-core-b31v3qpv.js";
38
+ import"../../../shared/@ai-setting/roy-agent-core-m3vjepzz.js";
28
39
  import"../../../shared/@ai-setting/roy-agent-core-na18zwj0.js";
29
40
  import"../../../shared/@ai-setting/roy-agent-core-9vxh6f8h.js";
30
41
  import"../../../shared/@ai-setting/roy-agent-core-ezvpreqz.js";
@@ -55,7 +66,7 @@ import {
55
66
  renderWorkflowInfoLines,
56
67
  resolveTaskTitleForDisplay,
57
68
  sanitizeInlineText
58
- } from "../../../shared/@ai-setting/roy-agent-core-w0qjeq2v.js";
69
+ } from "../../../shared/@ai-setting/roy-agent-core-7dd0s3xb.js";
59
70
  import"../../../shared/@ai-setting/roy-agent-core-1v4g0d4x.js";
60
71
  import"../../../shared/@ai-setting/roy-agent-core-cgtq6427.js";
61
72
  import"../../../shared/@ai-setting/roy-agent-core-er070zjq.js";
@@ -87,24 +98,32 @@ export {
87
98
  registerLayaCompletionTaskHook,
88
99
  parseExtractorOutput,
89
100
  humanizeValue,
101
+ getDefaultWecomCardDbPath,
90
102
  getDefaultLarkCardDbPath,
91
103
  formatTimestampForDisplay,
92
104
  formatExtractorInputFromDescription,
93
105
  formatExtractorInput,
94
106
  formatDurationMs,
95
107
  formatDateTimeForDisplay,
108
+ extractWecomFields,
109
+ createWecomTaskNotifyHook,
110
+ createWecomCardStateStore,
96
111
  createTaskOpWatermarkPlugin,
97
112
  createPerTaskGroupChatPlugin,
113
+ createMemoryWecomCardStore,
98
114
  createLayaDecisionPlugin,
99
115
  createLayaCompletionPlugin,
100
116
  createLarkCliTaskNotifyHook,
101
117
  createLarkCardStateStore,
102
118
  createAutoTaskPlugin,
103
119
  buildWorkflowCard,
120
+ buildWecomTaskCard,
104
121
  buildTaskCard,
105
122
  buildCompletionQuestion,
106
123
  buildCompletionHint,
107
124
  buildChatAppLink,
125
+ WecomTaskNotifyHook,
126
+ WecomNotifyType,
108
127
  WORKFLOW_EXTRACTOR_PROMPT,
109
128
  TaskTagPlugin,
110
129
  TaskOpWatermarkPlugin,
@@ -115,9 +134,11 @@ export {
115
134
  TASK_COMPLETE_VERIFY_DUTY,
116
135
  TASK_COMPLETE_ITEM_BY_ITEM,
117
136
  TASK_COMPLETE_ACCEPTANCE,
137
+ SqliteWecomCardStateStore,
118
138
  SqliteLarkCardStateStore,
119
139
  PerTaskGroupChatPlugin,
120
140
  NotifyType,
141
+ MemoryWecomCardStateStore,
121
142
  MemoryLarkCardStateStore,
122
143
  LayaDecisionPlugin,
123
144
  LayaCompletionPlugin,
@@ -79,7 +79,14 @@ export type CardStatus = "running" | "completed" | "failed" | "stopped"
79
79
  * 语义上必须分开:用户看到「🚫 已取消」会以为任务还能找回来;
80
80
  * 硬删除后任务真的没了,卡片应显示「🗑️ 已删除」。
81
81
  */
82
- | "deleted";
82
+ | "deleted"
83
+ /**
84
+ * ★ Task #5164 需求 2b:任务进入「待验证」(两阶段验收,
85
+ * task_pre_complete 置 to_validate)。**非终态**活跃等待态:
86
+ * 卡片保持可更新,但 header 第二行显示专属短语「🔍 待验证」,
87
+ * 让用户一眼看出任务在等验收而不是在跑。
88
+ */
89
+ | "to_validate";
83
90
  /** workflow 卡片状态(与 CardStatus 同集合;语义别名,便于阅读) */
84
91
  export type WorkflowCardStatus = CardStatus;
85
92
  /** 里程碑(关键节点):时间 + 标题 + 描述 */
@@ -262,7 +269,12 @@ export interface StartTaskResult {
262
269
  export interface LarkCardPatchNotifierOptions {
263
270
  /** 启动时是否 pin(默认 true) */
264
271
  pinOnStart?: boolean;
265
- /** 结束时是否 unpin(默认 true) */
272
+ /**
273
+ * 结束时是否 unpin(Task #5164 需求 2a:**默认 false**)
274
+ *
275
+ * 任务完成/暂停时不再自动取消置顶 —— pin 去留由用户手动决定。
276
+ * 需要旧行为(自动 unpin)的调用方显式传 true。
277
+ */
266
278
  unpinOnFinish?: boolean;
267
279
  }
268
280
  export interface CardPayload {
@@ -805,6 +817,33 @@ export declare class LarkCardPatchNotifier {
805
817
  * 不会被旧 messageId 的终态记录误伤。
806
818
  */
807
819
  private finalisedCards;
820
+ /**
821
+ * ★ Task #5182 follow-up:解除某张卡片的终态标记(reopen 用)。
822
+ *
823
+ * ## 为什么需要
824
+ *
825
+ * `finalisedCards` 守卫(Task #5020)会吞掉 finishTask 之后的
826
+ * 一切 updateTask —— 这对「迟到的并发更新」是正确语义,但对
827
+ * **reopen**(closed 卡片 + 任务重新激活 → 复用原卡)是错的:
828
+ * reopen 本来就是要"复活"这张卡。真网取证(2026-11-08 18:00):
829
+ * reopenReuseCard 打了「已复用原卡」日志 + pin 成功,但 patch
830
+ * 被守卫静默吞掉,卡片内容停在「已完成」。
831
+ *
832
+ * ## 行为
833
+ *
834
+ * - 从 finalisedCards 删除 messageId(守卫解除)
835
+ * - 内存态不存在时从 exportState 快照恢复?—— 不,states 已被
836
+ * finishTask delete,快照无从取。调用方(reopenReuseCard)
837
+ * 会经 mergeTimelineState/updateTask 的默认 state 重建时间线,
838
+ * 并由 hook 层 hydrate(restoreCardState → hydrateState)补齐。
839
+ * - 对未终结的卡是 no-op(finalisedCards 本就没有该 id)
840
+ */
841
+ unfinaliseCard(messageId: string): void;
842
+ /**
843
+ * ★ Task #5182 follow-up:测试注入点 —— 替换 runLarkCli 的执行器。
844
+ * 仅测试使用(生产路径不设置),避免真 spawn lark-cli。
845
+ */
846
+ testRunner?: (argv: string[], op: string) => Promise<string>;
808
847
  /** 诊断:当前跟踪中的卡片数(测试/自检用) */
809
848
  trackedCardCount(): number;
810
849
  /** 诊断:当前跟踪中的 workflow 卡片数(测试/自检用) */
@@ -22,7 +22,7 @@ import {
22
22
  resolveTaskTitleForDisplay,
23
23
  sanitizeInlineText,
24
24
  truncateHeadTitle
25
- } from "../../../shared/@ai-setting/roy-agent-core-w0qjeq2v.js";
25
+ } from "../../../shared/@ai-setting/roy-agent-core-7dd0s3xb.js";
26
26
  import"../../../shared/@ai-setting/roy-agent-core-qq96p0tj.js";
27
27
  import"../../../shared/@ai-setting/roy-agent-core-7f7t9wwp.js";
28
28
  import"../../../shared/@ai-setting/roy-agent-core-85xyctnb.js";
@@ -339,6 +339,22 @@ export declare class LarkCliTaskNotifyHook implements Hook {
339
339
  * 持久层 `pinned=false`(如实反映真实状态,不谎报)。
340
340
  */
341
341
  private repinAfterResume;
342
+ /**
343
+ * ★ Task #5182 — reopen 复用原卡(用户明令 2026-11-08 15:56)
344
+ *
345
+ * 场景:lark-cards.db 里该 task 的记录是 `closed`,但任务被重新激活
346
+ * (status → active 等活跃态)。旧实现发一张新卡(同 task 两张卡、
347
+ * 历史时间线留在旧卡上);新实现:
348
+ *
349
+ * 1. patch 原 messageId:内容 = 当前任务态 + 「🔄 任务重新打开」里程碑
350
+ * 2. 新增一条 reopen 操作记录进卡片时间线(用户可见的 reopen 痕迹)
351
+ * 3. 重新 pin(终态时被 unpin 过;pin 状态必须跟任务状态一致)
352
+ * 4. 持久层 markReopened(closed → open,messageId 不变)
353
+ *
354
+ * @returns true = 原卡复用成功(caller 直接返回,不再走建卡路径);
355
+ * false = 原卡 patch 失败(caller 降级走发新卡路径)
356
+ */
357
+ private reopenReuseCard;
342
358
  /** 合并「写记录」所需的公共字段(读旧记录失败也不抛,降级为 now) */
343
359
  private buildCardState;
344
360
  /** 对外只读:某 task 的持久化卡片记录(debug / 排查用) */