@cxyhhhhh/openclaw-qqbot 2.0.0-dev.202607101541 → 2.0.0-dev.202607101939
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/index.cjs +1139 -835
- package/dist/index.cjs.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/adapter/contract.ts +1 -1
- package/src/adapter/resolve.ts +38 -0
- package/src/channel.ts +15 -0
- package/src/features/approval-utils.ts +0 -4
- package/src/openclaw-plugin-sdk.d.ts +16 -0
- package/src/outbound/media-send.ts +48 -9
- package/src/setup/account-key.ts +41 -0
- package/src/setup/finalize.ts +15 -14
- package/src/setup/login.ts +197 -0
- package/src/setup/surface.ts +9 -1
- package/skills/qqbot-group/SKILL.md +0 -75
- package/skills/qqbot-group/references/api_reference.md +0 -94
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
@@ -31,6 +34,272 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
34
|
));
|
|
32
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
36
|
|
|
37
|
+
// src/config.ts
|
|
38
|
+
var config_exports = {};
|
|
39
|
+
__export(config_exports, {
|
|
40
|
+
DEFAULT_ACCOUNT_ID: () => DEFAULT_ACCOUNT_ID,
|
|
41
|
+
applyQQBotAccountConfig: () => applyQQBotAccountConfig,
|
|
42
|
+
isGroupAllowed: () => isGroupAllowed,
|
|
43
|
+
listQQBotAccountIds: () => listQQBotAccountIds,
|
|
44
|
+
resolveDefaultQQBotAccountId: () => resolveDefaultQQBotAccountId,
|
|
45
|
+
resolveGroupAllowFrom: () => resolveGroupAllowFrom,
|
|
46
|
+
resolveGroupConfig: () => resolveGroupConfig,
|
|
47
|
+
resolveGroupConfigFromAccount: () => resolveGroupConfigFromAccount,
|
|
48
|
+
resolveGroupName: () => resolveGroupName,
|
|
49
|
+
resolveGroupPolicy: () => resolveGroupPolicy,
|
|
50
|
+
resolveGroupPrompt: () => resolveGroupPrompt,
|
|
51
|
+
resolveHistoryLimit: () => resolveHistoryLimit,
|
|
52
|
+
resolveIgnoreOtherMentions: () => resolveIgnoreOtherMentions,
|
|
53
|
+
resolveMentionPatterns: () => resolveMentionPatterns,
|
|
54
|
+
resolveProcessingTimeoutMs: () => resolveProcessingTimeoutMs,
|
|
55
|
+
resolveQQBotAccount: () => resolveQQBotAccount,
|
|
56
|
+
resolveRequireMention: () => resolveRequireMention,
|
|
57
|
+
resolveToolPolicy: () => resolveToolPolicy,
|
|
58
|
+
resolveUserAgentSuffix: () => resolveUserAgentSuffix
|
|
59
|
+
});
|
|
60
|
+
function resolveMentionPatterns(cfg, agentId) {
|
|
61
|
+
if (agentId) {
|
|
62
|
+
const agents = cfg.agents;
|
|
63
|
+
const entry = agents?.list?.find((a) => a.id?.trim().toLowerCase() === agentId.trim().toLowerCase());
|
|
64
|
+
const agentGroupChat = entry?.groupChat;
|
|
65
|
+
if (agentGroupChat && Object.hasOwn(agentGroupChat, "mentionPatterns")) {
|
|
66
|
+
return agentGroupChat.mentionPatterns ?? [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const globalGroupChat = cfg?.messages?.groupChat;
|
|
70
|
+
if (globalGroupChat && typeof globalGroupChat === "object" && Object.hasOwn(globalGroupChat, "mentionPatterns")) {
|
|
71
|
+
return globalGroupChat.mentionPatterns ?? [];
|
|
72
|
+
}
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
function evaluateMatchedGroupAccessForPolicy(params) {
|
|
76
|
+
if (params.groupPolicy === "disabled") {
|
|
77
|
+
return { allowed: false, groupPolicy: params.groupPolicy, reason: "disabled" };
|
|
78
|
+
}
|
|
79
|
+
if (params.groupPolicy === "allowlist") {
|
|
80
|
+
if (params.requireMatchInput && !params.hasMatchInput) {
|
|
81
|
+
return { allowed: false, groupPolicy: params.groupPolicy, reason: "missing_match_input" };
|
|
82
|
+
}
|
|
83
|
+
if (!params.allowlistConfigured) {
|
|
84
|
+
return { allowed: false, groupPolicy: params.groupPolicy, reason: "empty_allowlist" };
|
|
85
|
+
}
|
|
86
|
+
if (!params.allowlistMatched) {
|
|
87
|
+
return { allowed: false, groupPolicy: params.groupPolicy, reason: "not_allowlisted" };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { allowed: true, groupPolicy: params.groupPolicy, reason: "allowed" };
|
|
91
|
+
}
|
|
92
|
+
function resolveGroupPolicy(cfg, accountId) {
|
|
93
|
+
const account = resolveQQBotAccount(cfg, accountId);
|
|
94
|
+
return account.config?.groupPolicy ?? DEFAULT_GROUP_POLICY;
|
|
95
|
+
}
|
|
96
|
+
function resolveGroupAllowFrom(cfg, accountId) {
|
|
97
|
+
const account = resolveQQBotAccount(cfg, accountId);
|
|
98
|
+
return (account.config?.groupAllowFrom ?? []).map((id) => String(id).trim().toUpperCase());
|
|
99
|
+
}
|
|
100
|
+
function isGroupAllowed(cfg, groupOpenid, accountId) {
|
|
101
|
+
const account = resolveQQBotAccount(cfg, accountId);
|
|
102
|
+
const policy = account.config?.groupPolicy ?? DEFAULT_GROUP_POLICY;
|
|
103
|
+
const allowList = (account.config?.groupAllowFrom ?? []).map((id) => String(id).trim().toUpperCase());
|
|
104
|
+
const allowlistConfigured = allowList.length > 0;
|
|
105
|
+
const allowlistMatched = allowList.some((id) => id === "*" || id === groupOpenid.toUpperCase());
|
|
106
|
+
return evaluateMatchedGroupAccessForPolicy({
|
|
107
|
+
groupPolicy: policy,
|
|
108
|
+
allowlistConfigured,
|
|
109
|
+
allowlistMatched
|
|
110
|
+
}).allowed;
|
|
111
|
+
}
|
|
112
|
+
function resolveGroupConfigFromAccount(account, groupOpenid) {
|
|
113
|
+
const groups = account.config?.groups ?? {};
|
|
114
|
+
const wildcardCfg = groups["*"] ?? {};
|
|
115
|
+
const specificCfg = groups[groupOpenid] ?? {};
|
|
116
|
+
const accountDefaultRequireMention = account.config?.defaultRequireMention ?? DEFAULT_GROUP_CONFIG.requireMention;
|
|
117
|
+
return {
|
|
118
|
+
requireMention: specificCfg.requireMention ?? wildcardCfg.requireMention ?? accountDefaultRequireMention,
|
|
119
|
+
ignoreOtherMentions: specificCfg.ignoreOtherMentions ?? wildcardCfg.ignoreOtherMentions ?? DEFAULT_GROUP_CONFIG.ignoreOtherMentions,
|
|
120
|
+
toolPolicy: specificCfg.toolPolicy ?? wildcardCfg.toolPolicy ?? DEFAULT_GROUP_CONFIG.toolPolicy,
|
|
121
|
+
name: specificCfg.name ?? wildcardCfg.name ?? DEFAULT_GROUP_CONFIG.name,
|
|
122
|
+
prompt: specificCfg.prompt ?? wildcardCfg.prompt ?? DEFAULT_GROUP_PROMPT,
|
|
123
|
+
historyLimit: specificCfg.historyLimit ?? wildcardCfg.historyLimit ?? DEFAULT_GROUP_CONFIG.historyLimit
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function resolveGroupConfig(cfg, groupOpenid, accountId) {
|
|
127
|
+
return resolveGroupConfigFromAccount(resolveQQBotAccount(cfg, accountId), groupOpenid);
|
|
128
|
+
}
|
|
129
|
+
function resolveHistoryLimit(cfg, groupOpenid, accountId) {
|
|
130
|
+
return Math.max(0, resolveGroupConfig(cfg, groupOpenid, accountId).historyLimit);
|
|
131
|
+
}
|
|
132
|
+
function resolveGroupPrompt(cfg, groupOpenid, accountId) {
|
|
133
|
+
return resolveGroupConfig(cfg, groupOpenid, accountId).prompt;
|
|
134
|
+
}
|
|
135
|
+
function resolveRequireMention(cfg, groupOpenid, accountId) {
|
|
136
|
+
return resolveGroupConfig(cfg, groupOpenid, accountId).requireMention;
|
|
137
|
+
}
|
|
138
|
+
function resolveIgnoreOtherMentions(cfg, groupOpenid, accountId) {
|
|
139
|
+
return resolveGroupConfig(cfg, groupOpenid, accountId).ignoreOtherMentions;
|
|
140
|
+
}
|
|
141
|
+
function resolveToolPolicy(cfg, groupOpenid, accountId) {
|
|
142
|
+
return resolveGroupConfig(cfg, groupOpenid, accountId).toolPolicy;
|
|
143
|
+
}
|
|
144
|
+
function resolveGroupName(cfg, groupOpenid, accountId) {
|
|
145
|
+
const name = resolveGroupConfig(cfg, groupOpenid, accountId).name;
|
|
146
|
+
return name || groupOpenid.slice(0, 8);
|
|
147
|
+
}
|
|
148
|
+
function normalizeAppId(raw) {
|
|
149
|
+
if (raw === null || raw === void 0) return "";
|
|
150
|
+
return String(raw).trim();
|
|
151
|
+
}
|
|
152
|
+
function listQQBotAccountIds(cfg) {
|
|
153
|
+
const ids = /* @__PURE__ */ new Set();
|
|
154
|
+
const qqbot = cfg.channels?.qqbot;
|
|
155
|
+
if (qqbot?.appId) {
|
|
156
|
+
ids.add(DEFAULT_ACCOUNT_ID);
|
|
157
|
+
}
|
|
158
|
+
if (qqbot?.accounts) {
|
|
159
|
+
for (const accountId of Object.keys(qqbot.accounts)) {
|
|
160
|
+
if (qqbot.accounts[accountId]?.appId) {
|
|
161
|
+
ids.add(accountId);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return Array.from(ids);
|
|
166
|
+
}
|
|
167
|
+
function resolveDefaultQQBotAccountId(cfg) {
|
|
168
|
+
const qqbot = cfg.channels?.qqbot;
|
|
169
|
+
if (qqbot?.appId) {
|
|
170
|
+
return DEFAULT_ACCOUNT_ID;
|
|
171
|
+
}
|
|
172
|
+
if (qqbot?.accounts) {
|
|
173
|
+
const ids = Object.keys(qqbot.accounts);
|
|
174
|
+
if (ids.length > 0) {
|
|
175
|
+
return ids[0];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return DEFAULT_ACCOUNT_ID;
|
|
179
|
+
}
|
|
180
|
+
function resolveUserAgentSuffix(cfg) {
|
|
181
|
+
const qqbot = cfg.channels?.qqbot;
|
|
182
|
+
return qqbot?.userAgentSuffix ? String(qqbot.userAgentSuffix).trim() : "";
|
|
183
|
+
}
|
|
184
|
+
function resolveProcessingTimeoutMs(accountConfig) {
|
|
185
|
+
if (accountConfig?.processingTimeoutMs !== void 0) {
|
|
186
|
+
return accountConfig.processingTimeoutMs;
|
|
187
|
+
}
|
|
188
|
+
const env = process.env.OPENCLAW_PROCESSING_TIMEOUT_MS;
|
|
189
|
+
if (env) {
|
|
190
|
+
const v = Number(env);
|
|
191
|
+
if (!Number.isNaN(v) && v >= 0) return v;
|
|
192
|
+
}
|
|
193
|
+
return DEFAULT_PROCESSING_TIMEOUT_MS;
|
|
194
|
+
}
|
|
195
|
+
function resolveQQBotAccount(cfg, accountId) {
|
|
196
|
+
const resolvedAccountId = accountId ?? resolveDefaultQQBotAccountId(cfg);
|
|
197
|
+
const qqbot = cfg.channels?.qqbot;
|
|
198
|
+
let accountConfig = {};
|
|
199
|
+
let appId = "";
|
|
200
|
+
let clientSecret = "";
|
|
201
|
+
let secretSource = "none";
|
|
202
|
+
if (resolvedAccountId === DEFAULT_ACCOUNT_ID) {
|
|
203
|
+
const { accounts: _accounts, ...topLevelConfig } = qqbot ?? {};
|
|
204
|
+
accountConfig = {
|
|
205
|
+
...topLevelConfig,
|
|
206
|
+
markdownSupport: qqbot?.markdownSupport ?? true
|
|
207
|
+
};
|
|
208
|
+
appId = normalizeAppId(qqbot?.appId);
|
|
209
|
+
} else {
|
|
210
|
+
const account = qqbot?.accounts?.[resolvedAccountId];
|
|
211
|
+
accountConfig = account ?? {};
|
|
212
|
+
appId = normalizeAppId(account?.appId);
|
|
213
|
+
}
|
|
214
|
+
if (accountConfig.clientSecret) {
|
|
215
|
+
clientSecret = accountConfig.clientSecret;
|
|
216
|
+
secretSource = "config";
|
|
217
|
+
} else if (accountConfig.clientSecretFile) {
|
|
218
|
+
secretSource = "file";
|
|
219
|
+
} else if (process.env.QQBOT_CLIENT_SECRET && resolvedAccountId === DEFAULT_ACCOUNT_ID) {
|
|
220
|
+
clientSecret = process.env.QQBOT_CLIENT_SECRET;
|
|
221
|
+
secretSource = "env";
|
|
222
|
+
}
|
|
223
|
+
if (!appId && process.env.QQBOT_APP_ID && resolvedAccountId === DEFAULT_ACCOUNT_ID) {
|
|
224
|
+
appId = normalizeAppId(process.env.QQBOT_APP_ID);
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
accountId: resolvedAccountId,
|
|
228
|
+
name: accountConfig.name,
|
|
229
|
+
enabled: accountConfig.enabled !== false,
|
|
230
|
+
appId,
|
|
231
|
+
clientSecret,
|
|
232
|
+
secretSource,
|
|
233
|
+
systemPrompt: accountConfig.systemPrompt,
|
|
234
|
+
markdownSupport: accountConfig.markdownSupport !== false,
|
|
235
|
+
userAgentSuffix: resolveUserAgentSuffix(cfg),
|
|
236
|
+
processingTimeoutMs: resolveProcessingTimeoutMs(accountConfig),
|
|
237
|
+
config: accountConfig
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function applyQQBotAccountConfig(cfg, accountId, input) {
|
|
241
|
+
const next = { ...cfg };
|
|
242
|
+
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
243
|
+
const existingConfig = next.channels?.qqbot || {};
|
|
244
|
+
const allowFrom = existingConfig.allowFrom ?? ["*"];
|
|
245
|
+
next.channels = {
|
|
246
|
+
...next.channels,
|
|
247
|
+
qqbot: {
|
|
248
|
+
...next.channels?.qqbot || {},
|
|
249
|
+
enabled: true,
|
|
250
|
+
allowFrom,
|
|
251
|
+
...input.appId ? { appId: input.appId } : {},
|
|
252
|
+
...input.clientSecret ? { clientSecret: input.clientSecret } : input.clientSecretFile ? { clientSecretFile: input.clientSecretFile } : {},
|
|
253
|
+
...input.name ? { name: input.name } : {}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
} else {
|
|
257
|
+
const existingAccountConfig = next.channels?.qqbot?.accounts?.[accountId] || {};
|
|
258
|
+
const allowFrom = existingAccountConfig.allowFrom ?? ["*"];
|
|
259
|
+
next.channels = {
|
|
260
|
+
...next.channels,
|
|
261
|
+
qqbot: {
|
|
262
|
+
...next.channels?.qqbot || {},
|
|
263
|
+
enabled: true,
|
|
264
|
+
accounts: {
|
|
265
|
+
...next.channels?.qqbot?.accounts || {},
|
|
266
|
+
[accountId]: {
|
|
267
|
+
...next.channels?.qqbot?.accounts?.[accountId] || {},
|
|
268
|
+
enabled: true,
|
|
269
|
+
allowFrom,
|
|
270
|
+
...input.appId ? { appId: input.appId } : {},
|
|
271
|
+
...input.clientSecret ? { clientSecret: input.clientSecret } : input.clientSecretFile ? { clientSecretFile: input.clientSecretFile } : {},
|
|
272
|
+
...input.name ? { name: input.name } : {}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return next;
|
|
279
|
+
}
|
|
280
|
+
var DEFAULT_ACCOUNT_ID, DEFAULT_GROUP_POLICY, DEFAULT_GROUP_HISTORY_LIMIT, DEFAULT_PROCESSING_TIMEOUT_MS, DEFAULT_GROUP_CONFIG, DEFAULT_GROUP_PROMPT;
|
|
281
|
+
var init_config = __esm({
|
|
282
|
+
"src/config.ts"() {
|
|
283
|
+
"use strict";
|
|
284
|
+
DEFAULT_ACCOUNT_ID = "default";
|
|
285
|
+
DEFAULT_GROUP_POLICY = "open";
|
|
286
|
+
DEFAULT_GROUP_HISTORY_LIMIT = 20;
|
|
287
|
+
DEFAULT_PROCESSING_TIMEOUT_MS = 0;
|
|
288
|
+
DEFAULT_GROUP_CONFIG = {
|
|
289
|
+
requireMention: true,
|
|
290
|
+
ignoreOtherMentions: false,
|
|
291
|
+
toolPolicy: "restricted",
|
|
292
|
+
name: "",
|
|
293
|
+
historyLimit: DEFAULT_GROUP_HISTORY_LIMIT
|
|
294
|
+
};
|
|
295
|
+
DEFAULT_GROUP_PROMPT = [
|
|
296
|
+
"\u82E5\u53D1\u9001\u8005\u4E3A\u673A\u5668\u4EBA\uFF0C\u4EC5\u5728\u5BF9\u65B9\u660E\u786E@\u4F60\u63D0\u95EE\u6216\u8BF7\u6C42\u534F\u52A9\u5177\u4F53\u4EFB\u52A1\u65F6\uFF0C\u4EE5\u7B80\u6D01\u660E\u4E86\u7684\u5185\u5BB9\u56DE\u590D\uFF0C",
|
|
297
|
+
"\u907F\u514D\u4E0E\u5176\u4ED6\u673A\u5668\u4EBA\u4EA7\u751F\u62A2\u7B54\u6216\u591A\u8F6E\u65E0\u610F\u4E49\u5BF9\u8BDD\u3002",
|
|
298
|
+
"\u5728\u7FA4\u804A\u4E2D\u4F18\u5148\u8BA9\u4EBA\u7C7B\u7528\u6237\u7684\u6D88\u606F\u5F97\u5230\u54CD\u5E94\uFF0C\u673A\u5668\u4EBA\u4E4B\u95F4\u4FDD\u6301\u534F\u4F5C\u800C\u975E\u7ADE\u4E89\uFF0C\u786E\u4FDD\u5BF9\u8BDD\u6709\u5E8F\u4E0D\u5237\u5C4F\u3002"
|
|
299
|
+
].join("");
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
34
303
|
// node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js
|
|
35
304
|
var require_constants = __commonJS({
|
|
36
305
|
"node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js"(exports2, module2) {
|
|
@@ -3710,16 +3979,248 @@ var require_websocket_server = __commonJS({
|
|
|
3710
3979
|
}
|
|
3711
3980
|
});
|
|
3712
3981
|
|
|
3713
|
-
//
|
|
3714
|
-
var
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3982
|
+
// src/adapter/resolve.ts
|
|
3983
|
+
var resolve_exports = {};
|
|
3984
|
+
__export(resolve_exports, {
|
|
3985
|
+
_resetAdaptersCache: () => _resetAdaptersCache,
|
|
3986
|
+
getAdapters: () => getAdapters,
|
|
3987
|
+
persistAuthConfig: () => persistAuthConfig,
|
|
3988
|
+
resolveRuntimeAdapters: () => resolveRuntimeAdapters
|
|
3989
|
+
});
|
|
3990
|
+
function probeFunction(rt, paths) {
|
|
3991
|
+
for (const path22 of paths) {
|
|
3992
|
+
let target = rt;
|
|
3993
|
+
let parent = rt;
|
|
3994
|
+
for (let i = 0; i < path22.length; i++) {
|
|
3995
|
+
parent = target;
|
|
3996
|
+
target = target?.[path22[i]];
|
|
3997
|
+
if (target === void 0 || target === null) break;
|
|
3998
|
+
}
|
|
3999
|
+
if (typeof target === "function") {
|
|
4000
|
+
return target.bind(parent);
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
return null;
|
|
4004
|
+
}
|
|
4005
|
+
function resolveRuntimeAdapters(rt, log4) {
|
|
4006
|
+
const version = rt.version ?? "unknown";
|
|
4007
|
+
const inboundRun = probeFunction(rt, [
|
|
4008
|
+
["channel", "inbound", "run"],
|
|
4009
|
+
// current (2026-05+)
|
|
4010
|
+
["channel", "turn", "run"]
|
|
4011
|
+
// legacy (removed 2026-05-27)
|
|
4012
|
+
]);
|
|
4013
|
+
const dispatchReply = probeFunction(rt, [
|
|
4014
|
+
["channel", "reply", "dispatchReplyWithBufferedBlockDispatcher"]
|
|
4015
|
+
]);
|
|
4016
|
+
const resolveAgentRoute = probeFunction(rt, [
|
|
4017
|
+
["channel", "routing", "resolveAgentRoute"]
|
|
4018
|
+
]);
|
|
4019
|
+
const rawBuildContext = probeFunction(rt, [
|
|
4020
|
+
["channel", "inbound", "buildContext"]
|
|
4021
|
+
]);
|
|
4022
|
+
const rawFinalizeContext = !rawBuildContext ? probeFunction(rt, [["channel", "reply", "finalizeInboundContext"]]) : null;
|
|
4023
|
+
const buildInboundContext = rawBuildContext ? (params) => rawBuildContext(params) : rawFinalizeContext ? (params) => {
|
|
4024
|
+
const isCommand = params.access?.commands?.authorized ?? false;
|
|
4025
|
+
const rawCtx = {
|
|
4026
|
+
Body: params.message.body,
|
|
4027
|
+
BodyForAgent: params.message.bodyForAgent,
|
|
4028
|
+
RawBody: params.message.rawBody,
|
|
4029
|
+
CommandBody: params.message.commandBody ?? params.message.rawBody,
|
|
4030
|
+
CommandSource: isCommand ? "text" : void 0,
|
|
4031
|
+
CommandTurn: params.command ?? void 0,
|
|
4032
|
+
CommandAuthorized: isCommand,
|
|
4033
|
+
From: params.from,
|
|
4034
|
+
To: params.reply.to,
|
|
4035
|
+
SessionKey: params.route.routeSessionKey,
|
|
4036
|
+
AccountId: params.route.accountId ?? params.accountId,
|
|
4037
|
+
ChatType: params.conversation.kind,
|
|
4038
|
+
GroupSystemPrompt: params.conversation.label,
|
|
4039
|
+
SenderId: params.sender.id,
|
|
4040
|
+
SenderName: params.sender.name,
|
|
4041
|
+
Provider: params.provider ?? params.channel,
|
|
4042
|
+
Surface: params.surface ?? params.channel,
|
|
4043
|
+
MessageSid: params.messageId,
|
|
4044
|
+
Timestamp: params.timestamp ?? Date.now(),
|
|
4045
|
+
OriginatingChannel: params.channel,
|
|
4046
|
+
OriginatingTo: params.reply.originatingTo ?? params.reply.to,
|
|
4047
|
+
...params.extra
|
|
4048
|
+
};
|
|
4049
|
+
return rawFinalizeContext(rawCtx);
|
|
4050
|
+
} : null;
|
|
4051
|
+
const resolveStorePath = probeFunction(rt, [
|
|
4052
|
+
["channel", "session", "resolveStorePath"]
|
|
4053
|
+
]);
|
|
4054
|
+
const recordInboundSession = probeFunction(rt, [
|
|
4055
|
+
["channel", "session", "recordInboundSession"]
|
|
4056
|
+
]);
|
|
4057
|
+
const formatEnvelope = probeFunction(rt, [
|
|
4058
|
+
["channel", "reply", "formatAgentEnvelope"],
|
|
4059
|
+
// current (2026-06+)
|
|
4060
|
+
["channel", "reply", "formatInboundEnvelope"]
|
|
4061
|
+
// deprecated,低版本兼容
|
|
4062
|
+
]);
|
|
4063
|
+
const resolveEnvelopeFormatOptions = probeFunction(rt, [
|
|
4064
|
+
["channel", "reply", "resolveEnvelopeFormatOptions"]
|
|
4065
|
+
]);
|
|
4066
|
+
const chunkMarkdownText = probeFunction(rt, [
|
|
4067
|
+
["channel", "text", "chunkMarkdownText"]
|
|
4068
|
+
]);
|
|
4069
|
+
const saveRemoteMedia = probeFunction(rt, [
|
|
4070
|
+
["channel", "media", "saveRemoteMedia"]
|
|
4071
|
+
]);
|
|
4072
|
+
const getConfig = probeFunction(rt, [
|
|
4073
|
+
["config", "current"]
|
|
4074
|
+
]) ?? probeFunction(rt, [
|
|
4075
|
+
["getConfig"]
|
|
4076
|
+
]) ?? probeFunction(rt, [
|
|
4077
|
+
["config", "loadConfig"]
|
|
4078
|
+
]);
|
|
4079
|
+
const rawMutateConfig = probeFunction(rt, [["config", "mutateConfigFile"]]);
|
|
4080
|
+
const rawWriteConfig = probeFunction(rt, [["config", "writeConfigFile"]]);
|
|
4081
|
+
const persistConfig = rawMutateConfig ? async (mutator) => {
|
|
4082
|
+
await rawMutateConfig({
|
|
4083
|
+
afterWrite: "hot-reload",
|
|
4084
|
+
mutate: mutator
|
|
4085
|
+
});
|
|
4086
|
+
} : rawWriteConfig && getConfig ? async (mutator) => {
|
|
4087
|
+
const current = JSON.parse(JSON.stringify(getConfig()));
|
|
4088
|
+
mutator(current);
|
|
4089
|
+
await rawWriteConfig(current);
|
|
4090
|
+
} : null;
|
|
4091
|
+
const resolved = [
|
|
4092
|
+
inboundRun && "inboundRun",
|
|
4093
|
+
dispatchReply && "dispatchReply",
|
|
4094
|
+
resolveAgentRoute && "resolveAgentRoute",
|
|
4095
|
+
buildInboundContext && "buildInboundContext",
|
|
4096
|
+
resolveStorePath && "resolveStorePath",
|
|
4097
|
+
recordInboundSession && "recordInboundSession",
|
|
4098
|
+
formatEnvelope && "formatEnvelope",
|
|
4099
|
+
chunkMarkdownText && "chunkMarkdownText",
|
|
4100
|
+
saveRemoteMedia && "saveRemoteMedia",
|
|
4101
|
+
getConfig && "getConfig",
|
|
4102
|
+
persistConfig && `persistConfig(${rawMutateConfig ? "mutate" : "write"})`
|
|
4103
|
+
].filter(Boolean);
|
|
4104
|
+
log4?.info(
|
|
4105
|
+
`[qqbot:adapter] openclaw=${version} resolved ${resolved.length} adapters: ${resolved.join(", ")}`
|
|
4106
|
+
);
|
|
4107
|
+
return {
|
|
4108
|
+
inboundRun,
|
|
4109
|
+
dispatchReply,
|
|
4110
|
+
resolveAgentRoute,
|
|
4111
|
+
buildInboundContext,
|
|
4112
|
+
resolveStorePath,
|
|
4113
|
+
recordInboundSession,
|
|
4114
|
+
formatEnvelope,
|
|
4115
|
+
resolveEnvelopeFormatOptions,
|
|
4116
|
+
chunkMarkdownText,
|
|
4117
|
+
saveRemoteMedia,
|
|
4118
|
+
getConfig,
|
|
4119
|
+
persistConfig,
|
|
4120
|
+
version
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
function getAdapters(rt, log4) {
|
|
4124
|
+
const cached = _cachedRuntimeRef?.deref();
|
|
4125
|
+
if (cached === rt && _cachedAdapters) {
|
|
4126
|
+
return _cachedAdapters;
|
|
4127
|
+
}
|
|
4128
|
+
_cachedAdapters = resolveRuntimeAdapters(rt, log4);
|
|
4129
|
+
_cachedRuntimeRef = new WeakRef(rt);
|
|
4130
|
+
return _cachedAdapters;
|
|
4131
|
+
}
|
|
4132
|
+
async function persistAuthConfig(runtime2, cfg, afterWrite = "restart") {
|
|
4133
|
+
const config = runtime2.config;
|
|
4134
|
+
if (typeof config?.mutateConfigFile === "function") {
|
|
4135
|
+
await config.mutateConfigFile({
|
|
4136
|
+
mutate: () => cfg,
|
|
4137
|
+
afterWrite
|
|
4138
|
+
});
|
|
4139
|
+
return;
|
|
4140
|
+
}
|
|
4141
|
+
if (typeof config?.writeConfigFile === "function") {
|
|
4142
|
+
await config.writeConfigFile(cfg);
|
|
4143
|
+
return;
|
|
4144
|
+
}
|
|
4145
|
+
if (typeof runtime2.writeConfigFile === "function") {
|
|
4146
|
+
await runtime2.writeConfigFile(cfg);
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
4149
|
+
const { homedir: homedir5 } = await import("os");
|
|
4150
|
+
const { join: join8 } = await import("path");
|
|
4151
|
+
const { writeFileSync: writeFileSync5 } = await import("fs");
|
|
4152
|
+
writeFileSync5(join8(homedir5(), ".openclaw", "openclaw.json"), JSON.stringify(cfg, null, 2) + "\n", "utf-8");
|
|
4153
|
+
}
|
|
4154
|
+
function _resetAdaptersCache() {
|
|
4155
|
+
_cachedAdapters = null;
|
|
4156
|
+
_cachedRuntimeRef = null;
|
|
4157
|
+
}
|
|
4158
|
+
var _cachedAdapters, _cachedRuntimeRef;
|
|
4159
|
+
var init_resolve = __esm({
|
|
4160
|
+
"src/adapter/resolve.ts"() {
|
|
4161
|
+
"use strict";
|
|
4162
|
+
_cachedAdapters = null;
|
|
4163
|
+
_cachedRuntimeRef = null;
|
|
4164
|
+
}
|
|
4165
|
+
});
|
|
4166
|
+
|
|
4167
|
+
// src/adapter/setup.ts
|
|
4168
|
+
function loadSetup() {
|
|
4169
|
+
if (_setup !== void 0) return _setup;
|
|
4170
|
+
try {
|
|
4171
|
+
_setup = req2("openclaw/plugin-sdk/setup");
|
|
4172
|
+
} catch {
|
|
4173
|
+
_setup = null;
|
|
4174
|
+
}
|
|
4175
|
+
return _setup;
|
|
4176
|
+
}
|
|
4177
|
+
function loadTools() {
|
|
4178
|
+
if (_tools !== void 0) return _tools;
|
|
4179
|
+
try {
|
|
4180
|
+
_tools = req2("openclaw/plugin-sdk/setup-tools");
|
|
4181
|
+
} catch {
|
|
4182
|
+
_tools = null;
|
|
4183
|
+
}
|
|
4184
|
+
return _tools;
|
|
4185
|
+
}
|
|
4186
|
+
function createStandardChannelSetupStatus(...args) {
|
|
4187
|
+
const mod = loadSetup();
|
|
4188
|
+
if (mod) return mod.createStandardChannelSetupStatus(...args);
|
|
4189
|
+
return {
|
|
4190
|
+
channelLabel: args[0]?.channelLabel ?? "QQ Bot",
|
|
4191
|
+
configuredLabel: "Configured",
|
|
4192
|
+
unconfiguredLabel: "Not configured",
|
|
4193
|
+
resolveConfigured: () => false
|
|
4194
|
+
};
|
|
4195
|
+
}
|
|
4196
|
+
function setSetupChannelEnabled(...args) {
|
|
4197
|
+
loadSetup()?.setSetupChannelEnabled?.(...args);
|
|
4198
|
+
}
|
|
4199
|
+
function formatDocsLink(...args) {
|
|
4200
|
+
const mod = loadTools();
|
|
4201
|
+
if (mod) return mod.formatDocsLink(...args);
|
|
4202
|
+
return args[1] ? `${args[1]}: ${args[0]}` : args[0];
|
|
4203
|
+
}
|
|
4204
|
+
var import_node_module2, req2, _setup, _tools, DEFAULT_ACCOUNT_ID2;
|
|
4205
|
+
var init_setup = __esm({
|
|
4206
|
+
"src/adapter/setup.ts"() {
|
|
4207
|
+
"use strict";
|
|
4208
|
+
import_node_module2 = require("module");
|
|
4209
|
+
req2 = (0, import_node_module2.createRequire)(__filename);
|
|
4210
|
+
DEFAULT_ACCOUNT_ID2 = "default";
|
|
4211
|
+
}
|
|
4212
|
+
});
|
|
4213
|
+
|
|
4214
|
+
// node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRMode.js
|
|
4215
|
+
var require_QRMode = __commonJS({
|
|
4216
|
+
"node_modules/.pnpm/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRMode.js"(exports2, module2) {
|
|
4217
|
+
"use strict";
|
|
4218
|
+
module2.exports = {
|
|
4219
|
+
MODE_NUMBER: 1 << 0,
|
|
4220
|
+
MODE_ALPHA_NUM: 1 << 1,
|
|
4221
|
+
MODE_8BIT_BYTE: 1 << 2,
|
|
4222
|
+
MODE_KANJI: 1 << 3
|
|
4223
|
+
};
|
|
3723
4224
|
}
|
|
3724
4225
|
});
|
|
3725
4226
|
|
|
@@ -4791,295 +5292,323 @@ var require_main = __commonJS({
|
|
|
4791
5292
|
}
|
|
4792
5293
|
});
|
|
4793
5294
|
|
|
4794
|
-
//
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
DEFAULT_ACCOUNT_ID: () => DEFAULT_ACCOUNT_ID,
|
|
4798
|
-
MSG_TYPE_QUOTE: () => MSG_TYPE_QUOTE2,
|
|
4799
|
-
MSG_TYPE_TEXT: () => MSG_TYPE_TEXT,
|
|
4800
|
-
PersistedRefIndexStore: () => PersistedRefIndexStore,
|
|
4801
|
-
QQBotGateway: () => QQBotGateway,
|
|
4802
|
-
StreamContentType: () => StreamContentType2,
|
|
4803
|
-
StreamInputMode: () => StreamInputMode2,
|
|
4804
|
-
StreamInputState: () => StreamInputState2,
|
|
4805
|
-
StreamingController: () => StreamingController,
|
|
4806
|
-
applyQQBotAccountConfig: () => applyQQBotAccountConfig,
|
|
4807
|
-
buildUserAgent: () => buildUserAgent,
|
|
4808
|
-
default: () => index_default,
|
|
4809
|
-
dispatchToOpenClaw: () => dispatchToOpenClaw,
|
|
4810
|
-
flushAllRefIndexStores: () => flushAllRefIndexStores,
|
|
4811
|
-
getBotForAccount: () => getBotForAccount,
|
|
4812
|
-
getPersistedRefIndexStore: () => getPersistedRefIndexStore,
|
|
4813
|
-
getQQBotRuntime: () => getQQBotRuntime,
|
|
4814
|
-
isGroupAllowed: () => isGroupAllowed,
|
|
4815
|
-
listQQBotAccountIds: () => listQQBotAccountIds,
|
|
4816
|
-
parseTarget: () => parseTarget,
|
|
4817
|
-
qqbotOnboardingAdapter: () => qqbotOnboardingAdapter,
|
|
4818
|
-
qqbotPlugin: () => qqbotPlugin,
|
|
4819
|
-
resolveDefaultQQBotAccountId: () => resolveDefaultQQBotAccountId,
|
|
4820
|
-
resolveGroupAllowFrom: () => resolveGroupAllowFrom,
|
|
4821
|
-
resolveGroupConfig: () => resolveGroupConfig,
|
|
4822
|
-
resolveGroupConfigFromAccount: () => resolveGroupConfigFromAccount,
|
|
4823
|
-
resolveGroupName: () => resolveGroupName,
|
|
4824
|
-
resolveGroupPolicy: () => resolveGroupPolicy,
|
|
4825
|
-
resolveGroupPrompt: () => resolveGroupPrompt,
|
|
4826
|
-
resolveHistoryLimit: () => resolveHistoryLimit,
|
|
4827
|
-
resolveIgnoreOtherMentions: () => resolveIgnoreOtherMentions,
|
|
4828
|
-
resolveMentionPatterns: () => resolveMentionPatterns,
|
|
4829
|
-
resolveProcessingTimeoutMs: () => resolveProcessingTimeoutMs,
|
|
4830
|
-
resolveQQBotAccount: () => resolveQQBotAccount,
|
|
4831
|
-
resolveRequireMention: () => resolveRequireMention,
|
|
4832
|
-
resolveToolPolicy: () => resolveToolPolicy,
|
|
4833
|
-
resolveUserAgentSuffix: () => resolveUserAgentSuffix,
|
|
4834
|
-
sendMedia: () => sendMedia,
|
|
4835
|
-
sendText: () => sendText,
|
|
4836
|
-
setQQBotRuntime: () => setQQBotRuntime,
|
|
4837
|
-
shouldUseStreaming: () => shouldUseStreaming,
|
|
4838
|
-
tryGetBotForAccount: () => tryGetBotForAccount
|
|
4839
|
-
});
|
|
4840
|
-
module.exports = __toCommonJS(index_exports);
|
|
4841
|
-
var import_plugin_sdk = require("openclaw/plugin-sdk");
|
|
4842
|
-
|
|
4843
|
-
// src/channel.ts
|
|
4844
|
-
var import_core = require("openclaw/plugin-sdk/core");
|
|
4845
|
-
|
|
4846
|
-
// src/config.ts
|
|
4847
|
-
function resolveMentionPatterns(cfg, agentId) {
|
|
4848
|
-
if (agentId) {
|
|
4849
|
-
const agents = cfg.agents;
|
|
4850
|
-
const entry = agents?.list?.find((a) => a.id?.trim().toLowerCase() === agentId.trim().toLowerCase());
|
|
4851
|
-
const agentGroupChat = entry?.groupChat;
|
|
4852
|
-
if (agentGroupChat && Object.hasOwn(agentGroupChat, "mentionPatterns")) {
|
|
4853
|
-
return agentGroupChat.mentionPatterns ?? [];
|
|
4854
|
-
}
|
|
4855
|
-
}
|
|
4856
|
-
const globalGroupChat = cfg?.messages?.groupChat;
|
|
4857
|
-
if (globalGroupChat && typeof globalGroupChat === "object" && Object.hasOwn(globalGroupChat, "mentionPatterns")) {
|
|
4858
|
-
return globalGroupChat.mentionPatterns ?? [];
|
|
4859
|
-
}
|
|
4860
|
-
return [];
|
|
4861
|
-
}
|
|
4862
|
-
var DEFAULT_ACCOUNT_ID = "default";
|
|
4863
|
-
function evaluateMatchedGroupAccessForPolicy(params) {
|
|
4864
|
-
if (params.groupPolicy === "disabled") {
|
|
4865
|
-
return { allowed: false, groupPolicy: params.groupPolicy, reason: "disabled" };
|
|
4866
|
-
}
|
|
4867
|
-
if (params.groupPolicy === "allowlist") {
|
|
4868
|
-
if (params.requireMatchInput && !params.hasMatchInput) {
|
|
4869
|
-
return { allowed: false, groupPolicy: params.groupPolicy, reason: "missing_match_input" };
|
|
4870
|
-
}
|
|
4871
|
-
if (!params.allowlistConfigured) {
|
|
4872
|
-
return { allowed: false, groupPolicy: params.groupPolicy, reason: "empty_allowlist" };
|
|
4873
|
-
}
|
|
4874
|
-
if (!params.allowlistMatched) {
|
|
4875
|
-
return { allowed: false, groupPolicy: params.groupPolicy, reason: "not_allowlisted" };
|
|
4876
|
-
}
|
|
4877
|
-
}
|
|
4878
|
-
return { allowed: true, groupPolicy: params.groupPolicy, reason: "allowed" };
|
|
4879
|
-
}
|
|
4880
|
-
var DEFAULT_GROUP_POLICY = "open";
|
|
4881
|
-
var DEFAULT_GROUP_HISTORY_LIMIT = 20;
|
|
4882
|
-
var DEFAULT_PROCESSING_TIMEOUT_MS = 0;
|
|
4883
|
-
var DEFAULT_GROUP_CONFIG = {
|
|
4884
|
-
requireMention: true,
|
|
4885
|
-
ignoreOtherMentions: false,
|
|
4886
|
-
toolPolicy: "restricted",
|
|
4887
|
-
name: "",
|
|
4888
|
-
historyLimit: DEFAULT_GROUP_HISTORY_LIMIT
|
|
4889
|
-
};
|
|
4890
|
-
var DEFAULT_GROUP_PROMPT = [
|
|
4891
|
-
"\u82E5\u53D1\u9001\u8005\u4E3A\u673A\u5668\u4EBA\uFF0C\u4EC5\u5728\u5BF9\u65B9\u660E\u786E@\u4F60\u63D0\u95EE\u6216\u8BF7\u6C42\u534F\u52A9\u5177\u4F53\u4EFB\u52A1\u65F6\uFF0C\u4EE5\u7B80\u6D01\u660E\u4E86\u7684\u5185\u5BB9\u56DE\u590D\uFF0C",
|
|
4892
|
-
"\u907F\u514D\u4E0E\u5176\u4ED6\u673A\u5668\u4EBA\u4EA7\u751F\u62A2\u7B54\u6216\u591A\u8F6E\u65E0\u610F\u4E49\u5BF9\u8BDD\u3002",
|
|
4893
|
-
"\u5728\u7FA4\u804A\u4E2D\u4F18\u5148\u8BA9\u4EBA\u7C7B\u7528\u6237\u7684\u6D88\u606F\u5F97\u5230\u54CD\u5E94\uFF0C\u673A\u5668\u4EBA\u4E4B\u95F4\u4FDD\u6301\u534F\u4F5C\u800C\u975E\u7ADE\u4E89\uFF0C\u786E\u4FDD\u5BF9\u8BDD\u6709\u5E8F\u4E0D\u5237\u5C4F\u3002"
|
|
4894
|
-
].join("");
|
|
4895
|
-
function resolveGroupPolicy(cfg, accountId) {
|
|
4896
|
-
const account = resolveQQBotAccount(cfg, accountId);
|
|
4897
|
-
return account.config?.groupPolicy ?? DEFAULT_GROUP_POLICY;
|
|
4898
|
-
}
|
|
4899
|
-
function resolveGroupAllowFrom(cfg, accountId) {
|
|
4900
|
-
const account = resolveQQBotAccount(cfg, accountId);
|
|
4901
|
-
return (account.config?.groupAllowFrom ?? []).map((id) => String(id).trim().toUpperCase());
|
|
4902
|
-
}
|
|
4903
|
-
function isGroupAllowed(cfg, groupOpenid, accountId) {
|
|
4904
|
-
const account = resolveQQBotAccount(cfg, accountId);
|
|
4905
|
-
const policy = account.config?.groupPolicy ?? DEFAULT_GROUP_POLICY;
|
|
4906
|
-
const allowList = (account.config?.groupAllowFrom ?? []).map((id) => String(id).trim().toUpperCase());
|
|
4907
|
-
const allowlistConfigured = allowList.length > 0;
|
|
4908
|
-
const allowlistMatched = allowList.some((id) => id === "*" || id === groupOpenid.toUpperCase());
|
|
4909
|
-
return evaluateMatchedGroupAccessForPolicy({
|
|
4910
|
-
groupPolicy: policy,
|
|
4911
|
-
allowlistConfigured,
|
|
4912
|
-
allowlistMatched
|
|
4913
|
-
}).allowed;
|
|
4914
|
-
}
|
|
4915
|
-
function resolveGroupConfigFromAccount(account, groupOpenid) {
|
|
4916
|
-
const groups = account.config?.groups ?? {};
|
|
4917
|
-
const wildcardCfg = groups["*"] ?? {};
|
|
4918
|
-
const specificCfg = groups[groupOpenid] ?? {};
|
|
4919
|
-
const accountDefaultRequireMention = account.config?.defaultRequireMention ?? DEFAULT_GROUP_CONFIG.requireMention;
|
|
4920
|
-
return {
|
|
4921
|
-
requireMention: specificCfg.requireMention ?? wildcardCfg.requireMention ?? accountDefaultRequireMention,
|
|
4922
|
-
ignoreOtherMentions: specificCfg.ignoreOtherMentions ?? wildcardCfg.ignoreOtherMentions ?? DEFAULT_GROUP_CONFIG.ignoreOtherMentions,
|
|
4923
|
-
toolPolicy: specificCfg.toolPolicy ?? wildcardCfg.toolPolicy ?? DEFAULT_GROUP_CONFIG.toolPolicy,
|
|
4924
|
-
name: specificCfg.name ?? wildcardCfg.name ?? DEFAULT_GROUP_CONFIG.name,
|
|
4925
|
-
prompt: specificCfg.prompt ?? wildcardCfg.prompt ?? DEFAULT_GROUP_PROMPT,
|
|
4926
|
-
historyLimit: specificCfg.historyLimit ?? wildcardCfg.historyLimit ?? DEFAULT_GROUP_CONFIG.historyLimit
|
|
4927
|
-
};
|
|
5295
|
+
// node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/qqbot-session.js
|
|
5296
|
+
function d(t = "production") {
|
|
5297
|
+
return E[t];
|
|
4928
5298
|
}
|
|
4929
|
-
function
|
|
4930
|
-
return
|
|
5299
|
+
function l() {
|
|
5300
|
+
return import_node_crypto.default.randomBytes(32).toString("base64");
|
|
4931
5301
|
}
|
|
4932
|
-
function
|
|
4933
|
-
|
|
5302
|
+
function b(t, r) {
|
|
5303
|
+
const a = Buffer.from(r, "base64"), n = Buffer.from(t, "base64"), e = n.subarray(0, 12), c = n.subarray(n.length - 16), s = n.subarray(12, n.length - 16), o = import_node_crypto.default.createDecipheriv("aes-256-gcm", a, e);
|
|
5304
|
+
return o.setAuthTag(c), Buffer.concat([o.update(s), o.final()]).toString("utf8");
|
|
4934
5305
|
}
|
|
4935
|
-
function
|
|
4936
|
-
return
|
|
5306
|
+
function h(t, r, a) {
|
|
5307
|
+
return new Promise((n, e) => {
|
|
5308
|
+
const c = JSON.stringify(r), s = new URL(t), o = import_node_https.default.request({ hostname: s.hostname, path: s.pathname + s.search, method: "POST", timeout: a, headers: { "Content-Type": "application/json", Accept: "application/json", "Content-Length": Buffer.byteLength(c) } }, (i) => {
|
|
5309
|
+
if (i.statusCode !== 200) {
|
|
5310
|
+
i.resume(), e(new Error(`HTTP ${i.statusCode} from ${t}`));
|
|
5311
|
+
return;
|
|
5312
|
+
}
|
|
5313
|
+
let f = "";
|
|
5314
|
+
i.on("data", (p2) => {
|
|
5315
|
+
f += p2;
|
|
5316
|
+
}), i.on("end", () => {
|
|
5317
|
+
try {
|
|
5318
|
+
n(JSON.parse(f));
|
|
5319
|
+
} catch (p2) {
|
|
5320
|
+
e(p2);
|
|
5321
|
+
}
|
|
5322
|
+
});
|
|
5323
|
+
});
|
|
5324
|
+
o.on("error", e), o.on("timeout", () => {
|
|
5325
|
+
o.destroy(), e(new Error(`timeout fetching ${t}`));
|
|
5326
|
+
}), o.end(c);
|
|
5327
|
+
});
|
|
4937
5328
|
}
|
|
4938
|
-
function
|
|
4939
|
-
|
|
5329
|
+
async function y(t = "production", r = 1e4) {
|
|
5330
|
+
const a = `https://${d(t)}/lite/create_bind_task`, n = l(), e = await h(a, { key: n }, r);
|
|
5331
|
+
if (e.retcode !== 0) throw new Error(e.msg ?? "create_bind_task failed");
|
|
5332
|
+
if (!e.data?.task_id) throw new Error("create_bind_task: missing task_id");
|
|
5333
|
+
return { taskId: e.data.task_id, key: n };
|
|
4940
5334
|
}
|
|
4941
|
-
function
|
|
4942
|
-
|
|
5335
|
+
async function g(t, r = "production", a = 1e4) {
|
|
5336
|
+
const n = `https://${d(r)}/lite/poll_bind_result`, e = await h(n, { task_id: t }, a);
|
|
5337
|
+
if (e.retcode !== 0) throw new Error(e.msg ?? "poll_bind_result failed");
|
|
5338
|
+
return { status: e.data?.status ?? u.NONE, botAppId: String(e.data?.bot_appid ?? ""), botEncryptSecret: e.data?.bot_encrypt_secret ?? "", userOpenid: e.data?.user_openid || void 0 };
|
|
4943
5339
|
}
|
|
4944
|
-
function
|
|
4945
|
-
return
|
|
5340
|
+
function w(t, r = "") {
|
|
5341
|
+
return `https://${d("production")}/qqbot/openclaw/connect.html?task_id=${encodeURIComponent(t)}&source=${encodeURIComponent(r)}&_wv=2`;
|
|
4946
5342
|
}
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
5343
|
+
var import_node_crypto, import_node_https, E, u;
|
|
5344
|
+
var init_qqbot_session = __esm({
|
|
5345
|
+
"node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/qqbot-session.js"() {
|
|
5346
|
+
"use strict";
|
|
5347
|
+
import_node_crypto = __toESM(require("crypto"), 1);
|
|
5348
|
+
import_node_https = __toESM(require("https"), 1);
|
|
5349
|
+
E = { production: "q.qq.com", test: "test.q.qq.com" };
|
|
5350
|
+
(function(t) {
|
|
5351
|
+
t[t.NONE = 0] = "NONE", t[t.PENDING = 1] = "PENDING", t[t.COMPLETED = 2] = "COMPLETED", t[t.EXPIRED = 3] = "EXPIRED";
|
|
5352
|
+
})(u || (u = {}));
|
|
5353
|
+
}
|
|
5354
|
+
});
|
|
5355
|
+
|
|
5356
|
+
// node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/qr-connect.js
|
|
5357
|
+
function F(r) {
|
|
5358
|
+
return new Promise((o) => {
|
|
5359
|
+
import_qrcode_terminal.default.generate(r, { small: true }, (e) => {
|
|
5360
|
+
o(e);
|
|
5361
|
+
});
|
|
5362
|
+
});
|
|
4950
5363
|
}
|
|
4951
|
-
function
|
|
4952
|
-
|
|
4953
|
-
|
|
5364
|
+
function d2(r, o) {
|
|
5365
|
+
return new Promise((e, t) => {
|
|
5366
|
+
if (o?.aborted) {
|
|
5367
|
+
t(new DOMException("Aborted", "AbortError"));
|
|
5368
|
+
return;
|
|
5369
|
+
}
|
|
5370
|
+
const n = setTimeout(e, r);
|
|
5371
|
+
o?.addEventListener("abort", () => {
|
|
5372
|
+
clearTimeout(n), t(new DOMException("Aborted", "AbortError"));
|
|
5373
|
+
}, { once: true });
|
|
5374
|
+
});
|
|
4954
5375
|
}
|
|
4955
|
-
function
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
5376
|
+
async function C(r, o, e) {
|
|
5377
|
+
for (; !e?.aborted; ) {
|
|
5378
|
+
let t;
|
|
5379
|
+
try {
|
|
5380
|
+
t = await g(r);
|
|
5381
|
+
} catch {
|
|
5382
|
+
await d2(p, e);
|
|
5383
|
+
continue;
|
|
5384
|
+
}
|
|
5385
|
+
if (t.status === u.COMPLETED) {
|
|
5386
|
+
const n = b(t.botEncryptSecret, o);
|
|
5387
|
+
return { outcome: "scanned", appId: t.botAppId, appSecret: n, userOpenid: t.userOpenid };
|
|
4966
5388
|
}
|
|
5389
|
+
if (t.status === u.EXPIRED) return { outcome: "expired" };
|
|
5390
|
+
await d2(p, e);
|
|
4967
5391
|
}
|
|
4968
|
-
|
|
5392
|
+
throw new DOMException("Aborted", "AbortError");
|
|
4969
5393
|
}
|
|
4970
|
-
function
|
|
4971
|
-
const
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
5394
|
+
function l2(r, o) {
|
|
5395
|
+
const e = new AbortController(), t = o?.signal ? AbortSignal.any([e.signal, o.signal]) : e.signal;
|
|
5396
|
+
return (async () => {
|
|
5397
|
+
const n = o?.displayQrCodeToConsole ?? true;
|
|
5398
|
+
for (; ; ) {
|
|
5399
|
+
if (t.aborted) throw new DOMException("Aborted", "AbortError");
|
|
5400
|
+
let a;
|
|
5401
|
+
try {
|
|
5402
|
+
a = await y();
|
|
5403
|
+
} catch (u2) {
|
|
5404
|
+
throw new Error(`\u83B7\u53D6\u7ED1\u5B9A\u4EFB\u52A1\u5931\u8D25: ${u2 instanceof Error ? u2.message : String(u2)}`, { cause: u2 });
|
|
5405
|
+
}
|
|
5406
|
+
const i = w(a.taskId, o?.source);
|
|
5407
|
+
if (n) {
|
|
5408
|
+
const u2 = await F(i);
|
|
5409
|
+
console.log(u2), console.log(`\u8BF7\u4F7F\u7528\u624B\u673A QQ \u626B\u63CF\u4E0A\u65B9\u4E8C\u7EF4\u7801\uFF0C\u5B8C\u6210\u673A\u5668\u4EBA\u7ED1\u5B9A\u3002
|
|
5410
|
+
`);
|
|
5411
|
+
}
|
|
5412
|
+
r.onQrDisplayed?.(i);
|
|
5413
|
+
const s = await C(a.taskId, a.key, t);
|
|
5414
|
+
if (s.outcome === "scanned") {
|
|
5415
|
+
r.onSuccess([{ appId: s.appId, appSecret: s.appSecret, userOpenid: s.userOpenid }]);
|
|
5416
|
+
return;
|
|
5417
|
+
}
|
|
5418
|
+
r.onQrExpired?.(), n && console.log(`\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u6B63\u5728\u5237\u65B0\u2026
|
|
5419
|
+
`);
|
|
4979
5420
|
}
|
|
4980
|
-
}
|
|
4981
|
-
|
|
5421
|
+
})().catch((n) => {
|
|
5422
|
+
if (n instanceof DOMException && n.name === "AbortError") {
|
|
5423
|
+
r.onFailure(new Error("\u5DF2\u53D6\u6D88"));
|
|
5424
|
+
return;
|
|
5425
|
+
}
|
|
5426
|
+
r.onFailure(n instanceof Error ? n : new Error(String(n)));
|
|
5427
|
+
}), () => e.abort();
|
|
4982
5428
|
}
|
|
4983
|
-
function
|
|
4984
|
-
|
|
4985
|
-
|
|
5429
|
+
function m2(r) {
|
|
5430
|
+
return new Promise((o, e) => {
|
|
5431
|
+
l2({ onSuccess: o, onFailure: e }, { ...r, displayQrCodeToConsole: true });
|
|
5432
|
+
});
|
|
4986
5433
|
}
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
5434
|
+
var import_qrcode_terminal, p;
|
|
5435
|
+
var init_qr_connect = __esm({
|
|
5436
|
+
"node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/qr-connect.js"() {
|
|
5437
|
+
"use strict";
|
|
5438
|
+
import_qrcode_terminal = __toESM(require_main(), 1);
|
|
5439
|
+
init_qqbot_session();
|
|
5440
|
+
p = 2e3;
|
|
4990
5441
|
}
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
5442
|
+
});
|
|
5443
|
+
|
|
5444
|
+
// node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/index.js
|
|
5445
|
+
var init_esm = __esm({
|
|
5446
|
+
"node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/index.js"() {
|
|
5447
|
+
"use strict";
|
|
5448
|
+
init_qr_connect();
|
|
4995
5449
|
}
|
|
4996
|
-
|
|
5450
|
+
});
|
|
5451
|
+
|
|
5452
|
+
// src/setup/account-key.ts
|
|
5453
|
+
var account_key_exports = {};
|
|
5454
|
+
__export(account_key_exports, {
|
|
5455
|
+
resolveAccountKey: () => resolveAccountKey
|
|
5456
|
+
});
|
|
5457
|
+
function resolveAccountKey(cfg, appId, resolvedId) {
|
|
5458
|
+
if (resolvedId) return resolvedId;
|
|
5459
|
+
for (const id of listQQBotAccountIds(cfg)) {
|
|
5460
|
+
if (resolveQQBotAccount(cfg, id).appId === appId) return id;
|
|
5461
|
+
}
|
|
5462
|
+
if (listQQBotAccountIds(cfg).length === 0) return "default";
|
|
5463
|
+
return appId;
|
|
4997
5464
|
}
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
let appId = "";
|
|
5003
|
-
let clientSecret = "";
|
|
5004
|
-
let secretSource = "none";
|
|
5005
|
-
if (resolvedAccountId === DEFAULT_ACCOUNT_ID) {
|
|
5006
|
-
const { accounts: _accounts, ...topLevelConfig } = qqbot ?? {};
|
|
5007
|
-
accountConfig = {
|
|
5008
|
-
...topLevelConfig,
|
|
5009
|
-
markdownSupport: qqbot?.markdownSupport ?? true
|
|
5010
|
-
};
|
|
5011
|
-
appId = normalizeAppId(qqbot?.appId);
|
|
5012
|
-
} else {
|
|
5013
|
-
const account = qqbot?.accounts?.[resolvedAccountId];
|
|
5014
|
-
accountConfig = account ?? {};
|
|
5015
|
-
appId = normalizeAppId(account?.appId);
|
|
5465
|
+
var init_account_key = __esm({
|
|
5466
|
+
"src/setup/account-key.ts"() {
|
|
5467
|
+
"use strict";
|
|
5468
|
+
init_config();
|
|
5016
5469
|
}
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5470
|
+
});
|
|
5471
|
+
|
|
5472
|
+
// src/setup/finalize.ts
|
|
5473
|
+
var finalize_exports = {};
|
|
5474
|
+
__export(finalize_exports, {
|
|
5475
|
+
applyAccountDefaults: () => applyAccountDefaults,
|
|
5476
|
+
finalizeQQBotSetup: () => finalizeQQBotSetup
|
|
5477
|
+
});
|
|
5478
|
+
function isConfigured(cfg, accountId) {
|
|
5479
|
+
const account = resolveQQBotAccount(cfg, accountId);
|
|
5480
|
+
return Boolean(account.appId && account.clientSecret);
|
|
5481
|
+
}
|
|
5482
|
+
async function linkViaQrCode(cfg, _accountId, prompter, rt) {
|
|
5483
|
+
try {
|
|
5484
|
+
const accounts = await m2({ source: "openclaw" });
|
|
5485
|
+
if (accounts.length === 0) {
|
|
5486
|
+
await prompter.note("\u672A\u83B7\u53D6\u5230\u4EFB\u4F55 QQ Bot \u8D26\u53F7\u4FE1\u606F\u3002", "QQ Bot");
|
|
5487
|
+
return cfg;
|
|
5488
|
+
}
|
|
5489
|
+
let next = cfg;
|
|
5490
|
+
for (const { appId, appSecret, userOpenid } of accounts) {
|
|
5491
|
+
const key = resolveAccountKey(cfg, appId);
|
|
5492
|
+
next = applyQQBotAccountConfig(next, key, { appId, clientSecret: appSecret });
|
|
5493
|
+
next = applyAccountDefaults(next, key, userOpenid);
|
|
5494
|
+
rt.log(`\u7ED1\u5B9A\u6210\u529F\uFF01\u8D26\u6237: ${key} (AppID: ${appId})`);
|
|
5495
|
+
}
|
|
5496
|
+
return next;
|
|
5497
|
+
} catch (err) {
|
|
5498
|
+
rt.error(`QQ Bot \u7ED1\u5B9A\u5931\u8D25: ${String(err)}`);
|
|
5499
|
+
await prompter.note(`\u7ED1\u5B9A\u5931\u8D25\uFF0C\u60A8\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u3002
|
|
5500
|
+
\u6587\u6863: ${formatDocsLink("/channels/qqbot", "qqbot")}`, "QQ Bot");
|
|
5501
|
+
return cfg;
|
|
5025
5502
|
}
|
|
5026
|
-
|
|
5027
|
-
|
|
5503
|
+
}
|
|
5504
|
+
async function linkViaManual(cfg, _accountId, prompter) {
|
|
5505
|
+
const appIdInput = await prompter.text({ message: "\u8BF7\u8F93\u5165 QQ Bot AppID", validate: (v) => v.trim() ? void 0 : "AppID \u4E0D\u80FD\u4E3A\u7A7A" });
|
|
5506
|
+
const secret = await prompter.text({ message: "\u8BF7\u8F93\u5165 QQ Bot AppSecret", validate: (v) => v.trim() ? void 0 : "AppSecret \u4E0D\u80FD\u4E3A\u7A7A" });
|
|
5507
|
+
const appId = appIdInput.trim();
|
|
5508
|
+
const key = resolveAccountKey(cfg, appId);
|
|
5509
|
+
let next = applyQQBotAccountConfig(cfg, key, { appId, clientSecret: secret.trim() });
|
|
5510
|
+
next = applyAccountDefaults(next, key);
|
|
5511
|
+
await prompter.note("\u2714 QQ Bot \u914D\u7F6E\u5B8C\u6210\uFF01", "QQ Bot");
|
|
5512
|
+
return next;
|
|
5513
|
+
}
|
|
5514
|
+
async function finalizeQQBotSetup(params) {
|
|
5515
|
+
const accountId = params.accountId.trim() || DEFAULT_ACCOUNT_ID2;
|
|
5516
|
+
const configured = isConfigured(params.cfg, accountId);
|
|
5517
|
+
const mode = await params.prompter.select({
|
|
5518
|
+
message: configured ? "QQ \u5DF2\u7ED1\u5B9A\uFF0C\u9009\u62E9\u64CD\u4F5C" : "\u9009\u62E9 QQ \u7ED1\u5B9A\u65B9\u5F0F",
|
|
5519
|
+
options: [
|
|
5520
|
+
{ value: "qr", label: "\u626B\u7801\u7ED1\u5B9A\uFF08\u63A8\u8350\uFF09", hint: "\u4F7F\u7528 QQ \u626B\u63CF\u4E8C\u7EF4\u7801\u81EA\u52A8\u5B8C\u6210\u7ED1\u5B9A" },
|
|
5521
|
+
{ value: "manual", label: "\u624B\u52A8\u8F93\u5165 QQ Bot AppID \u548C AppSecret", hint: "\u9700\u5230 QQ \u5F00\u653E\u5E73\u53F0 q.qq.com \u67E5\u770B" },
|
|
5522
|
+
{ value: "skip", label: configured ? "\u4FDD\u6301\u5F53\u524D\u914D\u7F6E" : "\u7A0D\u540E\u914D\u7F6E" }
|
|
5523
|
+
]
|
|
5524
|
+
});
|
|
5525
|
+
let next = params.cfg;
|
|
5526
|
+
if (mode === "qr") {
|
|
5527
|
+
next = await linkViaQrCode(next, accountId, params.prompter, params.runtime);
|
|
5528
|
+
} else if (mode === "manual") {
|
|
5529
|
+
next = await linkViaManual(next, accountId, params.prompter);
|
|
5530
|
+
} else if (!configured) {
|
|
5531
|
+
await params.prompter.note("\u60A8\u53EF\u4EE5\u7A0D\u540E\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u91CD\u65B0\u914D\u7F6E\uFF1A\n openclaw channels add", "QQ Bot");
|
|
5028
5532
|
}
|
|
5029
|
-
return {
|
|
5030
|
-
accountId: resolvedAccountId,
|
|
5031
|
-
name: accountConfig.name,
|
|
5032
|
-
enabled: accountConfig.enabled !== false,
|
|
5033
|
-
appId,
|
|
5034
|
-
clientSecret,
|
|
5035
|
-
secretSource,
|
|
5036
|
-
systemPrompt: accountConfig.systemPrompt,
|
|
5037
|
-
markdownSupport: accountConfig.markdownSupport !== false,
|
|
5038
|
-
userAgentSuffix: resolveUserAgentSuffix(cfg),
|
|
5039
|
-
processingTimeoutMs: resolveProcessingTimeoutMs(accountConfig),
|
|
5040
|
-
config: accountConfig
|
|
5041
|
-
};
|
|
5533
|
+
return { cfg: next };
|
|
5042
5534
|
}
|
|
5043
|
-
function
|
|
5044
|
-
const next = { ...cfg };
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
qqbot: {
|
|
5051
|
-
...next.channels?.qqbot || {},
|
|
5052
|
-
enabled: true,
|
|
5053
|
-
allowFrom,
|
|
5054
|
-
...input.appId ? { appId: input.appId } : {},
|
|
5055
|
-
...input.clientSecret ? { clientSecret: input.clientSecret } : input.clientSecretFile ? { clientSecretFile: input.clientSecretFile } : {},
|
|
5056
|
-
...input.name ? { name: input.name } : {}
|
|
5057
|
-
}
|
|
5058
|
-
};
|
|
5535
|
+
function applyAccountDefaults(cfg, accountId, userOpenid) {
|
|
5536
|
+
const next = { ...cfg, channels: { ...cfg.channels } };
|
|
5537
|
+
const qqbot = { ...next.channels?.qqbot ?? {} };
|
|
5538
|
+
const defaults = { streaming: true, dmPolicy: "allowlist" };
|
|
5539
|
+
if (userOpenid) defaults.allowFrom = [userOpenid];
|
|
5540
|
+
if (accountId === DEFAULT_ACCOUNT_ID2) {
|
|
5541
|
+
Object.assign(qqbot, defaults);
|
|
5059
5542
|
} else {
|
|
5060
|
-
const
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
...next.channels,
|
|
5064
|
-
qqbot: {
|
|
5065
|
-
...next.channels?.qqbot || {},
|
|
5066
|
-
enabled: true,
|
|
5067
|
-
accounts: {
|
|
5068
|
-
...next.channels?.qqbot?.accounts || {},
|
|
5069
|
-
[accountId]: {
|
|
5070
|
-
...next.channels?.qqbot?.accounts?.[accountId] || {},
|
|
5071
|
-
enabled: true,
|
|
5072
|
-
allowFrom,
|
|
5073
|
-
...input.appId ? { appId: input.appId } : {},
|
|
5074
|
-
...input.clientSecret ? { clientSecret: input.clientSecret } : input.clientSecretFile ? { clientSecretFile: input.clientSecretFile } : {},
|
|
5075
|
-
...input.name ? { name: input.name } : {}
|
|
5076
|
-
}
|
|
5077
|
-
}
|
|
5078
|
-
}
|
|
5079
|
-
};
|
|
5543
|
+
const accounts = { ...qqbot.accounts ?? {} };
|
|
5544
|
+
accounts[accountId] = { ...accounts[accountId] ?? {}, ...defaults };
|
|
5545
|
+
qqbot.accounts = accounts;
|
|
5080
5546
|
}
|
|
5547
|
+
next.channels = { ...next.channels, qqbot };
|
|
5081
5548
|
return next;
|
|
5082
5549
|
}
|
|
5550
|
+
var init_finalize = __esm({
|
|
5551
|
+
"src/setup/finalize.ts"() {
|
|
5552
|
+
"use strict";
|
|
5553
|
+
init_setup();
|
|
5554
|
+
init_esm();
|
|
5555
|
+
init_config();
|
|
5556
|
+
init_account_key();
|
|
5557
|
+
}
|
|
5558
|
+
});
|
|
5559
|
+
|
|
5560
|
+
// index.ts
|
|
5561
|
+
var index_exports = {};
|
|
5562
|
+
__export(index_exports, {
|
|
5563
|
+
DEFAULT_ACCOUNT_ID: () => DEFAULT_ACCOUNT_ID,
|
|
5564
|
+
MSG_TYPE_QUOTE: () => MSG_TYPE_QUOTE2,
|
|
5565
|
+
MSG_TYPE_TEXT: () => MSG_TYPE_TEXT,
|
|
5566
|
+
PersistedRefIndexStore: () => PersistedRefIndexStore,
|
|
5567
|
+
QQBotGateway: () => QQBotGateway,
|
|
5568
|
+
StreamContentType: () => StreamContentType2,
|
|
5569
|
+
StreamInputMode: () => StreamInputMode2,
|
|
5570
|
+
StreamInputState: () => StreamInputState2,
|
|
5571
|
+
StreamingController: () => StreamingController,
|
|
5572
|
+
applyQQBotAccountConfig: () => applyQQBotAccountConfig,
|
|
5573
|
+
buildUserAgent: () => buildUserAgent,
|
|
5574
|
+
default: () => index_default,
|
|
5575
|
+
dispatchToOpenClaw: () => dispatchToOpenClaw,
|
|
5576
|
+
flushAllRefIndexStores: () => flushAllRefIndexStores,
|
|
5577
|
+
getBotForAccount: () => getBotForAccount,
|
|
5578
|
+
getPersistedRefIndexStore: () => getPersistedRefIndexStore,
|
|
5579
|
+
getQQBotRuntime: () => getQQBotRuntime,
|
|
5580
|
+
isGroupAllowed: () => isGroupAllowed,
|
|
5581
|
+
listQQBotAccountIds: () => listQQBotAccountIds,
|
|
5582
|
+
parseTarget: () => parseTarget,
|
|
5583
|
+
qqbotOnboardingAdapter: () => qqbotOnboardingAdapter,
|
|
5584
|
+
qqbotPlugin: () => qqbotPlugin,
|
|
5585
|
+
resolveDefaultQQBotAccountId: () => resolveDefaultQQBotAccountId,
|
|
5586
|
+
resolveGroupAllowFrom: () => resolveGroupAllowFrom,
|
|
5587
|
+
resolveGroupConfig: () => resolveGroupConfig,
|
|
5588
|
+
resolveGroupConfigFromAccount: () => resolveGroupConfigFromAccount,
|
|
5589
|
+
resolveGroupName: () => resolveGroupName,
|
|
5590
|
+
resolveGroupPolicy: () => resolveGroupPolicy,
|
|
5591
|
+
resolveGroupPrompt: () => resolveGroupPrompt,
|
|
5592
|
+
resolveHistoryLimit: () => resolveHistoryLimit,
|
|
5593
|
+
resolveIgnoreOtherMentions: () => resolveIgnoreOtherMentions,
|
|
5594
|
+
resolveMentionPatterns: () => resolveMentionPatterns,
|
|
5595
|
+
resolveProcessingTimeoutMs: () => resolveProcessingTimeoutMs,
|
|
5596
|
+
resolveQQBotAccount: () => resolveQQBotAccount,
|
|
5597
|
+
resolveRequireMention: () => resolveRequireMention,
|
|
5598
|
+
resolveToolPolicy: () => resolveToolPolicy,
|
|
5599
|
+
resolveUserAgentSuffix: () => resolveUserAgentSuffix,
|
|
5600
|
+
sendMedia: () => sendMedia,
|
|
5601
|
+
sendText: () => sendText,
|
|
5602
|
+
setQQBotRuntime: () => setQQBotRuntime,
|
|
5603
|
+
shouldUseStreaming: () => shouldUseStreaming,
|
|
5604
|
+
tryGetBotForAccount: () => tryGetBotForAccount
|
|
5605
|
+
});
|
|
5606
|
+
module.exports = __toCommonJS(index_exports);
|
|
5607
|
+
var import_plugin_sdk = require("openclaw/plugin-sdk");
|
|
5608
|
+
|
|
5609
|
+
// src/channel.ts
|
|
5610
|
+
var import_core = require("openclaw/plugin-sdk/core");
|
|
5611
|
+
init_config();
|
|
5083
5612
|
|
|
5084
5613
|
// src/bot-instance.ts
|
|
5085
5614
|
var import_node_os = __toESM(require("os"), 1);
|
|
@@ -9295,7 +9824,7 @@ var import_node_path2 = __toESM(require("path"), 1);
|
|
|
9295
9824
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
9296
9825
|
var _cachedOpenclawVersion;
|
|
9297
9826
|
function getPackageVersion() {
|
|
9298
|
-
return true ? "2.0.0-dev.
|
|
9827
|
+
return true ? "2.0.0-dev.202607101939" : "unknown";
|
|
9299
9828
|
}
|
|
9300
9829
|
function getOpenclawVersion(runtimeVersion) {
|
|
9301
9830
|
if (_cachedOpenclawVersion) return _cachedOpenclawVersion;
|
|
@@ -9636,224 +10165,81 @@ var PersistedRefIndexStore = class {
|
|
|
9636
10165
|
get size() {
|
|
9637
10166
|
return this.memory.size;
|
|
9638
10167
|
}
|
|
9639
|
-
/** 是否已完成初始化(磁盘回放) */
|
|
9640
|
-
get isInitialized() {
|
|
9641
|
-
return this.initialized;
|
|
9642
|
-
}
|
|
9643
|
-
/** 诊断快照 */
|
|
9644
|
-
stats() {
|
|
9645
|
-
return {
|
|
9646
|
-
memoryEntries: this.memory.size,
|
|
9647
|
-
diskLines: this.diskLineCount,
|
|
9648
|
-
maxEntries: this.maxEntries,
|
|
9649
|
-
filePath: this.filePath
|
|
9650
|
-
};
|
|
9651
|
-
}
|
|
9652
|
-
/**
|
|
9653
|
-
* 强制将当前内存状态持久化到磁盘(进程退出前调用)
|
|
9654
|
-
*/
|
|
9655
|
-
flush() {
|
|
9656
|
-
this.compactSync();
|
|
9657
|
-
}
|
|
9658
|
-
};
|
|
9659
|
-
var stores = /* @__PURE__ */ new Map();
|
|
9660
|
-
function getPersistedRefIndexStore(accountId) {
|
|
9661
|
-
let store = stores.get(accountId);
|
|
9662
|
-
if (!store) {
|
|
9663
|
-
const filePath = import_node_path3.default.join(getQQBotDataDir("data", accountId), DEFAULT_FILENAME);
|
|
9664
|
-
store = new PersistedRefIndexStore({ filePath });
|
|
9665
|
-
stores.set(accountId, store);
|
|
9666
|
-
}
|
|
9667
|
-
return store;
|
|
9668
|
-
}
|
|
9669
|
-
function flushAllRefIndexStores() {
|
|
9670
|
-
for (const store of stores.values()) {
|
|
9671
|
-
store.flush();
|
|
9672
|
-
}
|
|
9673
|
-
}
|
|
9674
|
-
|
|
9675
|
-
// src/runtime.ts
|
|
9676
|
-
var runtime = null;
|
|
9677
|
-
var exitHooksInstalled = false;
|
|
9678
|
-
function setQQBotRuntime(next) {
|
|
9679
|
-
runtime = next;
|
|
9680
|
-
const version = getOpenclawVersion(next.version);
|
|
9681
|
-
setOpenClawVersion(version);
|
|
9682
|
-
installExitHooksOnce();
|
|
9683
|
-
}
|
|
9684
|
-
function installExitHooksOnce() {
|
|
9685
|
-
if (exitHooksInstalled) return;
|
|
9686
|
-
exitHooksInstalled = true;
|
|
9687
|
-
const flush = () => {
|
|
9688
|
-
try {
|
|
9689
|
-
flushAllRefIndexStores();
|
|
9690
|
-
} catch {
|
|
9691
|
-
}
|
|
9692
|
-
};
|
|
9693
|
-
process.on("beforeExit", flush);
|
|
9694
|
-
process.on("SIGINT", () => {
|
|
9695
|
-
flush();
|
|
9696
|
-
process.exit(0);
|
|
9697
|
-
});
|
|
9698
|
-
process.on("SIGTERM", () => {
|
|
9699
|
-
flush();
|
|
9700
|
-
process.exit(0);
|
|
9701
|
-
});
|
|
9702
|
-
}
|
|
9703
|
-
function getQQBotRuntime() {
|
|
9704
|
-
if (!runtime) throw new Error("QQBot runtime not initialized");
|
|
9705
|
-
return runtime;
|
|
9706
|
-
}
|
|
9707
|
-
function tryGetQQBotRuntime() {
|
|
9708
|
-
return runtime;
|
|
9709
|
-
}
|
|
9710
|
-
|
|
9711
|
-
// src/adapter/resolve.ts
|
|
9712
|
-
function probeFunction(rt, paths) {
|
|
9713
|
-
for (const path22 of paths) {
|
|
9714
|
-
let target = rt;
|
|
9715
|
-
let parent = rt;
|
|
9716
|
-
for (let i = 0; i < path22.length; i++) {
|
|
9717
|
-
parent = target;
|
|
9718
|
-
target = target?.[path22[i]];
|
|
9719
|
-
if (target === void 0 || target === null) break;
|
|
9720
|
-
}
|
|
9721
|
-
if (typeof target === "function") {
|
|
9722
|
-
return target.bind(parent);
|
|
9723
|
-
}
|
|
9724
|
-
}
|
|
9725
|
-
return null;
|
|
9726
|
-
}
|
|
9727
|
-
function resolveRuntimeAdapters(rt, log4) {
|
|
9728
|
-
const version = rt.version ?? "unknown";
|
|
9729
|
-
const inboundRun = probeFunction(rt, [
|
|
9730
|
-
["channel", "inbound", "run"],
|
|
9731
|
-
// current (2026-05+)
|
|
9732
|
-
["channel", "turn", "run"]
|
|
9733
|
-
// legacy (removed 2026-05-27)
|
|
9734
|
-
]);
|
|
9735
|
-
const dispatchReply = probeFunction(rt, [
|
|
9736
|
-
["channel", "reply", "dispatchReplyWithBufferedBlockDispatcher"]
|
|
9737
|
-
]);
|
|
9738
|
-
const resolveAgentRoute = probeFunction(rt, [
|
|
9739
|
-
["channel", "routing", "resolveAgentRoute"]
|
|
9740
|
-
]);
|
|
9741
|
-
const rawBuildContext = probeFunction(rt, [
|
|
9742
|
-
["channel", "inbound", "buildContext"]
|
|
9743
|
-
]);
|
|
9744
|
-
const rawFinalizeContext = !rawBuildContext ? probeFunction(rt, [["channel", "reply", "finalizeInboundContext"]]) : null;
|
|
9745
|
-
const buildInboundContext = rawBuildContext ? (params) => rawBuildContext(params) : rawFinalizeContext ? (params) => {
|
|
9746
|
-
const isCommand = params.access?.commands?.authorized ?? false;
|
|
9747
|
-
const rawCtx = {
|
|
9748
|
-
Body: params.message.body,
|
|
9749
|
-
BodyForAgent: params.message.bodyForAgent,
|
|
9750
|
-
RawBody: params.message.rawBody,
|
|
9751
|
-
CommandBody: params.message.commandBody ?? params.message.rawBody,
|
|
9752
|
-
CommandSource: isCommand ? "text" : void 0,
|
|
9753
|
-
CommandTurn: params.command ?? void 0,
|
|
9754
|
-
CommandAuthorized: isCommand,
|
|
9755
|
-
From: params.from,
|
|
9756
|
-
To: params.reply.to,
|
|
9757
|
-
SessionKey: params.route.routeSessionKey,
|
|
9758
|
-
AccountId: params.route.accountId ?? params.accountId,
|
|
9759
|
-
ChatType: params.conversation.kind,
|
|
9760
|
-
GroupSystemPrompt: params.conversation.label,
|
|
9761
|
-
SenderId: params.sender.id,
|
|
9762
|
-
SenderName: params.sender.name,
|
|
9763
|
-
Provider: params.provider ?? params.channel,
|
|
9764
|
-
Surface: params.surface ?? params.channel,
|
|
9765
|
-
MessageSid: params.messageId,
|
|
9766
|
-
Timestamp: params.timestamp ?? Date.now(),
|
|
9767
|
-
OriginatingChannel: params.channel,
|
|
9768
|
-
OriginatingTo: params.reply.originatingTo ?? params.reply.to,
|
|
9769
|
-
...params.extra
|
|
9770
|
-
};
|
|
9771
|
-
return rawFinalizeContext(rawCtx);
|
|
9772
|
-
} : null;
|
|
9773
|
-
const resolveStorePath = probeFunction(rt, [
|
|
9774
|
-
["channel", "session", "resolveStorePath"]
|
|
9775
|
-
]);
|
|
9776
|
-
const recordInboundSession = probeFunction(rt, [
|
|
9777
|
-
["channel", "session", "recordInboundSession"]
|
|
9778
|
-
]);
|
|
9779
|
-
const formatEnvelope = probeFunction(rt, [
|
|
9780
|
-
["channel", "reply", "formatAgentEnvelope"],
|
|
9781
|
-
// current (2026-06+)
|
|
9782
|
-
["channel", "reply", "formatInboundEnvelope"]
|
|
9783
|
-
// deprecated,低版本兼容
|
|
9784
|
-
]);
|
|
9785
|
-
const resolveEnvelopeFormatOptions = probeFunction(rt, [
|
|
9786
|
-
["channel", "reply", "resolveEnvelopeFormatOptions"]
|
|
9787
|
-
]);
|
|
9788
|
-
const chunkMarkdownText = probeFunction(rt, [
|
|
9789
|
-
["channel", "text", "chunkMarkdownText"]
|
|
9790
|
-
]);
|
|
9791
|
-
const saveRemoteMedia = probeFunction(rt, [
|
|
9792
|
-
["channel", "media", "saveRemoteMedia"]
|
|
9793
|
-
]);
|
|
9794
|
-
const getConfig = probeFunction(rt, [
|
|
9795
|
-
["config", "current"]
|
|
9796
|
-
]) ?? probeFunction(rt, [
|
|
9797
|
-
["getConfig"]
|
|
9798
|
-
]) ?? probeFunction(rt, [
|
|
9799
|
-
["config", "loadConfig"]
|
|
9800
|
-
]);
|
|
9801
|
-
const rawMutateConfig = probeFunction(rt, [["config", "mutateConfigFile"]]);
|
|
9802
|
-
const rawWriteConfig = probeFunction(rt, [["config", "writeConfigFile"]]);
|
|
9803
|
-
const persistConfig = rawMutateConfig ? async (mutator) => {
|
|
9804
|
-
await rawMutateConfig({
|
|
9805
|
-
afterWrite: "hot-reload",
|
|
9806
|
-
mutate: mutator
|
|
9807
|
-
});
|
|
9808
|
-
} : rawWriteConfig && getConfig ? async (mutator) => {
|
|
9809
|
-
const current = JSON.parse(JSON.stringify(getConfig()));
|
|
9810
|
-
mutator(current);
|
|
9811
|
-
await rawWriteConfig(current);
|
|
9812
|
-
} : null;
|
|
9813
|
-
const resolved = [
|
|
9814
|
-
inboundRun && "inboundRun",
|
|
9815
|
-
dispatchReply && "dispatchReply",
|
|
9816
|
-
resolveAgentRoute && "resolveAgentRoute",
|
|
9817
|
-
buildInboundContext && "buildInboundContext",
|
|
9818
|
-
resolveStorePath && "resolveStorePath",
|
|
9819
|
-
recordInboundSession && "recordInboundSession",
|
|
9820
|
-
formatEnvelope && "formatEnvelope",
|
|
9821
|
-
chunkMarkdownText && "chunkMarkdownText",
|
|
9822
|
-
saveRemoteMedia && "saveRemoteMedia",
|
|
9823
|
-
getConfig && "getConfig",
|
|
9824
|
-
persistConfig && `persistConfig(${rawMutateConfig ? "mutate" : "write"})`
|
|
9825
|
-
].filter(Boolean);
|
|
9826
|
-
log4?.info(
|
|
9827
|
-
`[qqbot:adapter] openclaw=${version} resolved ${resolved.length} adapters: ${resolved.join(", ")}`
|
|
9828
|
-
);
|
|
9829
|
-
return {
|
|
9830
|
-
inboundRun,
|
|
9831
|
-
dispatchReply,
|
|
9832
|
-
resolveAgentRoute,
|
|
9833
|
-
buildInboundContext,
|
|
9834
|
-
resolveStorePath,
|
|
9835
|
-
recordInboundSession,
|
|
9836
|
-
formatEnvelope,
|
|
9837
|
-
resolveEnvelopeFormatOptions,
|
|
9838
|
-
chunkMarkdownText,
|
|
9839
|
-
saveRemoteMedia,
|
|
9840
|
-
getConfig,
|
|
9841
|
-
persistConfig,
|
|
9842
|
-
version
|
|
9843
|
-
};
|
|
10168
|
+
/** 是否已完成初始化(磁盘回放) */
|
|
10169
|
+
get isInitialized() {
|
|
10170
|
+
return this.initialized;
|
|
10171
|
+
}
|
|
10172
|
+
/** 诊断快照 */
|
|
10173
|
+
stats() {
|
|
10174
|
+
return {
|
|
10175
|
+
memoryEntries: this.memory.size,
|
|
10176
|
+
diskLines: this.diskLineCount,
|
|
10177
|
+
maxEntries: this.maxEntries,
|
|
10178
|
+
filePath: this.filePath
|
|
10179
|
+
};
|
|
10180
|
+
}
|
|
10181
|
+
/**
|
|
10182
|
+
* 强制将当前内存状态持久化到磁盘(进程退出前调用)
|
|
10183
|
+
*/
|
|
10184
|
+
flush() {
|
|
10185
|
+
this.compactSync();
|
|
10186
|
+
}
|
|
10187
|
+
};
|
|
10188
|
+
var stores = /* @__PURE__ */ new Map();
|
|
10189
|
+
function getPersistedRefIndexStore(accountId) {
|
|
10190
|
+
let store = stores.get(accountId);
|
|
10191
|
+
if (!store) {
|
|
10192
|
+
const filePath = import_node_path3.default.join(getQQBotDataDir("data", accountId), DEFAULT_FILENAME);
|
|
10193
|
+
store = new PersistedRefIndexStore({ filePath });
|
|
10194
|
+
stores.set(accountId, store);
|
|
10195
|
+
}
|
|
10196
|
+
return store;
|
|
9844
10197
|
}
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
const cached = _cachedRuntimeRef?.deref();
|
|
9849
|
-
if (cached === rt && _cachedAdapters) {
|
|
9850
|
-
return _cachedAdapters;
|
|
10198
|
+
function flushAllRefIndexStores() {
|
|
10199
|
+
for (const store of stores.values()) {
|
|
10200
|
+
store.flush();
|
|
9851
10201
|
}
|
|
9852
|
-
_cachedAdapters = resolveRuntimeAdapters(rt, log4);
|
|
9853
|
-
_cachedRuntimeRef = new WeakRef(rt);
|
|
9854
|
-
return _cachedAdapters;
|
|
9855
10202
|
}
|
|
9856
10203
|
|
|
10204
|
+
// src/runtime.ts
|
|
10205
|
+
var runtime = null;
|
|
10206
|
+
var exitHooksInstalled = false;
|
|
10207
|
+
function setQQBotRuntime(next) {
|
|
10208
|
+
runtime = next;
|
|
10209
|
+
const version = getOpenclawVersion(next.version);
|
|
10210
|
+
setOpenClawVersion(version);
|
|
10211
|
+
installExitHooksOnce();
|
|
10212
|
+
}
|
|
10213
|
+
function installExitHooksOnce() {
|
|
10214
|
+
if (exitHooksInstalled) return;
|
|
10215
|
+
exitHooksInstalled = true;
|
|
10216
|
+
const flush = () => {
|
|
10217
|
+
try {
|
|
10218
|
+
flushAllRefIndexStores();
|
|
10219
|
+
} catch {
|
|
10220
|
+
}
|
|
10221
|
+
};
|
|
10222
|
+
process.on("beforeExit", flush);
|
|
10223
|
+
process.on("SIGINT", () => {
|
|
10224
|
+
flush();
|
|
10225
|
+
process.exit(0);
|
|
10226
|
+
});
|
|
10227
|
+
process.on("SIGTERM", () => {
|
|
10228
|
+
flush();
|
|
10229
|
+
process.exit(0);
|
|
10230
|
+
});
|
|
10231
|
+
}
|
|
10232
|
+
function getQQBotRuntime() {
|
|
10233
|
+
if (!runtime) throw new Error("QQBot runtime not initialized");
|
|
10234
|
+
return runtime;
|
|
10235
|
+
}
|
|
10236
|
+
function tryGetQQBotRuntime() {
|
|
10237
|
+
return runtime;
|
|
10238
|
+
}
|
|
10239
|
+
|
|
10240
|
+
// src/channel.ts
|
|
10241
|
+
init_resolve();
|
|
10242
|
+
|
|
9857
10243
|
// src/outbound/media-send.ts
|
|
9858
10244
|
var path8 = __toESM(require("path"), 1);
|
|
9859
10245
|
var fs9 = __toESM(require("fs"), 1);
|
|
@@ -9877,6 +10263,9 @@ function resolveAgentWorkspace(cfg, agentId) {
|
|
|
9877
10263
|
return getQQBotMediaDir();
|
|
9878
10264
|
}
|
|
9879
10265
|
|
|
10266
|
+
// src/outbound/media-send.ts
|
|
10267
|
+
init_resolve();
|
|
10268
|
+
|
|
9880
10269
|
// src/utils/ssrf-guard.ts
|
|
9881
10270
|
var import_node_net = __toESM(require("net"), 1);
|
|
9882
10271
|
var import_promises = __toESM(require("dns/promises"), 1);
|
|
@@ -10043,14 +10432,36 @@ function resolveTempRoots() {
|
|
|
10043
10432
|
}
|
|
10044
10433
|
return [...roots];
|
|
10045
10434
|
}
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
path8.
|
|
10049
|
-
|
|
10050
|
-
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
|
|
10435
|
+
function buildDynamicAllowedRoots(workspaceDir) {
|
|
10436
|
+
const home = os4.homedir();
|
|
10437
|
+
const derivedBase = workspaceDir ? path8.dirname(workspaceDir) : path8.join(home, ".openclaw");
|
|
10438
|
+
const roots = [];
|
|
10439
|
+
const added = /* @__PURE__ */ new Set();
|
|
10440
|
+
const addRoot = (p2) => {
|
|
10441
|
+
try {
|
|
10442
|
+
const real = fs9.existsSync(p2) ? fs9.realpathSync(p2) : p2;
|
|
10443
|
+
if (!added.has(real)) {
|
|
10444
|
+
added.add(real);
|
|
10445
|
+
roots.push(real);
|
|
10446
|
+
}
|
|
10447
|
+
} catch {
|
|
10448
|
+
}
|
|
10449
|
+
};
|
|
10450
|
+
const knownBases = [path8.join(home, ".openclaw"), path8.join(home, ".openclaw-dev")];
|
|
10451
|
+
if (workspaceDir) {
|
|
10452
|
+
addRoot(path8.join(derivedBase, "media"));
|
|
10453
|
+
addRoot(path8.join(derivedBase, "workspace"));
|
|
10454
|
+
addRoot(path8.join(derivedBase, "outbound"));
|
|
10455
|
+
addRoot(workspaceDir);
|
|
10456
|
+
}
|
|
10457
|
+
for (const base of knownBases) {
|
|
10458
|
+
addRoot(path8.join(base, "media"));
|
|
10459
|
+
addRoot(path8.join(base, "workspace"));
|
|
10460
|
+
addRoot(path8.join(base, "outbound"));
|
|
10461
|
+
}
|
|
10462
|
+
for (const t of resolveTempRoots()) addRoot(t);
|
|
10463
|
+
return roots;
|
|
10464
|
+
}
|
|
10054
10465
|
var MAX_DATA_URL_BYTES = 10 * 1024 * 1024;
|
|
10055
10466
|
async function sendMedia2(params) {
|
|
10056
10467
|
const { source, accountId, log: log4 } = params;
|
|
@@ -10119,363 +10530,110 @@ async function resolveMediaPath(source, log4, workspaceDir) {
|
|
|
10119
10530
|
} catch {
|
|
10120
10531
|
return { ok: false, error: `Cannot resolve path: ${resolved}` };
|
|
10121
10532
|
}
|
|
10122
|
-
const
|
|
10533
|
+
const dynamicRoots = buildDynamicAllowedRoots(workspaceDir);
|
|
10534
|
+
const allowed = isPathInAllowedRoots(real, dynamicRoots);
|
|
10123
10535
|
if (!allowed) {
|
|
10124
10536
|
log4?.warn(`path blocked \u2014 not in allowed directory: ${real}`);
|
|
10125
10537
|
return { ok: false, error: `\u6587\u4EF6\u8DEF\u5F84\u4E0D\u5728\u5141\u8BB8\u7684\u76EE\u5F55\u4E2D` };
|
|
10126
10538
|
}
|
|
10127
|
-
return { ok: true, path: real, isLocal: true };
|
|
10128
|
-
}
|
|
10129
|
-
function resolveWorkspaceFromAgent(agentId) {
|
|
10130
|
-
const cfg = resolveConfigViaAdapter();
|
|
10131
|
-
if (!cfg) return void 0;
|
|
10132
|
-
return resolveAgentWorkspace(cfg, agentId);
|
|
10133
|
-
}
|
|
10134
|
-
function resolveConfigViaAdapter() {
|
|
10135
|
-
try {
|
|
10136
|
-
const rt = tryGetQQBotRuntime();
|
|
10137
|
-
if (!rt) return void 0;
|
|
10138
|
-
return getAdapters(rt).getConfig?.();
|
|
10139
|
-
} catch {
|
|
10140
|
-
return void 0;
|
|
10141
|
-
}
|
|
10142
|
-
}
|
|
10143
|
-
function resolveWorkingFile(name, workspaceDir) {
|
|
10144
|
-
for (const p2 of [path8.resolve(name), workspaceDir ? path8.join(workspaceDir, name) : null]) {
|
|
10145
|
-
if (p2 && fs9.existsSync(p2)) return p2;
|
|
10146
|
-
}
|
|
10147
|
-
return null;
|
|
10148
|
-
}
|
|
10149
|
-
async function sendImageMedia(gw, target, source, params) {
|
|
10150
|
-
try {
|
|
10151
|
-
const result = await gw.sendMedia(target, source, {
|
|
10152
|
-
text: params.text,
|
|
10153
|
-
msgId: params.replyToId
|
|
10154
|
-
});
|
|
10155
|
-
return { messageId: result.id };
|
|
10156
|
-
} catch (err) {
|
|
10157
|
-
return { error: formatErr(err) };
|
|
10158
|
-
}
|
|
10159
|
-
}
|
|
10160
|
-
async function sendVoiceMedia(gw, target, source, params) {
|
|
10161
|
-
const voiceSource = resolveVoiceSource2(source);
|
|
10162
|
-
try {
|
|
10163
|
-
const result = await gw.sendVoice(target, voiceSource, {
|
|
10164
|
-
msgId: params.replyToId
|
|
10165
|
-
});
|
|
10166
|
-
return { messageId: result.id };
|
|
10167
|
-
} catch (err) {
|
|
10168
|
-
params.log?.child("media")?.warn(`sendVoice failed (${formatErr(err)}), falling back to sendFile`);
|
|
10169
|
-
try {
|
|
10170
|
-
const fileName = path8.basename(source);
|
|
10171
|
-
const fallback = await gw.sendFile(target, source, {
|
|
10172
|
-
text: params.text,
|
|
10173
|
-
msgId: params.replyToId,
|
|
10174
|
-
fileName
|
|
10175
|
-
});
|
|
10176
|
-
return { messageId: fallback.id, fallback: true };
|
|
10177
|
-
} catch (fallbackErr) {
|
|
10178
|
-
return { error: `voice: ${formatErr(err)} | fallback file: ${formatErr(fallbackErr)}` };
|
|
10179
|
-
}
|
|
10180
|
-
}
|
|
10181
|
-
}
|
|
10182
|
-
async function sendVideoMedia(gw, target, source, params) {
|
|
10183
|
-
try {
|
|
10184
|
-
const result = await gw.sendVideo(target, source, {
|
|
10185
|
-
text: params.text,
|
|
10186
|
-
msgId: params.replyToId
|
|
10187
|
-
});
|
|
10188
|
-
return { messageId: result.id };
|
|
10189
|
-
} catch (err) {
|
|
10190
|
-
return { error: formatErr(err) };
|
|
10191
|
-
}
|
|
10192
|
-
}
|
|
10193
|
-
async function sendFileMedia(gw, target, source, params) {
|
|
10194
|
-
try {
|
|
10195
|
-
const fileName = path8.basename(source);
|
|
10196
|
-
const result = await gw.sendFile(target, source, {
|
|
10197
|
-
text: params.text,
|
|
10198
|
-
msgId: params.replyToId,
|
|
10199
|
-
fileName
|
|
10200
|
-
});
|
|
10201
|
-
return { messageId: result.id };
|
|
10202
|
-
} catch (err) {
|
|
10203
|
-
return { error: formatErr(err) };
|
|
10204
|
-
}
|
|
10205
|
-
}
|
|
10206
|
-
function resolveVoiceSource2(source) {
|
|
10207
|
-
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
10208
|
-
return { url: source };
|
|
10209
|
-
}
|
|
10210
|
-
if (source.startsWith("data:") || !source.startsWith("/") && !source.startsWith("./") && !source.startsWith("../") && !source.startsWith("~")) {
|
|
10211
|
-
const commaIdx = source.indexOf(",");
|
|
10212
|
-
return { base64: commaIdx > 0 ? source.slice(commaIdx + 1) : source };
|
|
10213
|
-
}
|
|
10214
|
-
return { localPath: source };
|
|
10215
|
-
}
|
|
10216
|
-
function formatErr(err) {
|
|
10217
|
-
if (err instanceof Error) return err.message;
|
|
10218
|
-
return String(err);
|
|
10219
|
-
}
|
|
10220
|
-
|
|
10221
|
-
// src/adapter/setup.ts
|
|
10222
|
-
var import_node_module2 = require("module");
|
|
10223
|
-
var req2 = (0, import_node_module2.createRequire)(__filename);
|
|
10224
|
-
var _setup;
|
|
10225
|
-
var _tools;
|
|
10226
|
-
function loadSetup() {
|
|
10227
|
-
if (_setup !== void 0) return _setup;
|
|
10228
|
-
try {
|
|
10229
|
-
_setup = req2("openclaw/plugin-sdk/setup");
|
|
10230
|
-
} catch {
|
|
10231
|
-
_setup = null;
|
|
10232
|
-
}
|
|
10233
|
-
return _setup;
|
|
10234
|
-
}
|
|
10235
|
-
function loadTools() {
|
|
10236
|
-
if (_tools !== void 0) return _tools;
|
|
10237
|
-
try {
|
|
10238
|
-
_tools = req2("openclaw/plugin-sdk/setup-tools");
|
|
10239
|
-
} catch {
|
|
10240
|
-
_tools = null;
|
|
10241
|
-
}
|
|
10242
|
-
return _tools;
|
|
10243
|
-
}
|
|
10244
|
-
var DEFAULT_ACCOUNT_ID2 = "default";
|
|
10245
|
-
function createStandardChannelSetupStatus(...args) {
|
|
10246
|
-
const mod = loadSetup();
|
|
10247
|
-
if (mod) return mod.createStandardChannelSetupStatus(...args);
|
|
10248
|
-
return {
|
|
10249
|
-
channelLabel: args[0]?.channelLabel ?? "QQ Bot",
|
|
10250
|
-
configuredLabel: "Configured",
|
|
10251
|
-
unconfiguredLabel: "Not configured",
|
|
10252
|
-
resolveConfigured: () => false
|
|
10253
|
-
};
|
|
10254
|
-
}
|
|
10255
|
-
function setSetupChannelEnabled(...args) {
|
|
10256
|
-
loadSetup()?.setSetupChannelEnabled?.(...args);
|
|
10257
|
-
}
|
|
10258
|
-
function formatDocsLink(...args) {
|
|
10259
|
-
const mod = loadTools();
|
|
10260
|
-
if (mod) return mod.formatDocsLink(...args);
|
|
10261
|
-
return args[1] ? `${args[1]}: ${args[0]}` : args[0];
|
|
10262
|
-
}
|
|
10263
|
-
|
|
10264
|
-
// node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/qr-connect.js
|
|
10265
|
-
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
10266
|
-
|
|
10267
|
-
// node_modules/.pnpm/@tencent-connect+qqbot-connector@1.2.0/node_modules/@tencent-connect/qqbot-connector/dist/esm/qqbot-session.js
|
|
10268
|
-
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
10269
|
-
var import_node_https = __toESM(require("https"), 1);
|
|
10270
|
-
var E = { production: "q.qq.com", test: "test.q.qq.com" };
|
|
10271
|
-
function d(t = "production") {
|
|
10272
|
-
return E[t];
|
|
10273
|
-
}
|
|
10274
|
-
function l() {
|
|
10275
|
-
return import_node_crypto.default.randomBytes(32).toString("base64");
|
|
10276
|
-
}
|
|
10277
|
-
var u;
|
|
10278
|
-
(function(t) {
|
|
10279
|
-
t[t.NONE = 0] = "NONE", t[t.PENDING = 1] = "PENDING", t[t.COMPLETED = 2] = "COMPLETED", t[t.EXPIRED = 3] = "EXPIRED";
|
|
10280
|
-
})(u || (u = {}));
|
|
10281
|
-
function b(t, r) {
|
|
10282
|
-
const a = Buffer.from(r, "base64"), n = Buffer.from(t, "base64"), e = n.subarray(0, 12), c = n.subarray(n.length - 16), s = n.subarray(12, n.length - 16), o = import_node_crypto.default.createDecipheriv("aes-256-gcm", a, e);
|
|
10283
|
-
return o.setAuthTag(c), Buffer.concat([o.update(s), o.final()]).toString("utf8");
|
|
10284
|
-
}
|
|
10285
|
-
function h(t, r, a) {
|
|
10286
|
-
return new Promise((n, e) => {
|
|
10287
|
-
const c = JSON.stringify(r), s = new URL(t), o = import_node_https.default.request({ hostname: s.hostname, path: s.pathname + s.search, method: "POST", timeout: a, headers: { "Content-Type": "application/json", Accept: "application/json", "Content-Length": Buffer.byteLength(c) } }, (i) => {
|
|
10288
|
-
if (i.statusCode !== 200) {
|
|
10289
|
-
i.resume(), e(new Error(`HTTP ${i.statusCode} from ${t}`));
|
|
10290
|
-
return;
|
|
10291
|
-
}
|
|
10292
|
-
let f = "";
|
|
10293
|
-
i.on("data", (p2) => {
|
|
10294
|
-
f += p2;
|
|
10295
|
-
}), i.on("end", () => {
|
|
10296
|
-
try {
|
|
10297
|
-
n(JSON.parse(f));
|
|
10298
|
-
} catch (p2) {
|
|
10299
|
-
e(p2);
|
|
10300
|
-
}
|
|
10301
|
-
});
|
|
10302
|
-
});
|
|
10303
|
-
o.on("error", e), o.on("timeout", () => {
|
|
10304
|
-
o.destroy(), e(new Error(`timeout fetching ${t}`));
|
|
10305
|
-
}), o.end(c);
|
|
10306
|
-
});
|
|
10539
|
+
return { ok: true, path: real, isLocal: true };
|
|
10307
10540
|
}
|
|
10308
|
-
|
|
10309
|
-
const
|
|
10310
|
-
if (
|
|
10311
|
-
|
|
10312
|
-
return { taskId: e.data.task_id, key: n };
|
|
10541
|
+
function resolveWorkspaceFromAgent(agentId) {
|
|
10542
|
+
const cfg = resolveConfigViaAdapter();
|
|
10543
|
+
if (!cfg) return void 0;
|
|
10544
|
+
return resolveAgentWorkspace(cfg, agentId);
|
|
10313
10545
|
}
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10546
|
+
function resolveConfigViaAdapter() {
|
|
10547
|
+
try {
|
|
10548
|
+
const rt = tryGetQQBotRuntime();
|
|
10549
|
+
if (!rt) return void 0;
|
|
10550
|
+
return getAdapters(rt).getConfig?.();
|
|
10551
|
+
} catch {
|
|
10552
|
+
return void 0;
|
|
10553
|
+
}
|
|
10318
10554
|
}
|
|
10319
|
-
function
|
|
10320
|
-
|
|
10555
|
+
function resolveWorkingFile(name, workspaceDir) {
|
|
10556
|
+
for (const p2 of [path8.resolve(name), workspaceDir ? path8.join(workspaceDir, name) : null]) {
|
|
10557
|
+
if (p2 && fs9.existsSync(p2)) return p2;
|
|
10558
|
+
}
|
|
10559
|
+
return null;
|
|
10321
10560
|
}
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
import_qrcode_terminal.default.generate(r, { small: true }, (e) => {
|
|
10328
|
-
o(e);
|
|
10561
|
+
async function sendImageMedia(gw, target, source, params) {
|
|
10562
|
+
try {
|
|
10563
|
+
const result = await gw.sendMedia(target, source, {
|
|
10564
|
+
text: params.text,
|
|
10565
|
+
msgId: params.replyToId
|
|
10329
10566
|
});
|
|
10330
|
-
|
|
10331
|
-
}
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
if (o?.aborted) {
|
|
10335
|
-
t(new DOMException("Aborted", "AbortError"));
|
|
10336
|
-
return;
|
|
10337
|
-
}
|
|
10338
|
-
const n = setTimeout(e, r);
|
|
10339
|
-
o?.addEventListener("abort", () => {
|
|
10340
|
-
clearTimeout(n), t(new DOMException("Aborted", "AbortError"));
|
|
10341
|
-
}, { once: true });
|
|
10342
|
-
});
|
|
10567
|
+
return { messageId: result.id };
|
|
10568
|
+
} catch (err) {
|
|
10569
|
+
return { error: formatErr(err) };
|
|
10570
|
+
}
|
|
10343
10571
|
}
|
|
10344
|
-
async function
|
|
10345
|
-
|
|
10346
|
-
|
|
10572
|
+
async function sendVoiceMedia(gw, target, source, params) {
|
|
10573
|
+
const voiceSource = resolveVoiceSource2(source);
|
|
10574
|
+
try {
|
|
10575
|
+
const result = await gw.sendVoice(target, voiceSource, {
|
|
10576
|
+
msgId: params.replyToId
|
|
10577
|
+
});
|
|
10578
|
+
return { messageId: result.id };
|
|
10579
|
+
} catch (err) {
|
|
10580
|
+
params.log?.child("media")?.warn(`sendVoice failed (${formatErr(err)}), falling back to sendFile`);
|
|
10347
10581
|
try {
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10582
|
+
const fileName = path8.basename(source);
|
|
10583
|
+
const fallback = await gw.sendFile(target, source, {
|
|
10584
|
+
text: params.text,
|
|
10585
|
+
msgId: params.replyToId,
|
|
10586
|
+
fileName
|
|
10587
|
+
});
|
|
10588
|
+
return { messageId: fallback.id, fallback: true };
|
|
10589
|
+
} catch (fallbackErr) {
|
|
10590
|
+
return { error: `voice: ${formatErr(err)} | fallback file: ${formatErr(fallbackErr)}` };
|
|
10356
10591
|
}
|
|
10357
|
-
if (t.status === u.EXPIRED) return { outcome: "expired" };
|
|
10358
|
-
await d2(p, e);
|
|
10359
10592
|
}
|
|
10360
|
-
throw new DOMException("Aborted", "AbortError");
|
|
10361
|
-
}
|
|
10362
|
-
function l2(r, o) {
|
|
10363
|
-
const e = new AbortController(), t = o?.signal ? AbortSignal.any([e.signal, o.signal]) : e.signal;
|
|
10364
|
-
return (async () => {
|
|
10365
|
-
const n = o?.displayQrCodeToConsole ?? true;
|
|
10366
|
-
for (; ; ) {
|
|
10367
|
-
if (t.aborted) throw new DOMException("Aborted", "AbortError");
|
|
10368
|
-
let a;
|
|
10369
|
-
try {
|
|
10370
|
-
a = await y();
|
|
10371
|
-
} catch (u2) {
|
|
10372
|
-
throw new Error(`\u83B7\u53D6\u7ED1\u5B9A\u4EFB\u52A1\u5931\u8D25: ${u2 instanceof Error ? u2.message : String(u2)}`, { cause: u2 });
|
|
10373
|
-
}
|
|
10374
|
-
const i = w(a.taskId, o?.source);
|
|
10375
|
-
if (n) {
|
|
10376
|
-
const u2 = await F(i);
|
|
10377
|
-
console.log(u2), console.log(`\u8BF7\u4F7F\u7528\u624B\u673A QQ \u626B\u63CF\u4E0A\u65B9\u4E8C\u7EF4\u7801\uFF0C\u5B8C\u6210\u673A\u5668\u4EBA\u7ED1\u5B9A\u3002
|
|
10378
|
-
`);
|
|
10379
|
-
}
|
|
10380
|
-
r.onQrDisplayed?.(i);
|
|
10381
|
-
const s = await C(a.taskId, a.key, t);
|
|
10382
|
-
if (s.outcome === "scanned") {
|
|
10383
|
-
r.onSuccess([{ appId: s.appId, appSecret: s.appSecret, userOpenid: s.userOpenid }]);
|
|
10384
|
-
return;
|
|
10385
|
-
}
|
|
10386
|
-
r.onQrExpired?.(), n && console.log(`\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u6B63\u5728\u5237\u65B0\u2026
|
|
10387
|
-
`);
|
|
10388
|
-
}
|
|
10389
|
-
})().catch((n) => {
|
|
10390
|
-
if (n instanceof DOMException && n.name === "AbortError") {
|
|
10391
|
-
r.onFailure(new Error("\u5DF2\u53D6\u6D88"));
|
|
10392
|
-
return;
|
|
10393
|
-
}
|
|
10394
|
-
r.onFailure(n instanceof Error ? n : new Error(String(n)));
|
|
10395
|
-
}), () => e.abort();
|
|
10396
|
-
}
|
|
10397
|
-
function m2(r) {
|
|
10398
|
-
return new Promise((o, e) => {
|
|
10399
|
-
l2({ onSuccess: o, onFailure: e }, { ...r, displayQrCodeToConsole: true });
|
|
10400
|
-
});
|
|
10401
|
-
}
|
|
10402
|
-
|
|
10403
|
-
// src/setup/finalize.ts
|
|
10404
|
-
function isConfigured(cfg, accountId) {
|
|
10405
|
-
const account = resolveQQBotAccount(cfg, accountId);
|
|
10406
|
-
return Boolean(account.appId && account.clientSecret);
|
|
10407
10593
|
}
|
|
10408
|
-
async function
|
|
10594
|
+
async function sendVideoMedia(gw, target, source, params) {
|
|
10409
10595
|
try {
|
|
10410
|
-
const
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
}
|
|
10415
|
-
let next = cfg;
|
|
10416
|
-
for (const { appId, appSecret, userOpenid } of accounts) {
|
|
10417
|
-
next = applyQQBotAccountConfig(next, appId, { appId, clientSecret: appSecret });
|
|
10418
|
-
next = applyAccountDefaults(next, appId, userOpenid);
|
|
10419
|
-
}
|
|
10420
|
-
if (accounts.length === 1) {
|
|
10421
|
-
rt.log(`\u2714 QQ Bot \u7ED1\u5B9A\u6210\u529F\uFF01(AppID: ${accounts[0].appId})`);
|
|
10422
|
-
} else {
|
|
10423
|
-
rt.log(`\u2714 ${accounts.length} \u4E2A QQ Bot \u7ED1\u5B9A\u6210\u529F\uFF01(AppID: ${accounts.map((a) => a.appId).join(", ")})`);
|
|
10424
|
-
}
|
|
10425
|
-
return next;
|
|
10596
|
+
const result = await gw.sendVideo(target, source, {
|
|
10597
|
+
text: params.text,
|
|
10598
|
+
msgId: params.replyToId
|
|
10599
|
+
});
|
|
10600
|
+
return { messageId: result.id };
|
|
10426
10601
|
} catch (err) {
|
|
10427
|
-
|
|
10428
|
-
await prompter.note(`\u7ED1\u5B9A\u5931\u8D25\uFF0C\u60A8\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u3002
|
|
10429
|
-
\u6587\u6863: ${formatDocsLink("/channels/qqbot", "qqbot")}`, "QQ Bot");
|
|
10430
|
-
return cfg;
|
|
10602
|
+
return { error: formatErr(err) };
|
|
10431
10603
|
}
|
|
10432
10604
|
}
|
|
10433
|
-
async function
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
}
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
const mode = await params.prompter.select({
|
|
10445
|
-
message: configured ? "QQ \u5DF2\u7ED1\u5B9A\uFF0C\u9009\u62E9\u64CD\u4F5C" : "\u9009\u62E9 QQ \u7ED1\u5B9A\u65B9\u5F0F",
|
|
10446
|
-
options: [
|
|
10447
|
-
{ value: "qr", label: "\u626B\u7801\u7ED1\u5B9A\uFF08\u63A8\u8350\uFF09", hint: "\u4F7F\u7528 QQ \u626B\u63CF\u4E8C\u7EF4\u7801\u81EA\u52A8\u5B8C\u6210\u7ED1\u5B9A" },
|
|
10448
|
-
{ value: "manual", label: "\u624B\u52A8\u8F93\u5165 QQ Bot AppID \u548C AppSecret", hint: "\u9700\u5230 QQ \u5F00\u653E\u5E73\u53F0 q.qq.com \u67E5\u770B" },
|
|
10449
|
-
{ value: "skip", label: configured ? "\u4FDD\u6301\u5F53\u524D\u914D\u7F6E" : "\u7A0D\u540E\u914D\u7F6E" }
|
|
10450
|
-
]
|
|
10451
|
-
});
|
|
10452
|
-
let next = params.cfg;
|
|
10453
|
-
if (mode === "qr") {
|
|
10454
|
-
next = await linkViaQrCode(next, accountId, params.prompter, params.runtime);
|
|
10455
|
-
} else if (mode === "manual") {
|
|
10456
|
-
next = await linkViaManual(next, params.prompter);
|
|
10457
|
-
} else if (!configured) {
|
|
10458
|
-
await params.prompter.note("\u60A8\u53EF\u4EE5\u7A0D\u540E\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u91CD\u65B0\u914D\u7F6E\uFF1A\n openclaw channels add", "QQ Bot");
|
|
10605
|
+
async function sendFileMedia(gw, target, source, params) {
|
|
10606
|
+
try {
|
|
10607
|
+
const fileName = path8.basename(source);
|
|
10608
|
+
const result = await gw.sendFile(target, source, {
|
|
10609
|
+
text: params.text,
|
|
10610
|
+
msgId: params.replyToId,
|
|
10611
|
+
fileName
|
|
10612
|
+
});
|
|
10613
|
+
return { messageId: result.id };
|
|
10614
|
+
} catch (err) {
|
|
10615
|
+
return { error: formatErr(err) };
|
|
10459
10616
|
}
|
|
10460
|
-
return { cfg: next };
|
|
10461
10617
|
}
|
|
10462
|
-
function
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
const defaults = { streaming: true, dmPolicy: "allowlist" };
|
|
10466
|
-
if (userOpenid) defaults.allowFrom = [userOpenid];
|
|
10467
|
-
if (accountId === DEFAULT_ACCOUNT_ID2) {
|
|
10468
|
-
Object.assign(qqbot, defaults);
|
|
10469
|
-
} else {
|
|
10470
|
-
const accounts = { ...qqbot.accounts ?? {} };
|
|
10471
|
-
accounts[accountId] = { ...accounts[accountId] ?? {}, ...defaults };
|
|
10472
|
-
qqbot.accounts = accounts;
|
|
10618
|
+
function resolveVoiceSource2(source) {
|
|
10619
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
10620
|
+
return { url: source };
|
|
10473
10621
|
}
|
|
10474
|
-
|
|
10475
|
-
|
|
10622
|
+
if (source.startsWith("data:") || !source.startsWith("/") && !source.startsWith("./") && !source.startsWith("../") && !source.startsWith("~")) {
|
|
10623
|
+
const commaIdx = source.indexOf(",");
|
|
10624
|
+
return { base64: commaIdx > 0 ? source.slice(commaIdx + 1) : source };
|
|
10625
|
+
}
|
|
10626
|
+
return { localPath: source };
|
|
10627
|
+
}
|
|
10628
|
+
function formatErr(err) {
|
|
10629
|
+
if (err instanceof Error) return err.message;
|
|
10630
|
+
return String(err);
|
|
10476
10631
|
}
|
|
10477
10632
|
|
|
10478
10633
|
// src/setup/surface.ts
|
|
10634
|
+
init_setup();
|
|
10635
|
+
init_config();
|
|
10636
|
+
init_finalize();
|
|
10479
10637
|
var CHANNEL = "qqbot";
|
|
10480
10638
|
var qqbotSetupWizard = {
|
|
10481
10639
|
channel: CHANNEL,
|
|
@@ -10492,6 +10650,14 @@ var qqbotSetupWizard = {
|
|
|
10492
10650
|
return Boolean(account.appId && account.clientSecret);
|
|
10493
10651
|
})
|
|
10494
10652
|
}),
|
|
10653
|
+
// 未配置时默认使用 default 账号,有账户时框架会提示选择
|
|
10654
|
+
resolveAccountIdForConfigure: async ({ cfg, shouldPromptAccountIds, accountOverride, defaultAccountId }) => {
|
|
10655
|
+
if (accountOverride) return accountOverride;
|
|
10656
|
+
const ids = listQQBotAccountIds(cfg);
|
|
10657
|
+
if (ids.length === 0) return "default";
|
|
10658
|
+
if (!shouldPromptAccountIds) return ids[0];
|
|
10659
|
+
return defaultAccountId || resolveDefaultQQBotAccountId(cfg);
|
|
10660
|
+
},
|
|
10495
10661
|
credentials: [],
|
|
10496
10662
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10497
10663
|
finalize: (async ({ cfg, accountId, prompter, runtime: runtime2 }) => finalizeQQBotSetup({ cfg, accountId, prompter, runtime: runtime2 })),
|
|
@@ -10501,6 +10667,118 @@ var qqbotSetupWizard = {
|
|
|
10501
10667
|
}
|
|
10502
10668
|
};
|
|
10503
10669
|
|
|
10670
|
+
// src/setup/login.ts
|
|
10671
|
+
init_esm();
|
|
10672
|
+
var pendingSessions = /* @__PURE__ */ new Map();
|
|
10673
|
+
function startQrLogin(accountId, source = "openclaw") {
|
|
10674
|
+
const key = accountId ?? "default";
|
|
10675
|
+
pendingSessions.get(key)?.dispose();
|
|
10676
|
+
pendingSessions.delete(key);
|
|
10677
|
+
return new Promise((resolve2) => {
|
|
10678
|
+
let credentialsResolve;
|
|
10679
|
+
let credentialsReject;
|
|
10680
|
+
const credentialsPromise = new Promise((res, rej) => {
|
|
10681
|
+
credentialsResolve = res;
|
|
10682
|
+
credentialsReject = rej;
|
|
10683
|
+
});
|
|
10684
|
+
const dispose = l2(
|
|
10685
|
+
{
|
|
10686
|
+
onQrDisplayed(url) {
|
|
10687
|
+
resolve2({
|
|
10688
|
+
qrDataUrl: url,
|
|
10689
|
+
message: "\u8BF7\u4F7F\u7528\u624B\u673A QQ \u626B\u63CF\u4E8C\u7EF4\u7801\u5B8C\u6210\u7ED1\u5B9A"
|
|
10690
|
+
});
|
|
10691
|
+
},
|
|
10692
|
+
onSuccess: (creds) => credentialsResolve(creds),
|
|
10693
|
+
onFailure: (err) => credentialsReject(err)
|
|
10694
|
+
},
|
|
10695
|
+
{ displayQrCodeToConsole: true, source }
|
|
10696
|
+
);
|
|
10697
|
+
pendingSessions.set(key, { dispose, credentialsPromise });
|
|
10698
|
+
});
|
|
10699
|
+
}
|
|
10700
|
+
async function waitQrLogin(accountId) {
|
|
10701
|
+
const key = accountId ?? "default";
|
|
10702
|
+
const session = pendingSessions.get(key);
|
|
10703
|
+
if (!session) {
|
|
10704
|
+
return { connected: false, message: "\u6CA1\u6709\u6B63\u5728\u8FDB\u884C\u7684\u767B\u5F55\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u8FD0\u884C login \u547D\u4EE4\u3002" };
|
|
10705
|
+
}
|
|
10706
|
+
try {
|
|
10707
|
+
const credentials = await session.credentialsPromise;
|
|
10708
|
+
pendingSessions.delete(key);
|
|
10709
|
+
if (credentials.length === 0) {
|
|
10710
|
+
return { connected: false, message: "\u672A\u83B7\u53D6\u5230 QQ Bot \u51ED\u636E\u3002" };
|
|
10711
|
+
}
|
|
10712
|
+
return {
|
|
10713
|
+
connected: true,
|
|
10714
|
+
message: `\u7ED1\u5B9A\u6210\u529F\uFF01AppID: ${credentials.map((c) => c.appId).join(", ")}`,
|
|
10715
|
+
credentials
|
|
10716
|
+
};
|
|
10717
|
+
} catch (err) {
|
|
10718
|
+
pendingSessions.delete(key);
|
|
10719
|
+
return {
|
|
10720
|
+
connected: false,
|
|
10721
|
+
message: `\u7ED1\u5B9A\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`
|
|
10722
|
+
};
|
|
10723
|
+
}
|
|
10724
|
+
}
|
|
10725
|
+
function parseChannelInput(channelInput) {
|
|
10726
|
+
if (!channelInput) return null;
|
|
10727
|
+
const parts = channelInput.trim().split(":");
|
|
10728
|
+
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
10729
|
+
return { appId: parts[0], clientSecret: parts[1] };
|
|
10730
|
+
}
|
|
10731
|
+
return null;
|
|
10732
|
+
}
|
|
10733
|
+
async function qqbotLogin({
|
|
10734
|
+
cfg,
|
|
10735
|
+
accountId,
|
|
10736
|
+
channelInput,
|
|
10737
|
+
verbose,
|
|
10738
|
+
...rest
|
|
10739
|
+
}) {
|
|
10740
|
+
const { applyQQBotAccountConfig: applyQQBotAccountConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
10741
|
+
const { persistAuthConfig: persistAuthConfig2 } = await Promise.resolve().then(() => (init_resolve(), resolve_exports));
|
|
10742
|
+
const { applyAccountDefaults: applyAccountDefaults2 } = await Promise.resolve().then(() => (init_finalize(), finalize_exports));
|
|
10743
|
+
const { resolveAccountKey: resolveAccountKey2 } = await Promise.resolve().then(() => (init_account_key(), account_key_exports));
|
|
10744
|
+
const runtime2 = rest;
|
|
10745
|
+
const resolvedId = accountId ? accountId.trim().toLowerCase() : null;
|
|
10746
|
+
const parsed = parseChannelInput(channelInput);
|
|
10747
|
+
if (parsed) {
|
|
10748
|
+
const key = resolveAccountKey2(cfg, parsed.appId, resolvedId);
|
|
10749
|
+
const result2 = applyQQBotAccountConfig2(cfg, key, {
|
|
10750
|
+
appId: parsed.appId,
|
|
10751
|
+
clientSecret: parsed.clientSecret
|
|
10752
|
+
});
|
|
10753
|
+
Object.assign(cfg, result2);
|
|
10754
|
+
const withDefaults = applyAccountDefaults2(cfg, key);
|
|
10755
|
+
Object.assign(cfg, withDefaults);
|
|
10756
|
+
await persistAuthConfig2(runtime2, cfg, "restart");
|
|
10757
|
+
if (verbose) console.log(`QQ Bot \u5DF2\u914D\u7F6E (${key}) AppID: ${parsed.appId}`);
|
|
10758
|
+
return;
|
|
10759
|
+
}
|
|
10760
|
+
const { qrDataUrl, message } = await startQrLogin(resolvedId || "pending");
|
|
10761
|
+
console.log(`
|
|
10762
|
+
${message}`);
|
|
10763
|
+
if (qrDataUrl) console.log(`QR \u94FE\u63A5: ${qrDataUrl}`);
|
|
10764
|
+
const result = await waitQrLogin(resolvedId || "pending");
|
|
10765
|
+
if (!result.connected || !result.credentials) {
|
|
10766
|
+
throw new Error(result.message);
|
|
10767
|
+
}
|
|
10768
|
+
for (const cred of result.credentials) {
|
|
10769
|
+
const key = resolveAccountKey2(cfg, cred.appId, resolvedId);
|
|
10770
|
+
const next = applyQQBotAccountConfig2(cfg, key, {
|
|
10771
|
+
appId: cred.appId,
|
|
10772
|
+
clientSecret: cred.appSecret
|
|
10773
|
+
});
|
|
10774
|
+
Object.assign(cfg, next);
|
|
10775
|
+
const withDefaults = applyAccountDefaults2(cfg, key, cred.userOpenid);
|
|
10776
|
+
Object.assign(cfg, withDefaults);
|
|
10777
|
+
}
|
|
10778
|
+
await persistAuthConfig2(runtime2, cfg, "restart");
|
|
10779
|
+
console.log(`QQ Bot \u767B\u5F55\u6210\u529F\uFF01`);
|
|
10780
|
+
}
|
|
10781
|
+
|
|
10504
10782
|
// src/outbound/sanitize.ts
|
|
10505
10783
|
var INTERNAL_TAGS = [
|
|
10506
10784
|
// 框架脚手架标签
|
|
@@ -10526,6 +10804,10 @@ function sanitizeQQBotText(text) {
|
|
|
10526
10804
|
return result.trim();
|
|
10527
10805
|
}
|
|
10528
10806
|
|
|
10807
|
+
// src/gateway/lifecycle.ts
|
|
10808
|
+
init_config();
|
|
10809
|
+
init_resolve();
|
|
10810
|
+
|
|
10529
10811
|
// src/gateway/qqbot-gateway.ts
|
|
10530
10812
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
10531
10813
|
|
|
@@ -10762,6 +11044,7 @@ function botMe() {
|
|
|
10762
11044
|
}
|
|
10763
11045
|
|
|
10764
11046
|
// src/commands/config-util.ts
|
|
11047
|
+
init_resolve();
|
|
10765
11048
|
function checkCommandAuth(ctx) {
|
|
10766
11049
|
const p2 = ctx.state.policy;
|
|
10767
11050
|
const mode = p2?.c2cMode ?? "allowlist";
|
|
@@ -11009,6 +11292,7 @@ var import_node_fs5 = __toESM(require("fs"), 1);
|
|
|
11009
11292
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
11010
11293
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
11011
11294
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
11295
|
+
init_resolve();
|
|
11012
11296
|
var MAX_LINES_PER_FILE = 1e3;
|
|
11013
11297
|
var MAX_FILES = 4;
|
|
11014
11298
|
var LOG_KEYWORDS = ["gateway", "openclaw", "clawdbot", "moltbot"];
|
|
@@ -11213,6 +11497,7 @@ function botLogs(runtime2) {
|
|
|
11213
11497
|
}
|
|
11214
11498
|
|
|
11215
11499
|
// src/commands/bot-approve.ts
|
|
11500
|
+
init_resolve();
|
|
11216
11501
|
var PRESETS = {
|
|
11217
11502
|
on: { security: "allowlist", ask: "on-miss", desc: "\u5F00\u542F\u5BA1\u6279\uFF08\u767D\u540D\u5355\u6A21\u5F0F\uFF09" },
|
|
11218
11503
|
off: { security: "full", ask: "off", desc: "\u5173\u95ED\u5BA1\u6279" },
|
|
@@ -11865,6 +12150,7 @@ async function downloadViaFetch(opts) {
|
|
|
11865
12150
|
}
|
|
11866
12151
|
|
|
11867
12152
|
// src/middleware/attachment.ts
|
|
12153
|
+
init_resolve();
|
|
11868
12154
|
function attachmentProcessor(opts) {
|
|
11869
12155
|
return async (ctx, next) => {
|
|
11870
12156
|
const msg = ctx.message;
|
|
@@ -12068,6 +12354,7 @@ async function downloadMediaFile(url, filename, log4) {
|
|
|
12068
12354
|
}
|
|
12069
12355
|
|
|
12070
12356
|
// src/dispatch/body-assembler.ts
|
|
12357
|
+
init_resolve();
|
|
12071
12358
|
var QUOTE_BEGIN = "[Quoted message begins]";
|
|
12072
12359
|
var QUOTE_END = "[Quoted message ends]";
|
|
12073
12360
|
var REF_BEGIN = "[Reference message begins]";
|
|
@@ -12271,6 +12558,7 @@ function normalizeTimestamp(ts) {
|
|
|
12271
12558
|
}
|
|
12272
12559
|
|
|
12273
12560
|
// src/middleware/policy-injector.ts
|
|
12561
|
+
init_config();
|
|
12274
12562
|
function createPolicyInjector(account) {
|
|
12275
12563
|
return async (ctx, next) => {
|
|
12276
12564
|
const msg = ctx.message;
|
|
@@ -12941,6 +13229,7 @@ function shouldUseStreaming(account, targetScope) {
|
|
|
12941
13229
|
}
|
|
12942
13230
|
|
|
12943
13231
|
// src/dispatch/dispatch.ts
|
|
13232
|
+
init_resolve();
|
|
12944
13233
|
async function dispatchToOpenClaw(ctx, msg, account, runtime2, log4) {
|
|
12945
13234
|
const dlog = log4?.child("dispatch");
|
|
12946
13235
|
const adapters = getAdapters(runtime2, dlog);
|
|
@@ -13502,6 +13791,7 @@ function getApprovalHandler(accountId) {
|
|
|
13502
13791
|
// src/features/proactive.ts
|
|
13503
13792
|
var fs19 = __toESM(require("fs"), 1);
|
|
13504
13793
|
var path20 = __toESM(require("path"), 1);
|
|
13794
|
+
init_config();
|
|
13505
13795
|
var log2 = createPluginLogger({ prefix: "[proactive]" });
|
|
13506
13796
|
var STORAGE_DIR = getQQBotDataDir("data");
|
|
13507
13797
|
var KNOWN_USERS_FILE = path20.join(STORAGE_DIR, "known-users.json");
|
|
@@ -13608,6 +13898,8 @@ function getCachedMsgId(scope, targetId) {
|
|
|
13608
13898
|
}
|
|
13609
13899
|
|
|
13610
13900
|
// src/gateway/event-handlers.ts
|
|
13901
|
+
init_resolve();
|
|
13902
|
+
init_config();
|
|
13611
13903
|
async function handleMessage(ctx, msg, account, runtime2, log4) {
|
|
13612
13904
|
const hlog = log4.child("handle");
|
|
13613
13905
|
const scope = msg.replyTarget.scope;
|
|
@@ -14452,10 +14744,6 @@ var approvalStubs = {
|
|
|
14452
14744
|
buildPendingPayload: () => null,
|
|
14453
14745
|
buildResolvedPayload: () => null
|
|
14454
14746
|
},
|
|
14455
|
-
auth: {
|
|
14456
|
-
authorizeActorAction: () => ({ authorized: true }),
|
|
14457
|
-
getActionAvailabilityState: () => ({ kind: "enabled" })
|
|
14458
|
-
},
|
|
14459
14747
|
approvals: {
|
|
14460
14748
|
delivery: {
|
|
14461
14749
|
hasConfiguredDmRoute: () => true,
|
|
@@ -14469,6 +14757,7 @@ var approvalStubs = {
|
|
|
14469
14757
|
};
|
|
14470
14758
|
|
|
14471
14759
|
// src/features/onboarding.ts
|
|
14760
|
+
init_config();
|
|
14472
14761
|
var qqbotOnboardingAdapter = {
|
|
14473
14762
|
getStatus: (ctx) => {
|
|
14474
14763
|
const cfg = ctx.config;
|
|
@@ -14512,6 +14801,7 @@ var qqbotPlugin = {
|
|
|
14512
14801
|
threads: false,
|
|
14513
14802
|
blockStreaming: false
|
|
14514
14803
|
},
|
|
14804
|
+
gatewayMethods: ["web.login.start", "web.login.wait"],
|
|
14515
14805
|
reload: { configPrefixes: ["channels.qqbot"] },
|
|
14516
14806
|
// ── 群消息策略 ──
|
|
14517
14807
|
groups: {
|
|
@@ -14690,7 +14980,19 @@ ${line}` : line;
|
|
|
14690
14980
|
log: ctx.log
|
|
14691
14981
|
});
|
|
14692
14982
|
},
|
|
14693
|
-
logoutAccount: (params) => logoutAndClearCredentials(params)
|
|
14983
|
+
logoutAccount: (params) => logoutAndClearCredentials(params),
|
|
14984
|
+
loginWithQrStart: async ({ accountId }) => startQrLogin(accountId),
|
|
14985
|
+
loginWithQrWait: async ({ accountId }) => {
|
|
14986
|
+
const result = await waitQrLogin(accountId);
|
|
14987
|
+
return { connected: result.connected, message: result.message };
|
|
14988
|
+
}
|
|
14989
|
+
},
|
|
14990
|
+
// ── 登录认证 ──
|
|
14991
|
+
auth: {
|
|
14992
|
+
login: qqbotLogin,
|
|
14993
|
+
// 审批权限(从 approvalStubs 迁移)
|
|
14994
|
+
authorizeActorAction: () => ({ authorized: true }),
|
|
14995
|
+
getActionAvailabilityState: () => ({ kind: "enabled" })
|
|
14694
14996
|
},
|
|
14695
14997
|
// ── 状态 ──
|
|
14696
14998
|
status: {
|
|
@@ -14754,6 +15056,7 @@ function createOutLog(accountId) {
|
|
|
14754
15056
|
}
|
|
14755
15057
|
|
|
14756
15058
|
// src/tools/platform.ts
|
|
15059
|
+
init_config();
|
|
14757
15060
|
var PlatformApiSchema = {
|
|
14758
15061
|
type: "object",
|
|
14759
15062
|
properties: {
|
|
@@ -15063,7 +15366,7 @@ function registerRemindTool(api) {
|
|
|
15063
15366
|
}
|
|
15064
15367
|
|
|
15065
15368
|
// src/adapter/contract.ts
|
|
15066
|
-
var log3 = createPluginLogger({ prefix: "[contract]", forceConsole:
|
|
15369
|
+
var log3 = createPluginLogger({ prefix: "[contract]", forceConsole: false });
|
|
15067
15370
|
var REQUIRED = [
|
|
15068
15371
|
{
|
|
15069
15372
|
name: "channel.reply.dispatchReplyWithBufferedBlockDispatcher",
|
|
@@ -15123,6 +15426,7 @@ var StreamContentType2 = {
|
|
|
15123
15426
|
};
|
|
15124
15427
|
|
|
15125
15428
|
// index.ts
|
|
15429
|
+
init_config();
|
|
15126
15430
|
var registered = false;
|
|
15127
15431
|
var plugin = {
|
|
15128
15432
|
id: "openclaw-qqbot",
|