@agent-wechat/wechat 0.8.1 → 0.8.2

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.
Files changed (2) hide show
  1. package/dist/index.js +51 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5520,6 +5520,9 @@ import {
5520
5520
  resolveDefaultGroupPolicy,
5521
5521
  resolveSenderCommandAuthorization
5522
5522
  } from "openclaw/plugin-sdk";
5523
+ var INVISIBLE_TEXT_RE = /[\u200b-\u200f\u202a-\u202e\u2060-\u206f]/g;
5524
+ var MENTION_SEPARATOR_RE = /[\s\u2005]+/u;
5525
+ var WECHAT_MENTION_TOKEN_RE = /^[@@][^\s\u2005]+$/u;
5523
5526
  function unique(values) {
5524
5527
  return Array.from(new Set(values));
5525
5528
  }
@@ -5554,6 +5557,39 @@ function normalizeWeChatAllowFrom(values) {
5554
5557
  const normalized = (values ?? []).map((entry) => String(entry).trim()).filter(Boolean).map((entry) => entry === "*" ? "*" : normalizeWeChatId(entry)).filter(Boolean);
5555
5558
  return unique(normalized);
5556
5559
  }
5560
+ function findCommandTokenStart(input) {
5561
+ const match = /(?:^|\s)([/!][A-Za-z])/u.exec(input);
5562
+ if (!match) {
5563
+ return -1;
5564
+ }
5565
+ const whole = match[0] ?? "";
5566
+ const startsWithSpace = whole.startsWith(" ");
5567
+ return (match.index ?? 0) + (startsWithSpace ? 1 : 0);
5568
+ }
5569
+ function normalizeWeChatCommandBody(raw, params) {
5570
+ const trimmed = raw.replace(INVISIBLE_TEXT_RE, "").trim();
5571
+ if (!trimmed) {
5572
+ return "";
5573
+ }
5574
+ const isGroup = params?.isGroup === true;
5575
+ const wasMentioned = params?.wasMentioned === true;
5576
+ if (!isGroup || !wasMentioned) {
5577
+ return trimmed;
5578
+ }
5579
+ const commandStart = findCommandTokenStart(trimmed);
5580
+ if (commandStart < 0) {
5581
+ return trimmed;
5582
+ }
5583
+ const prefix = trimmed.slice(0, commandStart).trim();
5584
+ if (!prefix) {
5585
+ return trimmed.slice(commandStart).trimStart();
5586
+ }
5587
+ const prefixTokens = prefix.split(MENTION_SEPARATOR_RE).map((token) => token.trim()).filter(Boolean);
5588
+ if (prefixTokens.length > 0 && prefixTokens.every((token) => WECHAT_MENTION_TOKEN_RE.test(token))) {
5589
+ return trimmed.slice(commandStart).trimStart();
5590
+ }
5591
+ return trimmed;
5592
+ }
5557
5593
  function isWeChatSenderAllowed(senderId, allowFrom) {
5558
5594
  if (allowFrom.includes("*")) {
5559
5595
  return true;
@@ -5851,6 +5887,7 @@ async function prepareMessage(client, msg, chatId, chat, liveAccount, policy, lo
5851
5887
  const isGroup = chatId.includes("@chatroom");
5852
5888
  const senderId = msg.sender ?? chatId;
5853
5889
  const senderName = msg.senderName ?? msg.sender ?? chat.name;
5890
+ const wasMentioned = isGroup && msg.isMentioned === true;
5854
5891
  const access = resolveWeChatInboundAccessDecision({
5855
5892
  isGroup,
5856
5893
  senderId,
@@ -5937,7 +5974,10 @@ ${replyBlock}` : replyBlock;
5937
5974
  return {
5938
5975
  msg,
5939
5976
  rawBody,
5940
- commandBody: rawBody,
5977
+ commandBody: normalizeWeChatCommandBody(rawBody, {
5978
+ isGroup,
5979
+ wasMentioned
5980
+ }),
5941
5981
  mediaPath,
5942
5982
  mediaMime,
5943
5983
  senderName,
@@ -5945,7 +5985,7 @@ ${replyBlock}` : replyBlock;
5945
5985
  isGroup,
5946
5986
  timestamp,
5947
5987
  hasMedia,
5948
- isMentioned: isGroup && msg.isMentioned === true
5988
+ isMentioned: wasMentioned
5949
5989
  };
5950
5990
  }
5951
5991
  function buildSegments(processed) {
@@ -5977,7 +6017,7 @@ async function dispatchSegment(segment, client, chatId, chat, liveAccount, polic
5977
6017
  log?.info?.(
5978
6018
  `[wechat:${liveAccount.accountId}] Dispatching segment: ${segment.length} msg(s), last=${msg.localId}${mediaPath ? ` media=${mediaPath}` : ""}`
5979
6019
  );
5980
- const hasControlCommand = allowTextCommands && core.channel.text.hasControlCommand(commandBody, cfg);
6020
+ const hasControlCommand = allowTextCommands && core.channel.commands.isControlCommandMessage(commandBody, cfg);
5981
6021
  const commandAuthorized = await resolveWeChatCommandAuthorization({
5982
6022
  cfg,
5983
6023
  rawBody: commandBody,
@@ -6302,7 +6342,7 @@ async function processUnreadChat(client, chat, lastSeenId, account, cfg, log, sk
6302
6342
  }
6303
6343
  const isGroup = chatId.includes("@chatroom");
6304
6344
  let clearBufferedHistory = false;
6305
- const hasControlCommandInWindow = allowTextCommands && processed.some((pm) => core.channel.text.hasControlCommand(pm.commandBody, cfg));
6345
+ const hasControlCommandInWindow = allowTextCommands && processed.some((pm) => core.channel.commands.isControlCommandMessage(pm.commandBody, cfg));
6306
6346
  if (isGroup && groupHistory) {
6307
6347
  if (policy.requireMention) {
6308
6348
  const hasMention = processed.some((pm) => pm.isMentioned);
@@ -7058,6 +7098,13 @@ var wechatPlugin = {
7058
7098
  return wechat.groups?.["*"]?.requireMention ?? true;
7059
7099
  }
7060
7100
  },
7101
+ // ---- Mention adapter ----
7102
+ mentions: {
7103
+ stripMentions: ({ text, ctx }) => normalizeWeChatCommandBody(text, {
7104
+ isGroup: ctx.ChatType === "group",
7105
+ wasMentioned: ctx.WasMentioned === true
7106
+ })
7107
+ },
7061
7108
  // ---- Messaging adapter ----
7062
7109
  messaging: {
7063
7110
  normalizeTarget: (raw) => raw.replace(/^wechat:/i, "").trim() || void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-wechat/wechat",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",