@openclaw/qqbot 2026.5.18-beta.1 → 2026.5.19-alpha.1

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/api.js CHANGED
@@ -1,9 +1,9 @@
1
- import { C as recordMessageReply, E as setOutboundAudioPort, S as getMessageReplyStats, T as OUTBOUND_ERROR_CODES, _ as sendVoice, a as sendText, b as checkMessageReplyLimit, d as buildMediaTarget, f as parseTarget, g as sendVideoMsg, h as sendPhoto, i as sendProactiveMessage, m as sendDocument, n as sendCronMessage, p as resolveOutboundMediaPath, r as sendMedia, v as resolveUserFacingMediaError, w as DEFAULT_MEDIA_SEND_ERROR, x as getMessageReplyConfig, y as MESSAGE_REPLY_LIMIT } from "./outbound-CiZ7556q.js";
2
- import { c as listQQBotAccountIds, l as resolveDefaultQQBotAccountId, o as DEFAULT_ACCOUNT_ID, s as applyQQBotAccountConfig, u as resolveQQBotAccount } from "./config-schema-BE5YP0NG.js";
3
- import { t as qqbotPlugin } from "./channel-Dp4lpH09.js";
4
- import { C as debugError, l as getAccessToken, w as debugLog, z as formatErrorMessage } from "./runtime-BfsyXEkf.js";
5
- import { t as qqbotSetupPlugin } from "./channel.setup-D_8Ryfln.js";
6
- import { r as getFrameworkCommands, t as getRequestContext } from "./request-context-qmCvaQlt.js";
1
+ import { C as recordMessageReply, E as setOutboundAudioPort, S as getMessageReplyStats, T as OUTBOUND_ERROR_CODES, _ as sendVoice, a as sendText, b as checkMessageReplyLimit, d as buildMediaTarget, f as parseTarget, g as sendVideoMsg, h as sendPhoto, i as sendProactiveMessage, m as sendDocument, n as sendCronMessage, p as resolveOutboundMediaPath, r as sendMedia, v as resolveUserFacingMediaError, w as DEFAULT_MEDIA_SEND_ERROR, x as getMessageReplyConfig, y as MESSAGE_REPLY_LIMIT } from "./outbound-DE6E79k5.js";
2
+ import { c as listQQBotAccountIds, l as resolveDefaultQQBotAccountId, o as DEFAULT_ACCOUNT_ID, s as applyQQBotAccountConfig, u as resolveQQBotAccount } from "./config-schema-S5Xdt1tV.js";
3
+ import { t as qqbotPlugin } from "./channel-CD_RD3Ro.js";
4
+ import { C as debugError, l as getAccessToken, w as debugLog, z as formatErrorMessage } from "./runtime-Dcl6gcEg.js";
5
+ import { t as qqbotSetupPlugin } from "./channel.setup-t_t2xa93.js";
6
+ import { r as getFrameworkCommands, t as getRequestContext } from "./request-context-B2yIu7CE.js";
7
7
  import { callGatewayTool } from "openclaw/plugin-sdk/agent-harness-runtime";
8
8
  //#region extensions/qqbot/src/engine/tools/channel-api.ts
9
9
  /**
@@ -1,6 +1,6 @@
1
- import { c as getPlatformAdapter, t as asOptionalObjectRecord } from "./string-normalize-C46CS-F1.js";
2
- import { a as qqbotSetupAdapterShared, c as listQQBotAccountIds, i as qqbotMeta, m as getBridgeLogger, n as qqbotSetupWizard, o as DEFAULT_ACCOUNT_ID$1, p as ensurePlatformAdapter, r as qqbotConfigAdapter, s as applyQQBotAccountConfig, t as qqbotChannelConfigSchema, u as resolveQQBotAccount } from "./config-schema-BE5YP0NG.js";
3
- import { T as debugWarn, t as getQQBotRuntime, w as debugLog, z as formatErrorMessage } from "./runtime-BfsyXEkf.js";
1
+ import { c as getPlatformAdapter, t as asOptionalObjectRecord } from "./string-normalize-DKS36VHd.js";
2
+ import { a as qqbotSetupAdapterShared, c as listQQBotAccountIds, i as qqbotMeta, m as getBridgeLogger, n as qqbotSetupWizard, o as DEFAULT_ACCOUNT_ID$1, p as ensurePlatformAdapter, r as qqbotConfigAdapter, s as applyQQBotAccountConfig, t as qqbotChannelConfigSchema, u as resolveQQBotAccount } from "./config-schema-S5Xdt1tV.js";
3
+ import { T as debugWarn, t as getQQBotRuntime, w as debugLog, z as formatErrorMessage } from "./runtime-Dcl6gcEg.js";
4
4
  import { getExecApprovalReplyMetadata } from "openclaw/plugin-sdk/approval-runtime";
5
5
  import { createMessageReceiptFromOutboundResults, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-message";
6
6
  import { createChannelApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
@@ -374,16 +374,16 @@ function createQQBotApprovalCapability() {
374
374
  },
375
375
  load: async () => {
376
376
  ensurePlatformAdapter();
377
- return (await import("./handler-runtime-861iuTRE.js")).qqbotApprovalNativeRuntime;
377
+ return (await import("./handler-runtime-DUd04TKq.js")).qqbotApprovalNativeRuntime;
378
378
  }
379
379
  })
380
380
  });
381
381
  }
382
382
  const qqbotApprovalCapability = createQQBotApprovalCapability();
383
- let _cachedCapability;
383
+ let cachedCapability;
384
384
  function getQQBotApprovalCapability() {
385
- _cachedCapability ??= qqbotApprovalCapability;
386
- return _cachedCapability;
385
+ cachedCapability ??= qqbotApprovalCapability;
386
+ return cachedCapability;
387
387
  }
388
388
  //#endregion
389
389
  //#region extensions/qqbot/src/bridge/narrowing.ts
@@ -480,20 +480,20 @@ function isWindows() {
480
480
  function getTempDir() {
481
481
  return getPlatformAdapter().getTempDir();
482
482
  }
483
- let _silkWasmAvailable = null;
483
+ let silkWasmAvailable = null;
484
484
  /** Check whether silk-wasm can run in the current environment. */
485
485
  async function checkSilkWasmAvailable() {
486
- if (_silkWasmAvailable !== null) return _silkWasmAvailable;
486
+ if (silkWasmAvailable !== null) return silkWasmAvailable;
487
487
  try {
488
488
  const { isSilk } = await import("silk-wasm");
489
489
  isSilk(new Uint8Array(0));
490
- _silkWasmAvailable = true;
490
+ silkWasmAvailable = true;
491
491
  debugLog("[platform] silk-wasm: available");
492
492
  } catch (err) {
493
- _silkWasmAvailable = false;
493
+ silkWasmAvailable = false;
494
494
  debugWarn(`[platform] silk-wasm: NOT available (${formatErrorMessage(err)})`);
495
495
  }
496
- return _silkWasmAvailable;
496
+ return silkWasmAvailable;
497
497
  }
498
498
  /** Expand `~` to the current user's home directory. */
499
499
  function expandTilde(p) {
@@ -826,7 +826,7 @@ function looksLikeQQBotTarget(id) {
826
826
  //#region extensions/qqbot/src/channel.ts
827
827
  let gatewayModulePromise;
828
828
  function loadGatewayModule() {
829
- gatewayModulePromise ??= import("./gateway-DJ8IM_ty.js");
829
+ gatewayModulePromise ??= import("./gateway-C5NbXHnt.js");
830
830
  return gatewayModulePromise;
831
831
  }
832
832
  function createQQBotSendReceipt(params) {
@@ -844,7 +844,7 @@ function createQQBotSendReceipt(params) {
844
844
  async function sendQQBotText(params) {
845
845
  await loadGatewayModule();
846
846
  const account = resolveQQBotAccount(params.cfg, params.accountId);
847
- const { sendText } = await import("./outbound-CiZ7556q.js").then((n) => n.t);
847
+ const { sendText } = await import("./outbound-DE6E79k5.js").then((n) => n.t);
848
848
  const result = await sendText({
849
849
  to: params.to,
850
850
  text: params.text,
@@ -866,7 +866,7 @@ async function sendQQBotText(params) {
866
866
  async function sendQQBotMedia(params) {
867
867
  await loadGatewayModule();
868
868
  const account = resolveQQBotAccount(params.cfg, params.accountId);
869
- const { sendMedia } = await import("./outbound-CiZ7556q.js").then((n) => n.t);
869
+ const { sendMedia } = await import("./outbound-DE6E79k5.js").then((n) => n.t);
870
870
  const result = await sendMedia({
871
871
  to: params.to,
872
872
  text: params.text ?? "",
@@ -1,2 +1,2 @@
1
- import { t as qqbotPlugin } from "./channel-Dp4lpH09.js";
1
+ import { t as qqbotPlugin } from "./channel-CD_RD3Ro.js";
2
2
  export { qqbotPlugin };
@@ -1,4 +1,4 @@
1
- import { a as qqbotSetupAdapterShared, i as qqbotMeta, n as qqbotSetupWizard, r as qqbotConfigAdapter, t as qqbotChannelConfigSchema } from "./config-schema-BE5YP0NG.js";
1
+ import { a as qqbotSetupAdapterShared, i as qqbotMeta, n as qqbotSetupWizard, r as qqbotConfigAdapter, t as qqbotChannelConfigSchema } from "./config-schema-S5Xdt1tV.js";
2
2
  //#region extensions/qqbot/src/channel.setup.ts
3
3
  /**
4
4
  * Setup-only QQBot plugin — lightweight subset used during `openclaw onboard`
@@ -1,4 +1,4 @@
1
- import { a as normalizeStringifiedOptionalString, c as getPlatformAdapter, d as registerPlatformAdapterFactory, l as hasPlatformAdapter, n as normalizeLowercaseStringOrEmpty, o as readStringField, r as normalizeOptionalLowercaseString, t as asOptionalObjectRecord, u as registerPlatformAdapter } from "./string-normalize-C46CS-F1.js";
1
+ import { a as normalizeStringifiedOptionalString, c as getPlatformAdapter, d as registerPlatformAdapterFactory, l as hasPlatformAdapter, n as normalizeLowercaseStringOrEmpty, o as readStringField, r as normalizeOptionalLowercaseString, t as asOptionalObjectRecord, u as registerPlatformAdapter } from "./string-normalize-DKS36VHd.js";
2
2
  import { buildSecretInputSchema, coerceSecretRef, hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
3
3
  import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
4
4
  import fs from "node:fs";
@@ -9,14 +9,14 @@ import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
9
9
  import { AllowFromListSchema, buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
10
10
  import { z } from "zod";
11
11
  //#region extensions/qqbot/src/bridge/logger.ts
12
- let _logger = null;
12
+ let loggerInstance = null;
13
13
  /** Register the framework logger. Called once in startGateway(). */
14
14
  function setBridgeLogger(logger) {
15
- _logger = logger;
15
+ loggerInstance = logger;
16
16
  }
17
17
  /** Get the bridge logger. Falls back to console if not yet registered. */
18
18
  function getBridgeLogger() {
19
- return _logger ?? {
19
+ return loggerInstance ?? {
20
20
  info: (msg) => console.log(msg),
21
21
  error: (msg) => console.error(msg),
22
22
  debug: (msg) => console.log(msg)
@@ -1,9 +1,9 @@
1
- import { E as setOutboundAudioPort, _ as sendVoice, c as isMediaPayload, g as sendVideoMsg, h as sendPhoto, l as parseQQBotPayload, m as sendDocument, o as encodePayloadForCron, r as sendMedia, s as isCronReminderPayload, u as normalizeMediaTags, v as resolveUserFacingMediaError, w as DEFAULT_MEDIA_SEND_ERROR } from "./outbound-CiZ7556q.js";
2
- import { c as getPlatformAdapter, i as normalizeOptionalString, n as normalizeLowercaseStringOrEmpty, o as readStringField, s as sanitizeFileName, t as asOptionalObjectRecord } from "./string-normalize-C46CS-F1.js";
3
- import { f as resolveAccountBase, h as setBridgeLogger, p as ensurePlatformAdapter } from "./config-schema-BE5YP0NG.js";
4
- import { C as parseApprovalButtonData, a as getQQBotDataDir, d as isWindows, f as normalizePath$1, h as authorizeQQBotApprovalAction, i as getHomeDir, l as getTempDir, m as toGatewayAccount, o as getQQBotDataPath, p as resolveQQBotPayloadLocalFilePath, r as checkSilkWasmAvailable, s as getQQBotMediaDir, u as isLocalPath } from "./channel-Dp4lpH09.js";
5
- import { B as StreamContentType, C as debugError, D as getNextMsgSeq, F as getImageMimeType, H as StreamInputState, I as getMaxUploadSize, N as formatFileSize, R as formatDuration, S as withTokenRetry, T as debugWarn, V as StreamInputMode, _ as sendInputNotify, a as acknowledgeInteraction, b as startBackgroundTokenRefresh, c as createRawInputNotifyFn, d as getMessageApi, f as getPluginUserAgent, g as registerAccount, h as onMessageSent, i as accountToCreds, j as downloadFile, k as openLocalFile, l as getAccessToken, m as initSender, n as getQQBotRuntimeForEngine, o as buildDeliveryTarget, p as initApiConfig, s as clearTokenCache, t as getQQBotRuntime, u as getGatewayUrl, v as sendMedia$1, w as debugLog, x as stopBackgroundTokenRefresh, y as sendText, z as formatErrorMessage } from "./runtime-BfsyXEkf.js";
6
- import { a as getPluginVersion, i as getFrameworkVersion, n as runWithRequestContext, o as initCommands, s as matchSlashCommand } from "./request-context-qmCvaQlt.js";
1
+ import { E as setOutboundAudioPort, _ as sendVoice, c as isMediaPayload, g as sendVideoMsg, h as sendPhoto, l as parseQQBotPayload, m as sendDocument, o as encodePayloadForCron, r as sendMedia, s as isCronReminderPayload, u as normalizeMediaTags, v as resolveUserFacingMediaError, w as DEFAULT_MEDIA_SEND_ERROR } from "./outbound-DE6E79k5.js";
2
+ import { c as getPlatformAdapter, i as normalizeOptionalString, n as normalizeLowercaseStringOrEmpty, o as readStringField, s as sanitizeFileName, t as asOptionalObjectRecord } from "./string-normalize-DKS36VHd.js";
3
+ import { f as resolveAccountBase, h as setBridgeLogger, p as ensurePlatformAdapter } from "./config-schema-S5Xdt1tV.js";
4
+ import { C as parseApprovalButtonData, a as getQQBotDataDir, d as isWindows, f as normalizePath$1, h as authorizeQQBotApprovalAction, i as getHomeDir, l as getTempDir, m as toGatewayAccount, o as getQQBotDataPath, p as resolveQQBotPayloadLocalFilePath, r as checkSilkWasmAvailable, s as getQQBotMediaDir, u as isLocalPath } from "./channel-CD_RD3Ro.js";
5
+ import { B as StreamContentType, C as debugError, D as getNextMsgSeq, F as getImageMimeType, H as StreamInputState, I as getMaxUploadSize, N as formatFileSize, R as formatDuration, S as withTokenRetry, T as debugWarn, V as StreamInputMode, _ as sendInputNotify, a as acknowledgeInteraction, b as startBackgroundTokenRefresh, c as createRawInputNotifyFn, d as getMessageApi, f as getPluginUserAgent, g as registerAccount, h as onMessageSent, i as accountToCreds, j as downloadFile, k as openLocalFile, l as getAccessToken, m as initSender, n as getQQBotRuntimeForEngine, o as buildDeliveryTarget, p as initApiConfig, s as clearTokenCache, t as getQQBotRuntime, u as getGatewayUrl, v as sendMedia$1, w as debugLog, x as stopBackgroundTokenRefresh, y as sendText, z as formatErrorMessage } from "./runtime-Dcl6gcEg.js";
6
+ import { a as getPluginVersion, i as getFrameworkVersion, n as runWithRequestContext, o as initCommands, s as matchSlashCommand } from "./request-context-B2yIu7CE.js";
7
7
  import * as fs$1 from "node:fs";
8
8
  import fs from "node:fs";
9
9
  import * as os$1 from "node:os";
@@ -201,7 +201,7 @@ function loadFromFile() {
201
201
  }
202
202
  cache.set(entry.k, {
203
203
  ...entry.v,
204
- _createdAt: entry.t
204
+ createdAt: entry.t
205
205
  });
206
206
  } catch {}
207
207
  }
@@ -248,7 +248,7 @@ function compactFile() {
248
248
  isBot: entry.isBot,
249
249
  attachments: entry.attachments
250
250
  },
251
- t: entry._createdAt
251
+ t: entry.createdAt
252
252
  }));
253
253
  replaceFileAtomicSync({
254
254
  filePath: refIndexFile,
@@ -264,9 +264,9 @@ function compactFile() {
264
264
  function evictIfNeeded() {
265
265
  if (!cache || cache.size < MAX_ENTRIES) return;
266
266
  const now = Date.now();
267
- for (const [key, entry] of cache) if (now - entry._createdAt > TTL_MS) cache.delete(key);
267
+ for (const [key, entry] of cache) if (now - entry.createdAt > TTL_MS) cache.delete(key);
268
268
  if (cache.size >= MAX_ENTRIES) {
269
- const toRemove = [...cache.entries()].toSorted((a, b) => a[1]._createdAt - b[1]._createdAt).slice(0, cache.size - MAX_ENTRIES + 1e3);
269
+ const toRemove = [...cache.entries()].toSorted((a, b) => a[1].createdAt - b[1].createdAt).slice(0, cache.size - MAX_ENTRIES + 1e3);
270
270
  for (const [key] of toRemove) cache.delete(key);
271
271
  debugLog(`[ref-index-store] Evicted ${toRemove.length} oldest entries`);
272
272
  }
@@ -278,7 +278,7 @@ function setRefIndex(refIdx, entry) {
278
278
  const now = Date.now();
279
279
  store.set(refIdx, {
280
280
  ...entry,
281
- _createdAt: now
281
+ createdAt: now
282
282
  });
283
283
  appendLine({
284
284
  k: refIdx,
@@ -299,7 +299,7 @@ function getRefIndex(refIdx) {
299
299
  const store = loadFromFile();
300
300
  const entry = store.get(refIdx);
301
301
  if (!entry) return null;
302
- if (Date.now() - entry._createdAt > TTL_MS) {
302
+ if (Date.now() - entry.createdAt > TTL_MS) {
303
303
  store.delete(refIdx);
304
304
  return null;
305
305
  }
@@ -4574,7 +4574,7 @@ var FlushController = class {
4574
4574
  this.pendingFlushTimer = null;
4575
4575
  this.lastUpdateTime = 0;
4576
4576
  this.isCompleted = false;
4577
- this._ready = false;
4577
+ this.isReady = false;
4578
4578
  this.doFlush = doFlush;
4579
4579
  }
4580
4580
  /** 标记为已完成 —— 当前 flush 之后不再调度新 flush */
@@ -4603,11 +4603,11 @@ var FlushController = class {
4603
4603
  }
4604
4604
  /** 标记流式会话就绪(首次 API 调用成功后) */
4605
4605
  setReady(ready) {
4606
- this._ready = ready;
4606
+ this.isReady = ready;
4607
4607
  if (ready) this.lastUpdateTime = Date.now();
4608
4608
  }
4609
4609
  get ready() {
4610
- return this._ready;
4610
+ return this.isReady;
4611
4611
  }
4612
4612
  /** 重置为初始状态(用于流式会话恢复) */
4613
4613
  reset(doFlush) {
@@ -4618,11 +4618,11 @@ var FlushController = class {
4618
4618
  this.needsReflush = false;
4619
4619
  this.lastUpdateTime = 0;
4620
4620
  this.isCompleted = false;
4621
- this._ready = false;
4621
+ this.isReady = false;
4622
4622
  }
4623
4623
  /** 执行一次 flush(互斥锁 + 冲突时 reflush) */
4624
4624
  async flush() {
4625
- if (!this._ready || this.flushInProgress || this.isCompleted) {
4625
+ if (!this.isReady || this.flushInProgress || this.isCompleted) {
4626
4626
  if (this.flushInProgress && !this.isCompleted) this.needsReflush = true;
4627
4627
  return;
4628
4628
  }
@@ -4648,7 +4648,7 @@ var FlushController = class {
4648
4648
  }
4649
4649
  /** 节流入口:根据 throttleMs 控制 flush 频率 */
4650
4650
  async throttledUpdate(throttleMs) {
4651
- if (!this._ready) return;
4651
+ if (!this.isReady) return;
4652
4652
  const now = Date.now();
4653
4653
  const elapsed = now - this.lastUpdateTime;
4654
4654
  if (elapsed >= throttleMs) {
@@ -4705,18 +4705,18 @@ var StreamingController = class {
4705
4705
  this.phase = "idle";
4706
4706
  this.lastNormalizedFull = "";
4707
4707
  this.lastRawFull = "";
4708
- this._boundaryPrefix = null;
4708
+ this.boundaryPrefix = null;
4709
4709
  this.sentIndex = 0;
4710
4710
  this.streamMsgId = null;
4711
4711
  this.msgSeq = null;
4712
4712
  this.streamIndex = 0;
4713
4713
  this.dispatchFullyComplete = false;
4714
- this._callbackChain = Promise.resolve();
4714
+ this.callbackChain = Promise.resolve();
4715
4715
  this.firstCallbackSource = null;
4716
4716
  this.sentStreamChunkCount = 0;
4717
4717
  this.sentMediaCount = 0;
4718
4718
  this.startingPromise = null;
4719
- this._pendingSessionText = null;
4719
+ this.pendingSessionText = null;
4720
4720
  this.deps = deps;
4721
4721
  this.flush = new FlushController(() => this.performFlush());
4722
4722
  this.throttleMs = THROTTLE_CONSTANTS.DEFAULT_MS;
@@ -4797,14 +4797,14 @@ var StreamingController = class {
4797
4797
  if (this.isTerminalPhase) return;
4798
4798
  if (!payload.text) return;
4799
4799
  if (!this.acquireCallbackLock("partial")) return;
4800
- this._callbackChain = this._callbackChain.then(() => this._doPartialReply(payload), (err) => {
4800
+ this.callbackChain = this.callbackChain.then(() => this.handlePartialReply(payload), (err) => {
4801
4801
  this.logError(`onPartialReply chain error: ${formatStreamErr(err)}`);
4802
- return this._doPartialReply(payload);
4802
+ return this.handlePartialReply(payload);
4803
4803
  });
4804
- return this._callbackChain;
4804
+ return this.callbackChain;
4805
4805
  }
4806
- /** onPartialReply 的实际逻辑(由 _callbackChain 保证串行调用) */
4807
- async _doPartialReply(payload) {
4806
+ /** onPartialReply 的实际逻辑(由 callbackChain 保证串行调用) */
4807
+ async handlePartialReply(payload) {
4808
4808
  this.logDebug(`onPartialReply: rawLen=${payload.text?.length ?? 0}, phase=${this.phase}, streamMsgId=${this.streamMsgId}, sentIndex=${this.sentIndex}, firstCB=${this.firstCallbackSource}`);
4809
4809
  if (this.isTerminalPhase) {
4810
4810
  this.logDebug(`onPartialReply: skipped (terminal phase)`);
@@ -4815,11 +4815,11 @@ var StreamingController = class {
4815
4815
  this.logDebug(`onPartialReply: skipped (empty text)`);
4816
4816
  return;
4817
4817
  }
4818
- const fullText = this._boundaryPrefix !== null ? this._boundaryPrefix + text : text;
4818
+ const fullText = this.boundaryPrefix !== null ? this.boundaryPrefix + text : text;
4819
4819
  if (this.lastRawFull && fullText.length > 0 && !fullText.startsWith(this.lastRawFull)) {
4820
4820
  this.logInfo(`onPartialReply: reply boundary detected — raw prefix mismatch (new len=${fullText.length}, prev len=${this.lastRawFull.length}), appending with separator`);
4821
- this._boundaryPrefix = this.lastRawFull + "\n\n";
4822
- const merged = this._boundaryPrefix + text;
4821
+ this.boundaryPrefix = this.lastRawFull + "\n\n";
4822
+ const merged = this.boundaryPrefix + text;
4823
4823
  this.lastRawFull = merged;
4824
4824
  this.lastNormalizedFull = normalizeMediaTags(merged);
4825
4825
  await this.processMediaTags(this.lastNormalizedFull);
@@ -4853,7 +4853,7 @@ var StreamingController = class {
4853
4853
  /**
4854
4854
  * 处理 onIdle 回调(分发完成时调用)
4855
4855
  *
4856
- * ★ 挂到 _callbackChain 上,保证在所有 onPartialReply 执行完之后才执行。
4856
+ * ★ 挂到 callbackChain 上,保证在所有 onPartialReply 执行完之后才执行。
4857
4857
  *
4858
4858
  * onIdle 会传入最终的全量文本。如果该文本**包含**之前存储的 lastNormalizedFull,
4859
4859
  * 说明一致,继续处理剩余内容;否则忽略(防止 onIdle 修改文本导致的不一致)。
@@ -4864,14 +4864,14 @@ var StreamingController = class {
4864
4864
  return;
4865
4865
  }
4866
4866
  if (this.isTerminalPhase) return;
4867
- this._callbackChain = this._callbackChain.then(() => this._doIdle(payload), (err) => {
4867
+ this.callbackChain = this.callbackChain.then(() => this.handleIdle(payload), (err) => {
4868
4868
  this.logError(`onIdle chain error: ${formatStreamErr(err)}`);
4869
- return this._doIdle(payload);
4869
+ return this.handleIdle(payload);
4870
4870
  });
4871
- return this._callbackChain;
4871
+ return this.callbackChain;
4872
4872
  }
4873
- /** onIdle 的实际逻辑(由 _callbackChain 保证在 onPartialReply 之后执行) */
4874
- async _doIdle(payload) {
4873
+ /** onIdle 的实际逻辑(由 callbackChain 保证在 onPartialReply 之后执行) */
4874
+ async handleIdle(payload) {
4875
4875
  this.logDebug(`onIdle: dispatchFullyComplete=${this.dispatchFullyComplete}, phase=${this.phase}, streamChunks=${this.sentStreamChunkCount}, mediaCount=${this.sentMediaCount}, sentIndex=${this.sentIndex}`);
4876
4876
  if (this.isTerminalPhase) {
4877
4877
  this.logDebug(`onIdle: skipped (terminal phase)`);
@@ -5048,9 +5048,9 @@ var StreamingController = class {
5048
5048
  this.logError(`${caller}: failed to end stream: ${formatStreamErr(err)}`);
5049
5049
  }
5050
5050
  else if (safeText && safeText.trim()) {
5051
- this._pendingSessionText = safeText;
5051
+ this.pendingSessionText = safeText;
5052
5052
  await this.ensureStreamingStarted(textEndInFull);
5053
- this._pendingSessionText = null;
5053
+ this.pendingSessionText = null;
5054
5054
  if (this.isTerminalPhase) return;
5055
5055
  if (this.startingPromise) await this.startingPromise;
5056
5056
  if (this.streamMsgId) try {
@@ -5096,7 +5096,7 @@ var StreamingController = class {
5096
5096
  /** 实际执行流式启动逻辑 */
5097
5097
  async doStartStreaming(textEndInFull) {
5098
5098
  try {
5099
- const [safeText] = stripIncompleteMediaTag(this._pendingSessionText ?? this.lastNormalizedFull.slice(this.sentIndex, textEndInFull));
5099
+ const [safeText] = stripIncompleteMediaTag(this.pendingSessionText ?? this.lastNormalizedFull.slice(this.sentIndex, textEndInFull));
5100
5100
  if (!safeText?.trim()) {
5101
5101
  this.logDebug(`doStartStreaming: skipped (session text is empty or whitespace-only)`);
5102
5102
  this.transition("idle", "doStartStreaming", "whitespace_only_text");
@@ -5214,15 +5214,15 @@ function shouldUseOfficialC2cStream(account, targetType) {
5214
5214
  *
5215
5215
  * Self-contained within engine/ — no framework SDK dependency.
5216
5216
  */
5217
- let _silkWasmPromise = null;
5217
+ let silkWasmPromise = null;
5218
5218
  /** Lazy-load the silk-wasm module (singleton cache; returns null on failure). */
5219
5219
  function loadSilkWasm() {
5220
- if (_silkWasmPromise) return _silkWasmPromise;
5221
- _silkWasmPromise = import("silk-wasm").catch((err) => {
5220
+ if (silkWasmPromise) return silkWasmPromise;
5221
+ silkWasmPromise = import("silk-wasm").catch((err) => {
5222
5222
  debugWarn(`[audio-convert] silk-wasm not available; SILK encode/decode disabled (${formatErrorMessage(err)})`);
5223
5223
  return null;
5224
5224
  });
5225
- return _silkWasmPromise;
5225
+ return silkWasmPromise;
5226
5226
  }
5227
5227
  /** Wrap raw PCM s16le data into a standard WAV file. */
5228
5228
  function pcmToWav(pcmData, sampleRate, channels = 1, bitsPerSample = 16) {
@@ -6401,9 +6401,9 @@ async function resolveQQBotSlashCommandAuthorized(params) {
6401
6401
  *
6402
6402
  * All adapter dependencies are assembled here in one place.
6403
6403
  */
6404
- const _pluginVersion = resolveQQBotPluginVersion(import.meta.url);
6404
+ const pluginVersion = resolveQQBotPluginVersion(import.meta.url);
6405
6405
  initSender({
6406
- pluginVersion: _pluginVersion,
6406
+ pluginVersion,
6407
6407
  openclawVersion: resolveRuntimeServiceVersion()
6408
6408
  });
6409
6409
  /**
@@ -6413,7 +6413,7 @@ initSender({
6413
6413
  * happens here. The engine receives a fully-populated
6414
6414
  * {@link EngineAdapters} object with zero global singletons.
6415
6415
  */
6416
- function createEngineAdapters(_runtime) {
6416
+ function createEngineAdapters() {
6417
6417
  return {
6418
6418
  history: createSdkHistoryAdapter(),
6419
6419
  mentionGate: createSdkMentionGateAdapter(),
@@ -6431,7 +6431,7 @@ function createEngineAdapters(_runtime) {
6431
6431
  },
6432
6432
  commands: {
6433
6433
  resolveVersion: resolveRuntimeServiceVersion,
6434
- pluginVersion: _pluginVersion,
6434
+ pluginVersion,
6435
6435
  approveRuntimeGetter: () => {
6436
6436
  return { config: getQQBotRuntime().config };
6437
6437
  }
@@ -6472,7 +6472,7 @@ async function startGateway(ctx) {
6472
6472
  onError: ctx.onError,
6473
6473
  log: accountLogger,
6474
6474
  runtime,
6475
- adapters: createEngineAdapters(runtime)
6475
+ adapters: createEngineAdapters()
6476
6476
  });
6477
6477
  }
6478
6478
  function createAccountLogger(raw, accountId) {
@@ -1,6 +1,6 @@
1
- import { m as getBridgeLogger, p as ensurePlatformAdapter, u as resolveQQBotAccount } from "./config-schema-BE5YP0NG.js";
2
- import { S as buildPluginApprovalText, _ as matchesQQBotApprovalAccount, b as buildApprovalKeyboard, g as isQQBotExecApprovalClientEnabled, v as resolveQQBotExecApprovalConfig, w as resolveApprovalTarget, x as buildExecApprovalText, y as shouldHandleQQBotExecApprovalRequest } from "./channel-Dp4lpH09.js";
3
- import { d as getMessageApi, i as accountToCreds } from "./runtime-BfsyXEkf.js";
1
+ import { m as getBridgeLogger, p as ensurePlatformAdapter, u as resolveQQBotAccount } from "./config-schema-S5Xdt1tV.js";
2
+ import { S as buildPluginApprovalText, _ as matchesQQBotApprovalAccount, b as buildApprovalKeyboard, g as isQQBotExecApprovalClientEnabled, v as resolveQQBotExecApprovalConfig, w as resolveApprovalTarget, x as buildExecApprovalText, y as shouldHandleQQBotExecApprovalRequest } from "./channel-CD_RD3Ro.js";
3
+ import { d as getMessageApi, i as accountToCreds } from "./runtime-Dcl6gcEg.js";
4
4
  import { resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
5
5
  import { createChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
6
6
  //#region extensions/qqbot/src/bridge/approval/handler-runtime.ts
@@ -1,6 +1,6 @@
1
- import { i as normalizeOptionalString, n as normalizeLowercaseStringOrEmpty, s as sanitizeFileName } from "./string-normalize-C46CS-F1.js";
2
- import { a as getQQBotDataDir, f as normalizePath, n as parseTarget$1, p as resolveQQBotPayloadLocalFilePath, s as getQQBotMediaDir, u as isLocalPath } from "./channel-Dp4lpH09.js";
3
- import { A as checkFileSize, C as debugError, E as UploadDailyLimitExceededError, F as getImageMimeType, I as getMaxUploadSize, L as readFileAsync, M as fileExistsAsync, N as formatFileSize, O as UPLOAD_PREPARE_FALLBACK_CODE, P as getFileTypeName, T as debugWarn, i as accountToCreds, j as downloadFile, p as initApiConfig, v as sendMedia$1, w as debugLog, y as sendText$1, z as formatErrorMessage } from "./runtime-BfsyXEkf.js";
1
+ import { i as normalizeOptionalString, n as normalizeLowercaseStringOrEmpty, s as sanitizeFileName } from "./string-normalize-DKS36VHd.js";
2
+ import { a as getQQBotDataDir, f as normalizePath, n as parseTarget$1, p as resolveQQBotPayloadLocalFilePath, s as getQQBotMediaDir, u as isLocalPath } from "./channel-CD_RD3Ro.js";
3
+ import { A as checkFileSize, C as debugError, E as UploadDailyLimitExceededError, F as getImageMimeType, I as getMaxUploadSize, L as readFileAsync, M as fileExistsAsync, N as formatFileSize, O as UPLOAD_PREPARE_FALLBACK_CODE, P as getFileTypeName, T as debugWarn, i as accountToCreds, j as downloadFile, p as initApiConfig, v as sendMedia$1, w as debugLog, y as sendText$1, z as formatErrorMessage } from "./runtime-Dcl6gcEg.js";
4
4
  import { pathExistsSync, resolveLocalPathFromRootsSync } from "openclaw/plugin-sdk/security-runtime";
5
5
  import path from "node:path";
6
6
  import { getFileExtension } from "openclaw/plugin-sdk/media-mime";
@@ -17,17 +17,17 @@ var __exportAll = (all, no_symbols) => {
17
17
  };
18
18
  //#endregion
19
19
  //#region extensions/qqbot/src/engine/messaging/outbound-audio-port.ts
20
- let _audioPort = null;
20
+ let outboundAudioPort = null;
21
21
  /**
22
22
  * Initialize the outbound audio adapter. Called once by gateway startup
23
23
  * via `adapters.outboundAudio`.
24
24
  */
25
25
  function setOutboundAudioPort(port) {
26
- _audioPort = port;
26
+ outboundAudioPort = port;
27
27
  }
28
28
  function getAudio() {
29
- if (!_audioPort) throw new Error("OutboundAudioPort not initialized — call setOutboundAudioPort first");
30
- return _audioPort;
29
+ if (!outboundAudioPort) throw new Error("OutboundAudioPort not initialized — call setOutboundAudioPort first");
30
+ return outboundAudioPort;
31
31
  }
32
32
  function audioFileToSilkBase64(p, f) {
33
33
  return getAudio().audioFileToSilkBase64(p, f);
@@ -1,33 +1,33 @@
1
- import { a as getQQBotDataDir, c as getQQBotMediaPath, d as isWindows, i as getHomeDir } from "./channel-Dp4lpH09.js";
2
- import { w as debugLog } from "./runtime-BfsyXEkf.js";
1
+ import { a as getQQBotDataDir, c as getQQBotMediaPath, d as isWindows, i as getHomeDir } from "./channel-CD_RD3Ro.js";
2
+ import { w as debugLog } from "./runtime-Dcl6gcEg.js";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { loadJsonFile } from "openclaw/plugin-sdk/json-store";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  //#region extensions/qqbot/src/engine/commands/builtin/state.ts
8
- let _resolveVersion = () => "unknown";
9
- let _approveRuntimeGetter = null;
8
+ let resolveVersionGetter = () => "unknown";
9
+ let approveRuntimeGetter = null;
10
10
  let PLUGIN_VERSION = "unknown";
11
11
  /**
12
12
  * Initialize command dependencies from the EngineAdapters.commands port.
13
13
  * Called once by the bridge layer during startup.
14
14
  */
15
15
  function initSlashCommandDeps(port) {
16
- _resolveVersion = port.resolveVersion;
16
+ resolveVersionGetter = port.resolveVersion;
17
17
  PLUGIN_VERSION = port.pluginVersion;
18
- _approveRuntimeGetter = port.approveRuntimeGetter ?? null;
18
+ approveRuntimeGetter = port.approveRuntimeGetter ?? null;
19
19
  }
20
20
  function resolveRuntimeServiceVersion() {
21
- return _resolveVersion();
21
+ return resolveVersionGetter();
22
22
  }
23
23
  function getPluginVersionString() {
24
24
  return PLUGIN_VERSION;
25
25
  }
26
26
  function getFrameworkVersionString() {
27
- return _resolveVersion();
27
+ return resolveVersionGetter();
28
28
  }
29
29
  function getApproveRuntimeGetter() {
30
- return _approveRuntimeGetter;
30
+ return approveRuntimeGetter;
31
31
  }
32
32
  //#endregion
33
33
  //#region extensions/qqbot/src/engine/commands/builtin/register-approve.ts
@@ -1,4 +1,4 @@
1
- import { c as getPlatformAdapter, i as normalizeOptionalString, s as sanitizeFileName } from "./string-normalize-C46CS-F1.js";
1
+ import { c as getPlatformAdapter, i as normalizeOptionalString, s as sanitizeFileName } from "./string-normalize-DKS36VHd.js";
2
2
  import * as fs$1 from "node:fs";
3
3
  import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
4
4
  import os from "node:os";
@@ -1539,7 +1539,7 @@ function setCachedFileInfo(contentHash, scope, targetId, fileType, fileInfo, fil
1539
1539
  * Each account gets its own isolated resource stack:
1540
1540
  *
1541
1541
  * ```
1542
- * _accountRegistry: Map<appId, AccountContext>
1542
+ * accountRegistry: Map<appId, AccountContext>
1543
1543
  *
1544
1544
  * AccountContext {
1545
1545
  * logger — per-account prefixed logger
@@ -1554,11 +1554,11 @@ function setCachedFileInfo(contentHash, scope, targetId, fileType, fileInfo, fil
1554
1554
  * always go through exported functions that resolve the correct
1555
1555
  * `AccountContext` by appId.
1556
1556
  */
1557
- let _pluginVersion = "unknown";
1558
- let _openclawVersion = "unknown";
1557
+ let pluginVersion = "unknown";
1558
+ let openclawVersion = "unknown";
1559
1559
  /** Build the User-Agent string from the current plugin and framework versions. */
1560
1560
  function buildUserAgent() {
1561
- return `QQBotPlugin/${_pluginVersion} (Node/${process.versions.node}; ${os.platform()}; OpenClaw/${_openclawVersion})`;
1561
+ return `QQBotPlugin/${pluginVersion} (Node/${process.versions.node}; ${os.platform()}; OpenClaw/${openclawVersion})`;
1562
1562
  }
1563
1563
  /** Return the current User-Agent string. */
1564
1564
  function getPluginUserAgent() {
@@ -1569,17 +1569,17 @@ function getPluginUserAgent() {
1569
1569
  * Must be called once during startup before any API calls.
1570
1570
  */
1571
1571
  function initSender(options) {
1572
- if (options.pluginVersion) _pluginVersion = options.pluginVersion;
1573
- if (options.openclawVersion) _openclawVersion = options.openclawVersion;
1572
+ if (options.pluginVersion) pluginVersion = options.pluginVersion;
1573
+ if (options.openclawVersion) openclawVersion = options.openclawVersion;
1574
1574
  }
1575
1575
  /** Update the OpenClaw framework version in the User-Agent (called after runtime injection). */
1576
1576
  function setOpenClawVersion(version) {
1577
- if (version) _openclawVersion = version;
1577
+ if (version) openclawVersion = version;
1578
1578
  }
1579
1579
  /** Per-appId account registry — each account owns all its resources. */
1580
- const _accountRegistry = /* @__PURE__ */ new Map();
1580
+ const accountRegistry = /* @__PURE__ */ new Map();
1581
1581
  /** Fallback logger for unregistered accounts (CLI / test scenarios). */
1582
- const _fallbackLogger = {
1582
+ const fallbackLogger = {
1583
1583
  info: (msg) => debugLog(msg),
1584
1584
  error: (msg) => debugError(msg),
1585
1585
  warn: (msg) => debugWarn(msg),
@@ -1636,7 +1636,7 @@ function buildAccountContext(logger, markdownSupport) {
1636
1636
  function registerAccount(appId, options) {
1637
1637
  const key = appId.trim();
1638
1638
  const md = options.markdownSupport === true;
1639
- _accountRegistry.set(key, buildAccountContext(options.logger, md));
1639
+ accountRegistry.set(key, buildAccountContext(options.logger, md));
1640
1640
  }
1641
1641
  /**
1642
1642
  * Initialize per-app API behavior such as markdown support.
@@ -1648,14 +1648,14 @@ function registerAccount(appId, options) {
1648
1648
  function initApiConfig(appId, options) {
1649
1649
  const key = appId.trim();
1650
1650
  const md = options.markdownSupport === true;
1651
- const existing = _accountRegistry.get(key);
1651
+ const existing = accountRegistry.get(key);
1652
1652
  if (existing) {
1653
1653
  existing.messageApi = new MessageApi(existing.client, existing.tokenMgr, {
1654
1654
  markdownSupport: md,
1655
1655
  logger: existing.logger
1656
1656
  });
1657
1657
  existing.markdownSupport = md;
1658
- } else _accountRegistry.set(key, buildAccountContext(_fallbackLogger, md));
1658
+ } else accountRegistry.set(key, buildAccountContext(fallbackLogger, md));
1659
1659
  }
1660
1660
  /**
1661
1661
  * Resolve the AccountContext for a given appId.
@@ -1665,10 +1665,10 @@ function initApiConfig(appId, options) {
1665
1665
  */
1666
1666
  function resolveAccount(appId) {
1667
1667
  const key = appId.trim();
1668
- let ctx = _accountRegistry.get(key);
1668
+ let ctx = accountRegistry.get(key);
1669
1669
  if (!ctx) {
1670
- ctx = buildAccountContext(_fallbackLogger, false);
1671
- _accountRegistry.set(key, ctx);
1670
+ ctx = buildAccountContext(fallbackLogger, false);
1671
+ accountRegistry.set(key, ctx);
1672
1672
  }
1673
1673
  return ctx;
1674
1674
  }
@@ -1685,14 +1685,14 @@ async function getAccessToken(appId, clientSecret) {
1685
1685
  }
1686
1686
  function clearTokenCache(appId) {
1687
1687
  if (appId) resolveAccount(appId).tokenMgr.clearCache(appId);
1688
- else for (const ctx of _accountRegistry.values()) ctx.tokenMgr.clearCache();
1688
+ else for (const ctx of accountRegistry.values()) ctx.tokenMgr.clearCache();
1689
1689
  }
1690
1690
  function startBackgroundTokenRefresh(appId, clientSecret, options) {
1691
1691
  resolveAccount(appId).tokenMgr.startBackgroundRefresh(appId, clientSecret, options);
1692
1692
  }
1693
1693
  function stopBackgroundTokenRefresh(appId) {
1694
1694
  if (appId) resolveAccount(appId).tokenMgr.stopBackgroundRefresh(appId);
1695
- else for (const ctx of _accountRegistry.values()) ctx.tokenMgr.stopBackgroundRefresh();
1695
+ else for (const ctx of accountRegistry.values()) ctx.tokenMgr.stopBackgroundRefresh();
1696
1696
  }
1697
1697
  async function getGatewayUrl(accessToken, appId) {
1698
1698
  return (await resolveAccount(appId).client.request(accessToken, "GET", "/gateway")).url;
@@ -1,2 +1,2 @@
1
- import { r as setQQBotRuntime, t as getQQBotRuntime } from "./runtime-BfsyXEkf.js";
1
+ import { r as setQQBotRuntime, t as getQQBotRuntime } from "./runtime-Dcl6gcEg.js";
2
2
  export { getQQBotRuntime, setQQBotRuntime };
@@ -1,2 +1,2 @@
1
- import { t as qqbotSetupPlugin } from "./channel.setup-D_8Ryfln.js";
1
+ import { t as qqbotSetupPlugin } from "./channel.setup-t_t2xa93.js";
2
2
  export { qqbotSetupPlugin };
@@ -1,19 +1,19 @@
1
1
  //#region extensions/qqbot/src/engine/adapter/index.ts
2
- let _adapter = null;
3
- let _adapterFactory = null;
2
+ let platformAdapter = null;
3
+ let platformAdapterFactory = null;
4
4
  function registerPlatformAdapter(adapter) {
5
- _adapter = adapter;
5
+ platformAdapter = adapter;
6
6
  }
7
7
  function registerPlatformAdapterFactory(factory) {
8
- _adapterFactory = factory;
8
+ platformAdapterFactory = factory;
9
9
  }
10
10
  function getPlatformAdapter() {
11
- if (!_adapter && _adapterFactory) _adapter = _adapterFactory();
12
- if (!_adapter) throw new Error("PlatformAdapter not registered. Call registerPlatformAdapter() during bootstrap.");
13
- return _adapter;
11
+ if (!platformAdapter && platformAdapterFactory) platformAdapter = platformAdapterFactory();
12
+ if (!platformAdapter) throw new Error("PlatformAdapter not registered. Call registerPlatformAdapter() during bootstrap.");
13
+ return platformAdapter;
14
14
  }
15
15
  function hasPlatformAdapter() {
16
- return _adapter !== null || _adapterFactory !== null;
16
+ return platformAdapter !== null || platformAdapterFactory !== null;
17
17
  }
18
18
  //#endregion
19
19
  //#region extensions/qqbot/src/engine/utils/string-normalize.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/qqbot",
3
- "version": "2026.5.18-beta.1",
3
+ "version": "2026.5.19-alpha.1",
4
4
  "private": false,
5
5
  "description": "OpenClaw QQ Bot channel plugin",
6
6
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "openclaw": "workspace:*"
22
22
  },
23
23
  "peerDependencies": {
24
- "openclaw": ">=2026.5.18-beta.1"
24
+ "openclaw": ">=2026.5.19-alpha.1"
25
25
  },
26
26
  "peerDependenciesMeta": {
27
27
  "openclaw": {
@@ -50,10 +50,10 @@
50
50
  "minHostVersion": ">=2026.4.10"
51
51
  },
52
52
  "compat": {
53
- "pluginApi": ">=2026.5.18-beta.1"
53
+ "pluginApi": ">=2026.5.19-alpha.1"
54
54
  },
55
55
  "build": {
56
- "openclawVersion": "2026.5.18-beta.1"
56
+ "openclawVersion": "2026.5.19-alpha.1"
57
57
  },
58
58
  "release": {
59
59
  "publishToClawHub": true,