@openclaw/qqbot 2026.7.1-beta.6 → 2026.7.2-beta.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 +8 -7
- package/dist/{channel-D1UztsnG.js → channel-BbwpkiY3.js} +99 -54
- package/dist/{channel-entry-C5YdhX3Y.js → channel-entry-Cj1lWXpt.js} +4 -4
- package/dist/channel-entry-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-2ItDYKhz.js → channel.setup-DfhritPL.js} +1 -1
- package/dist/{config-C1qZbh0K.js → config-CpOXnoEc.js} +2 -2
- package/dist/{config-schema-JZEf1dvB.js → config-schema-B5Mle_87.js} +38 -47
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{gateway-pJQppxe4.js → gateway-be5-Ckdc.js} +284 -174
- package/dist/{group-o0GmovSf.js → group-Dbpnjalm.js} +19 -17
- package/dist/{handler-runtime-zQvT6SrI.js → handler-runtime-BvR-ayNW.js} +8 -12
- package/dist/{log-DEtcoDWe.js → log-Da4jz75I.js} +4 -8
- package/dist/{outbound-BIrfvvFJ.js → outbound-BLl8Tsu7.js} +8 -142
- package/dist/{runtime-DodcT_fQ.js → runtime-Du28LbOJ.js} +2 -2
- package/dist/runtime-api.js +1 -1
- package/dist/secret-contract-api.js +6 -22
- package/dist/{sender-CjDuU-uz.js → sender-0vqsivoI.js} +220 -66
- package/dist/setup-plugin-api.js +1 -1
- package/dist/state-keys-jLJ2SmJA.js +225 -0
- package/dist/{tools-UJJ-tLHP.js → tools-DYb23LBU.js} +48 -6
- package/dist/tools-api.js +1 -1
- package/node_modules/p-map/index.d.ts +155 -0
- package/node_modules/p-map/index.js +284 -0
- package/node_modules/p-map/license +9 -0
- package/node_modules/p-map/package.json +57 -0
- package/node_modules/p-map/readme.md +190 -0
- package/node_modules/parse-ms/index.d.ts +30 -0
- package/node_modules/parse-ms/index.js +45 -0
- package/node_modules/parse-ms/license +9 -0
- package/node_modules/parse-ms/package.json +47 -0
- package/node_modules/parse-ms/readme.md +46 -0
- package/node_modules/pretty-ms/index.d.ts +157 -0
- package/node_modules/pretty-ms/index.js +149 -0
- package/node_modules/pretty-ms/license +9 -0
- package/node_modules/pretty-ms/package.json +55 -0
- package/node_modules/pretty-ms/readme.md +179 -0
- package/npm-shrinkwrap.json +44 -3
- package/openclaw.plugin.json +61 -89
- package/package.json +8 -4
- package/dist/state-keys-CQKlAFyo.js +0 -141
package/dist/api.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as
|
|
7
|
-
import { t as
|
|
1
|
+
import { C as checkMessageReplyLimit, D as recordMessageReply, E as getMessageReplyStats, S as MESSAGE_REPLY_LIMIT, T as getMessageReplyConfig } from "./sender-0vqsivoI.js";
|
|
2
|
+
import { t as qqbotPlugin } from "./channel-BbwpkiY3.js";
|
|
3
|
+
import { a as resolveQQBotAccount, i as resolveDefaultQQBotAccountId, n as applyQQBotAccountConfig, r as listQQBotAccountIds, t as DEFAULT_ACCOUNT_ID } from "./config-CpOXnoEc.js";
|
|
4
|
+
import { t as qqbotSetupPlugin } from "./channel.setup-DfhritPL.js";
|
|
5
|
+
import { o as getFrameworkCommands } from "./group-Dbpnjalm.js";
|
|
6
|
+
import { C as resolveUserFacingMediaError, E as setOutboundAudioPort, T as OUTBOUND_ERROR_CODES, _ as sendVideoMsg, a as sendText, f as buildMediaTarget, g as sendPhoto, h as sendDocument, i as sendProactiveMessage, m as resolveOutboundMediaPath, n as sendCronMessage, p as parseTarget, r as sendMedia, v as sendVoice, w as DEFAULT_MEDIA_SEND_ERROR } from "./outbound-BLl8Tsu7.js";
|
|
7
|
+
import { n as registerRemindTool, r as registerChannelTool, t as registerQQBotTools } from "./tools-DYb23LBU.js";
|
|
8
|
+
import { t as registerQQBotFull } from "./channel-entry-Cj1lWXpt.js";
|
|
8
9
|
export { DEFAULT_ACCOUNT_ID, DEFAULT_MEDIA_SEND_ERROR, MESSAGE_REPLY_LIMIT, OUTBOUND_ERROR_CODES, applyQQBotAccountConfig, buildMediaTarget, checkMessageReplyLimit, getFrameworkCommands, getMessageReplyConfig, getMessageReplyStats, listQQBotAccountIds, parseTarget, qqbotPlugin, qqbotSetupPlugin, recordMessageReply, registerChannelTool, registerQQBotFull, registerQQBotTools, registerRemindTool, resolveDefaultQQBotAccountId, resolveOutboundMediaPath, resolveQQBotAccount, resolveUserFacingMediaError, sendCronMessage, sendDocument, sendMedia, sendPhoto, sendProactiveMessage, sendText, sendVideoMsg, sendVoice, setOutboundAudioPort };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as asOptionalObjectRecord } from "./string-normalize-R_0cKO7Q.js";
|
|
2
|
-
import { a as qqbotSetupAdapterShared, i as qqbotMeta, n as qqbotSetupWizard, o as ensurePlatformAdapter, r as qqbotConfigAdapter, s as getBridgeLogger, t as qqbotChannelConfigSchema } from "./config-schema-
|
|
3
|
-
import { a as resolveQQBotAccount, n as applyQQBotAccountConfig, r as listQQBotAccountIds, t as DEFAULT_ACCOUNT_ID$1 } from "./config-
|
|
4
|
-
import { t as getQQBotRuntime } from "./runtime-
|
|
5
|
-
import { n as legacyConfigRules, r as normalizeCompatibilityConfig, t as buildQQBotStateKey } from "./state-keys-
|
|
2
|
+
import { a as qqbotSetupAdapterShared, i as qqbotMeta, n as qqbotSetupWizard, o as ensurePlatformAdapter, r as qqbotConfigAdapter, s as getBridgeLogger, t as qqbotChannelConfigSchema } from "./config-schema-B5Mle_87.js";
|
|
3
|
+
import { a as resolveQQBotAccount, n as applyQQBotAccountConfig, r as listQQBotAccountIds, t as DEFAULT_ACCOUNT_ID$1 } from "./config-CpOXnoEc.js";
|
|
4
|
+
import { t as getQQBotRuntime } from "./runtime-Du28LbOJ.js";
|
|
5
|
+
import { n as legacyConfigRules, r as normalizeCompatibilityConfig, t as buildQQBotStateKey } from "./state-keys-jLJ2SmJA.js";
|
|
6
6
|
import { n as normalizeTarget, r as parseTarget, t as looksLikeQQBotTarget } from "./target-parser-DagYRQkP.js";
|
|
7
|
-
import { getExecApprovalReplyMetadata } from "openclaw/plugin-sdk/approval-runtime";
|
|
7
|
+
import { getExecApprovalReplyMetadata, resolveExecApprovalCommandDisplay } from "openclaw/plugin-sdk/approval-runtime";
|
|
8
8
|
import { buildChannelOutboundSessionRoute } from "openclaw/plugin-sdk/channel-core";
|
|
9
9
|
import { createMessageReceiptFromOutboundResults, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
|
|
10
10
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
@@ -17,34 +17,66 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
|
17
17
|
import { markImplicitSameChatApprovalAuthorization, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
18
18
|
import { createChannelExecApprovalProfile, isChannelExecApprovalClientEnabledFromConfig, matchesApprovalRequestFilters } from "openclaw/plugin-sdk/approval-client-runtime";
|
|
19
19
|
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
|
20
|
-
import {
|
|
20
|
+
import { buildChannelGroupsScopeTree, resolveScopeKeyCaseInsensitive, resolveScopeToolsPolicy } from "openclaw/plugin-sdk/channel-policy";
|
|
21
21
|
//#region extensions/qqbot/src/engine/approval/index.ts
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
function
|
|
30
|
-
const
|
|
22
|
+
const COMMAND_PREVIEW_MAX_LENGTH = 300;
|
|
23
|
+
const COMMAND_PREVIEW_GRAPHEMES_PER_LINE = 24;
|
|
24
|
+
const COMMAND_PREVIEW_WRAP_MARKER = "↩";
|
|
25
|
+
const commandPreviewSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
26
|
+
function splitCommandPreviewGraphemes(commandText) {
|
|
27
|
+
return commandPreviewSegmenter ? Array.from(commandPreviewSegmenter.segment(commandText), ({ segment }) => segment) : Array.from(commandText);
|
|
28
|
+
}
|
|
29
|
+
function formatCommandPreview(commandText) {
|
|
30
|
+
const lines = [""];
|
|
31
|
+
const displayText = commandText.replaceAll(COMMAND_PREVIEW_WRAP_MARKER, "\\u{21A9}");
|
|
32
|
+
let previewLength = 0;
|
|
33
|
+
let lineGraphemes = 0;
|
|
34
|
+
let truncated = false;
|
|
35
|
+
let wrapped = false;
|
|
36
|
+
for (const grapheme of splitCommandPreviewGraphemes(displayText)) {
|
|
37
|
+
if (previewLength + grapheme.length > COMMAND_PREVIEW_MAX_LENGTH) {
|
|
38
|
+
if (previewLength === 0) lines[0] = truncateUtf16Safe(grapheme, COMMAND_PREVIEW_MAX_LENGTH);
|
|
39
|
+
truncated = true;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
previewLength += grapheme.length;
|
|
43
|
+
if (lineGraphemes === COMMAND_PREVIEW_GRAPHEMES_PER_LINE) {
|
|
44
|
+
lines[lines.length - 1] += COMMAND_PREVIEW_WRAP_MARKER;
|
|
45
|
+
lines.push("");
|
|
46
|
+
lineGraphemes = 0;
|
|
47
|
+
wrapped = true;
|
|
48
|
+
}
|
|
49
|
+
lines[lines.length - 1] += grapheme;
|
|
50
|
+
lineGraphemes += 1;
|
|
51
|
+
}
|
|
52
|
+
const preview = `${lines.join("\n")}${truncated ? "\n…[truncated]" : ""}`;
|
|
53
|
+
const longestBacktickRun = Math.max(0, ...preview.match(/`+/g)?.map((run) => run.length) ?? []);
|
|
54
|
+
const fence = "`".repeat(Math.max(3, longestBacktickRun + 1));
|
|
55
|
+
const block = `${fence}\n${preview}\n${fence}`;
|
|
56
|
+
return wrapped ? `${COMMAND_PREVIEW_WRAP_MARKER} = display wrap only; not command text\n${block}` : block;
|
|
57
|
+
}
|
|
58
|
+
function formatApprovalMetadata(value) {
|
|
59
|
+
const sanitized = resolveExecApprovalCommandDisplay({ command: value }).commandText;
|
|
60
|
+
return formatCommandPreview(sanitized);
|
|
61
|
+
}
|
|
62
|
+
function buildExecApprovalText(view, nowMs = Date.now()) {
|
|
63
|
+
const expiresIn = Math.max(0, Math.round((view.expiresAtMs - nowMs) / 1e3));
|
|
31
64
|
const lines = ["🔐 命令执行审批", ""];
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
if (
|
|
35
|
-
if (request.request.agentId) lines.push(`\u{1f916} Agent: ${request.request.agentId}`);
|
|
65
|
+
if (view.commandText) lines.push(formatCommandPreview(view.commandText));
|
|
66
|
+
if (view.cwd) lines.push(`\u{1f4c1} \u76ee\u5f55:\n${formatApprovalMetadata(view.cwd)}`);
|
|
67
|
+
if (view.agentId) lines.push(`\u{1f916} Agent:\n${formatApprovalMetadata(view.agentId)}`);
|
|
36
68
|
lines.push("", `\u23f1\ufe0f \u8d85\u65f6: ${expiresIn} \u79d2`);
|
|
37
69
|
return lines.join("\n");
|
|
38
70
|
}
|
|
39
|
-
function buildPluginApprovalText(
|
|
40
|
-
const
|
|
41
|
-
const lines = [`${
|
|
42
|
-
lines.push(`\u{1f4cb} ${
|
|
43
|
-
if (
|
|
44
|
-
if (
|
|
45
|
-
if (
|
|
46
|
-
if (
|
|
47
|
-
lines.push("", `\u23f1\ufe0f \u8d85\u65f6: ${
|
|
71
|
+
function buildPluginApprovalText(view, nowMs = Date.now()) {
|
|
72
|
+
const expiresIn = Math.max(0, Math.round((view.expiresAtMs - nowMs) / 1e3));
|
|
73
|
+
const lines = [`${view.severity === "critical" ? "🔴" : view.severity === "info" ? "🔵" : "🟡"} \u5ba1\u6279\u8bf7\u6c42`, ""];
|
|
74
|
+
lines.push(`\u{1f4cb} ${view.title}`);
|
|
75
|
+
if (view.description) lines.push(`\u{1f4dd} ${view.description}`);
|
|
76
|
+
if (view.toolName) lines.push(`\u{1f527} \u5de5\u5177: ${view.toolName}`);
|
|
77
|
+
if (view.pluginId) lines.push(`\u{1f50c} \u63d2\u4ef6: ${view.pluginId}`);
|
|
78
|
+
if (view.agentId) lines.push(`\u{1f916} Agent: ${view.agentId}`);
|
|
79
|
+
lines.push("", `\u23f1\ufe0f \u8d85\u65f6: ${expiresIn} \u79d2`);
|
|
48
80
|
return lines.join("\n");
|
|
49
81
|
}
|
|
50
82
|
/**
|
|
@@ -55,11 +87,12 @@ function buildPluginApprovalText(request) {
|
|
|
55
87
|
* click_limit=1: each user can only click once.
|
|
56
88
|
* permission.type=2: all users can interact.
|
|
57
89
|
*/
|
|
58
|
-
function buildApprovalKeyboard(approvalId, allowedDecisions = [
|
|
90
|
+
function buildApprovalKeyboard(approvalId, approvalKind, allowedDecisions = [
|
|
59
91
|
"allow-once",
|
|
60
92
|
"allow-always",
|
|
61
93
|
"deny"
|
|
62
94
|
]) {
|
|
95
|
+
const actionPrefix = `approve:v2:${approvalKind}:${encodeURIComponent(approvalId)}`;
|
|
63
96
|
const makeBtn = (id, label, visitedLabel, data, style) => ({
|
|
64
97
|
id,
|
|
65
98
|
render_data: {
|
|
@@ -76,9 +109,9 @@ function buildApprovalKeyboard(approvalId, allowedDecisions = [
|
|
|
76
109
|
group_id: "approval"
|
|
77
110
|
});
|
|
78
111
|
const buttons = [];
|
|
79
|
-
if (allowedDecisions.includes("allow-once")) buttons.push(makeBtn("allow", "✅ 允许一次", "
|
|
80
|
-
if (allowedDecisions.includes("allow-always")) buttons.push(makeBtn("always", "⭐ 始终允许", "
|
|
81
|
-
if (allowedDecisions.includes("deny")) buttons.push(makeBtn("deny", "❌ 拒绝", "
|
|
112
|
+
if (allowedDecisions.includes("allow-once")) buttons.push(makeBtn("allow", "✅ 允许一次", "已处理", `${actionPrefix}:allow-once`, 1));
|
|
113
|
+
if (allowedDecisions.includes("allow-always")) buttons.push(makeBtn("always", "⭐ 始终允许", "已处理", `${actionPrefix}:allow-always`, 1));
|
|
114
|
+
if (allowedDecisions.includes("deny")) buttons.push(makeBtn("deny", "❌ 拒绝", "已处理", `${actionPrefix}:deny`, 0));
|
|
82
115
|
return { content: { rows: [{ buttons }] } };
|
|
83
116
|
}
|
|
84
117
|
/**
|
|
@@ -96,25 +129,39 @@ function resolveApprovalTarget(sessionKey, turnSourceTo) {
|
|
|
96
129
|
if (!sk) return null;
|
|
97
130
|
const m = sk.match(/qqbot:(c2c|direct|group):([A-F0-9]+)/i);
|
|
98
131
|
if (!m) return null;
|
|
132
|
+
const scope = m[1];
|
|
133
|
+
const id = m[2];
|
|
134
|
+
if (scope === void 0 || id === void 0) return null;
|
|
99
135
|
return {
|
|
100
|
-
type:
|
|
101
|
-
id
|
|
136
|
+
type: scope.toLowerCase() === "group" ? "group" : "c2c",
|
|
137
|
+
id
|
|
102
138
|
};
|
|
103
139
|
}
|
|
104
140
|
/**
|
|
105
141
|
* Parse the button_data string from an INTERACTION_CREATE event.
|
|
106
142
|
*
|
|
107
|
-
* Expected format: `approve:<
|
|
108
|
-
* where approvalId may be prefixed with "exec:" or "plugin:".
|
|
143
|
+
* Expected format: `approve:v2:<approvalKind>:<encodedApprovalId>:<decision>`.
|
|
109
144
|
*
|
|
110
145
|
* Returns null if the data does not match the approval button format.
|
|
111
146
|
*/
|
|
112
147
|
function parseApprovalButtonData(buttonData) {
|
|
113
|
-
const m = buttonData.match(/^approve:(
|
|
114
|
-
if (!m) return null;
|
|
148
|
+
const m = buttonData.match(/^approve:v2:(exec|plugin):([^:]+):(allow-once|allow-always|deny)$/);
|
|
149
|
+
if (!m || m[0] !== buttonData) return null;
|
|
150
|
+
let approvalId;
|
|
151
|
+
const kind = m[1];
|
|
152
|
+
const encodedId = m[2];
|
|
153
|
+
const decision = m[3];
|
|
154
|
+
if (kind !== "exec" && kind !== "plugin" || encodedId === void 0 || decision !== "allow-once" && decision !== "allow-always" && decision !== "deny") return null;
|
|
155
|
+
try {
|
|
156
|
+
approvalId = decodeURIComponent(encodedId);
|
|
157
|
+
} catch {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
if (!approvalId) return null;
|
|
115
161
|
return {
|
|
116
|
-
approvalId
|
|
117
|
-
|
|
162
|
+
approvalId,
|
|
163
|
+
approvalKind: kind,
|
|
164
|
+
decision
|
|
118
165
|
};
|
|
119
166
|
}
|
|
120
167
|
//#endregion
|
|
@@ -375,7 +422,7 @@ function createQQBotApprovalCapability() {
|
|
|
375
422
|
},
|
|
376
423
|
load: async () => {
|
|
377
424
|
ensurePlatformAdapter();
|
|
378
|
-
return (await import("./handler-runtime-
|
|
425
|
+
return (await import("./handler-runtime-BvR-ayNW.js")).qqbotApprovalNativeRuntime;
|
|
379
426
|
}
|
|
380
427
|
})
|
|
381
428
|
});
|
|
@@ -746,7 +793,8 @@ var QQBotMarkdownChunkingState = class {
|
|
|
746
793
|
const bodyLines = pendingFenceOpenLine ? [...this.textLines] : this.textLines.slice(1);
|
|
747
794
|
this.textLines = [];
|
|
748
795
|
this.pendingTextFenceOpenLine = null;
|
|
749
|
-
|
|
796
|
+
const lastBodyLine = bodyLines.at(-1);
|
|
797
|
+
if (lastBodyLine !== void 0 && isClosingFenceLine(lastBodyLine, fence)) bodyLines.pop();
|
|
750
798
|
if (this.activeFence && bodyLines.length === 0) return true;
|
|
751
799
|
pushFenceLineChunks({
|
|
752
800
|
chunks,
|
|
@@ -994,22 +1042,19 @@ function isClosingFenceLine(line, fence) {
|
|
|
994
1042
|
//#endregion
|
|
995
1043
|
//#region extensions/qqbot/src/group-policy.ts
|
|
996
1044
|
function resolveQQBotGroupToolPolicy(params) {
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
senderName: params.senderName,
|
|
1005
|
-
senderUsername: params.senderUsername,
|
|
1006
|
-
senderE164: params.senderE164
|
|
1045
|
+
const tree = buildChannelGroupsScopeTree(params.cfg, "qqbot", params.accountId);
|
|
1046
|
+
const scopeKey = resolveScopeKeyCaseInsensitive(tree, params.groupId);
|
|
1047
|
+
return resolveScopeToolsPolicy({
|
|
1048
|
+
...params,
|
|
1049
|
+
tree,
|
|
1050
|
+
path: scopeKey ? [scopeKey] : [],
|
|
1051
|
+
messageProvider: "qqbot"
|
|
1007
1052
|
});
|
|
1008
1053
|
}
|
|
1009
1054
|
//#endregion
|
|
1010
1055
|
//#region extensions/qqbot/src/channel.ts
|
|
1011
|
-
const loadGatewayModule = createLazyRuntimeModule(() => import("./gateway-
|
|
1012
|
-
const loadOutboundMessagingModule = createLazyRuntimeModule(() => import("./outbound-
|
|
1056
|
+
const loadGatewayModule = createLazyRuntimeModule(() => import("./gateway-be5-Ckdc.js"));
|
|
1057
|
+
const loadOutboundMessagingModule = createLazyRuntimeModule(() => import("./outbound-BLl8Tsu7.js").then((n) => n.t));
|
|
1013
1058
|
function createQQBotSendReceipt(params) {
|
|
1014
1059
|
const messageId = params.messageId?.trim();
|
|
1015
1060
|
return createMessageReceiptFromOutboundResults({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as resolveQQBotAccount } from "./config-
|
|
2
|
-
import { d as PRIVATE_CHAT_ONLY_TEXT, n as resolveGroupCommandLevelFromAccountConfig, o as getFrameworkCommands } from "./group-
|
|
3
|
-
import { h as sendDocument } from "./outbound-
|
|
4
|
-
import { t as registerQQBotTools } from "./tools-
|
|
1
|
+
import { a as resolveQQBotAccount } from "./config-CpOXnoEc.js";
|
|
2
|
+
import { d as PRIVATE_CHAT_ONLY_TEXT, n as resolveGroupCommandLevelFromAccountConfig, o as getFrameworkCommands } from "./group-Dbpnjalm.js";
|
|
3
|
+
import { h as sendDocument } from "./outbound-BLl8Tsu7.js";
|
|
4
|
+
import { t as registerQQBotTools } from "./tools-DYb23LBU.js";
|
|
5
5
|
//#region extensions/qqbot/src/bridge/commands/framework-context-adapter.ts
|
|
6
6
|
/**
|
|
7
7
|
* Default queue snapshot used for framework-registered commands.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as registerQQBotFull } from "./channel-entry-
|
|
1
|
+
import { t as registerQQBotFull } from "./channel-entry-Cj1lWXpt.js";
|
|
2
2
|
export { registerQQBotFull };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as qqbotPlugin } from "./channel-
|
|
1
|
+
import { t as qqbotPlugin } from "./channel-BbwpkiY3.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-
|
|
1
|
+
import { a as qqbotSetupAdapterShared, i as qqbotMeta, n as qqbotSetupWizard, r as qqbotConfigAdapter, t as qqbotChannelConfigSchema } from "./config-schema-B5Mle_87.js";
|
|
2
2
|
//#region extensions/qqbot/src/channel.setup.ts
|
|
3
3
|
/**
|
|
4
4
|
* Setup-only QQBot plugin — lightweight subset used during `openclaw onboard`
|
|
@@ -56,8 +56,8 @@ function resolveDefaultAccountId(cfg) {
|
|
|
56
56
|
if (configuredDefaultAccountId && (configuredDefaultAccountId === "default" || Boolean(qqbot?.accounts?.[configuredDefaultAccountId]?.appId))) return configuredDefaultAccountId;
|
|
57
57
|
if (qqbot?.appId || process.env.QQBOT_APP_ID) return DEFAULT_ACCOUNT_ID$1;
|
|
58
58
|
if (qqbot?.accounts) {
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
59
|
+
const firstId = Object.keys(qqbot.accounts).at(0);
|
|
60
|
+
if (firstId !== void 0) return firstId;
|
|
61
61
|
}
|
|
62
62
|
return DEFAULT_ACCOUNT_ID$1;
|
|
63
63
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { d as registerPlatformAdapterFactory, l as hasPlatformAdapter, n as normalizeLowercaseStringOrEmpty, u as registerPlatformAdapter } from "./string-normalize-R_0cKO7Q.js";
|
|
2
|
-
import { a as resolveQQBotAccount, c as describeAccount, i as resolveDefaultQQBotAccountId, l as formatAllowFrom, n as applyQQBotAccountConfig, r as listQQBotAccountIds, s as applyAccountConfig, u as isAccountConfigured } from "./config-
|
|
2
|
+
import { a as resolveQQBotAccount, c as describeAccount, i as resolveDefaultQQBotAccountId, l as formatAllowFrom, n as applyQQBotAccountConfig, r as listQQBotAccountIds, s as applyAccountConfig, u as isAccountConfigured } from "./config-CpOXnoEc.js";
|
|
3
3
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
4
4
|
import { buildSecretInputSchema, hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
5
5
|
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
|
6
6
|
import { applyAccountNameToChannelSection, deleteAccountFromConfigSection, setAccountEnabledInConfigSection } from "openclaw/plugin-sdk/core";
|
|
7
7
|
import { DEFAULT_ACCOUNT_ID, createStandardChannelSetupStatus, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
8
|
+
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
8
9
|
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
9
10
|
import { AllowFromListSchema, ToolPolicySchema, buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
10
11
|
import { z } from "zod";
|
|
@@ -24,30 +25,6 @@ function getBridgeLogger() {
|
|
|
24
25
|
}
|
|
25
26
|
//#endregion
|
|
26
27
|
//#region extensions/qqbot/src/bridge/bootstrap.ts
|
|
27
|
-
/**
|
|
28
|
-
* Bootstrap the PlatformAdapter for the built-in version.
|
|
29
|
-
*
|
|
30
|
-
* ## Design
|
|
31
|
-
*
|
|
32
|
-
* The adapter is registered via two complementary mechanisms:
|
|
33
|
-
*
|
|
34
|
-
* 1. **Factory registration** (`registerPlatformAdapterFactory`) — a lightweight
|
|
35
|
-
* callback stored in `adapter/index.ts` that is invoked lazily by
|
|
36
|
-
* `getPlatformAdapter()` on first access. This guarantees the adapter is
|
|
37
|
-
* available regardless of module evaluation order or bundler chunk splitting.
|
|
38
|
-
*
|
|
39
|
-
* 2. **Eager side-effect** (`ensurePlatformAdapter()`) — called at module
|
|
40
|
-
* evaluation time when `channel.ts` imports this file. Provides the adapter
|
|
41
|
-
* immediately for code that runs synchronously during startup.
|
|
42
|
-
*
|
|
43
|
-
* Heavy async-only dependencies (`media-runtime`, `config-runtime`,
|
|
44
|
-
* `approval-gateway-runtime`) are lazy-imported inside each async method body
|
|
45
|
-
* so that this module evaluates with minimal overhead.
|
|
46
|
-
*
|
|
47
|
-
* Synchronous dependencies (`secret-input`, `temp-path`) are imported
|
|
48
|
-
* statically at the top level so they work reliably in both production and
|
|
49
|
-
* vitest (which resolves bare specifiers via `resolve.alias`, not Node CJS).
|
|
50
|
-
*/
|
|
51
28
|
const loadMediaRuntimeModule = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/media-runtime"));
|
|
52
29
|
function createBuiltinAdapter() {
|
|
53
30
|
return {
|
|
@@ -75,6 +52,8 @@ function createBuiltinAdapter() {
|
|
|
75
52
|
filePathHint: options.filePathHint,
|
|
76
53
|
maxBytes: options.maxBytes,
|
|
77
54
|
maxRedirects: options.maxRedirects,
|
|
55
|
+
timeoutMs: options.timeoutMs,
|
|
56
|
+
responseHeaderTimeoutMs: options.responseHeaderTimeoutMs,
|
|
78
57
|
ssrfPolicy: options.ssrfPolicy,
|
|
79
58
|
requestInit: options.requestInit
|
|
80
59
|
});
|
|
@@ -95,20 +74,20 @@ function createBuiltinAdapter() {
|
|
|
95
74
|
resolveSecretInputString(params) {
|
|
96
75
|
return normalizeResolvedSecretInputString(params) ?? void 0;
|
|
97
76
|
},
|
|
98
|
-
async resolveApproval(
|
|
77
|
+
async resolveApproval(params) {
|
|
99
78
|
try {
|
|
100
79
|
const { getRuntimeConfig } = await import("openclaw/plugin-sdk/runtime-config-snapshot");
|
|
101
80
|
const { resolveApprovalOverGateway } = await import("openclaw/plugin-sdk/approval-gateway-runtime");
|
|
102
|
-
await resolveApprovalOverGateway({
|
|
81
|
+
return await resolveApprovalOverGateway({
|
|
103
82
|
cfg: getRuntimeConfig(),
|
|
104
|
-
approvalId,
|
|
105
|
-
|
|
83
|
+
approvalId: params.approvalId,
|
|
84
|
+
approvalKind: params.approvalKind,
|
|
85
|
+
decision: params.decision,
|
|
106
86
|
clientDisplayName: "QQBot Approval Handler"
|
|
107
87
|
});
|
|
108
|
-
return true;
|
|
109
88
|
} catch (err) {
|
|
110
89
|
getBridgeLogger().error(`[qqbot] resolveApproval failed: ${String(err)}`);
|
|
111
|
-
|
|
90
|
+
throw err;
|
|
112
91
|
}
|
|
113
92
|
}
|
|
114
93
|
};
|
|
@@ -247,32 +226,43 @@ function isQQBotAccountConfigured(cfg, accountId) {
|
|
|
247
226
|
const account = resolveQQBotAccount(cfg, accountId, { allowUnresolvedSecretRef: true });
|
|
248
227
|
return Boolean(account.appId && account.clientSecret);
|
|
249
228
|
}
|
|
229
|
+
async function reportQQBotLinkFailure(params, error) {
|
|
230
|
+
params.runtime.error(`QQ Bot 绑定失败: ${String(error)}`);
|
|
231
|
+
await params.prompter.note(["绑定失败,您可以稍后手动配置。", `文档: ${formatDocsLink("/channels/qqbot", "qqbot")}`].join("\n"), "QQ Bot");
|
|
232
|
+
}
|
|
250
233
|
async function linkViaQrCode(params) {
|
|
234
|
+
let connector;
|
|
251
235
|
try {
|
|
252
|
-
|
|
253
|
-
|
|
236
|
+
connector = await import("@tencent-connect/qqbot-connector");
|
|
237
|
+
} catch (error) {
|
|
238
|
+
await reportQQBotLinkFailure(params, error);
|
|
239
|
+
return params.cfg;
|
|
240
|
+
}
|
|
241
|
+
await params.beforePersistentEffect?.();
|
|
242
|
+
try {
|
|
243
|
+
const accounts = await connector.qrConnect({ source: "openclaw" });
|
|
254
244
|
if (accounts.length === 0) {
|
|
255
245
|
await params.prompter.note("未获取到任何 QQ Bot 账号信息。", "QQ Bot");
|
|
256
246
|
return params.cfg;
|
|
257
247
|
}
|
|
258
248
|
let next = params.cfg;
|
|
259
|
-
for (
|
|
260
|
-
const { appId, appSecret } = accounts[i];
|
|
249
|
+
for (const [i, { appId, appSecret }] of accounts.entries()) {
|
|
261
250
|
const targetAccountId = i === 0 ? params.accountId : appId;
|
|
262
251
|
next = applyQQBotAccountConfig(next, targetAccountId, {
|
|
263
252
|
appId,
|
|
264
253
|
clientSecret: appSecret
|
|
265
254
|
});
|
|
266
255
|
}
|
|
267
|
-
if (accounts.length === 1)
|
|
268
|
-
|
|
256
|
+
if (accounts.length === 1) {
|
|
257
|
+
const account = expectDefined(accounts.at(0), "single linked QQ Bot account");
|
|
258
|
+
params.runtime.log(`✔ QQ Bot 绑定成功!(AppID: ${account.appId})`);
|
|
259
|
+
} else {
|
|
269
260
|
const idList = accounts.map((a) => a.appId).join(", ");
|
|
270
261
|
params.runtime.log(`✔ ${accounts.length} 个 QQ Bot 绑定成功!(AppID: ${idList})`);
|
|
271
262
|
}
|
|
272
263
|
return next;
|
|
273
264
|
} catch (error) {
|
|
274
|
-
params
|
|
275
|
-
await params.prompter.note(["绑定失败,您可以稍后手动配置。", `文档: ${formatDocsLink("/channels/qqbot", "qqbot")}`].join("\n"), "QQ Bot");
|
|
265
|
+
await reportQQBotLinkFailure(params, error);
|
|
276
266
|
return params.cfg;
|
|
277
267
|
}
|
|
278
268
|
}
|
|
@@ -319,7 +309,8 @@ async function finalizeQQBotSetup(params) {
|
|
|
319
309
|
cfg: next,
|
|
320
310
|
accountId,
|
|
321
311
|
prompter: params.prompter,
|
|
322
|
-
runtime: params.runtime
|
|
312
|
+
runtime: params.runtime,
|
|
313
|
+
beforePersistentEffect: params.options?.beforePersistentEffect
|
|
323
314
|
});
|
|
324
315
|
else if (mode === "manual") next = await linkViaManualInput({
|
|
325
316
|
cfg: next,
|
|
@@ -347,12 +338,13 @@ const qqbotSetupWizard = {
|
|
|
347
338
|
})
|
|
348
339
|
}),
|
|
349
340
|
credentials: [],
|
|
350
|
-
finalize: async ({ cfg, accountId, forceAllowFrom, prompter, runtime }) => await finalizeQQBotSetup({
|
|
341
|
+
finalize: async ({ cfg, accountId, forceAllowFrom, prompter, runtime, options }) => await finalizeQQBotSetup({
|
|
351
342
|
cfg,
|
|
352
343
|
accountId,
|
|
353
344
|
forceAllowFrom,
|
|
354
345
|
prompter,
|
|
355
|
-
runtime
|
|
346
|
+
runtime,
|
|
347
|
+
options
|
|
356
348
|
}),
|
|
357
349
|
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
|
|
358
350
|
};
|
|
@@ -370,13 +362,12 @@ const QQBotSttSchema = z.object({
|
|
|
370
362
|
apiKey: z.string().optional(),
|
|
371
363
|
model: z.string().optional()
|
|
372
364
|
}).strict().optional();
|
|
373
|
-
|
|
374
|
-
const QQBotStreamingSchema = z.union([z.boolean(), z.object({
|
|
365
|
+
const QQBotStreamingSchema = z.object({
|
|
375
366
|
/** "partial" (default) enables block streaming; "off" disables it. */
|
|
376
367
|
mode: z.enum(["off", "partial"]).default("partial"),
|
|
377
|
-
/**
|
|
378
|
-
|
|
379
|
-
}).
|
|
368
|
+
/** Use QQ's official C2C `stream_messages` API for DM replies. */
|
|
369
|
+
nativeTransport: z.boolean().optional()
|
|
370
|
+
}).strict().optional();
|
|
380
371
|
const QQBotExecApprovalsSchema = z.object({
|
|
381
372
|
enabled: z.union([z.boolean(), z.literal("auto")]).optional(),
|
|
382
373
|
approvers: z.array(z.string()).optional(),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as legacyConfigRules, r as normalizeCompatibilityConfig, t as buildQQBotStateKey } from "./state-keys-
|
|
1
|
+
import { n as legacyConfigRules, r as normalizeCompatibilityConfig, t as buildQQBotStateKey } from "./state-keys-jLJ2SmJA.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
//#region extensions/qqbot/src/state-migrations.ts
|