@youdu/openclaw-youdu 2026.8.20 → 2026.9.16

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 (51) hide show
  1. package/README.md +211 -2
  2. package/dist/index.esm.js +8 -2
  3. package/dist/src/channel.d.ts +11 -0
  4. package/dist/src/channel.js +365 -260
  5. package/dist/src/dm-policy.d.ts +3 -1
  6. package/dist/src/dm-policy.js +2 -2
  7. package/dist/src/event-callback.d.ts +34 -0
  8. package/dist/src/event-callback.js +105 -0
  9. package/dist/src/group-mention.d.ts +55 -0
  10. package/dist/src/group-mention.js +114 -0
  11. package/dist/src/group-policy.d.ts +27 -3
  12. package/dist/src/group-policy.js +128 -36
  13. package/dist/src/group-resolve.d.ts +70 -0
  14. package/dist/src/group-resolve.js +195 -0
  15. package/dist/src/kb/cli-runner.d.ts +50 -0
  16. package/dist/src/kb/cli-runner.js +206 -0
  17. package/dist/src/kb/endpoint.d.ts +9 -0
  18. package/dist/src/kb/endpoint.js +53 -0
  19. package/dist/src/kb/protocol.d.ts +66 -0
  20. package/dist/src/kb/protocol.js +233 -0
  21. package/dist/src/kb/request-context.d.ts +15 -0
  22. package/dist/src/kb/run-context.d.ts +21 -0
  23. package/dist/src/kb/run-context.js +85 -0
  24. package/dist/src/kb/tool-policy.d.ts +7 -0
  25. package/dist/src/kb/tool-policy.js +90 -0
  26. package/dist/src/kb/tool.d.ts +48 -0
  27. package/dist/src/kb/tool.js +122 -0
  28. package/dist/src/media.d.ts +1 -1
  29. package/dist/src/mention-gate.d.ts +63 -0
  30. package/dist/src/mention-gate.js +78 -0
  31. package/dist/src/message-sender.d.ts +43 -2
  32. package/dist/src/message-sender.js +153 -20
  33. package/dist/src/monitor.d.ts +14 -1
  34. package/dist/src/monitor.js +209 -46
  35. package/dist/src/onboarding.js +24 -6
  36. package/dist/src/sdk/ws-client.d.ts +12 -4
  37. package/dist/src/sdk/ws-client.js +12 -2
  38. package/dist/src/sdk/ws-manager.d.ts +13 -1
  39. package/dist/src/sdk/ws-manager.js +19 -0
  40. package/dist/src/sdk/ws-utils.d.ts +1 -1
  41. package/dist/src/state-manager.d.ts +16 -5
  42. package/dist/src/state-manager.js +25 -21
  43. package/dist/src/target-store.d.ts +73 -0
  44. package/dist/src/target-store.js +349 -0
  45. package/dist/src/tls.d.ts +1 -0
  46. package/dist/src/tls.js +30 -4
  47. package/dist/src/utils.d.ts +55 -6
  48. package/dist/src/utils.js +152 -14
  49. package/openclaw.plugin.json +125 -1
  50. package/package.json +16 -4
  51. package/skills/youdu-kb-tool/SKILL.md +89 -0
package/README.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  有度机器人接入插件,基于 WebSocket 长连接实现消息收发。
4
4
 
5
+ ## 版本要求
6
+
7
+ | 项 | 要求 | 说明 |
8
+ | --- | --- | --- |
9
+ | OpenClaw | **>= 2026.7.1-2** | 与 `peerDependencies` 一致,也是插件实际开发/测试的版本(开发依赖用 2026.9.4)。本插件在旧版宿主上仍可用(见下)。 |
10
+ | Node.js | **>=20** | 插件的 `engines`。宿主 OpenClaw 2026.9.4 自身要求 `>=24.16.0 <25 \|\| >=26.1.0`,实际部署按宿主口径;实测本插件产物在 Node 22.23.2 下也能正常加载。 |
11
+
12
+ ### 跨 OpenClaw 版本兼容
13
+
14
+ OpenClaw 2026.9.x 调整了入站 @ 门控 API:`resolveMentionGatingWithBypass`(扁平入参)被移除,改为 `resolveInboundMentionDecision`(`{ facts, policy }` 两段式),两者**判定结果字段相同**。
15
+
16
+ 插件通过 `src/mention-gate.ts` 做运行时探测:优先用新 API,旧宿主回落到旧 API,两者都没有才报错。因此**升级插件不会让旧版 OpenClaw 用户失效**:
17
+
18
+ | 宿主 OpenClaw | `resolveInboundMentionDecision` | `resolveMentionGatingWithBypass` | 插件行为 |
19
+ | --- | --- | --- | --- |
20
+ | 2026.7.1-2(实测) | 有 | 有 | 走新 API;与宿主原生判定**逐字段一致**(15/15 项对照通过) |
21
+ | 2026.9.4(实测) | 有 | 已移除 | 走新 API |
22
+ | 更早版本(未实测) | 未知 | 未知 | 两者都缺时报明确错误,不会静默放行或静默丢弃 |
23
+
24
+ > 说明:插件对 `openclaw/plugin-sdk/*` 一律使用 `import type` 或命名空间导入 + 运行时取值,避免"宿主缺少某个导出"变成 `import` 阶段的链接失败。
25
+
26
+ 知识库 Tool 需要 OpenClaw 提供 Tool hook 参数调整能力(`before_tool_call` 可返回调整后的 `params`),该能力自 `2026.7.1-2` 起具备。可信有度 IM 上下文由插件按 OpenClaw `runId` 短期保存,并在本轮 dispatch 结束时清理;插件不会在注册结束后调用注册期 API。
27
+
28
+ 安全边界:知识库调用的短期 `invocationToken` 只由插件 hook 注入并一次性消费,不进入 CLI 请求、stdin、Tool 返回值或插件日志。OpenClaw 会在进程内保存调整后的参数,并将其提供给 `after_tool_call`;同时完整调整参数可能出现在宿主受控的 private diagnostic payload 和 loop-tracking 内存中。该 token 不写入模型会话 transcript,也不作为模型工具 schema 字段。宿主诊断的可见范围由 OpenClaw 控制,部署时应按受控诊断数据处理。
29
+
5
30
  ## 功能特性
6
31
 
7
32
  - 🔗 WebSocket 长连接 — 基于 wss 建立持久连接(可通过配置自定义)
@@ -54,9 +79,141 @@ openclaw gateway restart
54
79
  | `channels.youdu.botId` | 有度机器人 ID | — | — |
55
80
  | `channels.youdu.secret` | 有度机器人密钥 | — | — |
56
81
  | `channels.youdu.enabled` | 启用频道 | true / false | false |
57
- | `channels.youdu.websocketUrl` | WebSocket 地址 | — | — |
82
+ | `channels.youdu.url` | 有度服务器地址(纯主机名) | — | — |
58
83
  | `channels.youdu.dmPolicy` | 私聊访问策略 | pairing / open / allowlist / disabled | pairing |
59
- | `channels.youdu.allowFrom` | 私聊允许列表 | — | [] |
84
+ | `channels.youdu.allowFrom` | 私聊允许列表(账号名、昵称或数字 userId) | — | [] |
85
+ | `channels.youdu.groupPolicy` | 群访问策略 | open / allowlist / disabled | open |
86
+ | `channels.youdu.groupAllowFrom` | 群白名单(仅 `groupPolicy=allowlist` 时生效) | 群 ID、群名或别名,`*` 表示全部 | [] |
87
+ | `channels.youdu.aliases.groups` | 群名 → 群 ID 的显式别名 | 名称 → `{GUID}` | — |
88
+ | `channels.youdu.aliases.users` | 昵称 → 账号名/userId 的显式别名 | 名称 → 账号名或数字 userId | — |
89
+ | `channels.youdu.groups.<群ID或群名>.title` | 群标题(老群兜底;也用于按群名发送) | — | — |
90
+ | `channels.youdu.groups.<群ID或群名>.allowFrom` | 该群内允许触发的发送者 | 账号名或昵称列表(**不接受数字 userId**),`*` 表示全部 | 全部 |
91
+ | `channels.youdu.groups.<群ID或群名>.requireMention` | 该群是否必须 @ 机器人 | true / false | true |
92
+ | `channels.youdu.groups."*".requireMention` | 所有群的默认 @ 要求 | true / false | true |
93
+ | `channels.youdu.historyLimit` | 未被 @ 的群消息保留条数(作为下次被 @ 时的上下文);**不配置即默认 50**,`0` 关闭 | 数字(≥0) | 50 |
94
+ | `channels.youdu.defaultAccount` | 默认账号 ID | 任意账号 ID | — |
95
+ | `channels.youdu.accounts` | 多账号配置 | 账号 ID → 账号级字段的映射 | — |
96
+
97
+ ### 名称与别名(群 ID / 账号 与「群名 / 昵称」的对应关系)
98
+
99
+ 有度回调里,**用户**会同时带上账号名(`from.account`,如 `lewis.liu`)和昵称(`from.name`,如 `刘钟泽`);
100
+ **群**的 `msg_callback` 只有会话 ID(`{GUID}`),群名只在 `event_callback` 会话事件里下发(`data.title`)。
101
+ 插件因此维护这样一张对应关系:
102
+
103
+ | 对象 | 可寻址的名字 | 权威标识 | 来源 |
104
+ | --- | --- | --- | --- |
105
+ | 用户 | 账号名 `lewis.liu`、昵称 `刘钟泽`、`aliases.users` 里的别名 | 单聊 chatId(= 数字 userId) | `msg_callback.from` |
106
+ | 群 | 会话标题、`groups.<id>.title`、`aliases.groups` 里的别名 | 群会话 ID `{GUID}` | `event_callback` / 配置 |
107
+
108
+ - **群名自动学习**:收到 `session_create` / `session_update` / `session_destroy` 事件时记录 `data.title`,
109
+ 持久化后可显示(`群名 (群 ID)`)、可按群名发送、也可用于 `groupAllowFrom` 与 `groups.<群名>` 配置键。
110
+ - **老群兜底**:机器人入群前就存在、且之后没有改名/建群事件的群,拿不到标题,用配置补:
111
+
112
+ ```bash
113
+ openclaw config set channels.youdu.groups.'{0798E01E-CD68-42BB-813C-EB51593BB0F5}'.title "研发讨论组"
114
+ # 或用别名(别名还支持与群名不同的叫法)
115
+ openclaw config set channels.youdu.aliases.groups.项目群 '{0798E01E-CD68-42BB-813C-EB51593BB0F5}'
116
+ openclaw config set channels.youdu.aliases.users.老板 boss.account
117
+ ```
118
+
119
+ - **不做模糊匹配**:只认精确名字(大小写不敏感回退);账号名优先于同名昵称;重名一律报错要求用 ID/账号名。
120
+ 这是刻意的——飞书 `receive_id`、企业微信 `touser`/`chatid` 也都是 ID 优先,姓名不保证唯一。
121
+ - **群白名单接受群名**:`groupAllowFrom` 与 `groups.<键>` 的键都可写群名或别名,群名歧义时按**拒绝**处理。
122
+ 账号级与通道级的 `groupAllowFrom` 取**并集**,两边都不会因为另一边存在而失效。
123
+ - **发送者白名单接受昵称**:`allowFrom`(私聊)与 `groups.<键>.allowFrom`(群内发送者)里既可以写账号名
124
+ (`lewis`),也可以写昵称/姓名(`刘钟泽`),还可以用 `user:` / `account:` / `name:` 前缀消歧;
125
+ 同样是精确匹配(大小写不敏感),不做模糊匹配。账号名与昵称相同时按命中处理,无需二选一。
126
+ - 私聊还额外接受**数字 userId**:有度单聊的 `chatId` 就是对方 userId,`allowFrom: ["1001"]` 生效。
127
+ - 群内发送者白名单**只认账号名与昵称**:入站消息里群成员的标识就是账号名(`from.account`),
128
+ `groups.<键>.allowFrom: ["1001"]` 不会命中——要按人放行请写账号名或昵称。
129
+
130
+ ### 群聊 @ 回复(默认)
131
+
132
+ 从本版本起,**群聊里只有 @ 了机器人的消息才会触发回复**。行为对齐 OpenClaw 其它渠道的 mention gating:
133
+
134
+ - 判定依据是有度回调 `raw.decoded.atUser` 是否包含机器人自身的用户 ID(`gid`,来自认证应答);
135
+ 配置文件里的 `mentionPatterns` 同样计入。斜杠命令(`/new`、`/status` 等)不受 @ 限制,
136
+ 仍按现有命令权限执行。
137
+ - 送进模型前会剥掉消息里的 `@账号(显示名)` 包装,避免模型看到 @ 前缀。
138
+ - **未被 @ 的消息不会进入会话**:不研究、不下载附件、不发"思考中"占位消息。它们只按群进入一个
139
+ **内存中的 pending 窗口**(**默认每个群保留最近 50 条,无需配置**;`channels.youdu.historyLimit` 可调,
140
+ `0` 关闭;窗口在每次回复结束、以及进程重启后清空)。下一次被 @ 时,这些消息会以
141
+ `[Chat messages since your last reply - for context]` 的形式随当次请求一起注入,让机器人知道群里刚才说了什么。
142
+ - 窗口大小按 `账号级 historyLimit` → `channels.youdu.historyLimit` → `messages.groupChat.historyLimit`
143
+ (OpenClaw 全局群聊配置)→ 内置默认 50 依次取值,四层都不配就是 50;多账号模式下该值在通道级共享。
144
+ - 判定能力缺失时(认证应答没有 `gid`,也没有配置 `mentionPatterns`)**宁可不回**:会记录一条错误日志并丢弃
145
+ 该消息,而不会退化成"群里全回"。
146
+ - 想让某个群恢复"全部回复",在该群配置里显式关闭即可(键可以写群 ID,也可以写群名):
147
+
148
+ ```bash
149
+ openclaw config set channels.youdu.groups.'{0798E01E-CD68-42BB-813C-EB51593BB0F5}'.requireMention false
150
+ openclaw config set channels.youdu.groups.'研发讨论组'.requireMention false
151
+ ```
152
+
153
+ - 群访问仍然先由 `channels.youdu.groupPolicy`(open / allowlist / disabled)控制,@ 判定在其后。
154
+
155
+ ### 多账号配置
156
+
157
+ 插件支持配置多个有度机器人账号,每个账号可拥有独立的凭据和访问策略;账号级字段会覆盖顶层默认值。
158
+
159
+ **CLI 配置示例:**
160
+
161
+ ```bash
162
+ openclaw config set channels.youdu.accounts.bot-one.botId "<BOT_ID_1>"
163
+ openclaw config set channels.youdu.accounts.bot-one.secret "<BOT_SECRET_1>"
164
+ openclaw config set channels.youdu.accounts.bot-one.url "<HOST_1>"
165
+
166
+ openclaw config set channels.youdu.accounts.bot-two.botId "<BOT_ID_2>"
167
+ openclaw config set channels.youdu.accounts.bot-two.secret "<BOT_SECRET_2>"
168
+ openclaw config set channels.youdu.accounts.bot-two.url "<HOST_2>"
169
+
170
+ # 指定默认账号
171
+ openclaw config set channels.youdu.defaultAccount bot-one
172
+
173
+ openclaw gateway restart
174
+ ```
175
+
176
+ **等效的配置文件写法:**
177
+
178
+ ```json
179
+ {
180
+ "channels": {
181
+ "youdu": {
182
+ "enabled": true,
183
+ "dmPolicy": "pairing",
184
+ "defaultAccount": "bot-one",
185
+ "accounts": {
186
+ "bot-one": {
187
+ "botId": "<BOT_ID_1>",
188
+ "secret": "<BOT_SECRET_1>",
189
+ "url": "<HOST_1>"
190
+ },
191
+ "bot-two": {
192
+ "botId": "<BOT_ID_2>",
193
+ "secret": "<BOT_SECRET_2>",
194
+ "url": "<HOST_2>"
195
+ }
196
+ }
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ **规则说明:**
203
+
204
+ - `url` 只填主机名(如 `youdu.example.com`),不要带 `https://` 协议前缀或端口
205
+ - 顶层字段作为默认值:账号级未配置的字段(如 `dmPolicy`、`allowFrom`、`groupPolicy`)会继承顶层值
206
+ - `defaultAccount` 指定默认账号;未指定时优先使用 `default` 账号,否则取第一个账号
207
+ - 若顶层同时配置了 `botId`/`secret`/`url`,顶层凭据会作为一个独立的 `default` 账号保留(除非某个命名账号的 botId 与之重复)
208
+ - 账号级可用字段与顶层一致:`botId`、`secret`、`url`、`enabled`、`name`、`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`、`aliases`、`sendThinkingMessage`、`mediaMaxMb`、`mediaLocalRoots`
209
+ - 查看多账号运行状态:`openclaw channels status youdu`
210
+ - 仅配置顶层凭据(不配置 `accounts`)时行为与之前完全一致,即为单账号模式
211
+
212
+ ### 知识库工具授权
213
+
214
+ OpenClaw 的 `coding` 工具 profile 默认不包含插件工具。有度频道的 `botId`、`secret` 和 Host 配置完整后,插件会在 Gateway 启动或配置热加载时,将精确工具名 `youdu_kb` 追加到 `tools.alsoAllow`。有度 Channel 会在当前运行配置确认包含该授权后才建立连接;首次补齐配置时,本轮启动等待 OpenClaw 自动热加载或重启后再连接,因此首条有度消息不会早于工具授权。
215
+
216
+ 插件不会添加 `group:plugins`,也不会修改 `tools.profile`、`tools.allow`、`tools.deny` 或其他工具策略。`youdu_kb` 只在有度 IM 会话中挂载;它在 webchat 等其他频道不可见属于预期行为。用户额外配置的 agent、provider、sandbox 或 deny 策略仍可能进一步过滤该工具。
60
217
 
61
218
  ## 使用
62
219
 
@@ -71,6 +228,58 @@ openclaw status
71
228
  openclaw channels status youdu
72
229
  ```
73
230
 
231
+ ## 主动发送(Outbound)
232
+
233
+ 机器人可以在没有人先说话的情况下主动发消息(定时任务、告警、后台任务结果):
234
+
235
+ ```bash
236
+ # 私聊:数字 userId 直接可用(有度单聊的 chatId 就是对方 userId)
237
+ openclaw message send --channel youdu --to 6463894 --message "早上好"
238
+
239
+ # 私聊:账号名,或该账号的昵称(需该账号先私聊过机器人,插件会记住映射)
240
+ openclaw message send --channel youdu --to lewis.liu --message "早上好"
241
+ openclaw message send --channel youdu --to 刘钟泽 --message "早上好"
242
+
243
+ # 群聊:群名(会话标题 / groups.<id>.title / aliases.groups 里的名字)
244
+ openclaw message send --channel youdu --to 研发讨论组 --message "群公告"
245
+
246
+ # 群聊:群 ID,或显式声明类型
247
+ openclaw message send --channel youdu --to "group:{0798E01E-CD68-42BB-813C-EB51593BB0F5}" --message "群公告"
248
+ ```
249
+
250
+ 目标解析顺序(`src/message-sender.ts` 的 `resolveOutboundTarget`):
251
+
252
+ 1. 去掉 `youdu:` 前缀,以及可选的显式类型前缀 `group:` / `user:`(`single:` 亦可);
253
+ 2. 形如 `{GUID}` 的群 ID 直接按群处理(ID 是权威标识,不做名称解析);
254
+ 3. 配置别名 `channels.youdu.aliases.users`;
255
+ 4. 已学到的私聊账号名 → 该账号的 chatId(单聊);
256
+ 5. 群名(`aliases.groups` → 已学到的会话标题 → `groups.<id>.title`)→ 群聊;
257
+ 6. 已学到的昵称(精确匹配)→ 单聊;
258
+ 7. 纯数字 → 单聊;
259
+ 8. 其余报错,并提示可用写法。
260
+
261
+ **名称撞车怎么办**(群名/昵称在服务端都不保证唯一,因此不做模糊匹配):
262
+
263
+ - 账号名优先于同名昵称:`lewis.liu` 永远解析到本人,不会被别人的同名昵称抢走;
264
+ - 昵称重名(两个「张伟」)→ 报错并列出候选账号名,请改用账号名或数字 userId;
265
+ - 群名重名(两个「项目群」)→ 报错并列出候选群 ID,请改用群 ID 或加 `aliases.groups` 消歧;
266
+ - 只做精确匹配:`刘` 不会匹配 `刘钟泽`。
267
+
268
+ 学习与持久化(`src/target-store.ts`):
269
+
270
+ - 收到私聊消息时记录 `账号名 → chatId` 与昵称;收到群消息时记录群 ID;
271
+ - 消费 `event_callback` 会话事件,把 `data.title` 记为群名(`session_update` 的新标题为空时回退 `oldSession.title`),
272
+ 因此群在 `directory` 里显示为 `群名 (群 ID)`,也能直接按群名发送;
273
+ - 老群(机器人入群前就存在、拿不到会话事件)用 `channels.youdu.groups."<群 ID>".title` 或 `aliases.groups` 兜底;
274
+ - 记录写入 `~/.openclaw/youdu-targets.json`(权限 0600、先写临时文件再 rename、变更后去抖落盘),
275
+ **进程重启后仍然可用**;
276
+ - 账号从配置中移除时会一并清掉该账号的目标;
277
+ - `openclaw channels directory youdu`(`directory.listPeers` / `listGroups`)会列出这些已聊过的联系人与群,
278
+ 方便确认可投递目标。
279
+
280
+ > 注意:`send_msg` 必须带 `chatType`(`single`/`group`)。有度服务端只在 `chatType === 'group'`
281
+ > 时按群会话投递,其余值一律按单聊处理,漏传会把群 ID 当成用户 ID 发成私聊。
282
+
74
283
  ## 消息处理流程
75
284
 
76
285
  1. 插件通过 WebSocket 连接到有度服务
package/dist/index.esm.js CHANGED
@@ -1,7 +1,10 @@
1
- import { youduPlugin } from './src/channel.js';
1
+ import { createYouDuPlugin } from './src/channel.js';
2
2
  import { emptyPluginConfigSchema } from './src/openclaw-compat.js';
3
3
  import { setYouDuRuntime } from './src/runtime.js';
4
4
  import { CHANNEL_ID } from './src/const.js';
5
+ import { youduKbToolFactory } from './src/kb/tool.js';
6
+ import { registerYouDuKbRunContext } from './src/kb/run-context.js';
7
+ import { createYouDuKbToolPolicy } from './src/kb/tool-policy.js';
5
8
 
6
9
  /**
7
10
  * YouDu OpenClaw Plugin - 主入口
@@ -16,7 +19,10 @@ const plugin = {
16
19
  configSchema: emptyPluginConfigSchema(),
17
20
  register(api) {
18
21
  setYouDuRuntime(api.runtime);
19
- api.registerChannel({ plugin: youduPlugin });
22
+ registerYouDuKbRunContext(api);
23
+ const toolPolicy = createYouDuKbToolPolicy(api);
24
+ api.registerChannel({ plugin: createYouDuPlugin(toolPolicy) });
25
+ api.registerTool(youduKbToolFactory, { name: "youdu_kb", optional: false });
20
26
  /** 有度频道系统指令 — 条件→动作格式,便于 LLM 精确遵循 */
21
27
  const YOUDU_SYSTEM_CONTEXT_HINTS = [
22
28
  "## 有度频道输出约束",
@@ -1,9 +1,20 @@
1
1
  import { type ChannelPlugin } from "openclaw/plugin-sdk/core";
2
+ import { monitorYouDuProvider } from './monitor.js';
2
3
  import { type ResolvedYouDuAccount } from './utils.js';
4
+ import type { YouDuKbToolPolicy } from "./kb/tool-policy.js";
3
5
  import type { WsConnectionSnapshot } from "./sdk/types.js";
4
6
  export type YouDuProbeResult = WsConnectionSnapshot & {
5
7
  ok: boolean;
6
8
  status: number;
7
9
  error?: string;
8
10
  };
11
+ export type YouDuChannelLifecycleEvent = {
12
+ type: "gate-start" | "gate-result" | "gate-wait-start" | "gate-wait-abort" | "monitor-start" | "monitor-abort";
13
+ attemptId: string;
14
+ result?: Awaited<ReturnType<YouDuKbToolPolicy["ensureYouDuKbToolPolicy"]>>;
15
+ authorized: boolean;
16
+ profile?: string;
17
+ };
18
+ export type YouDuChannelLifecycleObserver = (event: YouDuChannelLifecycleEvent) => void | Promise<void>;
19
+ export declare function createYouDuPlugin(policy?: YouDuKbToolPolicy, monitor?: typeof monitorYouDuProvider, lifecycleObserver?: YouDuChannelLifecycleObserver): ChannelPlugin<ResolvedYouDuAccount, YouDuProbeResult>;
9
20
  export declare const youduPlugin: ChannelPlugin<ResolvedYouDuAccount, YouDuProbeResult>;