@agent-wechat/wechat 0.3.0 → 0.4.0

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 +173 -169
  2. package/package.json +6 -2
package/dist/index.js CHANGED
@@ -1106,6 +1106,21 @@ function resolveWeChatAccount(cfg, accountId) {
1106
1106
  };
1107
1107
  }
1108
1108
 
1109
+ // src/runtime.ts
1110
+ var runtime = null;
1111
+ function setWeChatRuntime(next) {
1112
+ runtime = next;
1113
+ }
1114
+ function getWeChatRuntime() {
1115
+ if (!runtime) {
1116
+ throw new Error("WeChat runtime not initialized");
1117
+ }
1118
+ return runtime;
1119
+ }
1120
+
1121
+ // src/monitor.ts
1122
+ import { execSync } from "node:child_process";
1123
+
1109
1124
  // ../shared/dist/client.js
1110
1125
  function normalizeUrl(base) {
1111
1126
  const url = base.startsWith("http") ? base : `http://${base}`;
@@ -5486,20 +5501,6 @@ var agentConfigSchema = external_exports.object({
5486
5501
 
5487
5502
  // src/monitor.ts
5488
5503
  import { createReplyPrefixOptions } from "openclaw/plugin-sdk";
5489
-
5490
- // src/runtime.ts
5491
- var runtime = null;
5492
- function setWeChatRuntime(next) {
5493
- runtime = next;
5494
- }
5495
- function getWeChatRuntime() {
5496
- if (!runtime) {
5497
- throw new Error("WeChat runtime not initialized");
5498
- }
5499
- return runtime;
5500
- }
5501
-
5502
- // src/monitor.ts
5503
5504
  var MEDIA_TYPES = /* @__PURE__ */ new Set([3, 34]);
5504
5505
  var HISTORY_CONTEXT_MARKER = "[Chat messages since your last reply - for context]";
5505
5506
  var CURRENT_MESSAGE_MARKER = "[Current message - respond to this]";
@@ -5552,8 +5553,16 @@ function enqueueWeChatSystemEvent(text, contextKey) {
5552
5553
  } catch {
5553
5554
  }
5554
5555
  }
5556
+ function enqueueAndWakeSystemEvent(text, contextKey, log) {
5557
+ enqueueWeChatSystemEvent(text, contextKey);
5558
+ try {
5559
+ execSync("openclaw system event --mode now", { timeout: 5e3, stdio: "ignore" });
5560
+ } catch {
5561
+ log?.info?.("Failed to trigger heartbeat wake \u2014 agent will see event on next prompt");
5562
+ }
5563
+ }
5555
5564
  async function startWeChatMonitor(opts) {
5556
- const { account, abortSignal, runtime: runtime2, setStatus, log } = opts;
5565
+ const { account, abortSignal, setStatus, log } = opts;
5557
5566
  const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
5558
5567
  const lastSeenId = /* @__PURE__ */ new Map();
5559
5568
  let lastAuthCheck = 0;
@@ -5581,12 +5590,13 @@ async function startWeChatMonitor(opts) {
5581
5590
  authStatus: auth.status
5582
5591
  });
5583
5592
  if (prevStatus === "logged_in" && !isLinked) {
5584
- const msg = auth.status === "app_not_running" ? "[WeChat] Application stopped. It will restart automatically \u2014 you may need to log in again." : "[WeChat] Session lost. Please log in again using the wechat_login tool.";
5585
- enqueueWeChatSystemEvent(msg, "wechat:auth_lost");
5593
+ const msg = auth.status === "app_not_running" ? "[WeChat] Application stopped. It will restart automatically \u2014 credentials may be cached, so you can try reconnecting using the wechat_login tool." : "[WeChat] Session ended. You can try reconnecting using the wechat_login tool \u2014 if credentials are cached, login may complete automatically.";
5594
+ enqueueAndWakeSystemEvent(msg, "wechat:auth_lost", log);
5586
5595
  } else if (prevStatus === void 0 && !isLinked) {
5587
- enqueueWeChatSystemEvent(
5588
- "[WeChat] Not logged in. Use the wechat_login tool to authenticate.",
5589
- "wechat:auth_required"
5596
+ enqueueAndWakeSystemEvent(
5597
+ "[WeChat] Not logged in. Use the wechat_login tool to authenticate \u2014 if credentials are cached from a previous session, login may complete automatically.",
5598
+ "wechat:auth_required",
5599
+ log
5590
5600
  );
5591
5601
  }
5592
5602
  prevStatus = auth.status;
@@ -5604,9 +5614,10 @@ async function startWeChatMonitor(opts) {
5604
5614
  lastError: String(err)
5605
5615
  });
5606
5616
  if (prevStatus === "logged_in") {
5607
- enqueueWeChatSystemEvent(
5617
+ enqueueAndWakeSystemEvent(
5608
5618
  "[WeChat] Cannot reach agent-wechat server. The container may have stopped.",
5609
- "wechat:server_unreachable"
5619
+ "wechat:server_unreachable",
5620
+ log
5610
5621
  );
5611
5622
  }
5612
5623
  prevStatus = void 0;
@@ -5768,7 +5779,8 @@ ${replyBlock}` : replyBlock;
5768
5779
  senderId,
5769
5780
  isGroup,
5770
5781
  timestamp,
5771
- hasMedia
5782
+ hasMedia,
5783
+ isMentioned: isGroup && msg.isMentioned === true
5772
5784
  };
5773
5785
  }
5774
5786
  function buildSegments(processed) {
@@ -5800,6 +5812,18 @@ async function dispatchSegment(segment, client, chatId, chat, liveAccount, cfg,
5800
5812
  log?.info?.(
5801
5813
  `[wechat:${liveAccount.accountId}] Dispatching segment: ${segment.length} msg(s), last=${msg.localId}${mediaPath ? ` media=${mediaPath}` : ""}`
5802
5814
  );
5815
+ if (isGroup) {
5816
+ const wechatCfg = cfg?.channels?.wechat;
5817
+ const groupEntry = wechatCfg?.groups?.[chatId];
5818
+ const defaultEntry = wechatCfg?.groups?.["*"];
5819
+ const requireMention = groupEntry?.requireMention ?? defaultEntry?.requireMention ?? true;
5820
+ if (requireMention && !lastMsg.isMentioned) {
5821
+ log?.info?.(
5822
+ `[wechat:${liveAccount.accountId}] Skipping group message (mention required, not mentioned) in ${chatId}`
5823
+ );
5824
+ return;
5825
+ }
5826
+ }
5803
5827
  try {
5804
5828
  const route = core.channel.routing.resolveAgentRoute({
5805
5829
  cfg,
@@ -5886,6 +5910,7 @@ async function dispatchSegment(segment, client, chatId, chat, liveAccount, cfg,
5886
5910
  Provider: "wechat",
5887
5911
  Surface: "wechat",
5888
5912
  MessageSid: `wechat:${chatId}:${msg.localId}`,
5913
+ WasMentioned: isGroup ? lastMsg.isMentioned : void 0,
5889
5914
  OriginatingChannel: "wechat",
5890
5915
  OriginatingTo: `wechat:${chatId}`,
5891
5916
  ...mediaPath ? { MediaPath: mediaPath, MediaUrl: mediaPath, MediaType: mediaMime } : {},
@@ -6289,24 +6314,26 @@ function readOrGenerateToken() {
6289
6314
  return token;
6290
6315
  }
6291
6316
  var wechatOnboardingAdapter = {
6292
- getStatus: async ({
6293
- account
6294
- }) => {
6295
- if (!account.serverUrl) {
6317
+ channel: "wechat",
6318
+ getStatus: async ({ cfg }) => {
6319
+ const account = resolveWeChatAccount(cfg);
6320
+ if (!account?.serverUrl) {
6296
6321
  return {
6322
+ channel: "wechat",
6297
6323
  configured: false,
6298
- lines: ["Not configured. Run: openclaw channels setup wechat"]
6324
+ statusLines: ["Not configured. Run: openclaw channels setup wechat"]
6299
6325
  };
6300
6326
  }
6301
6327
  const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
6302
- const lines = [];
6328
+ const statusLines = [];
6303
6329
  try {
6304
6330
  await client.status();
6305
- lines.push(`Connected to ${account.serverUrl}`);
6331
+ statusLines.push(`Connected to ${account.serverUrl}`);
6306
6332
  } catch {
6307
6333
  return {
6334
+ channel: "wechat",
6308
6335
  configured: true,
6309
- lines: [
6336
+ statusLines: [
6310
6337
  `Server URL: ${account.serverUrl}`,
6311
6338
  "Cannot reach server \u2014 is the agent-wechat container running?"
6312
6339
  ]
@@ -6315,45 +6342,44 @@ var wechatOnboardingAdapter = {
6315
6342
  try {
6316
6343
  const auth = await client.authStatus();
6317
6344
  if (auth.status === "logged_in") {
6318
- lines.push(
6345
+ statusLines.push(
6319
6346
  `Logged in${auth.loggedInUser ? ` as ${auth.loggedInUser}` : ""}`
6320
6347
  );
6321
6348
  } else {
6322
- lines.push("Not logged in. Run: openclaw channels login --channel wechat");
6349
+ statusLines.push("Not logged in. Run: openclaw channels login --channel wechat");
6323
6350
  }
6324
6351
  } catch {
6325
- lines.push("Could not check auth status");
6352
+ statusLines.push("Could not check auth status");
6326
6353
  }
6327
- lines.push(`DM policy: ${account.dmPolicy}`);
6354
+ statusLines.push(`DM policy: ${account.dmPolicy}`);
6328
6355
  if (account.allowFrom.length > 0) {
6329
- lines.push(`Allowed senders: ${account.allowFrom.join(", ")}`);
6356
+ statusLines.push(`Allowed senders: ${account.allowFrom.join(", ")}`);
6330
6357
  }
6331
- lines.push(`Group policy: ${account.groupPolicy}`);
6332
- return { configured: true, lines };
6358
+ statusLines.push(`Group policy: ${account.groupPolicy}`);
6359
+ return { channel: "wechat", configured: true, statusLines };
6333
6360
  },
6334
- configure: async ({
6335
- prompter,
6336
- cfg,
6337
- setCfg
6338
- }) => {
6339
- const existingUrl = cfg?.channels?.wechat?.serverUrl ?? "http://localhost:6174";
6361
+ configure: async ({ prompter, cfg }) => {
6362
+ const wechatCfg = {
6363
+ ...cfg?.channels?.wechat ?? {}
6364
+ };
6365
+ const existingUrl = wechatCfg.serverUrl ?? "http://localhost:6174";
6340
6366
  const serverUrl = await prompter.text({
6341
6367
  message: "Agent-wechat server URL",
6342
- default: existingUrl
6368
+ initialValue: existingUrl
6343
6369
  });
6344
- setCfg("channels.wechat.serverUrl", serverUrl);
6345
- const existingToken = cfg?.channels?.wechat?.token ?? "";
6370
+ wechatCfg.serverUrl = serverUrl;
6371
+ const existingToken = wechatCfg.token ?? "";
6346
6372
  const localDefault = existingToken || readOrGenerateToken();
6347
6373
  const token = await prompter.text({
6348
6374
  message: "Auth token (leave empty to use local token)",
6349
- default: localDefault
6375
+ initialValue: localDefault
6350
6376
  });
6351
- setCfg("channels.wechat.token", token || localDefault);
6377
+ wechatCfg.token = token || localDefault;
6352
6378
  const client = new WeChatClient({ baseUrl: serverUrl, token: token || void 0 });
6353
6379
  try {
6354
6380
  await client.status();
6355
6381
  } catch {
6356
- setCfg("channels.wechat.enabled", false);
6382
+ wechatCfg.enabled = false;
6357
6383
  throw new Error(
6358
6384
  `Cannot reach ${serverUrl}. Ensure the agent-wechat container is running.`
6359
6385
  );
@@ -6363,10 +6389,10 @@ var wechatOnboardingAdapter = {
6363
6389
  if (auth.status !== "logged_in") {
6364
6390
  const wantsLink = await prompter.confirm({
6365
6391
  message: "WeChat not logged in. Link now?",
6366
- default: true
6392
+ initialValue: true
6367
6393
  });
6368
6394
  if (wantsLink) {
6369
- await prompter.note?.(
6395
+ await prompter.note(
6370
6396
  "Starting login \u2014 watch for QR code or phone confirmation.",
6371
6397
  "WeChat Login"
6372
6398
  );
@@ -6375,52 +6401,37 @@ var wechatOnboardingAdapter = {
6375
6401
  onEvent: (event) => {
6376
6402
  switch (event.type) {
6377
6403
  case "status":
6378
- prompter.log?.(`Status: ${event.message}`);
6404
+ prompter.note?.(event.message, "Status");
6379
6405
  break;
6380
6406
  case "qr":
6381
- prompter.log?.("Scan this QR code with WeChat:\n");
6382
- if (event.qrData) {
6383
- try {
6384
- const qrTerminalMod = require_main();
6385
- const qrInput = event.qrBinaryData ? Buffer.from(event.qrBinaryData).toString("utf-8") : event.qrData;
6386
- qrTerminalMod.generate(qrInput, { small: true }, (qr) => {
6387
- prompter.log?.(qr);
6388
- });
6389
- } catch {
6390
- if (event.qrDataUrl) {
6391
- prompter.log?.("(QR data URL available \u2014 open in browser to scan)");
6392
- }
6393
- }
6394
- }
6395
- prompter.log?.("\nWaiting for scan...\n");
6407
+ prompter.note?.("Scan QR code with WeChat", "Login");
6396
6408
  break;
6397
6409
  case "phone_confirm":
6398
- prompter.log?.(
6399
- `
6400
- ${event.message || "Please confirm login on your phone"}
6401
- `
6410
+ prompter.note?.(
6411
+ event.message || "Please confirm login on your phone",
6412
+ "Confirm"
6402
6413
  );
6403
6414
  break;
6404
6415
  case "login_success":
6405
- prompter.log?.("\nLogin successful!");
6416
+ prompter.note?.("Login successful!", "Done");
6406
6417
  break;
6407
6418
  case "login_timeout":
6408
- prompter.log?.("\nLogin timed out.");
6419
+ prompter.note?.("Login timed out. Please try again.", "Timeout");
6409
6420
  break;
6410
6421
  case "error":
6411
- prompter.log?.(`
6412
- Error: ${event.message}`);
6422
+ prompter.note?.(`Error: ${event.message}`, "Error");
6413
6423
  break;
6414
6424
  }
6415
6425
  }
6416
6426
  });
6417
6427
  } catch (err) {
6418
- prompter.log?.(
6419
- `Login failed: ${err instanceof Error ? err.message : String(err)}`
6428
+ prompter.note?.(
6429
+ `Login failed: ${err instanceof Error ? err.message : String(err)}`,
6430
+ "Error"
6420
6431
  );
6421
6432
  }
6422
6433
  } else {
6423
- await prompter.note?.(
6434
+ await prompter.note(
6424
6435
  "Run `openclaw channels login --channel wechat` later to link.",
6425
6436
  "WeChat"
6426
6437
  );
@@ -6430,54 +6441,45 @@ Error: ${event.message}`);
6430
6441
  }
6431
6442
  const dmPolicy = await prompter.select({
6432
6443
  message: "DM (direct message) policy",
6433
- choices: [
6444
+ options: [
6434
6445
  { label: "Disabled \u2014 ignore all DMs", value: "disabled" },
6435
- {
6436
- label: "Allowlist \u2014 only respond to specific senders",
6437
- value: "allowlist"
6438
- },
6446
+ { label: "Allowlist \u2014 only respond to specific senders", value: "allowlist" },
6439
6447
  { label: "Open \u2014 respond to all DMs", value: "open" }
6440
6448
  ]
6441
6449
  });
6442
- setCfg("channels.wechat.dmPolicy", dmPolicy);
6450
+ wechatCfg.dmPolicy = dmPolicy;
6443
6451
  if (dmPolicy === "allowlist") {
6444
- const allowFrom = await prompter.multiText({
6445
- message: "Allowed WeChat IDs (wxid_xxx), one per line",
6446
- hint: "Enter wxid values, press Enter after each. Empty line to finish."
6452
+ const raw = await prompter.text({
6453
+ message: "Allowed WeChat IDs (comma-separated wxid_xxx values)"
6447
6454
  });
6448
- setCfg("channels.wechat.allowFrom", allowFrom);
6455
+ wechatCfg.allowFrom = raw.split(",").map((s) => s.trim()).filter(Boolean);
6449
6456
  }
6450
6457
  const groupPolicy = await prompter.select({
6451
6458
  message: "Group chat policy",
6452
- choices: [
6453
- {
6454
- label: "Disabled \u2014 ignore all group messages",
6455
- value: "disabled"
6456
- },
6457
- {
6458
- label: "Allowlist \u2014 only respond in specific groups",
6459
- value: "allowlist"
6460
- },
6461
- {
6462
- label: "Open \u2014 respond in all groups (when mentioned)",
6463
- value: "open"
6464
- }
6459
+ options: [
6460
+ { label: "Disabled \u2014 ignore all group messages", value: "disabled" },
6461
+ { label: "Allowlist \u2014 only respond in specific groups", value: "allowlist" },
6462
+ { label: "Open \u2014 respond in all groups (when mentioned)", value: "open" }
6465
6463
  ]
6466
6464
  });
6467
- setCfg("channels.wechat.groupPolicy", groupPolicy);
6465
+ wechatCfg.groupPolicy = groupPolicy;
6468
6466
  if (groupPolicy === "allowlist") {
6469
- const groupAllowFrom = await prompter.multiText({
6470
- message: "Allowed group IDs (xxx@chatroom), one per line",
6471
- hint: "Enter chatroom IDs, press Enter after each. Empty line to finish."
6467
+ const raw = await prompter.text({
6468
+ message: "Allowed group IDs (comma-separated xxx@chatroom values)"
6472
6469
  });
6473
- setCfg("channels.wechat.groupAllowFrom", groupAllowFrom);
6470
+ wechatCfg.groupAllowFrom = raw.split(",").map((s) => s.trim()).filter(Boolean);
6474
6471
  }
6475
- setCfg("channels.wechat.enabled", true);
6472
+ wechatCfg.enabled = true;
6473
+ const newCfg = {
6474
+ ...cfg,
6475
+ channels: { ...cfg.channels, wechat: wechatCfg }
6476
+ };
6477
+ return { cfg: newCfg };
6476
6478
  }
6477
6479
  };
6478
6480
 
6479
6481
  // src/status.ts
6480
- async function collectWeChatStatusIssues(accounts) {
6482
+ function collectWeChatStatusIssues(accounts) {
6481
6483
  const issues = [];
6482
6484
  for (const snapshot of accounts) {
6483
6485
  if (!snapshot.connected) {
@@ -6534,7 +6536,8 @@ function createWeChatLoginTool(account) {
6534
6536
  },
6535
6537
  required: ["action"]
6536
6538
  },
6537
- execute: async (_toolCallId, args) => {
6539
+ execute: async (_toolCallId, params) => {
6540
+ const args = params;
6538
6541
  const action = args.action;
6539
6542
  const force = args.force;
6540
6543
  const timeoutMs = args.timeoutMs;
@@ -6657,6 +6660,7 @@ var meta = {
6657
6660
  label: "WeChat",
6658
6661
  selectionLabel: "WeChat (\u5FAE\u4FE1)",
6659
6662
  blurb: "WeChat messaging via agent-wechat container.",
6663
+ docsPath: "wechat",
6660
6664
  aliases: ["weixin"],
6661
6665
  order: 80
6662
6666
  };
@@ -6773,14 +6777,16 @@ var wechatPlugin = {
6773
6777
  cfg
6774
6778
  );
6775
6779
  if (!account?.serverUrl) {
6776
- return { channel: "wechat", ok: false, error: "No serverUrl configured" };
6780
+ throw new Error("No serverUrl configured");
6777
6781
  }
6778
6782
  const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
6779
6783
  const result = await client.sendMessage({ chatId: to, text });
6784
+ if (!result.success) {
6785
+ throw new Error(result.error ?? "Send failed");
6786
+ }
6780
6787
  return {
6781
6788
  channel: "wechat",
6782
- ok: result.success,
6783
- error: result.error ?? void 0
6789
+ messageId: `wechat:${to}:${Date.now()}`
6784
6790
  };
6785
6791
  },
6786
6792
  sendMedia: async ({ cfg, to, text, mediaUrl }) => {
@@ -6788,68 +6794,64 @@ var wechatPlugin = {
6788
6794
  cfg
6789
6795
  );
6790
6796
  if (!account?.serverUrl) {
6791
- return { channel: "wechat", ok: false, error: "No serverUrl configured" };
6797
+ throw new Error("No serverUrl configured");
6792
6798
  }
6793
6799
  const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
6794
6800
  if (mediaUrl) {
6795
- try {
6796
- const fsmod = await import("fs/promises");
6797
- const pathmod = await import("path");
6798
- let base64;
6799
- let mimeType;
6800
- let filename;
6801
- if (mediaUrl.startsWith("http://") || mediaUrl.startsWith("https://")) {
6802
- const res = await fetch(mediaUrl);
6803
- const buffer = await res.arrayBuffer();
6804
- base64 = Buffer.from(buffer).toString("base64");
6805
- mimeType = res.headers.get("content-type") ?? "application/octet-stream";
6806
- const urlPath = new URL(mediaUrl).pathname;
6807
- filename = pathmod.basename(urlPath) || "file";
6808
- } else {
6809
- const buf = await fsmod.readFile(mediaUrl);
6810
- base64 = buf.toString("base64");
6811
- filename = pathmod.basename(mediaUrl);
6812
- const ext = pathmod.extname(mediaUrl).toLowerCase().replace(".", "");
6813
- const extMime = {
6814
- png: "image/png",
6815
- jpg: "image/jpeg",
6816
- jpeg: "image/jpeg",
6817
- gif: "image/gif",
6818
- webp: "image/webp"
6819
- };
6820
- mimeType = extMime[ext] ?? "application/octet-stream";
6821
- }
6822
- const isImage = mimeType.startsWith("image/");
6823
- const result2 = isImage ? await client.sendMessage({
6824
- chatId: to,
6825
- text: text || void 0,
6826
- image: { data: base64, mimeType }
6827
- }) : await client.sendMessage({
6828
- chatId: to,
6829
- text: text || void 0,
6830
- file: { data: base64, filename }
6831
- });
6832
- return {
6833
- channel: "wechat",
6834
- ok: result2.success,
6835
- error: result2.error ?? void 0
6836
- };
6837
- } catch (err) {
6838
- return {
6839
- channel: "wechat",
6840
- ok: false,
6841
- error: `Failed to send media: ${err}`
6801
+ const fsmod = await import("fs/promises");
6802
+ const pathmod = await import("path");
6803
+ let base64;
6804
+ let mimeType;
6805
+ let filename;
6806
+ if (mediaUrl.startsWith("http://") || mediaUrl.startsWith("https://")) {
6807
+ const res = await fetch(mediaUrl);
6808
+ const buffer = await res.arrayBuffer();
6809
+ base64 = Buffer.from(buffer).toString("base64");
6810
+ mimeType = res.headers.get("content-type") ?? "application/octet-stream";
6811
+ const urlPath = new URL(mediaUrl).pathname;
6812
+ filename = pathmod.basename(urlPath) || "file";
6813
+ } else {
6814
+ const buf = await fsmod.readFile(mediaUrl);
6815
+ base64 = buf.toString("base64");
6816
+ filename = pathmod.basename(mediaUrl);
6817
+ const ext = pathmod.extname(mediaUrl).toLowerCase().replace(".", "");
6818
+ const extMime = {
6819
+ png: "image/png",
6820
+ jpg: "image/jpeg",
6821
+ jpeg: "image/jpeg",
6822
+ gif: "image/gif",
6823
+ webp: "image/webp"
6842
6824
  };
6825
+ mimeType = extMime[ext] ?? "application/octet-stream";
6826
+ }
6827
+ const isImage = mimeType.startsWith("image/");
6828
+ const result2 = isImage ? await client.sendMessage({
6829
+ chatId: to,
6830
+ text: text || void 0,
6831
+ image: { data: base64, mimeType }
6832
+ }) : await client.sendMessage({
6833
+ chatId: to,
6834
+ text: text || void 0,
6835
+ file: { data: base64, filename }
6836
+ });
6837
+ if (!result2.success) {
6838
+ throw new Error(result2.error ?? "Send media failed");
6843
6839
  }
6840
+ return {
6841
+ channel: "wechat",
6842
+ messageId: `wechat:${to}:${Date.now()}`
6843
+ };
6844
6844
  }
6845
6845
  const result = await client.sendMessage({
6846
6846
  chatId: to,
6847
6847
  text: text || void 0
6848
6848
  });
6849
+ if (!result.success) {
6850
+ throw new Error(result.error ?? "Send failed");
6851
+ }
6849
6852
  return {
6850
6853
  channel: "wechat",
6851
- ok: result.success,
6852
- error: result.error ?? void 0
6854
+ messageId: `wechat:${to}:${Date.now()}`
6853
6855
  };
6854
6856
  }
6855
6857
  },
@@ -6868,7 +6870,8 @@ var wechatPlugin = {
6868
6870
  cfg: ctx.cfg
6869
6871
  });
6870
6872
  },
6871
- loginWithQrStart: async ({ cfg, accountId, force, timeoutMs }) => {
6873
+ loginWithQrStart: async ({ accountId, force, timeoutMs }) => {
6874
+ const cfg = getWeChatRuntime().config.loadConfig();
6872
6875
  const account = resolveWeChatAccount(
6873
6876
  cfg,
6874
6877
  accountId ?? void 0
@@ -6878,7 +6881,7 @@ var wechatPlugin = {
6878
6881
  }
6879
6882
  const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
6880
6883
  try {
6881
- const result = await loginStart(client, accountId, { timeoutMs, force });
6884
+ const result = await loginStart(client, accountId ?? DEFAULT_ACCOUNT_ID2, { timeoutMs, force });
6882
6885
  return result;
6883
6886
  } catch (err) {
6884
6887
  return {
@@ -6886,7 +6889,8 @@ var wechatPlugin = {
6886
6889
  };
6887
6890
  }
6888
6891
  },
6889
- logoutAccount: async ({ cfg, accountId }) => {
6892
+ logoutAccount: async ({ accountId }) => {
6893
+ const cfg = getWeChatRuntime().config.loadConfig();
6890
6894
  const account = resolveWeChatAccount(
6891
6895
  cfg,
6892
6896
  accountId ?? void 0
@@ -6901,7 +6905,7 @@ var wechatPlugin = {
6901
6905
  }
6902
6906
  },
6903
6907
  loginWithQrWait: async ({ accountId, timeoutMs }) => {
6904
- const result = await loginWait(accountId, { timeoutMs });
6908
+ const result = await loginWait(accountId ?? DEFAULT_ACCOUNT_ID2, { timeoutMs });
6905
6909
  return result;
6906
6910
  }
6907
6911
  },
@@ -6985,11 +6989,11 @@ Error: ${event.message}`);
6985
6989
  collectStatusIssues: collectWeChatStatusIssues
6986
6990
  },
6987
6991
  // ---- Agent tools adapter ----
6988
- agentTools: ({ cfg }) => {
6992
+ agentTools: (({ cfg }) => {
6989
6993
  const account = resolveWeChatAccount(cfg);
6990
6994
  if (!account?.serverUrl) return [];
6991
6995
  return [createWeChatLoginTool(account)];
6992
- },
6996
+ }),
6993
6997
  // ---- Directory adapter ----
6994
6998
  directory: {
6995
6999
  self: async ({ cfg }) => {
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@agent-wechat/wechat",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
7
7
  "openclaw.plugin.json"
8
8
  ],
9
9
  "devDependencies": {
10
+ "@types/node": "^22",
10
11
  "esbuild": "^0.25.0",
12
+ "openclaw": "^2026.2.22",
13
+ "typescript": "^5.4.5",
11
14
  "@agent-wechat/shared": "0.1.0"
12
15
  },
13
16
  "openclaw": {
@@ -37,6 +40,7 @@
37
40
  "directory": "packages/openclaw-extension"
38
41
  },
39
42
  "scripts": {
40
- "build": "esbuild index.ts --bundle --format=esm --platform=node --outfile=dist/index.js --external:openclaw"
43
+ "build": "esbuild index.ts --bundle --format=esm --platform=node --outfile=dist/index.js --external:openclaw",
44
+ "typecheck": "tsc --noEmit"
41
45
  }
42
46
  }