@wecom/wecom-openclaw-plugin 2026.3.24-beta.4 → 2026.3.25-beta.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.
package/dist/index.esm.js CHANGED
@@ -1498,14 +1498,6 @@ const PLUGIN_VERSION = getVersion();
1498
1498
  * - state-manager.ts : 全局状态管理(带 TTL 清理)
1499
1499
  * - timeout.ts : 超时工具
1500
1500
  */
1501
- /**
1502
- * 去除文本中的 `<think>...</think>` 标签(支持跨行),返回剩余可见文本。
1503
- * 用于判断大模型回复中是否包含实际用户可见内容(而非仅有 thinking 推理过程)。
1504
- */
1505
- function stripThinkTags(text) {
1506
- return text;
1507
- // return text.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
1508
- }
1509
1501
  // ============================================================================
1510
1502
  // 媒体本地路径白名单扩展
1511
1503
  // ============================================================================
@@ -1651,15 +1643,6 @@ async function sendThinkingReply(params) {
1651
1643
  runtime.error?.(`[wecom] Failed to send thinking message: ${String(err)}`);
1652
1644
  }
1653
1645
  }
1654
- /**
1655
- * 累积文本并判断是否有可见内容(去除 <think> 标签后)
1656
- */
1657
- function accumulateText(state, text) {
1658
- state.accumulatedText += text;
1659
- if (!state.hasText && stripThinkTags(state.accumulatedText)) {
1660
- state.hasText = true;
1661
- }
1662
- }
1663
1646
  /**
1664
1647
  * 上传并发送一批媒体文件(统一走主动发送通道)
1665
1648
  *
@@ -1715,30 +1698,22 @@ async function sendMediaBatch(ctx, mediaUrls) {
1715
1698
  */
1716
1699
  async function finishThinkingStream(ctx) {
1717
1700
  const { wsClient, frame, state, runtime } = ctx;
1718
- const visibleText = stripThinkTags(state.accumulatedText);
1719
- let finishText;
1720
- if (visibleText) {
1721
- // 有可见文本:用完整文本关闭流(覆盖 thinking 为真实内容)
1722
- finishText = state.accumulatedText;
1723
- }
1724
- else if (state.hasMedia) {
1725
- // 媒体成功发送:用友好提示告知用户
1726
- finishText = "📎 文件已发送,请查收。";
1727
- }
1728
- else if (state.hasMediaFailed && state.mediaErrorSummary) {
1729
- // 媒体发送失败:直接用错误摘要替换 thinking 流(不再额外发 sendMessage)
1730
- finishText = state.mediaErrorSummary;
1701
+ let finishText = state.accumulatedText;
1702
+ if (state.hasMedia) {
1703
+ if (state.hasMediaFailed && state.mediaErrorSummary) {
1704
+ // 媒体成功发送:用友好提示告知用户
1705
+ finishText = finishText ? `${finishText}\n\n${state.mediaErrorSummary}` : state.mediaErrorSummary;
1706
+ }
1707
+ else if (!finishText) {
1708
+ finishText = "📎 文件已发送,请查收。";
1709
+ }
1731
1710
  }
1732
- else {
1733
- // 核心无可见文本且 deliver 中未处理过媒体。
1734
- //
1735
- // 不使用错误提示,因为 agent 可能已通过内置 message 工具直接调用
1736
- // outbound.sendMedia 成功发送了文件——该路径完全绕过 monitor 的 deliver
1737
- // 回调,所以 state.deliverCalled / state.hasMedia 均为 false,但文件
1738
- // 实际已送达用户。此时显示 "未生成回复" 会误导用户。
1739
- finishText = "✅ 处理完成。";
1711
+ // if (!finishText) {
1712
+ // finishText = "✅ 处理完成。";
1713
+ // }
1714
+ if (finishText) {
1715
+ await sendWeComReply({ wsClient, frame, text: finishText, runtime, finish: true, streamId: state.streamId });
1740
1716
  }
1741
- await sendWeComReply({ wsClient, frame, text: finishText, runtime, finish: true, streamId: state.streamId });
1742
1717
  }
1743
1718
  /**
1744
1719
  * 路由消息到核心处理流程并处理回复
@@ -1755,17 +1730,29 @@ async function routeAndDispatchMessage(params) {
1755
1730
  onCleanup();
1756
1731
  }
1757
1732
  };
1733
+ let isShowThink = !(account.sendThinkingMessage ?? true);
1758
1734
  try {
1759
1735
  await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
1760
1736
  ctx: ctxPayload,
1761
1737
  cfg: config,
1762
1738
  dispatcherOptions: {
1739
+ onReplyStart: async () => {
1740
+ if (!isShowThink && state.streamId && !state.accumulatedText) {
1741
+ try {
1742
+ await sendThinkingReply({ wsClient, frame, streamId: state.streamId, runtime });
1743
+ }
1744
+ catch (e) {
1745
+ runtime.error?.(`[wecom] sendThinkingReply threw err: ${String(e)}`);
1746
+ }
1747
+ isShowThink = true;
1748
+ }
1749
+ },
1763
1750
  deliver: async (payload, info) => {
1764
1751
  state.deliverCalled = true;
1765
1752
  // runtime.log?.(`[openclaw -> plugin] kind=${info.kind}, text=${payload.text ?? ''}, mediaUrl=${payload.mediaUrl ?? ''}, mediaUrls=${JSON.stringify(payload.mediaUrls ?? [])}`);
1766
1753
  // 累积文本
1767
1754
  if (payload.text) {
1768
- accumulateText(state, payload.text);
1755
+ state.accumulatedText += (payload.text || '');
1769
1756
  }
1770
1757
  // 发送媒体(统一走主动发送)
1771
1758
  const mediaUrls = payload.mediaUrls?.length ? payload.mediaUrls : payload.mediaUrl ? [payload.mediaUrl] : [];
@@ -1903,11 +1890,11 @@ async function processWeComMessage(params) {
1903
1890
  const cleanupState = () => {
1904
1891
  deleteMessageState(messageId);
1905
1892
  };
1906
- // Step 6: 发送"思考中"消息
1907
- const shouldSendThinking = account.sendThinkingMessage ?? true;
1908
- if (shouldSendThinking) {
1909
- await sendThinkingReply({ wsClient, frame, streamId, runtime });
1910
- }
1893
+ // // Step 6: 发送"思考中"消息
1894
+ // const shouldSendThinking = account.sendThinkingMessage ?? true;
1895
+ // if (shouldSendThinking) {
1896
+ // await sendThinkingReply({ wsClient, frame, streamId, runtime });
1897
+ // }
1911
1898
  // Step 7: 构建上下文并路由到核心处理流程(带整体超时保护)
1912
1899
  const ctxPayload = buildMessageContext(frame, account, config, text, mediaList, quoteContent);
1913
1900
  // runtime.log?.(`[plugin -> openclaw] body=${text}, mediaPaths=${JSON.stringify(mediaList.map(m => m.path))}${quoteContent ? `, quote=${quoteContent}` : ''}`);
@@ -1925,22 +1912,6 @@ async function processWeComMessage(params) {
1925
1912
  }
1926
1913
  catch (err) {
1927
1914
  runtime.error?.(`[wecom][plugin] Message processing failed or timed out: ${String(err)}`);
1928
- // 确保 thinking 流被关闭,防止异常/超时时 thinking 消息一直残留
1929
- try {
1930
- if (shouldSendThinking) {
1931
- await sendWeComReply({
1932
- wsClient,
1933
- frame,
1934
- text: "处理消息时出现异常,请稍后重试。",
1935
- runtime,
1936
- finish: true,
1937
- streamId: state.streamId,
1938
- });
1939
- }
1940
- }
1941
- catch (finishErr) {
1942
- runtime.error?.(`[wecom] Failed to finish thinking stream on error: ${String(finishErr)}`);
1943
- }
1944
1915
  cleanupState();
1945
1916
  }
1946
1917
  }