@openclaw/qqbot 2026.5.2 → 2026.5.3-beta.2

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 (203) hide show
  1. package/dist/api.js +646 -0
  2. package/dist/approval-cg0SVahb.js +94 -0
  3. package/dist/channel-N6Y_Rcjp.js +551 -0
  4. package/dist/channel-plugin-api.js +2 -0
  5. package/dist/channel.setup-ByCRAe5H.js +25 -0
  6. package/dist/config-D6545NkC.js +94 -0
  7. package/dist/config-schema-DFcjQw73.js +309 -0
  8. package/dist/exec-approvals-COUsM6wZ.js +138 -0
  9. package/dist/gateway-CmSUJKSt.js +6726 -0
  10. package/dist/handler-runtime-Bqm6N0WG.js +120 -0
  11. package/dist/index.js +29 -0
  12. package/dist/narrowing-BoieBTIU.js +25 -0
  13. package/dist/outbound-BJfhwrPg.js +1357 -0
  14. package/dist/request-context-DXtpwWui.js +921 -0
  15. package/dist/resolve-D_06fV6-.js +284 -0
  16. package/dist/runtime-BJAS3eXW.js +18 -0
  17. package/dist/runtime-api.js +2 -0
  18. package/dist/secret-contract-api.js +56 -0
  19. package/dist/sender-p-B14eLG.js +1987 -0
  20. package/dist/setup-entry.js +15 -0
  21. package/dist/setup-plugin-api.js +2 -0
  22. package/dist/string-normalize-Ci6NM5DE.js +98 -0
  23. package/dist/target-parser-Y0prnrXD.js +245 -0
  24. package/package.json +15 -6
  25. package/api.ts +0 -56
  26. package/channel-plugin-api.ts +0 -1
  27. package/index.ts +0 -29
  28. package/runtime-api.ts +0 -9
  29. package/setup-entry.ts +0 -9
  30. package/setup-plugin-api.ts +0 -3
  31. package/src/bridge/approval/capability.ts +0 -237
  32. package/src/bridge/approval/handler-runtime.ts +0 -204
  33. package/src/bridge/bootstrap.ts +0 -135
  34. package/src/bridge/channel-entry.ts +0 -18
  35. package/src/bridge/commands/framework-context-adapter.ts +0 -60
  36. package/src/bridge/commands/framework-registration.ts +0 -47
  37. package/src/bridge/commands/from-parser.test.ts +0 -86
  38. package/src/bridge/commands/from-parser.ts +0 -60
  39. package/src/bridge/commands/result-dispatcher.ts +0 -76
  40. package/src/bridge/config-shared.ts +0 -132
  41. package/src/bridge/config.ts +0 -111
  42. package/src/bridge/gateway.ts +0 -174
  43. package/src/bridge/logger.ts +0 -31
  44. package/src/bridge/narrowing.ts +0 -31
  45. package/src/bridge/plugin-version.test.ts +0 -146
  46. package/src/bridge/plugin-version.ts +0 -102
  47. package/src/bridge/runtime.ts +0 -25
  48. package/src/bridge/sdk-adapter.ts +0 -131
  49. package/src/bridge/setup/finalize.ts +0 -144
  50. package/src/bridge/setup/surface.ts +0 -34
  51. package/src/bridge/tools/channel.ts +0 -58
  52. package/src/bridge/tools/index.ts +0 -15
  53. package/src/bridge/tools/remind.test.ts +0 -124
  54. package/src/bridge/tools/remind.ts +0 -91
  55. package/src/channel.setup.ts +0 -33
  56. package/src/channel.ts +0 -288
  57. package/src/command-auth.test.ts +0 -62
  58. package/src/config-schema.ts +0 -84
  59. package/src/config.test.ts +0 -364
  60. package/src/engine/access/access-control.test.ts +0 -198
  61. package/src/engine/access/access-control.ts +0 -226
  62. package/src/engine/access/index.ts +0 -16
  63. package/src/engine/access/resolve-policy.test.ts +0 -59
  64. package/src/engine/access/resolve-policy.ts +0 -57
  65. package/src/engine/access/sender-match.test.ts +0 -60
  66. package/src/engine/access/sender-match.ts +0 -55
  67. package/src/engine/access/types.ts +0 -53
  68. package/src/engine/adapter/audio.port.ts +0 -27
  69. package/src/engine/adapter/commands.port.ts +0 -22
  70. package/src/engine/adapter/history.port.ts +0 -52
  71. package/src/engine/adapter/index.ts +0 -139
  72. package/src/engine/adapter/mention-gate.port.ts +0 -50
  73. package/src/engine/adapter/types.ts +0 -38
  74. package/src/engine/api/api-client.ts +0 -212
  75. package/src/engine/api/media-chunked.test.ts +0 -336
  76. package/src/engine/api/media-chunked.ts +0 -622
  77. package/src/engine/api/media.ts +0 -218
  78. package/src/engine/api/messages.ts +0 -293
  79. package/src/engine/api/retry.ts +0 -217
  80. package/src/engine/api/routes.ts +0 -95
  81. package/src/engine/api/token.ts +0 -271
  82. package/src/engine/approval/index.test.ts +0 -22
  83. package/src/engine/approval/index.ts +0 -224
  84. package/src/engine/commands/builtin/log-helpers.ts +0 -319
  85. package/src/engine/commands/builtin/register-all.ts +0 -17
  86. package/src/engine/commands/builtin/register-approve.ts +0 -201
  87. package/src/engine/commands/builtin/register-basic.ts +0 -95
  88. package/src/engine/commands/builtin/register-clear-storage.ts +0 -187
  89. package/src/engine/commands/builtin/register-logs.ts +0 -20
  90. package/src/engine/commands/builtin/register-streaming.ts +0 -137
  91. package/src/engine/commands/builtin/state.ts +0 -31
  92. package/src/engine/commands/slash-command-auth.ts +0 -48
  93. package/src/engine/commands/slash-command-handler.ts +0 -146
  94. package/src/engine/commands/slash-commands-impl.test.ts +0 -8
  95. package/src/engine/commands/slash-commands-impl.ts +0 -61
  96. package/src/engine/commands/slash-commands.ts +0 -199
  97. package/src/engine/config/credential-backup.test.ts +0 -88
  98. package/src/engine/config/credential-backup.ts +0 -107
  99. package/src/engine/config/credentials.ts +0 -76
  100. package/src/engine/config/group.test.ts +0 -234
  101. package/src/engine/config/group.ts +0 -299
  102. package/src/engine/config/resolve.test.ts +0 -152
  103. package/src/engine/config/resolve.ts +0 -283
  104. package/src/engine/config/setup-logic.ts +0 -84
  105. package/src/engine/engine-import-boundary.test.ts +0 -73
  106. package/src/engine/gateway/codec.ts +0 -47
  107. package/src/engine/gateway/constants.ts +0 -117
  108. package/src/engine/gateway/event-dispatcher.ts +0 -177
  109. package/src/engine/gateway/gateway-connection.ts +0 -371
  110. package/src/engine/gateway/gateway.ts +0 -291
  111. package/src/engine/gateway/inbound-attachments.test.ts +0 -126
  112. package/src/engine/gateway/inbound-attachments.ts +0 -360
  113. package/src/engine/gateway/inbound-context.ts +0 -195
  114. package/src/engine/gateway/inbound-pipeline.self-echo.test.ts +0 -218
  115. package/src/engine/gateway/inbound-pipeline.ts +0 -235
  116. package/src/engine/gateway/interaction-handler.ts +0 -220
  117. package/src/engine/gateway/message-queue.test.ts +0 -282
  118. package/src/engine/gateway/message-queue.ts +0 -499
  119. package/src/engine/gateway/outbound-dispatch.test.ts +0 -231
  120. package/src/engine/gateway/outbound-dispatch.ts +0 -575
  121. package/src/engine/gateway/reconnect.ts +0 -199
  122. package/src/engine/gateway/stages/access-stage.ts +0 -132
  123. package/src/engine/gateway/stages/assembly-stage.ts +0 -156
  124. package/src/engine/gateway/stages/content-stage.test.ts +0 -77
  125. package/src/engine/gateway/stages/content-stage.ts +0 -77
  126. package/src/engine/gateway/stages/envelope-stage.test.ts +0 -152
  127. package/src/engine/gateway/stages/envelope-stage.ts +0 -144
  128. package/src/engine/gateway/stages/group-gate-stage.ts +0 -292
  129. package/src/engine/gateway/stages/index.ts +0 -18
  130. package/src/engine/gateway/stages/quote-stage.ts +0 -113
  131. package/src/engine/gateway/stages/refidx-stage.ts +0 -62
  132. package/src/engine/gateway/stages/stub-contexts.ts +0 -116
  133. package/src/engine/gateway/types.ts +0 -264
  134. package/src/engine/gateway/typing-keepalive.ts +0 -79
  135. package/src/engine/group/activation.test.ts +0 -114
  136. package/src/engine/group/activation.ts +0 -147
  137. package/src/engine/group/history.test.ts +0 -314
  138. package/src/engine/group/history.ts +0 -321
  139. package/src/engine/group/mention.test.ts +0 -141
  140. package/src/engine/group/mention.ts +0 -197
  141. package/src/engine/group/message-gating.test.ts +0 -188
  142. package/src/engine/group/message-gating.ts +0 -216
  143. package/src/engine/messaging/decode-media-path.ts +0 -82
  144. package/src/engine/messaging/media-source.ts +0 -215
  145. package/src/engine/messaging/media-type-detect.ts +0 -37
  146. package/src/engine/messaging/outbound-audio-port.ts +0 -38
  147. package/src/engine/messaging/outbound-deliver.ts +0 -810
  148. package/src/engine/messaging/outbound-media-send.ts +0 -702
  149. package/src/engine/messaging/outbound-reply.ts +0 -27
  150. package/src/engine/messaging/outbound-result-helpers.ts +0 -54
  151. package/src/engine/messaging/outbound-types.ts +0 -45
  152. package/src/engine/messaging/outbound.ts +0 -485
  153. package/src/engine/messaging/reply-dispatcher.ts +0 -597
  154. package/src/engine/messaging/reply-limiter.ts +0 -164
  155. package/src/engine/messaging/sender.ts +0 -729
  156. package/src/engine/messaging/streaming-c2c.ts +0 -1192
  157. package/src/engine/messaging/streaming-media-send.ts +0 -544
  158. package/src/engine/messaging/target-parser.ts +0 -104
  159. package/src/engine/ref/format-message-ref.ts +0 -142
  160. package/src/engine/ref/format-ref-entry.test.ts +0 -60
  161. package/src/engine/ref/format-ref-entry.ts +0 -27
  162. package/src/engine/ref/store.ts +0 -208
  163. package/src/engine/ref/types.ts +0 -27
  164. package/src/engine/session/known-users.ts +0 -137
  165. package/src/engine/session/session-store.ts +0 -204
  166. package/src/engine/tools/channel-api.ts +0 -244
  167. package/src/engine/tools/remind-logic.test.ts +0 -280
  168. package/src/engine/tools/remind-logic.ts +0 -377
  169. package/src/engine/types.ts +0 -313
  170. package/src/engine/utils/attachment-tags.test.ts +0 -186
  171. package/src/engine/utils/attachment-tags.ts +0 -174
  172. package/src/engine/utils/audio.test.ts +0 -250
  173. package/src/engine/utils/audio.ts +0 -585
  174. package/src/engine/utils/data-paths.ts +0 -38
  175. package/src/engine/utils/diagnostics.ts +0 -109
  176. package/src/engine/utils/file-utils.test.ts +0 -72
  177. package/src/engine/utils/file-utils.ts +0 -225
  178. package/src/engine/utils/format.test.ts +0 -68
  179. package/src/engine/utils/format.ts +0 -70
  180. package/src/engine/utils/image-size.test.ts +0 -158
  181. package/src/engine/utils/image-size.ts +0 -249
  182. package/src/engine/utils/log.test.ts +0 -28
  183. package/src/engine/utils/log.ts +0 -61
  184. package/src/engine/utils/media-tags.test.ts +0 -32
  185. package/src/engine/utils/media-tags.ts +0 -177
  186. package/src/engine/utils/payload.test.ts +0 -68
  187. package/src/engine/utils/payload.ts +0 -145
  188. package/src/engine/utils/platform-storage-laziness.test.ts +0 -63
  189. package/src/engine/utils/platform.test.ts +0 -148
  190. package/src/engine/utils/platform.ts +0 -343
  191. package/src/engine/utils/request-context.ts +0 -60
  192. package/src/engine/utils/string-normalize.ts +0 -91
  193. package/src/engine/utils/stt.test.ts +0 -104
  194. package/src/engine/utils/stt.ts +0 -100
  195. package/src/engine/utils/text-parsing.test.ts +0 -29
  196. package/src/engine/utils/text-parsing.ts +0 -155
  197. package/src/engine/utils/upload-cache.ts +0 -96
  198. package/src/engine/utils/voice-text.ts +0 -15
  199. package/src/exec-approvals.ts +0 -218
  200. package/src/manifest-schema.test.ts +0 -56
  201. package/src/qqbot-test-support.ts +0 -29
  202. package/src/types.ts +0 -210
  203. package/tsconfig.json +0 -16
@@ -0,0 +1,284 @@
1
+ import { a as normalizeStringifiedOptionalString, c as getPlatformAdapter, d as registerPlatformAdapterFactory, l as hasPlatformAdapter, o as readStringField, r as normalizeOptionalLowercaseString, t as asOptionalObjectRecord, u as registerPlatformAdapter } from "./string-normalize-Ci6NM5DE.js";
2
+ import { hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
3
+ import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
4
+ //#region extensions/qqbot/src/bridge/logger.ts
5
+ let _logger = null;
6
+ /** Register the framework logger. Called once in startGateway(). */
7
+ function setBridgeLogger(logger) {
8
+ _logger = logger;
9
+ }
10
+ /** Get the bridge logger. Falls back to console if not yet registered. */
11
+ function getBridgeLogger() {
12
+ return _logger ?? {
13
+ info: (msg) => console.log(msg),
14
+ error: (msg) => console.error(msg),
15
+ debug: (msg) => console.log(msg)
16
+ };
17
+ }
18
+ //#endregion
19
+ //#region extensions/qqbot/src/bridge/bootstrap.ts
20
+ /**
21
+ * Bootstrap the PlatformAdapter for the built-in version.
22
+ *
23
+ * ## Design
24
+ *
25
+ * The adapter is registered via two complementary mechanisms:
26
+ *
27
+ * 1. **Factory registration** (`registerPlatformAdapterFactory`) — a lightweight
28
+ * callback stored in `adapter/index.ts` that is invoked lazily by
29
+ * `getPlatformAdapter()` on first access. This guarantees the adapter is
30
+ * available regardless of module evaluation order or bundler chunk splitting.
31
+ *
32
+ * 2. **Eager side-effect** (`ensurePlatformAdapter()`) — called at module
33
+ * evaluation time when `channel.ts` imports this file. Provides the adapter
34
+ * immediately for code that runs synchronously during startup.
35
+ *
36
+ * Heavy async-only dependencies (`media-runtime`, `config-runtime`,
37
+ * `approval-gateway-runtime`) are lazy-imported inside each async method body
38
+ * so that this module evaluates with minimal overhead.
39
+ *
40
+ * Synchronous dependencies (`secret-input`, `temp-path`) are imported
41
+ * statically at the top level so they work reliably in both production and
42
+ * vitest (which resolves bare specifiers via `resolve.alias`, not Node CJS).
43
+ */
44
+ function createBuiltinAdapter() {
45
+ return {
46
+ async validateRemoteUrl(_url, _options) {},
47
+ async resolveSecret(value) {
48
+ if (typeof value === "string") return value || void 0;
49
+ },
50
+ async downloadFile(url, destDir, filename) {
51
+ const { fetchRemoteMedia } = await import("openclaw/plugin-sdk/media-runtime");
52
+ const result = await fetchRemoteMedia({
53
+ url,
54
+ filePathHint: filename
55
+ });
56
+ const fs = await import("node:fs");
57
+ const path = await import("node:path");
58
+ if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
59
+ const destPath = path.join(destDir, filename ?? "download");
60
+ fs.writeFileSync(destPath, result.buffer);
61
+ return destPath;
62
+ },
63
+ async fetchMedia(options) {
64
+ const { fetchRemoteMedia } = await import("openclaw/plugin-sdk/media-runtime");
65
+ const result = await fetchRemoteMedia({
66
+ url: options.url,
67
+ filePathHint: options.filePathHint,
68
+ maxBytes: options.maxBytes,
69
+ maxRedirects: options.maxRedirects,
70
+ ssrfPolicy: options.ssrfPolicy,
71
+ requestInit: options.requestInit
72
+ });
73
+ return {
74
+ buffer: result.buffer,
75
+ fileName: result.fileName
76
+ };
77
+ },
78
+ getTempDir() {
79
+ return resolvePreferredOpenClawTmpDir();
80
+ },
81
+ hasConfiguredSecret(value) {
82
+ return hasConfiguredSecretInput(value);
83
+ },
84
+ normalizeSecretInputString(value) {
85
+ return normalizeSecretInputString(value) ?? void 0;
86
+ },
87
+ resolveSecretInputString(params) {
88
+ return normalizeResolvedSecretInputString(params) ?? void 0;
89
+ },
90
+ async resolveApproval(approvalId, decision) {
91
+ try {
92
+ const { getRuntimeConfig } = await import("openclaw/plugin-sdk/runtime-config-snapshot");
93
+ const { resolveApprovalOverGateway } = await import("openclaw/plugin-sdk/approval-gateway-runtime");
94
+ await resolveApprovalOverGateway({
95
+ cfg: getRuntimeConfig(),
96
+ approvalId,
97
+ decision,
98
+ clientDisplayName: "QQBot Approval Handler"
99
+ });
100
+ return true;
101
+ } catch (err) {
102
+ getBridgeLogger().error(`[qqbot] resolveApproval failed: ${String(err)}`);
103
+ return false;
104
+ }
105
+ }
106
+ };
107
+ }
108
+ /**
109
+ * Ensure the built-in PlatformAdapter is registered.
110
+ *
111
+ * Safe to call multiple times — only registers on the first invocation.
112
+ * Exported for backward compatibility with code that calls it explicitly.
113
+ */
114
+ function ensurePlatformAdapter() {
115
+ if (!hasPlatformAdapter()) registerPlatformAdapter(createBuiltinAdapter());
116
+ }
117
+ registerPlatformAdapterFactory(createBuiltinAdapter);
118
+ ensurePlatformAdapter();
119
+ //#endregion
120
+ //#region extensions/qqbot/src/engine/config/resolve.ts
121
+ /**
122
+ * QQBot config resolution (pure logic layer).
123
+ * QQBot 配置解析(纯逻辑层)。
124
+ *
125
+ * Resolves account IDs, default account selection, and base account
126
+ * info from raw config objects. Secret/credential resolution is
127
+ * intentionally left to the outer layer (src/bridge/config.ts) so that
128
+ * this module stays framework-agnostic and self-contained.
129
+ */
130
+ /**
131
+ * Default account ID, used for the unnamed top-level account.
132
+ * 默认账号 ID,用于顶层配置中未命名的账号。
133
+ */
134
+ const DEFAULT_ACCOUNT_ID = "default";
135
+ function normalizeAppId(raw) {
136
+ if (typeof raw === "string") return raw.trim();
137
+ if (typeof raw === "number") return String(raw);
138
+ return "";
139
+ }
140
+ function normalizeAccountConfig(account) {
141
+ if (!account) return {};
142
+ const audioPolicy = asOptionalObjectRecord(account.audioFormatPolicy);
143
+ return {
144
+ ...account,
145
+ ...audioPolicy ? { audioFormatPolicy: { ...audioPolicy } } : {}
146
+ };
147
+ }
148
+ function readQQBotSection(cfg) {
149
+ return asOptionalObjectRecord(asOptionalObjectRecord(cfg.channels)?.qqbot);
150
+ }
151
+ /**
152
+ * List all configured QQBot account IDs.
153
+ * 列出所有已配置的 QQBot 账号 ID。
154
+ */
155
+ function listAccountIds(cfg) {
156
+ const ids = /* @__PURE__ */ new Set();
157
+ const qqbot = readQQBotSection(cfg);
158
+ if (qqbot?.appId || process.env.QQBOT_APP_ID) ids.add(DEFAULT_ACCOUNT_ID);
159
+ if (qqbot?.accounts) {
160
+ for (const accountId of Object.keys(qqbot.accounts)) if (qqbot.accounts[accountId]?.appId) ids.add(accountId);
161
+ }
162
+ return Array.from(ids);
163
+ }
164
+ /**
165
+ * Resolve the default QQBot account ID.
166
+ * 解析默认 QQBot 账号 ID(优先级:defaultAccount > 顶层 appId > 第一个命名账号)。
167
+ */
168
+ function resolveDefaultAccountId(cfg) {
169
+ const qqbot = readQQBotSection(cfg);
170
+ const configuredDefaultAccountId = normalizeOptionalLowercaseString(qqbot?.defaultAccount);
171
+ if (configuredDefaultAccountId && (configuredDefaultAccountId === "default" || Boolean(qqbot?.accounts?.[configuredDefaultAccountId]?.appId))) return configuredDefaultAccountId;
172
+ if (qqbot?.appId || process.env.QQBOT_APP_ID) return DEFAULT_ACCOUNT_ID;
173
+ if (qqbot?.accounts) {
174
+ const ids = Object.keys(qqbot.accounts);
175
+ if (ids.length > 0) return ids[0];
176
+ }
177
+ return DEFAULT_ACCOUNT_ID;
178
+ }
179
+ /**
180
+ * Resolve base account info (without credentials).
181
+ * 解析账号基础信息(不含凭证)。
182
+ *
183
+ * Resolves everything except Secret/credential fields. The outer
184
+ * config.ts layer calls this and adds Secret handling on top.
185
+ */
186
+ function resolveAccountBase(cfg, accountId) {
187
+ const resolvedAccountId = accountId ?? resolveDefaultAccountId(cfg);
188
+ const qqbot = readQQBotSection(cfg);
189
+ let accountConfig = {};
190
+ let appId = "";
191
+ if (resolvedAccountId === "default") {
192
+ accountConfig = normalizeAccountConfig(asOptionalObjectRecord(qqbot));
193
+ appId = normalizeAppId(qqbot?.appId);
194
+ } else {
195
+ const account = qqbot?.accounts?.[resolvedAccountId];
196
+ accountConfig = normalizeAccountConfig(asOptionalObjectRecord(account));
197
+ appId = normalizeAppId(asOptionalObjectRecord(account)?.appId);
198
+ }
199
+ if (!appId && process.env.QQBOT_APP_ID && resolvedAccountId === "default") appId = normalizeAppId(process.env.QQBOT_APP_ID);
200
+ return {
201
+ accountId: resolvedAccountId,
202
+ name: readStringField(accountConfig, "name"),
203
+ enabled: accountConfig.enabled !== false,
204
+ appId,
205
+ systemPrompt: readStringField(accountConfig, "systemPrompt"),
206
+ markdownSupport: accountConfig.markdownSupport !== false,
207
+ config: accountConfig
208
+ };
209
+ }
210
+ /** Apply account config updates into a raw config object. */
211
+ function applyAccountConfig(cfg, accountId, input) {
212
+ const next = { ...cfg };
213
+ const channels = asOptionalObjectRecord(cfg.channels) ?? {};
214
+ const existingQQBot = asOptionalObjectRecord(channels.qqbot) ?? {};
215
+ if (accountId === "default") {
216
+ const allowFrom = existingQQBot.allowFrom ?? ["*"];
217
+ next.channels = {
218
+ ...channels,
219
+ qqbot: {
220
+ ...existingQQBot,
221
+ enabled: true,
222
+ allowFrom,
223
+ ...input.appId ? { appId: input.appId } : {},
224
+ ...input.clientSecret ? {
225
+ clientSecret: input.clientSecret,
226
+ clientSecretFile: void 0
227
+ } : input.clientSecretFile ? {
228
+ clientSecretFile: input.clientSecretFile,
229
+ clientSecret: void 0
230
+ } : {},
231
+ ...input.name ? { name: input.name } : {}
232
+ }
233
+ };
234
+ } else {
235
+ const accounts = existingQQBot.accounts ?? {};
236
+ const existingAccount = accounts[accountId] ?? {};
237
+ const allowFrom = existingAccount.allowFrom ?? ["*"];
238
+ next.channels = {
239
+ ...channels,
240
+ qqbot: {
241
+ ...existingQQBot,
242
+ enabled: true,
243
+ accounts: {
244
+ ...accounts,
245
+ [accountId]: {
246
+ ...existingAccount,
247
+ enabled: true,
248
+ allowFrom,
249
+ ...input.appId ? { appId: input.appId } : {},
250
+ ...input.clientSecret ? {
251
+ clientSecret: input.clientSecret,
252
+ clientSecretFile: void 0
253
+ } : input.clientSecretFile ? {
254
+ clientSecretFile: input.clientSecretFile,
255
+ clientSecret: void 0
256
+ } : {},
257
+ ...input.name ? { name: input.name } : {}
258
+ }
259
+ }
260
+ }
261
+ };
262
+ }
263
+ return next;
264
+ }
265
+ /** Check whether a QQBot account has been fully configured. */
266
+ function isAccountConfigured(account) {
267
+ return Boolean(account?.appId && (Boolean(account?.clientSecret) || getPlatformAdapter().hasConfiguredSecret(account?.config?.clientSecret) || Boolean(account?.config?.clientSecretFile?.trim())));
268
+ }
269
+ /** Build a summary description of an account. */
270
+ function describeAccount(account) {
271
+ return {
272
+ accountId: account?.accountId ?? "default",
273
+ name: account?.name,
274
+ enabled: account?.enabled ?? false,
275
+ configured: isAccountConfigured(account),
276
+ tokenSource: account?.secretSource
277
+ };
278
+ }
279
+ /** Normalize allowFrom entries into uppercase strings without the qqbot: prefix. */
280
+ function formatAllowFrom(allowFrom) {
281
+ return (allowFrom ?? []).map((entry) => normalizeStringifiedOptionalString(entry)).filter((entry) => Boolean(entry)).map((entry) => entry.replace(/^qqbot:/i, "")).map((entry) => entry.toUpperCase());
282
+ }
283
+ //#endregion
284
+ export { isAccountConfigured as a, resolveDefaultAccountId as c, setBridgeLogger as d, formatAllowFrom as i, ensurePlatformAdapter as l, applyAccountConfig as n, listAccountIds as o, describeAccount as r, resolveAccountBase as s, DEFAULT_ACCOUNT_ID as t, getBridgeLogger as u };
@@ -0,0 +1,18 @@
1
+ import { _ as setOpenClawVersion } from "./sender-p-B14eLG.js";
2
+ import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
3
+ //#region extensions/qqbot/src/bridge/runtime.ts
4
+ const { setRuntime: _setRuntime, getRuntime: getQQBotRuntime } = createPluginRuntimeStore({
5
+ pluginId: "qqbot",
6
+ errorMessage: "QQBot runtime not initialized"
7
+ });
8
+ /** Set the QQBot runtime and inject the framework version into the User-Agent. */
9
+ function setQQBotRuntime(runtime) {
10
+ _setRuntime(runtime);
11
+ setOpenClawVersion(runtime.version);
12
+ }
13
+ /** Type-narrowed getter for engine/ modules that need GatewayPluginRuntime. */
14
+ function getQQBotRuntimeForEngine() {
15
+ return getQQBotRuntime();
16
+ }
17
+ //#endregion
18
+ export { getQQBotRuntimeForEngine as n, setQQBotRuntime as r, getQQBotRuntime as t };
@@ -0,0 +1,2 @@
1
+ import { r as setQQBotRuntime, t as getQQBotRuntime } from "./runtime-BJAS3eXW.js";
2
+ export { getQQBotRuntime, setQQBotRuntime };
@@ -0,0 +1,56 @@
1
+ import { collectConditionalChannelFieldAssignments, getChannelSurface, hasConfiguredSecretInputValue } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
2
+ //#region extensions/qqbot/src/secret-contract.ts
3
+ const DEFAULT_ACCOUNT_ID = "default";
4
+ const secretTargetRegistryEntries = [{
5
+ id: "channels.qqbot.accounts.*.clientSecret",
6
+ targetType: "channels.qqbot.accounts.*.clientSecret",
7
+ configFile: "openclaw.json",
8
+ pathPattern: "channels.qqbot.accounts.*.clientSecret",
9
+ secretShape: "secret_input",
10
+ expectedResolvedValue: "string",
11
+ includeInPlan: true,
12
+ includeInConfigure: true,
13
+ includeInAudit: true
14
+ }, {
15
+ id: "channels.qqbot.clientSecret",
16
+ targetType: "channels.qqbot.clientSecret",
17
+ configFile: "openclaw.json",
18
+ pathPattern: "channels.qqbot.clientSecret",
19
+ secretShape: "secret_input",
20
+ expectedResolvedValue: "string",
21
+ includeInPlan: true,
22
+ includeInConfigure: true,
23
+ includeInAudit: true
24
+ }];
25
+ function hasTopLevelAppId(qqbot) {
26
+ if (typeof qqbot.appId === "string") return qqbot.appId.trim().length > 0;
27
+ return typeof qqbot.appId === "number";
28
+ }
29
+ function collectRuntimeConfigAssignments(params) {
30
+ const resolved = getChannelSurface(params.config, "qqbot");
31
+ if (!resolved) return;
32
+ const { channel: qqbot, surface } = resolved;
33
+ const hasExplicitDefaultAccount = surface.accounts.some(({ accountId }) => accountId === DEFAULT_ACCOUNT_ID);
34
+ collectConditionalChannelFieldAssignments({
35
+ channelKey: "qqbot",
36
+ field: "clientSecret",
37
+ channel: qqbot,
38
+ surface,
39
+ defaults: params.defaults,
40
+ context: params.context,
41
+ topLevelActiveWithoutAccounts: true,
42
+ topLevelInheritedAccountActive: ({ accountId, account, enabled }) => {
43
+ if (accountId === DEFAULT_ACCOUNT_ID) return enabled && !hasConfiguredSecretInputValue(account.clientSecret, params.defaults);
44
+ return !hasExplicitDefaultAccount && hasTopLevelAppId(qqbot);
45
+ },
46
+ accountActive: ({ enabled }) => enabled,
47
+ topInactiveReason: "no enabled QQ Bot default surface uses this top-level clientSecret.",
48
+ accountInactiveReason: "QQ Bot account is disabled."
49
+ });
50
+ }
51
+ const channelSecrets = {
52
+ secretTargetRegistryEntries,
53
+ collectRuntimeConfigAssignments
54
+ };
55
+ //#endregion
56
+ export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };