@ai-setting/roy-agent-core 1.7.77 → 1.7.88
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/dist/config/config-protection.d.ts +89 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +23 -7
- package/dist/env/agent/agent-component.d.ts +43 -22
- package/dist/env/agent/agent-component.js +13 -12
- package/dist/env/agent/index.js +13 -12
- package/dist/env/agent/types.d.ts +46 -12
- package/dist/env/commands/index.js +7 -7
- package/dist/env/context/index.js +3 -3
- package/dist/env/debug/index.js +7 -7
- package/dist/env/error-reply.d.ts +6 -0
- package/dist/env/error-reply.js +1 -1
- package/dist/env/event-source/bounty-im-handler.d.ts +8 -0
- package/dist/env/event-source/es-command.d.ts +39 -0
- package/dist/env/event-source/es-plugins.d.ts +68 -0
- package/dist/env/event-source/event-source-component.d.ts +15 -0
- package/dist/env/event-source/event-source-handlers.d.ts +84 -0
- package/dist/env/event-source/event-source-handlers.js +40 -23
- package/dist/env/event-source/event-store.js +2 -2
- package/dist/env/event-source/index.d.ts +5 -1
- package/dist/env/event-source/index.js +75 -23
- package/dist/env/event-source/timer-handler.d.ts +98 -0
- package/dist/env/event-source/types.d.ts +154 -2
- package/dist/env/event-source/wecom-card-action-handler.d.ts +373 -0
- package/dist/env/event-source/wecom-card-builder.d.ts +426 -0
- package/dist/env/event-source/wecom-cli-handler.d.ts +291 -0
- package/dist/env/event-source/wecom-cli-sender.d.ts +88 -0
- package/dist/env/event-source/wecom-media.d.ts +130 -0
- package/dist/env/event-source/wecom-respond-registry.d.ts +151 -0
- package/dist/env/event-source/wecom-respond-registry.js +33 -0
- package/dist/env/event-source/wecom-session-card-sender.d.ts +135 -0
- package/dist/env/event-source/wecom-session-card-sender.js +153 -0
- package/dist/env/event-source/wecom-ws-bridge.d.ts +213 -0
- package/dist/env/hook/index.js +5 -5
- package/dist/env/index.js +51 -45
- package/dist/env/llm/index.js +9 -8
- package/dist/env/log-trace/index.js +7 -7
- package/dist/env/log-trace/trace-filters.d.ts +6 -1
- package/dist/env/mcp/index.js +7 -7
- package/dist/env/memory/index.js +7 -7
- package/dist/env/plugin/index.js +7 -7
- package/dist/env/prompt/index.js +8 -8
- package/dist/env/prompt/prompts-index.d.ts +1 -1
- package/dist/env/session/group-session-link.d.ts +99 -0
- package/dist/env/session/index.js +11 -10
- package/dist/env/session/session-component.d.ts +89 -0
- package/dist/env/session/storage/index.js +5 -4
- package/dist/env/session/types.d.ts +10 -0
- package/dist/env/skill/index.js +7 -7
- package/dist/env/task/delegate/delegate-channel-hint.d.ts +39 -0
- package/dist/env/task/delegate/delegate-tool.d.ts +132 -7
- package/dist/env/task/delegate/delegate-tool.js +13 -9
- package/dist/env/task/delegate/index.js +8 -8
- package/dist/env/task/index.js +18 -18
- package/dist/env/task/mcp/index.js +4 -4
- package/dist/env/task/plugins/card-subject.d.ts +117 -0
- package/dist/env/task/plugins/index.d.ts +2 -0
- package/dist/env/task/plugins/index.js +39 -16
- package/dist/env/task/plugins/lark-card-action-handler.d.ts +261 -6
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +542 -2
- package/dist/env/task/plugins/lark-card-patch-notifier.js +12 -2
- package/dist/env/task/plugins/lark-card-state-store.d.ts +60 -0
- package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +61 -0
- package/dist/env/task/plugins/sub-session-activity.d.ts +415 -0
- package/dist/env/task/plugins/wecom-card-state-store.d.ts +121 -0
- package/dist/env/task/plugins/wecom-session-card-store.d.ts +134 -0
- package/dist/env/task/plugins/wecom-session-card-store.js +23 -0
- package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +264 -0
- package/dist/env/task/storage/index.js +3 -3
- package/dist/env/task/tools/index.js +4 -4
- package/dist/env/tool/built-in/index.d.ts +2 -0
- package/dist/env/tool/built-in/index.js +9 -2
- package/dist/env/tool/index.js +14 -9
- package/dist/env/tool/types.d.ts +25 -0
- package/dist/env/tool/validator.d.ts +8 -0
- package/dist/env/workflow/engine/index.js +12 -12
- package/dist/env/workflow/hooks/index.js +7 -7
- package/dist/env/workflow/index.js +24 -23
- package/dist/env/workflow/nodes/index.js +2 -2
- package/dist/env/workflow/plugins/index.js +10 -8
- package/dist/env/workflow/service/index.js +2 -2
- package/dist/env/workflow/storage/index.js +3 -3
- package/dist/env/workflow/tools/index.js +16 -15
- package/dist/env/workflow/utils/index.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +118 -62
- package/dist/shared/@ai-setting/{roy-agent-core-dc9zq75z.js → roy-agent-core-0crmsc12.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-aa2j7bk9.js → roy-agent-core-0sbmdz8d.js} +171 -36
- package/dist/shared/@ai-setting/{roy-agent-core-87942bw4.js → roy-agent-core-1mhyh4c5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-v6vr6za7.js → roy-agent-core-1vv4fx15.js} +4 -4
- package/dist/shared/@ai-setting/roy-agent-core-2stt4rp5.js +134 -0
- package/dist/shared/@ai-setting/{roy-agent-core-nwbfepba.js → roy-agent-core-3e040tc5.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-418zc9ha.js +288 -0
- package/dist/shared/@ai-setting/{roy-agent-core-r5wt1h3c.js → roy-agent-core-4fkxy2gv.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-na18zwj0.js → roy-agent-core-4t3yskp8.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-5pr4zp88.js → roy-agent-core-5kzhaap1.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qq96p0tj.js → roy-agent-core-5s2t8z00.js} +22 -1
- package/dist/shared/@ai-setting/{roy-agent-core-6rh8k6ba.js → roy-agent-core-6gj1hc5z.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-ezvpreqz.js → roy-agent-core-6k8mb7zx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-g8htfwxj.js → roy-agent-core-7f10p7m2.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-7kvpc0w5.js +177 -0
- package/dist/shared/@ai-setting/{roy-agent-core-h21gngxf.js → roy-agent-core-7yh5wps0.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-efkjyh69.js → roy-agent-core-9710zwwz.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-6cy43nss.js → roy-agent-core-9c565frx.js} +49 -9
- package/dist/shared/@ai-setting/{roy-agent-core-fghc2m8z.js → roy-agent-core-aa8kv18f.js} +34 -2
- package/dist/shared/@ai-setting/{roy-agent-core-ew6qb5yx.js → roy-agent-core-an35dzbf.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-mww0mnd9.js → roy-agent-core-azyz78ky.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-264qexac.js → roy-agent-core-b7h39vrc.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-dqxec05w.js → roy-agent-core-bjtc9d35.js} +2 -2
- package/dist/shared/@ai-setting/roy-agent-core-c4ec7k0p.js +426 -0
- package/dist/shared/@ai-setting/{roy-agent-core-ddyk1rc0.js → roy-agent-core-cre2y2ct.js} +160 -4
- package/dist/shared/@ai-setting/{roy-agent-core-tr3ep81v.js → roy-agent-core-d6zdbgtc.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-0qyrk5k0.js → roy-agent-core-ds6qzmf8.js} +14 -5
- package/dist/shared/@ai-setting/{roy-agent-core-cgtq6427.js → roy-agent-core-e08bvpaq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-12n08pg5.js → roy-agent-core-e69qxdyy.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-rhtdspx6.js → roy-agent-core-fan8g0z1.js} +10 -10
- package/dist/shared/@ai-setting/{roy-agent-core-xcp8vwax.js → roy-agent-core-fepm835e.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-6j02sbee.js → roy-agent-core-fhg03v43.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-99nwgj84.js → roy-agent-core-fzw9xzm1.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-dvtg4sn0.js → roy-agent-core-g8yr733d.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-3gpygqcx.js → roy-agent-core-gr5h1dyr.js} +2753 -358
- package/dist/shared/@ai-setting/roy-agent-core-h1e1fm9b.js +380 -0
- package/dist/shared/@ai-setting/{roy-agent-core-c2gbt68e.js → roy-agent-core-h83zdsrq.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-8ez6mccb.js → roy-agent-core-k3gcvybs.js} +5 -1
- package/dist/shared/@ai-setting/{roy-agent-core-pgvcf91v.js → roy-agent-core-m39v7qpx.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-tm1mxttk.js → roy-agent-core-mf5p38yf.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-83bewqx8.js → roy-agent-core-mvh0td7p.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-v85n42ve.js → roy-agent-core-mx855td4.js} +17 -38
- package/dist/shared/@ai-setting/{roy-agent-core-v87njmq7.js → roy-agent-core-n197medr.js} +13 -13
- package/dist/shared/@ai-setting/{roy-agent-core-cmprygrp.js → roy-agent-core-nqkfkpf4.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-7cbpmk4q.js → roy-agent-core-p31ftgq9.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-vffccgf6.js → roy-agent-core-qwd2dq5q.js} +10 -3
- package/dist/shared/@ai-setting/{roy-agent-core-rsn44n9y.js → roy-agent-core-ra66sf50.js} +2526 -942
- package/dist/shared/@ai-setting/{roy-agent-core-1v4g0d4x.js → roy-agent-core-rm7seqwb.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-w0qjeq2v.js → roy-agent-core-shb1qsyg.js} +1041 -18
- package/dist/shared/@ai-setting/{roy-agent-core-ax9e9szb.js → roy-agent-core-smf94h73.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-acj8ag08.js → roy-agent-core-tjnabyvq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qqaak24r.js → roy-agent-core-tkpp1ba0.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-9vhq7fvv.js → roy-agent-core-tpm1dd1g.js} +34 -88
- package/dist/shared/@ai-setting/{roy-agent-core-ed233k5z.js → roy-agent-core-v1n0106v.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-zxz5fkwj.js → roy-agent-core-v6yshv0z.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mcy5apay.js → roy-agent-core-vf9sp6s3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-q813vafd.js → roy-agent-core-vpcxv1ty.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-bxkjk7zx.js → roy-agent-core-vx8zc847.js} +4 -1
- package/dist/shared/@ai-setting/{roy-agent-core-xvt7kf7p.js → roy-agent-core-w9ryeg2p.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-es203w7p.js → roy-agent-core-wqs6yypq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-hd3n57zs.js → roy-agent-core-wr1qexzq.js} +5 -5
- package/dist/shared/@ai-setting/roy-agent-core-wxrkcb17.js +56 -0
- package/dist/shared/@ai-setting/{roy-agent-core-0snm5hc5.js → roy-agent-core-y6shd91r.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-9vxh6f8h.js → roy-agent-core-y7fqtzk2.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-cpcd24n2.js → roy-agent-core-yet36q5k.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-3fh1f7s7.js → roy-agent-core-yfpnkc4z.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-0v27y99n.js → roy-agent-core-yh68z1bg.js} +65 -4
- package/package.json +18 -1
- /package/dist/shared/@ai-setting/{roy-agent-core-b4x6x4k2.js → roy-agent-core-m1fgtnrc.js} +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__resetWecomReplySentForTest,
|
|
3
|
+
__resetWecomRespondRegistryForTest,
|
|
4
|
+
autoReplyWecomTurn,
|
|
5
|
+
getWecomRespondTarget,
|
|
6
|
+
markWecomReplySent,
|
|
7
|
+
registerWecomRespondTarget,
|
|
8
|
+
sendWecomReply,
|
|
9
|
+
sendWecomTemplateCard,
|
|
10
|
+
unregisterWecomRespondTarget,
|
|
11
|
+
wasWecomReplySent,
|
|
12
|
+
wecomRespondTool
|
|
13
|
+
} from "../../shared/@ai-setting/roy-agent-core-h1e1fm9b.js";
|
|
14
|
+
import"../../shared/@ai-setting/roy-agent-core-c4ec7k0p.js";
|
|
15
|
+
import"../../shared/@ai-setting/roy-agent-core-418zc9ha.js";
|
|
16
|
+
import"../../shared/@ai-setting/roy-agent-core-p31ftgq9.js";
|
|
17
|
+
import"../../shared/@ai-setting/roy-agent-core-5s2t8z00.js";
|
|
18
|
+
import"../../shared/@ai-setting/roy-agent-core-7f7t9wwp.js";
|
|
19
|
+
import"../../shared/@ai-setting/roy-agent-core-85xyctnb.js";
|
|
20
|
+
import"../../shared/@ai-setting/roy-agent-core-fs0mn2jk.js";
|
|
21
|
+
export {
|
|
22
|
+
wecomRespondTool,
|
|
23
|
+
wasWecomReplySent,
|
|
24
|
+
unregisterWecomRespondTarget,
|
|
25
|
+
sendWecomTemplateCard,
|
|
26
|
+
sendWecomReply,
|
|
27
|
+
registerWecomRespondTarget,
|
|
28
|
+
markWecomReplySent,
|
|
29
|
+
getWecomRespondTarget,
|
|
30
|
+
autoReplyWecomTurn,
|
|
31
|
+
__resetWecomRespondRegistryForTest,
|
|
32
|
+
__resetWecomReplySentForTest
|
|
33
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Task #5360 —— 企微 **session 卡发送器**(无 task 的 sub-session)
|
|
3
|
+
*
|
|
4
|
+
* ## 用户需求
|
|
5
|
+
*
|
|
6
|
+
* > 「企微也是这个逻辑哈」(22:32)+「以 sub-session 为基底」(22:37)
|
|
7
|
+
*
|
|
8
|
+
* ## 为什么单独一个模块(不复用 lark 的 sessionCardSender)
|
|
9
|
+
*
|
|
10
|
+
* 飞书发卡是 `lark-cli im +messages-send --msg-type interactive`(spawn 子进程);
|
|
11
|
+
* 企微发卡是 WS `aibot_send_msg`(长连接帧)。两条完全不同的传输通道,
|
|
12
|
+
* 混在一个 sender 里只会靠 if/else 分支,且会把「渠道 guard」的责任
|
|
13
|
+
* 推给运行时的字符串比较 —— 那正是 R4 抓出的错渠道风险。
|
|
14
|
+
*
|
|
15
|
+
* ⇒ 明确分成两个 sender,各自由**渠道自己的**事件路径调用。
|
|
16
|
+
*
|
|
17
|
+
* ## 设计(纯函数 + 端口注入,便于单测)
|
|
18
|
+
*
|
|
19
|
+
* | 关注点 | 谁负责 |
|
|
20
|
+
* |--------|--------|
|
|
21
|
+
* | 卡片长什么样 | `buildWecomSessionCard`(wecom-card-builder,已测) |
|
|
22
|
+
* | 发到哪 | 本模块的 `resolveWecomSendTarget`(从 event 取 chatId/chatType/sourceId) |
|
|
23
|
+
* | 怎么发 | `sendCard` 端口(生产接 `sendWecomTemplateCard`) |
|
|
24
|
+
*
|
|
25
|
+
* ## 全链路 best-effort
|
|
26
|
+
*
|
|
27
|
+
* 任何一步失败(无 chatId / 无 sourceId / 发送报错)都只 log,**绝不抛** ——
|
|
28
|
+
* 生命周期事件是 fire-and-forget,抛出去会污染事件消费循环。
|
|
29
|
+
*/
|
|
30
|
+
import type { EnvEvent } from "../types";
|
|
31
|
+
import { type WecomSessionLifecycle } from "./wecom-card-builder";
|
|
32
|
+
import { type WecomSessionCardStore } from "../task/plugins/wecom-session-card-store";
|
|
33
|
+
/** 企微发送目标 */
|
|
34
|
+
export interface WecomSessionCardTarget {
|
|
35
|
+
/** 事件源 ID(WS 实例反查用) */
|
|
36
|
+
sourceId: string;
|
|
37
|
+
/** 单聊 = userid;群聊 = 群 chatid */
|
|
38
|
+
chatId: string;
|
|
39
|
+
chatType: "single" | "group";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 从事件里解析企微发送目标。
|
|
43
|
+
*
|
|
44
|
+
* ## 渠道判定(为什么这里要显式判断)
|
|
45
|
+
*
|
|
46
|
+
* 本 sender 只处理**企微**事件。若把飞书事件的 chatId(`oc_xxx`)当企微
|
|
47
|
+
* userid 发,WS 会静默丢弃(或报错)—— 与 R4 抓出的「错渠道发送」同一类问题,
|
|
48
|
+
* 只是方向相反。所以这里要求 `replyChannel.type === "wecom-cli"`,
|
|
49
|
+
* 判不出来就返回 `undefined`(调用方丢弃,不猜)。
|
|
50
|
+
*
|
|
51
|
+
* ## chatType 判定
|
|
52
|
+
*
|
|
53
|
+
* 优先 `params.chatType`(`buildWecomReplyChannel` 写入的权威值);
|
|
54
|
+
* 缺省时看 `params.wecomChatId` 是否存在 —— 有原始 group chatid ⇒ group。
|
|
55
|
+
* 都没有 ⇒ `single`(企微单聊的 chatId 就是 userid,官方语义)。
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveWecomSessionCardTarget(event: EnvEvent): WecomSessionCardTarget | undefined;
|
|
58
|
+
/** 从事件 payload 里取 session 卡需要的信息 */
|
|
59
|
+
export interface WecomSessionCardPayload {
|
|
60
|
+
sessionId: string;
|
|
61
|
+
lifecycle: WecomSessionLifecycle;
|
|
62
|
+
title?: string;
|
|
63
|
+
agentType?: string;
|
|
64
|
+
startedAt?: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 解析 `task.background.session_started` 的 payload。
|
|
68
|
+
*
|
|
69
|
+
* 缺 `subSessionId` ⇒ `undefined`(没有主键,无从发卡)。
|
|
70
|
+
* `lifecycle` 非法/缺失 ⇒ `running`(乐观:宁可显示在跑,也不凭空宣布结束)。
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseWecomSessionCardPayload(event: EnvEvent): WecomSessionCardPayload | undefined;
|
|
73
|
+
/** sender 依赖的最小端口集(全部可选 ⇒ 缺了只降级) */
|
|
74
|
+
export interface WecomSessionCardSenderPorts {
|
|
75
|
+
/**
|
|
76
|
+
* ★ Task #5364:session 卡持久层(**B 方案的核心**)。
|
|
77
|
+
*
|
|
78
|
+
* 一个 session 生命周期内只发一张卡 ⇒ 后续 lifecycle 必须落在这里,
|
|
79
|
+
* 刷新时才有数据可渲染。不注入 ⇒ 内部用内存实现兜底(同实例内仍只发
|
|
80
|
+
* 一次;进程重启会重发一张,属于可接受的降级)。
|
|
81
|
+
*/
|
|
82
|
+
store?: WecomSessionCardStore;
|
|
83
|
+
/**
|
|
84
|
+
* 发卡(生产:`sendWecomTemplateCard`)。
|
|
85
|
+
*
|
|
86
|
+
* `card` 是 `buildWecomSessionCard` 的输出,原样传给 WS 帧构造。
|
|
87
|
+
*/
|
|
88
|
+
sendCard?: (input: {
|
|
89
|
+
sourceId: string;
|
|
90
|
+
chatId: string;
|
|
91
|
+
chatType: "single" | "group";
|
|
92
|
+
card: Record<string, unknown>;
|
|
93
|
+
/** ★ sessionId(供实现方记录 sessionId→公开消息定位,便于后续 patch/诊断) */
|
|
94
|
+
sessionId: string;
|
|
95
|
+
}) => Promise<{
|
|
96
|
+
ok: boolean;
|
|
97
|
+
error?: string;
|
|
98
|
+
}>;
|
|
99
|
+
/** 日志(测试可注入;缺省 console) */
|
|
100
|
+
warn?: (msg: string) => void;
|
|
101
|
+
/** 时间基准(注入便于测试;缺省 Date.now()) */
|
|
102
|
+
now?: () => number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 造一个 `(event) => Promise<void>` 的企微 session 卡 sender。
|
|
106
|
+
*
|
|
107
|
+
* **永不抛**:这是 fire-and-forget 生命周期事件的投递路径。
|
|
108
|
+
*
|
|
109
|
+
* ## ★ Task #5364 语义变更(用户 2026-11-12 08:34 拍板 B)
|
|
110
|
+
*
|
|
111
|
+
* > 「企微改成**只维护一张卡 + 靠按钮触发更新**」
|
|
112
|
+
*
|
|
113
|
+
* | 事件 | 旧行为(#5360,被用户否掉) | 新行为(B 方案) |
|
|
114
|
+
* |------|---------------------------|------------------|
|
|
115
|
+
* | 首次 lifecycle | 发一张卡 | 发一张卡 + 落库 |
|
|
116
|
+
* | 后续 lifecycle | **再发一张卡**(刷屏 + 重复 pin) | **不发**,只更新持久层 |
|
|
117
|
+
* | 用户点「刷新」 | 只刷活性 | 从持久层 + 实时活性重建**整张卡** |
|
|
118
|
+
*
|
|
119
|
+
* ## 为什么这是唯一可行的形态(协议硬约束,不是偷懒)
|
|
120
|
+
*
|
|
121
|
+
* `aibot_respond_update_msg` 必须在 `template_card_event` 回调的 5 秒窗口内、
|
|
122
|
+
* 用回调带回的 `req_id` 发(#5203 已真网取证)。生命周期事件不是回调、
|
|
123
|
+
* 没有 req_id ⇒ **根本发不出 update 帧**。所以「主动 patch」这条路在企微
|
|
124
|
+
* 上不存在;要「一张卡」只能把更新的机会押在用户点按钮那一刻。
|
|
125
|
+
*
|
|
126
|
+
* 反过来:**如果我们仍然每条 lifecycle 都发卡,就不是一张卡** —— 这正是
|
|
127
|
+
* 用户否掉的形态。所以「后续不发」是本模块最重要的不变量,有测试断言
|
|
128
|
+
* `sendCard` 调用次数恒为 1。
|
|
129
|
+
*
|
|
130
|
+
* ## 发卡失败不落库(重要)
|
|
131
|
+
*
|
|
132
|
+
* 否则后续事件会以为「已经有卡了」而永不再发 ⇒ 用户真的一张卡都看不到。
|
|
133
|
+
* 失败就让它下次事件再试(最多多发一张,也好过零张)。
|
|
134
|
+
*/
|
|
135
|
+
export declare function createWecomSessionCardSender(ports: WecomSessionCardSenderPorts): (event: EnvEvent) => Promise<void>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createMemoryWecomSessionCardStore
|
|
3
|
+
} from "../../shared/@ai-setting/roy-agent-core-7kvpc0w5.js";
|
|
4
|
+
import {
|
|
5
|
+
buildWecomSessionCard
|
|
6
|
+
} from "../../shared/@ai-setting/roy-agent-core-c4ec7k0p.js";
|
|
7
|
+
import"../../shared/@ai-setting/roy-agent-core-418zc9ha.js";
|
|
8
|
+
import"../../shared/@ai-setting/roy-agent-core-6k8mb7zx.js";
|
|
9
|
+
import"../../shared/@ai-setting/roy-agent-core-5s2t8z00.js";
|
|
10
|
+
import"../../shared/@ai-setting/roy-agent-core-7f7t9wwp.js";
|
|
11
|
+
import"../../shared/@ai-setting/roy-agent-core-85xyctnb.js";
|
|
12
|
+
import"../../shared/@ai-setting/roy-agent-core-fs0mn2jk.js";
|
|
13
|
+
|
|
14
|
+
// src/env/event-source/wecom-session-card-sender.ts
|
|
15
|
+
function resolveWecomSessionCardTarget(event) {
|
|
16
|
+
const metadata = event?.metadata;
|
|
17
|
+
const rc = metadata?.replyChannel;
|
|
18
|
+
if (rc?.type !== "wecom-cli")
|
|
19
|
+
return;
|
|
20
|
+
const chatId = typeof rc.chatId === "string" && rc.chatId.trim() ? rc.chatId : undefined;
|
|
21
|
+
if (!chatId)
|
|
22
|
+
return;
|
|
23
|
+
const sourceId = typeof rc.params?.sourceId === "string" && rc.params.sourceId || (typeof metadata?.sourceId === "string" ? metadata.sourceId : undefined);
|
|
24
|
+
if (!sourceId)
|
|
25
|
+
return;
|
|
26
|
+
const chatType = rc.params?.chatType === "group" || rc.params?.chatType === "single" ? rc.params.chatType : rc.params?.wecomChatId ? "group" : "single";
|
|
27
|
+
return { sourceId, chatId, chatType };
|
|
28
|
+
}
|
|
29
|
+
var LIFECYCLES = new Set([
|
|
30
|
+
"running",
|
|
31
|
+
"completed",
|
|
32
|
+
"timeout",
|
|
33
|
+
"failed",
|
|
34
|
+
"stopped"
|
|
35
|
+
]);
|
|
36
|
+
var LIFECYCLE_MILESTONE_PHRASE = {
|
|
37
|
+
running: "运行中",
|
|
38
|
+
completed: "已完成",
|
|
39
|
+
timeout: "已超时",
|
|
40
|
+
failed: "已失败",
|
|
41
|
+
stopped: "已停止"
|
|
42
|
+
};
|
|
43
|
+
function parseWecomSessionCardPayload(event) {
|
|
44
|
+
const p = event?.payload ?? {};
|
|
45
|
+
const sessionId = typeof p.subSessionId === "string" && p.subSessionId.trim() ? p.subSessionId : undefined;
|
|
46
|
+
if (!sessionId)
|
|
47
|
+
return;
|
|
48
|
+
const lifecycle = typeof p.lifecycle === "string" && LIFECYCLES.has(p.lifecycle) ? p.lifecycle : "running";
|
|
49
|
+
return {
|
|
50
|
+
sessionId,
|
|
51
|
+
lifecycle,
|
|
52
|
+
...typeof p.description === "string" && p.description ? { title: p.description } : {},
|
|
53
|
+
...typeof p.subagentType === "string" && p.subagentType ? { agentType: p.subagentType } : {},
|
|
54
|
+
...typeof p.startedAt === "number" ? { startedAt: new Date(p.startedAt).toISOString() } : {}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function parseAssociatedTaskId(event) {
|
|
58
|
+
const p = event?.payload ?? {};
|
|
59
|
+
const raw = p.associatedTaskId;
|
|
60
|
+
const n = typeof raw === "number" ? raw : typeof raw === "string" && /^\d+$/.test(raw.trim()) ? Number(raw) : undefined;
|
|
61
|
+
return typeof n === "number" && Number.isSafeInteger(n) && n > 0 ? n : undefined;
|
|
62
|
+
}
|
|
63
|
+
function createWecomSessionCardSender(ports) {
|
|
64
|
+
const warn = ports.warn ?? ((m) => console.warn(m));
|
|
65
|
+
const store = ports.store ?? createMemoryWecomSessionCardStore();
|
|
66
|
+
const nowFn = ports.now ?? Date.now;
|
|
67
|
+
return async (event) => {
|
|
68
|
+
try {
|
|
69
|
+
const target = resolveWecomSessionCardTarget(event);
|
|
70
|
+
if (!target)
|
|
71
|
+
return;
|
|
72
|
+
const payload = parseWecomSessionCardPayload(event);
|
|
73
|
+
if (!payload)
|
|
74
|
+
return;
|
|
75
|
+
const existing = store.get(payload.sessionId);
|
|
76
|
+
const at = nowFn();
|
|
77
|
+
const milestone = {
|
|
78
|
+
title: LIFECYCLE_MILESTONE_PHRASE[payload.lifecycle],
|
|
79
|
+
timestamp: new Date(at).toISOString()
|
|
80
|
+
};
|
|
81
|
+
const prevMilestones = (() => {
|
|
82
|
+
if (!existing?.milestones)
|
|
83
|
+
return [];
|
|
84
|
+
try {
|
|
85
|
+
const arr = JSON.parse(existing.milestones);
|
|
86
|
+
return Array.isArray(arr) ? arr : [];
|
|
87
|
+
} catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
})();
|
|
91
|
+
const milestones = [...prevMilestones, milestone];
|
|
92
|
+
const associatedTaskId = parseAssociatedTaskId(event) ?? existing?.associatedTaskId;
|
|
93
|
+
const terminal = payload.lifecycle !== "running";
|
|
94
|
+
const persist = (over = {}) => {
|
|
95
|
+
try {
|
|
96
|
+
store.upsert({
|
|
97
|
+
sessionId: payload.sessionId,
|
|
98
|
+
chatId: target.chatId,
|
|
99
|
+
chatType: target.chatType,
|
|
100
|
+
sourceId: target.sourceId,
|
|
101
|
+
cardTaskId: existing?.cardTaskId ?? "",
|
|
102
|
+
lifecycle: payload.lifecycle,
|
|
103
|
+
...payload.title || existing?.title ? { title: payload.title ?? existing.title } : {},
|
|
104
|
+
...payload.agentType || existing?.agentType ? { agentType: payload.agentType ?? existing.agentType } : {},
|
|
105
|
+
...payload.startedAt || existing?.startedAt ? { startedAt: payload.startedAt ?? existing.startedAt } : {},
|
|
106
|
+
...associatedTaskId !== undefined ? { associatedTaskId } : {},
|
|
107
|
+
milestones: JSON.stringify(milestones),
|
|
108
|
+
createdAt: existing?.createdAt ?? at,
|
|
109
|
+
updatedAt: at,
|
|
110
|
+
...terminal ? { closedAt: at } : {},
|
|
111
|
+
...over
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
warn(`[wecom-session-card] store upsert failed for ${payload.sessionId}: ` + `${err instanceof Error ? err.message : String(err)}`);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
if (!existing) {
|
|
118
|
+
if (!ports.sendCard)
|
|
119
|
+
return;
|
|
120
|
+
const card = buildWecomSessionCard({
|
|
121
|
+
sessionId: payload.sessionId,
|
|
122
|
+
lifecycle: payload.lifecycle,
|
|
123
|
+
...payload.title ? { title: payload.title } : {},
|
|
124
|
+
...payload.agentType ? { agentType: payload.agentType } : {},
|
|
125
|
+
...payload.startedAt ? { startedAt: payload.startedAt } : {}
|
|
126
|
+
});
|
|
127
|
+
const r = await ports.sendCard({
|
|
128
|
+
sourceId: target.sourceId,
|
|
129
|
+
chatId: target.chatId,
|
|
130
|
+
chatType: target.chatType,
|
|
131
|
+
card,
|
|
132
|
+
sessionId: payload.sessionId
|
|
133
|
+
});
|
|
134
|
+
if (!r?.ok) {
|
|
135
|
+
warn(`[wecom-session-card] send failed for ${payload.sessionId}: ` + `${r?.error ?? "unknown"}`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
persist({
|
|
139
|
+
cardTaskId: String(card.task_id ?? payload.sessionId)
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
persist();
|
|
144
|
+
} catch (err) {
|
|
145
|
+
warn(`[wecom-session-card] sender threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
resolveWecomSessionCardTarget,
|
|
151
|
+
parseWecomSessionCardPayload,
|
|
152
|
+
createWecomSessionCardSender
|
|
153
|
+
};
|
|
@@ -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/hook/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createHook,
|
|
3
3
|
createPriorityHook,
|
|
4
4
|
init_hook
|
|
5
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
5
|
+
} from "../../shared/@ai-setting/roy-agent-core-smf94h73.js";
|
|
6
6
|
import {
|
|
7
7
|
AgentHookPoints,
|
|
8
8
|
HookManager,
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
executeLLMHook,
|
|
14
14
|
executeToolHook,
|
|
15
15
|
globalHookManager
|
|
16
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
17
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
18
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
19
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
16
|
+
} from "../../shared/@ai-setting/roy-agent-core-yet36q5k.js";
|
|
17
|
+
import"../../shared/@ai-setting/roy-agent-core-tkpp1ba0.js";
|
|
18
|
+
import"../../shared/@ai-setting/roy-agent-core-p31ftgq9.js";
|
|
19
|
+
import"../../shared/@ai-setting/roy-agent-core-5s2t8z00.js";
|
|
20
20
|
import"../../shared/@ai-setting/roy-agent-core-7f7t9wwp.js";
|
|
21
21
|
import"../../shared/@ai-setting/roy-agent-core-85xyctnb.js";
|
|
22
22
|
import"../../shared/@ai-setting/roy-agent-core-fs0mn2jk.js";
|