@openclaw/qqbot 2026.6.6-beta.1 → 2026.6.6
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 +1 -1
- package/dist/{channel-CQdcwOQZ.js → channel-CIb8DUm3.js} +2 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{gateway-DTfz_8KD.js → gateway-fUg0QRoq.js} +124 -44
- package/dist/{handler-runtime-CPzQAAn3.js → handler-runtime-ChANl8Bb.js} +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as qqbotPlugin } from "./channel-
|
|
1
|
+
import { t as qqbotPlugin } from "./channel-CIb8DUm3.js";
|
|
2
2
|
import { a as resolveQQBotAccount, i as resolveDefaultQQBotAccountId, n as applyQQBotAccountConfig, r as listQQBotAccountIds, t as DEFAULT_ACCOUNT_ID } from "./config-ZEfgeoL4.js";
|
|
3
3
|
import { t as qqbotSetupPlugin } from "./channel.setup-CQ_DFfPx.js";
|
|
4
4
|
import { t as getFrameworkCommands } from "./slash-commands-impl-DVApdSop.js";
|
|
@@ -377,7 +377,7 @@ function createQQBotApprovalCapability() {
|
|
|
377
377
|
},
|
|
378
378
|
load: async () => {
|
|
379
379
|
ensurePlatformAdapter();
|
|
380
|
-
return (await import("./handler-runtime-
|
|
380
|
+
return (await import("./handler-runtime-ChANl8Bb.js")).qqbotApprovalNativeRuntime;
|
|
381
381
|
}
|
|
382
382
|
})
|
|
383
383
|
});
|
|
@@ -667,7 +667,7 @@ function resolveQQBotGroupToolPolicy(params) {
|
|
|
667
667
|
//#region extensions/qqbot/src/channel.ts
|
|
668
668
|
let gatewayModulePromise;
|
|
669
669
|
function loadGatewayModule() {
|
|
670
|
-
gatewayModulePromise ??= import("./gateway-
|
|
670
|
+
gatewayModulePromise ??= import("./gateway-fUg0QRoq.js");
|
|
671
671
|
return gatewayModulePromise;
|
|
672
672
|
}
|
|
673
673
|
let outboundMessagingModulePromise;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as qqbotPlugin } from "./channel-
|
|
1
|
+
import { t as qqbotPlugin } from "./channel-CIb8DUm3.js";
|
|
2
2
|
export { qqbotPlugin };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as getNextMsgSeq, D as downloadFile, F as StreamInputMode, I as StreamInputState, M as getMaxUploadSize, P as StreamContentType, T as openLocalFile, a as createRawInputNotifyFn, b as stopBackgroundTokenRefresh, c as getMessageApi, d as initSender, f as onMessageSent, g as sendText, h as sendMedia, i as clearTokenCache, j as getImageMimeType, k as formatFileSize, l as getPluginUserAgent, m as sendInputNotify, n as acknowledgeInteraction, o as getAccessToken, p as registerAccount, r as buildDeliveryTarget, s as getGatewayUrl, t as accountToCreds, u as initApiConfig, x as withTokenRetry, y as startBackgroundTokenRefresh } from "./sender-DIMG7jHz.js";
|
|
2
2
|
import { c as getPlatformAdapter, i as normalizeOptionalString$1, n as normalizeLowercaseStringOrEmpty$1, o as readStringField, s as sanitizeFileName, t as asOptionalObjectRecord } from "./string-normalize-R_0cKO7Q.js";
|
|
3
3
|
import { c as setBridgeLogger, o as ensurePlatformAdapter } from "./config-schema-BFLNZ8Nf.js";
|
|
4
|
-
import { a as authorizeQQBotApprovalAction, i as toGatewayAccount, n as buildQQBotStateKey, p as parseApprovalButtonData, r as openQQBotSyncKeyedStore } from "./channel-
|
|
4
|
+
import { a as authorizeQQBotApprovalAction, i as toGatewayAccount, n as buildQQBotStateKey, p as parseApprovalButtonData, r as openQQBotSyncKeyedStore } from "./channel-CIb8DUm3.js";
|
|
5
5
|
import { d as resolveAccountBase } from "./config-ZEfgeoL4.js";
|
|
6
6
|
import { a as formatErrorMessage, i as formatDuration, n as debugLog, r as debugWarn, t as debugError } from "./log-SDfMMBWe.js";
|
|
7
7
|
import { n as getQQBotRuntimeForEngine, t as getQQBotRuntime } from "./runtime-B9UoQ5NI.js";
|
|
@@ -26,6 +26,7 @@ import { resolveRuntimeServiceVersion } from "openclaw/plugin-sdk/cli-runtime";
|
|
|
26
26
|
import WebSocket from "ws";
|
|
27
27
|
import { resolveAmbientNodeProxyAgent } from "openclaw/plugin-sdk/extension-shared";
|
|
28
28
|
import { buildChannelInboundEventContext } from "openclaw/plugin-sdk/channel-inbound";
|
|
29
|
+
import { SILENT_REPLY_TOKEN, isSilentReplyPayloadText } from "openclaw/plugin-sdk/reply-chunking";
|
|
29
30
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
30
31
|
import { fileURLToPath } from "node:url";
|
|
31
32
|
import { parseAccessGroupAllowFromEntry } from "openclaw/plugin-sdk/access-groups";
|
|
@@ -5736,6 +5737,19 @@ function immediateToolProgressText(payload) {
|
|
|
5736
5737
|
if (payload.mediaUrl || payload.mediaUrls?.length) return;
|
|
5737
5738
|
return text;
|
|
5738
5739
|
}
|
|
5740
|
+
function hasReplyMedia(payload) {
|
|
5741
|
+
return Boolean(payload.mediaUrl || payload.mediaUrls?.length);
|
|
5742
|
+
}
|
|
5743
|
+
function isSilentBlockReplyText(text) {
|
|
5744
|
+
return !text || text === "[SKIP]" || isSilentReplyPayloadText(text, SILENT_REPLY_TOKEN);
|
|
5745
|
+
}
|
|
5746
|
+
function blockReplyTextForDelivery(payload) {
|
|
5747
|
+
const text = payload.text ?? "";
|
|
5748
|
+
return isSilentBlockReplyText(text.trim()) ? "" : text;
|
|
5749
|
+
}
|
|
5750
|
+
function isSilentBlockReply(payload) {
|
|
5751
|
+
return !hasReplyMedia(payload) && isSilentBlockReplyText((payload.text ?? "").trim());
|
|
5752
|
+
}
|
|
5739
5753
|
/**
|
|
5740
5754
|
* Dispatch the AI reply for the given inbound context.
|
|
5741
5755
|
*
|
|
@@ -5763,50 +5777,78 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
5763
5777
|
const ctxPayload = await buildCtxPayload(inbound, runtime, cfg);
|
|
5764
5778
|
let hasResponse = false;
|
|
5765
5779
|
let hasBlockResponse = false;
|
|
5780
|
+
let hasVisibleBlockResponse = false;
|
|
5766
5781
|
let toolDeliverCount = 0;
|
|
5767
5782
|
const toolTexts = [];
|
|
5768
5783
|
const toolMediaUrls = [];
|
|
5769
5784
|
let toolFallbackSent = false;
|
|
5770
5785
|
let toolRenewalCount = 0;
|
|
5786
|
+
let skippedSilentBlockResponse = false;
|
|
5771
5787
|
let timeoutId = null;
|
|
5772
5788
|
let toolOnlyTimeoutId = null;
|
|
5789
|
+
const markBlockResponse = () => {
|
|
5790
|
+
hasBlockResponse = true;
|
|
5791
|
+
inbound.typing.keepAlive?.stop();
|
|
5792
|
+
if (timeoutId) {
|
|
5793
|
+
clearTimeout(timeoutId);
|
|
5794
|
+
timeoutId = null;
|
|
5795
|
+
}
|
|
5796
|
+
if (toolOnlyTimeoutId) {
|
|
5797
|
+
clearTimeout(toolOnlyTimeoutId);
|
|
5798
|
+
toolOnlyTimeoutId = null;
|
|
5799
|
+
}
|
|
5800
|
+
};
|
|
5801
|
+
const sendToolMediaWithTimeout = async (mediaUrl, labels) => {
|
|
5802
|
+
const ac = new AbortController();
|
|
5803
|
+
let mediaTimeoutId = null;
|
|
5804
|
+
try {
|
|
5805
|
+
const result = await Promise.race([sendMedia$1({
|
|
5806
|
+
to: qualifiedTarget,
|
|
5807
|
+
text: "",
|
|
5808
|
+
mediaUrl,
|
|
5809
|
+
accountId: account.accountId,
|
|
5810
|
+
replyToId: event.messageId,
|
|
5811
|
+
account
|
|
5812
|
+
}).then((r) => {
|
|
5813
|
+
if (ac.signal.aborted) return {
|
|
5814
|
+
channel: "qqbot",
|
|
5815
|
+
error: "suppressed"
|
|
5816
|
+
};
|
|
5817
|
+
return r;
|
|
5818
|
+
}), new Promise((resolve) => {
|
|
5819
|
+
mediaTimeoutId = setTimeout(() => {
|
|
5820
|
+
ac.abort();
|
|
5821
|
+
resolve({
|
|
5822
|
+
channel: "qqbot",
|
|
5823
|
+
error: "timeout"
|
|
5824
|
+
});
|
|
5825
|
+
}, TOOL_MEDIA_SEND_TIMEOUT);
|
|
5826
|
+
})]);
|
|
5827
|
+
if (result.error) log?.error(`${labels.resultError}: ${result.error}`);
|
|
5828
|
+
} catch (err) {
|
|
5829
|
+
log?.error(`${labels.thrownError}: ${String(err)}`);
|
|
5830
|
+
} finally {
|
|
5831
|
+
if (mediaTimeoutId) clearTimeout(mediaTimeoutId);
|
|
5832
|
+
}
|
|
5833
|
+
};
|
|
5773
5834
|
const sendToolFallback = async () => {
|
|
5774
5835
|
if (toolMediaUrls.length > 0) {
|
|
5775
|
-
for (const mediaUrl of toolMediaUrls) {
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
to: qualifiedTarget,
|
|
5780
|
-
text: "",
|
|
5781
|
-
mediaUrl,
|
|
5782
|
-
accountId: account.accountId,
|
|
5783
|
-
replyToId: event.messageId,
|
|
5784
|
-
account
|
|
5785
|
-
}).then((r) => {
|
|
5786
|
-
if (ac.signal.aborted) return {
|
|
5787
|
-
channel: "qqbot",
|
|
5788
|
-
error: "suppressed"
|
|
5789
|
-
};
|
|
5790
|
-
return r;
|
|
5791
|
-
}), new Promise((resolve) => {
|
|
5792
|
-
setTimeout(() => {
|
|
5793
|
-
ac.abort();
|
|
5794
|
-
resolve({
|
|
5795
|
-
channel: "qqbot",
|
|
5796
|
-
error: "timeout"
|
|
5797
|
-
});
|
|
5798
|
-
}, TOOL_MEDIA_SEND_TIMEOUT);
|
|
5799
|
-
})]);
|
|
5800
|
-
if (result.error) log?.error(`Tool fallback error: ${result.error}`);
|
|
5801
|
-
} catch (err) {
|
|
5802
|
-
log?.error(`Tool fallback failed: ${String(err)}`);
|
|
5803
|
-
}
|
|
5804
|
-
}
|
|
5836
|
+
for (const mediaUrl of toolMediaUrls) await sendToolMediaWithTimeout(mediaUrl, {
|
|
5837
|
+
resultError: "Tool fallback error",
|
|
5838
|
+
thrownError: "Tool fallback failed"
|
|
5839
|
+
});
|
|
5805
5840
|
return;
|
|
5806
5841
|
}
|
|
5807
5842
|
if (toolTexts.length > 0) await sendErrorMessage(toolTexts.slice(-3).join("\n---\n").slice(0, 2e3));
|
|
5808
5843
|
};
|
|
5809
5844
|
const hasPendingToolFallbackPayload = () => toolTexts.length > 0 || toolMediaUrls.length > 0;
|
|
5845
|
+
const flushPendingToolDeliveriesOnce = async () => {
|
|
5846
|
+
if (toolFallbackSent || !hasPendingToolFallbackPayload()) return false;
|
|
5847
|
+
await flushPendingToolDeliveries();
|
|
5848
|
+
toolFallbackSent = true;
|
|
5849
|
+
recordOutbound();
|
|
5850
|
+
return true;
|
|
5851
|
+
};
|
|
5810
5852
|
const renewToolOnlyFallback = () => {
|
|
5811
5853
|
if (toolFallbackSent) return false;
|
|
5812
5854
|
if (toolOnlyTimeoutId) {
|
|
@@ -5815,7 +5857,7 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
5815
5857
|
toolRenewalCount++;
|
|
5816
5858
|
}
|
|
5817
5859
|
toolOnlyTimeoutId = setTimeout(() => {
|
|
5818
|
-
if (!hasBlockResponse && !toolFallbackSent) {
|
|
5860
|
+
if (!hasBlockResponse && !toolFallbackSent && !skippedSilentBlockResponse) {
|
|
5819
5861
|
toolFallbackSent = true;
|
|
5820
5862
|
sendToolFallback().catch(() => {});
|
|
5821
5863
|
}
|
|
@@ -5842,6 +5884,32 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
5842
5884
|
textToSpeech: (params) => runtime.tts.textToSpeech(params),
|
|
5843
5885
|
audioFileToSilkBase64: async (p) => await audioFileToSilkBase64(p) ?? void 0
|
|
5844
5886
|
} };
|
|
5887
|
+
const flushPendingToolDeliveries = async () => {
|
|
5888
|
+
if (toolMediaUrls.length > 0) {
|
|
5889
|
+
const urlsToSend = [...toolMediaUrls];
|
|
5890
|
+
toolMediaUrls.length = 0;
|
|
5891
|
+
for (const mediaUrl of urlsToSend) await sendToolMediaWithTimeout(mediaUrl, {
|
|
5892
|
+
resultError: "Tool media forward error",
|
|
5893
|
+
thrownError: "Tool media forward failed"
|
|
5894
|
+
});
|
|
5895
|
+
}
|
|
5896
|
+
if (toolTexts.length > 0) {
|
|
5897
|
+
const textsToSend = [...toolTexts];
|
|
5898
|
+
toolTexts.length = 0;
|
|
5899
|
+
for (const text of textsToSend) await sendTextOnlyReply(text, {
|
|
5900
|
+
type: event.type,
|
|
5901
|
+
senderId: event.senderId,
|
|
5902
|
+
messageId: event.messageId,
|
|
5903
|
+
channelId: event.channelId,
|
|
5904
|
+
groupOpenid: event.groupOpenid,
|
|
5905
|
+
msgIdx: event.msgIdx
|
|
5906
|
+
}, {
|
|
5907
|
+
account,
|
|
5908
|
+
qualifiedTarget,
|
|
5909
|
+
log
|
|
5910
|
+
}, sendWithRetry, () => void 0, deliverDeps);
|
|
5911
|
+
}
|
|
5912
|
+
};
|
|
5845
5913
|
const recordOutbound = () => runtime.channel.activity.record({
|
|
5846
5914
|
channel: "qqbot",
|
|
5847
5915
|
accountId: account.accountId,
|
|
@@ -5945,16 +6013,12 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
5945
6013
|
renewToolOnlyFallback();
|
|
5946
6014
|
return;
|
|
5947
6015
|
}
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
timeoutId = null;
|
|
5953
|
-
}
|
|
5954
|
-
if (toolOnlyTimeoutId) {
|
|
5955
|
-
clearTimeout(toolOnlyTimeoutId);
|
|
5956
|
-
toolOnlyTimeoutId = null;
|
|
6016
|
+
markBlockResponse();
|
|
6017
|
+
if (!streamingController && isSilentBlockReply(payload)) {
|
|
6018
|
+
if (!await flushPendingToolDeliveriesOnce() && event.type === "group") log?.info(`Model decided to skip group message (${(payload.text ?? "").trim() || "empty reply"}) from ${event.senderId}`);
|
|
6019
|
+
return;
|
|
5957
6020
|
}
|
|
6021
|
+
hasVisibleBlockResponse = true;
|
|
5958
6022
|
if (streamingController && !streamingController.isTerminalPhase) {
|
|
5959
6023
|
try {
|
|
5960
6024
|
await streamingController.onDeliver(payload);
|
|
@@ -5980,7 +6044,7 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
5980
6044
|
return quoteRef;
|
|
5981
6045
|
}
|
|
5982
6046
|
};
|
|
5983
|
-
let replyText = payload
|
|
6047
|
+
let replyText = blockReplyTextForDelivery(payload);
|
|
5984
6048
|
const deliverEvent = {
|
|
5985
6049
|
type: event.type,
|
|
5986
6050
|
senderId: event.senderId,
|
|
@@ -6027,6 +6091,15 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
6027
6091
|
clearTimeout(timeoutId);
|
|
6028
6092
|
timeoutId = null;
|
|
6029
6093
|
}
|
|
6094
|
+
},
|
|
6095
|
+
onSkip: (_payload, info) => {
|
|
6096
|
+
if (!streamingController && (info.kind === "block" || info.kind === "final") && (info.reason === "silent" || info.reason === "empty")) skippedSilentBlockResponse = true;
|
|
6097
|
+
},
|
|
6098
|
+
onFreshSettledDelivery: async () => {
|
|
6099
|
+
if (skippedSilentBlockResponse && !hasVisibleBlockResponse) {
|
|
6100
|
+
markBlockResponse();
|
|
6101
|
+
if (await flushPendingToolDeliveriesOnce()) return { visibleReplySent: true };
|
|
6102
|
+
}
|
|
6030
6103
|
}
|
|
6031
6104
|
},
|
|
6032
6105
|
replyOptions: {
|
|
@@ -6050,13 +6123,20 @@ async function dispatchOutbound(inbound, deps) {
|
|
|
6050
6123
|
try {
|
|
6051
6124
|
await Promise.race([dispatchPromise, timeoutPromise]);
|
|
6052
6125
|
} catch {
|
|
6053
|
-
if (timeoutId)
|
|
6126
|
+
if (timeoutId) {
|
|
6127
|
+
clearTimeout(timeoutId);
|
|
6128
|
+
timeoutId = null;
|
|
6129
|
+
}
|
|
6054
6130
|
} finally {
|
|
6131
|
+
if (timeoutId) {
|
|
6132
|
+
clearTimeout(timeoutId);
|
|
6133
|
+
timeoutId = null;
|
|
6134
|
+
}
|
|
6055
6135
|
if (toolOnlyTimeoutId) {
|
|
6056
6136
|
clearTimeout(toolOnlyTimeoutId);
|
|
6057
6137
|
toolOnlyTimeoutId = null;
|
|
6058
6138
|
}
|
|
6059
|
-
if (toolDeliverCount > 0 && !hasBlockResponse && !toolFallbackSent) {
|
|
6139
|
+
if (toolDeliverCount > 0 && !hasBlockResponse && !toolFallbackSent && !skippedSilentBlockResponse) {
|
|
6060
6140
|
toolFallbackSent = true;
|
|
6061
6141
|
await sendToolFallback();
|
|
6062
6142
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c as getMessageApi, t as accountToCreds } from "./sender-DIMG7jHz.js";
|
|
2
2
|
import { o as ensurePlatformAdapter, s as getBridgeLogger } from "./config-schema-BFLNZ8Nf.js";
|
|
3
|
-
import { c as resolveQQBotExecApprovalConfig, d as buildExecApprovalText, f as buildPluginApprovalText, l as shouldHandleQQBotExecApprovalRequest, m as resolveApprovalTarget, o as isQQBotExecApprovalClientEnabled, s as matchesQQBotApprovalAccount, u as buildApprovalKeyboard } from "./channel-
|
|
3
|
+
import { c as resolveQQBotExecApprovalConfig, d as buildExecApprovalText, f as buildPluginApprovalText, l as shouldHandleQQBotExecApprovalRequest, m as resolveApprovalTarget, o as isQQBotExecApprovalClientEnabled, s as matchesQQBotApprovalAccount, u as buildApprovalKeyboard } from "./channel-CIb8DUm3.js";
|
|
4
4
|
import { a as resolveQQBotAccount } from "./config-ZEfgeoL4.js";
|
|
5
5
|
import { resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
6
6
|
import { createChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/qqbot",
|
|
3
|
-
"version": "2026.6.6
|
|
3
|
+
"version": "2026.6.6",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/qqbot",
|
|
9
|
-
"version": "2026.6.6
|
|
9
|
+
"version": "2026.6.6",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@tencent-connect/qqbot-connector": "1.1.0",
|
|
12
12
|
"mpg123-decoder": "1.0.3",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"zod": "4.4.3"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"openclaw": ">=2026.6.6
|
|
18
|
+
"openclaw": ">=2026.6.6"
|
|
19
19
|
},
|
|
20
20
|
"peerDependenciesMeta": {
|
|
21
21
|
"openclaw": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/qqbot",
|
|
3
|
-
"version": "2026.6.6
|
|
3
|
+
"version": "2026.6.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "OpenClaw QQ Bot channel plugin for group and direct-message workflows.",
|
|
6
6
|
"repository": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"zod": "4.4.3"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"openclaw": ">=2026.6.6
|
|
19
|
+
"openclaw": ">=2026.6.6"
|
|
20
20
|
},
|
|
21
21
|
"peerDependenciesMeta": {
|
|
22
22
|
"openclaw": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"minHostVersion": ">=2026.4.10"
|
|
46
46
|
},
|
|
47
47
|
"compat": {
|
|
48
|
-
"pluginApi": ">=2026.6.6
|
|
48
|
+
"pluginApi": ">=2026.6.6"
|
|
49
49
|
},
|
|
50
50
|
"build": {
|
|
51
|
-
"openclawVersion": "2026.6.6
|
|
51
|
+
"openclawVersion": "2026.6.6"
|
|
52
52
|
},
|
|
53
53
|
"release": {
|
|
54
54
|
"publishToClawHub": true,
|