@cxyhhhhh/openclaw-qqbot 2.0.0-dev.202607082219 → 2.0.0-dev.202607091556
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 +135 -62
- package/dist/index.cjs.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/adapter/resolve.ts +6 -1
- package/src/config.ts +1 -1
- package/src/dispatch/body-assembler.ts +58 -21
- package/src/dispatch/ctx-builder.ts +110 -0
- package/src/dispatch/dispatch.ts +3 -42
- package/src/features/history-store.ts +7 -2
- package/src/gateway/middleware-setup.ts +20 -12
- package/skills/qqbot-group/SKILL.md +0 -75
- package/skills/qqbot-group/references/api_reference.md +0 -94
package/dist/index.cjs
CHANGED
|
@@ -4819,7 +4819,7 @@ function evaluateMatchedGroupAccessForPolicy(params) {
|
|
|
4819
4819
|
return { allowed: true, groupPolicy: params.groupPolicy, reason: "allowed" };
|
|
4820
4820
|
}
|
|
4821
4821
|
var DEFAULT_GROUP_POLICY = "open";
|
|
4822
|
-
var DEFAULT_GROUP_HISTORY_LIMIT =
|
|
4822
|
+
var DEFAULT_GROUP_HISTORY_LIMIT = 20;
|
|
4823
4823
|
var DEFAULT_GROUP_CONFIG = {
|
|
4824
4824
|
requireMention: true,
|
|
4825
4825
|
ignoreOtherMentions: false,
|
|
@@ -9093,7 +9093,7 @@ var import_node_path2 = __toESM(require("path"), 1);
|
|
|
9093
9093
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
9094
9094
|
var _cachedOpenclawVersion;
|
|
9095
9095
|
function getPackageVersion() {
|
|
9096
|
-
return true ? "2.0.0-dev.
|
|
9096
|
+
return true ? "2.0.0-dev.202607091556" : "unknown";
|
|
9097
9097
|
}
|
|
9098
9098
|
function getOpenclawVersion(runtimeVersion) {
|
|
9099
9099
|
if (_cachedOpenclawVersion) return _cachedOpenclawVersion;
|
|
@@ -9541,11 +9541,15 @@ function resolveRuntimeAdapters(rt, log4) {
|
|
|
9541
9541
|
]);
|
|
9542
9542
|
const rawFinalizeContext = !rawBuildContext ? probeFunction(rt, [["channel", "reply", "finalizeInboundContext"]]) : null;
|
|
9543
9543
|
const buildInboundContext = rawBuildContext ? (params) => rawBuildContext(params) : rawFinalizeContext ? (params) => {
|
|
9544
|
+
const isCommand = params.access?.commands?.authorized ?? false;
|
|
9544
9545
|
const rawCtx = {
|
|
9545
9546
|
Body: params.message.body,
|
|
9546
9547
|
BodyForAgent: params.message.bodyForAgent,
|
|
9547
9548
|
RawBody: params.message.rawBody,
|
|
9548
9549
|
CommandBody: params.message.commandBody ?? params.message.rawBody,
|
|
9550
|
+
CommandSource: isCommand ? "text" : void 0,
|
|
9551
|
+
CommandTurn: params.command ?? void 0,
|
|
9552
|
+
CommandAuthorized: isCommand,
|
|
9549
9553
|
From: params.from,
|
|
9550
9554
|
To: params.reply.to,
|
|
9551
9555
|
SessionKey: params.route.routeSessionKey,
|
|
@@ -9560,7 +9564,6 @@ function resolveRuntimeAdapters(rt, log4) {
|
|
|
9560
9564
|
Timestamp: params.timestamp ?? Date.now(),
|
|
9561
9565
|
OriginatingChannel: params.channel,
|
|
9562
9566
|
OriginatingTo: params.reply.originatingTo ?? params.reply.to,
|
|
9563
|
-
CommandAuthorized: false,
|
|
9564
9567
|
...params.extra
|
|
9565
9568
|
};
|
|
9566
9569
|
return rawFinalizeContext(rawCtx);
|
|
@@ -9590,6 +9593,8 @@ function resolveRuntimeAdapters(rt, log4) {
|
|
|
9590
9593
|
["config", "current"]
|
|
9591
9594
|
]) ?? probeFunction(rt, [
|
|
9592
9595
|
["getConfig"]
|
|
9596
|
+
]) ?? probeFunction(rt, [
|
|
9597
|
+
["config", "loadConfig"]
|
|
9593
9598
|
]);
|
|
9594
9599
|
const rawMutateConfig = probeFunction(rt, [["config", "mutateConfigFile"]]);
|
|
9595
9600
|
const rawWriteConfig = probeFunction(rt, [["config", "writeConfigFile"]]);
|
|
@@ -11710,10 +11715,13 @@ async function downloadMediaFile(url, filename, log4) {
|
|
|
11710
11715
|
// src/dispatch/body-assembler.ts
|
|
11711
11716
|
var QUOTE_BEGIN = "[Quoted message begins]";
|
|
11712
11717
|
var QUOTE_END = "[Quoted message ends]";
|
|
11713
|
-
var
|
|
11714
|
-
var
|
|
11715
|
-
var
|
|
11716
|
-
var
|
|
11718
|
+
var REF_BEGIN = "[Reference message begins]";
|
|
11719
|
+
var REF_END = "[Reference message ends]";
|
|
11720
|
+
var HISTORY_BEGIN = "[Chat history begins]";
|
|
11721
|
+
var HISTORY_END = "[Chat history ends]";
|
|
11722
|
+
var MERGE_CTX_BEGIN = "[Merged messages begins]";
|
|
11723
|
+
var MERGE_CTX_END = "[Merged messages ends]";
|
|
11724
|
+
var CURRENT_MSG = "[Current message]";
|
|
11717
11725
|
function assembleBody(ctx, msg, account, getRuntime) {
|
|
11718
11726
|
const rawBody = msg.content ?? "";
|
|
11719
11727
|
const isGroup = msg.kind === "group";
|
|
@@ -11726,7 +11734,7 @@ function assembleBody(ctx, msg, account, getRuntime) {
|
|
|
11726
11734
|
const userContent = buildUserContent(ctx.message.content ?? "", processed);
|
|
11727
11735
|
const quotePart = buildQuotePart(quote);
|
|
11728
11736
|
const userMessage = mergedMessages && mergedMessages.length > 0 ? buildMergedUserMessage({ messages: mergedMessages, quotePart, isGroup, wasMentioned, getRuntime }) : buildUserMessage({ msg, userContent, quotePart, isGroup, wasMentioned });
|
|
11729
|
-
const dynamicCtx = buildDynamicCtx(processed);
|
|
11737
|
+
const dynamicCtx = buildDynamicCtx(processed, msg, quote);
|
|
11730
11738
|
const agentBody = buildAgentBody({
|
|
11731
11739
|
userContent,
|
|
11732
11740
|
base: dynamicCtx + userMessage,
|
|
@@ -11752,12 +11760,11 @@ ${voiceText}` : voiceText) + attachmentInfo;
|
|
|
11752
11760
|
}
|
|
11753
11761
|
function buildQuotePart(quote) {
|
|
11754
11762
|
if (!quote) return "";
|
|
11755
|
-
const sender = quote.entry?.senderName ? `${quote.entry.senderName} (${quote.entry.senderId})` : "";
|
|
11756
|
-
const senderLine = sender ? `${sender}: ` : "";
|
|
11757
11763
|
const text = quote.text || "Original content unavailable";
|
|
11758
11764
|
return `${QUOTE_BEGIN}
|
|
11759
|
-
${
|
|
11765
|
+
${text}
|
|
11760
11766
|
${QUOTE_END}
|
|
11767
|
+
${CURRENT_MSG}
|
|
11761
11768
|
`;
|
|
11762
11769
|
}
|
|
11763
11770
|
function buildUserMessage(input) {
|
|
@@ -11765,7 +11772,7 @@ function buildUserMessage(input) {
|
|
|
11765
11772
|
const atYouTag = isGroup && wasMentioned ? " (@you)" : "";
|
|
11766
11773
|
if (isGroup) {
|
|
11767
11774
|
const senderLabel = formatSenderLabel(msg.senderName, msg.senderId);
|
|
11768
|
-
return
|
|
11775
|
+
return `${quotePart}[${senderLabel}] ${userContent}${atYouTag}`;
|
|
11769
11776
|
}
|
|
11770
11777
|
return `${quotePart}${userContent}`;
|
|
11771
11778
|
}
|
|
@@ -11791,7 +11798,7 @@ function buildMergedUserMessage(input) {
|
|
|
11791
11798
|
return lines.join("\n");
|
|
11792
11799
|
}
|
|
11793
11800
|
const last = lines.pop();
|
|
11794
|
-
return [
|
|
11801
|
+
return [MERGE_CTX_BEGIN, ...lines, MERGE_CTX_END, CURRENT_MSG, last].join("\n");
|
|
11795
11802
|
}
|
|
11796
11803
|
function formatMergedLine(ctx, opts) {
|
|
11797
11804
|
const m3 = ctx.message;
|
|
@@ -11812,13 +11819,12 @@ function allSameSender(messages) {
|
|
|
11812
11819
|
const first = messages[0]?.message.senderId;
|
|
11813
11820
|
return messages.every((c) => c.message.senderId === first);
|
|
11814
11821
|
}
|
|
11815
|
-
function buildDynamicCtx(processed) {
|
|
11816
|
-
if (!processed) return "";
|
|
11822
|
+
function buildDynamicCtx(processed, msg, quote) {
|
|
11817
11823
|
const lines = [];
|
|
11818
|
-
if (processed
|
|
11824
|
+
if (processed?.imageUrls.length) {
|
|
11819
11825
|
lines.push(`- Images: ${processed.imageUrls.join(", ")}`);
|
|
11820
11826
|
}
|
|
11821
|
-
const transcripts = processed
|
|
11827
|
+
const transcripts = processed?.transcripts ?? [];
|
|
11822
11828
|
const voiceRefs = unique([
|
|
11823
11829
|
...transcripts.map((t) => t.localPath).filter(isNonEmpty),
|
|
11824
11830
|
...transcripts.map((t) => t.remoteUrl).filter(isNonEmpty)
|
|
@@ -11832,10 +11838,35 @@ function buildDynamicCtx(processed) {
|
|
|
11832
11838
|
if (asrTexts.length > 0) {
|
|
11833
11839
|
lines.push(`- ASR: ${asrTexts.join(" | ")}`);
|
|
11834
11840
|
}
|
|
11841
|
+
if (!quote) {
|
|
11842
|
+
const elementsCtx = buildMsgElementsContext(msg);
|
|
11843
|
+
if (elementsCtx.length > 0) {
|
|
11844
|
+
lines.push(REF_BEGIN, ...elementsCtx, REF_END);
|
|
11845
|
+
}
|
|
11846
|
+
}
|
|
11835
11847
|
return lines.length > 0 ? `${lines.join("\n")}
|
|
11836
11848
|
|
|
11837
11849
|
` : "";
|
|
11838
11850
|
}
|
|
11851
|
+
function buildMsgElementsContext(msg) {
|
|
11852
|
+
const elements = msg.msgElements;
|
|
11853
|
+
if (!elements || elements.length === 0) return [];
|
|
11854
|
+
const lines = [];
|
|
11855
|
+
let index = 0;
|
|
11856
|
+
for (const el of elements) {
|
|
11857
|
+
const content = el.content?.trim();
|
|
11858
|
+
if (!content) continue;
|
|
11859
|
+
index += 1;
|
|
11860
|
+
const author = el.author;
|
|
11861
|
+
const sender = author?.username ?? "\u672A\u77E5";
|
|
11862
|
+
lines.push(
|
|
11863
|
+
`=== \u6D88\u606F ${index} ===`,
|
|
11864
|
+
`[\u6D88\u606F\u5185\u5BB9] ${content}`,
|
|
11865
|
+
`[\u53D1\u9001\u8005] ${sender}`
|
|
11866
|
+
);
|
|
11867
|
+
}
|
|
11868
|
+
return lines;
|
|
11869
|
+
}
|
|
11839
11870
|
function unique(arr) {
|
|
11840
11871
|
return [...new Set(arr)];
|
|
11841
11872
|
}
|
|
@@ -11852,7 +11883,7 @@ function buildAgentBody(input) {
|
|
|
11852
11883
|
const label = formatSenderLabel(h2.senderName, h2.senderId);
|
|
11853
11884
|
return `[${label}] ${h2.content}`;
|
|
11854
11885
|
}).join("\n");
|
|
11855
|
-
return [
|
|
11886
|
+
return [HISTORY_BEGIN, historyText, "", HISTORY_END, CURRENT_MSG, base].join("\n");
|
|
11856
11887
|
}
|
|
11857
11888
|
return base;
|
|
11858
11889
|
}
|
|
@@ -11919,8 +11950,11 @@ function getHistoryStore() {
|
|
|
11919
11950
|
if (!_store) _store = new MemoryHistoryStore();
|
|
11920
11951
|
return _store;
|
|
11921
11952
|
}
|
|
11922
|
-
function
|
|
11923
|
-
|
|
11953
|
+
function historyGroupKey(accountId, groupId) {
|
|
11954
|
+
return `${accountId}:${groupId}`;
|
|
11955
|
+
}
|
|
11956
|
+
function clearGroupHistory(accountId, groupId) {
|
|
11957
|
+
_store?.clear?.(historyGroupKey(accountId, groupId));
|
|
11924
11958
|
}
|
|
11925
11959
|
|
|
11926
11960
|
// src/middleware/access-control.ts
|
|
@@ -12013,6 +12047,14 @@ function setupMiddlewares(bot, account, opts) {
|
|
|
12013
12047
|
bot.use(errorHandler());
|
|
12014
12048
|
bot.use(messageFilter({ skipSelfEcho: false }));
|
|
12015
12049
|
bot.use(createPolicyInjector(account));
|
|
12050
|
+
bot.use(historyBuffer({
|
|
12051
|
+
store: getHistoryStore(),
|
|
12052
|
+
groupKey: (ctx) => {
|
|
12053
|
+
const gid = ctx.message.groupOpenid;
|
|
12054
|
+
if (ctx.message.kind !== "group" || !gid) return void 0;
|
|
12055
|
+
return historyGroupKey(account.accountId, gid);
|
|
12056
|
+
}
|
|
12057
|
+
}));
|
|
12016
12058
|
bot.use(dynamicAccessControl({
|
|
12017
12059
|
accountId: account.accountId,
|
|
12018
12060
|
getRuntime: opts.getRuntime
|
|
@@ -12039,7 +12081,6 @@ function setupMiddlewares(bot, account, opts) {
|
|
|
12039
12081
|
bot.use(quoteRef({
|
|
12040
12082
|
store: getPersistedRefIndexStore(account.accountId)
|
|
12041
12083
|
}));
|
|
12042
|
-
bot.use(historyBuffer({ store: getHistoryStore() }));
|
|
12043
12084
|
bot.use(attachmentProcessor({ getRuntime: opts.getRuntime }));
|
|
12044
12085
|
bot.use(envelopeFormatter({
|
|
12045
12086
|
format: (ctx) => {
|
|
@@ -12207,6 +12248,77 @@ async function handleVoiceIntent(text, ctx) {
|
|
|
12207
12248
|
}
|
|
12208
12249
|
}
|
|
12209
12250
|
|
|
12251
|
+
// src/dispatch/ctx-builder.ts
|
|
12252
|
+
function buildCtxPayload(params) {
|
|
12253
|
+
const { assembled, envelope, route, msg, ctx, adapters } = params;
|
|
12254
|
+
const isSlashCommand = /^\//.test(assembled.rawBody ?? "");
|
|
12255
|
+
const convKind = envelope.chatScope === "group" ? "group" : "direct";
|
|
12256
|
+
const peerId = convKind === "group" ? envelope.groupId ?? envelope.senderId : envelope.senderId;
|
|
12257
|
+
const groupId = convKind === "group" ? envelope.groupId : void 0;
|
|
12258
|
+
const processed = ctx.state.processedAttachments;
|
|
12259
|
+
const voicePaths = processed?.localMediaPaths?.filter((_2, i) => processed.localMediaTypes?.[i]?.startsWith("audio/")) ?? [];
|
|
12260
|
+
const voiceUrls = processed?.remoteMediaUrls?.filter((_2, i) => processed.remoteMediaUrls?.[i]?.startsWith?.("audio/")) ?? [];
|
|
12261
|
+
const msgTimestamp = msg.timestamp ?? msg.Timestamp;
|
|
12262
|
+
return adapters.buildInboundContext?.({
|
|
12263
|
+
channel: "qqbot",
|
|
12264
|
+
accountId: route.accountId,
|
|
12265
|
+
provider: "qqbot",
|
|
12266
|
+
surface: "qqbot",
|
|
12267
|
+
messageId: envelope.messageId,
|
|
12268
|
+
timestamp: msgTimestamp ? new Date(msgTimestamp).getTime() : Date.now(),
|
|
12269
|
+
from: envelope.targetId,
|
|
12270
|
+
sender: { id: envelope.senderId, name: envelope.senderName },
|
|
12271
|
+
conversation: {
|
|
12272
|
+
kind: convKind,
|
|
12273
|
+
id: peerId,
|
|
12274
|
+
label: assembled.systemPrompt
|
|
12275
|
+
},
|
|
12276
|
+
message: {
|
|
12277
|
+
body: assembled.webBody,
|
|
12278
|
+
bodyForAgent: assembled.agentBody,
|
|
12279
|
+
rawBody: assembled.rawBody,
|
|
12280
|
+
commandBody: assembled.rawBody
|
|
12281
|
+
},
|
|
12282
|
+
route: {
|
|
12283
|
+
agentId: route.agentId ?? "default",
|
|
12284
|
+
routeSessionKey: route.sessionKey,
|
|
12285
|
+
accountId: route.accountId
|
|
12286
|
+
},
|
|
12287
|
+
reply: {
|
|
12288
|
+
to: envelope.targetId,
|
|
12289
|
+
replyToId: envelope.messageId,
|
|
12290
|
+
originatingTo: envelope.targetId
|
|
12291
|
+
},
|
|
12292
|
+
access: {
|
|
12293
|
+
commands: { authorized: isSlashCommand }
|
|
12294
|
+
},
|
|
12295
|
+
command: isSlashCommand ? { kind: "text-slash", body: assembled.rawBody, authorized: true } : void 0,
|
|
12296
|
+
media: voicePaths.length > 0 ? voicePaths.map((p2, i) => ({
|
|
12297
|
+
contentType: processed?.localMediaTypes?.[i] ?? "audio/silk",
|
|
12298
|
+
localPath: p2,
|
|
12299
|
+
url: voiceUrls[i]
|
|
12300
|
+
})) : voiceUrls.length > 0 ? voiceUrls.map((u2) => ({ contentType: "audio/wav", url: u2 })) : void 0,
|
|
12301
|
+
supplemental: {
|
|
12302
|
+
quote: envelope.quote ? { id: envelope.messageId, body: envelope.quote.content, sender: envelope.quote.senderId } : void 0,
|
|
12303
|
+
groupSystemPrompt: envelope.systemPrompt
|
|
12304
|
+
},
|
|
12305
|
+
extra: {
|
|
12306
|
+
...isSlashCommand ? { CommandSource: "text" } : {},
|
|
12307
|
+
...groupId ? { QQGroupOpenid: groupId } : {},
|
|
12308
|
+
...processed?.localMediaPaths?.length ? {
|
|
12309
|
+
MediaPaths: processed.localMediaPaths,
|
|
12310
|
+
MediaPath: processed.localMediaPaths[0],
|
|
12311
|
+
MediaTypes: processed.localMediaTypes,
|
|
12312
|
+
MediaType: processed.localMediaTypes?.[0]
|
|
12313
|
+
} : {},
|
|
12314
|
+
...processed?.remoteMediaUrls?.length ? {
|
|
12315
|
+
MediaUrls: processed.remoteMediaUrls,
|
|
12316
|
+
MediaUrl: processed.remoteMediaUrls[0]
|
|
12317
|
+
} : {}
|
|
12318
|
+
}
|
|
12319
|
+
});
|
|
12320
|
+
}
|
|
12321
|
+
|
|
12210
12322
|
// src/outbound/debounce.ts
|
|
12211
12323
|
var DEFAULT_WINDOW_MS = 1500;
|
|
12212
12324
|
var DEFAULT_MAX_WAIT_MS = 8e3;
|
|
@@ -12444,46 +12556,7 @@ async function dispatchToOpenClaw(ctx, msg, account, runtime2, log4) {
|
|
|
12444
12556
|
const qualifiedTarget = envelope.targetId;
|
|
12445
12557
|
const agentId = route.agentId ?? "default";
|
|
12446
12558
|
const storePath = adapters.resolveStorePath?.(cfg?.session?.store, { agentId }) ?? "";
|
|
12447
|
-
const ctxPayload =
|
|
12448
|
-
channel: "qqbot",
|
|
12449
|
-
accountId: route.accountId,
|
|
12450
|
-
provider: "qqbot",
|
|
12451
|
-
surface: "qqbot",
|
|
12452
|
-
messageId: envelope.messageId,
|
|
12453
|
-
timestamp: Date.now(),
|
|
12454
|
-
from: envelope.targetId,
|
|
12455
|
-
sender: { id: envelope.senderId, name: envelope.senderName },
|
|
12456
|
-
conversation: {
|
|
12457
|
-
kind: envelope.chatScope === "group" ? "group" : "direct",
|
|
12458
|
-
label: assembled.systemPrompt
|
|
12459
|
-
},
|
|
12460
|
-
message: {
|
|
12461
|
-
body: assembled.webBody,
|
|
12462
|
-
bodyForAgent: assembled.agentBody,
|
|
12463
|
-
rawBody: assembled.rawBody,
|
|
12464
|
-
commandBody: assembled.rawBody
|
|
12465
|
-
},
|
|
12466
|
-
route: {
|
|
12467
|
-
routeSessionKey: route.sessionKey,
|
|
12468
|
-
accountId: route.accountId
|
|
12469
|
-
},
|
|
12470
|
-
reply: {
|
|
12471
|
-
to: envelope.targetId,
|
|
12472
|
-
replyToId: envelope.messageId,
|
|
12473
|
-
originatingTo: envelope.targetId
|
|
12474
|
-
}
|
|
12475
|
-
});
|
|
12476
|
-
const processed = ctx.state.processedAttachments;
|
|
12477
|
-
if (processed?.localMediaPaths?.length) {
|
|
12478
|
-
ctxPayload.MediaPaths = processed.localMediaPaths;
|
|
12479
|
-
ctxPayload.MediaPath = processed.localMediaPaths[0];
|
|
12480
|
-
ctxPayload.MediaTypes = processed.localMediaTypes;
|
|
12481
|
-
ctxPayload.MediaType = processed.localMediaTypes?.[0];
|
|
12482
|
-
}
|
|
12483
|
-
if (processed?.remoteMediaUrls?.length) {
|
|
12484
|
-
ctxPayload.MediaUrls = processed.remoteMediaUrls;
|
|
12485
|
-
ctxPayload.MediaUrl = processed.remoteMediaUrls[0];
|
|
12486
|
-
}
|
|
12559
|
+
const ctxPayload = buildCtxPayload({ assembled, envelope, route, msg, ctx, adapters });
|
|
12487
12560
|
const ttsRuntime = runtime2?.tts ?? runtime2?.channel?.runtimeContexts?.get?.("tts");
|
|
12488
12561
|
const debounceConfig = account.config?.deliverDebounce;
|
|
12489
12562
|
const debouncer = debounceConfig?.enabled !== false ? new DeliverDebouncer(
|
|
@@ -12677,7 +12750,7 @@ async function dispatchToOpenClaw(ctx, msg, account, runtime2, log4) {
|
|
|
12677
12750
|
}
|
|
12678
12751
|
dlog?.debug(`inboundRun completed sessionKey=${route.sessionKey}`);
|
|
12679
12752
|
if (envelope.chatScope === "group") {
|
|
12680
|
-
clearGroupHistory(envelope.groupId ?? envelope.senderId);
|
|
12753
|
+
clearGroupHistory(account.accountId, envelope.groupId ?? envelope.senderId);
|
|
12681
12754
|
}
|
|
12682
12755
|
if (streamingController && !streamingController.isTerminal) {
|
|
12683
12756
|
await streamingController.finalize();
|