@53ai/53ai-openclaw 1.0.7 → 1.0.8

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/README.md CHANGED
@@ -142,8 +142,8 @@ openclaw plugins list | grep 53aihub
142
142
  # 检查通道配置
143
143
  openclaw config get channels.53aihub
144
144
 
145
- # 检查 Gateway 日志
146
- openclaw gateway logs | grep -i 53aihub
145
+ # 检查 Gateway 日志 (用户级服务)
146
+ journalctl --user -u openclaw-gateway.service -f | grep -i 53aihub
147
147
  ```
148
148
 
149
149
  ## 多模态消息支持
@@ -397,7 +397,7 @@ npm test
397
397
 
398
398
  1. 确认 `openclaw.plugin.json` 存在于插件根目录
399
399
  2. 确认 `dist/` 目录包含编译后的文件
400
- 3. 检查 Gateway 日志: `openclaw gateway logs`
400
+ 3. 检查 Gateway 日志: `journalctl --user -u openclaw-gateway.service -f`
401
401
 
402
402
  ### 通道未生效
403
403
 
package/dist/index.cjs.js CHANGED
@@ -334,7 +334,7 @@ function parseMessageContent(msg) {
334
334
  }
335
335
 
336
336
  async function sendReply(params) {
337
- const { wsClient, text, toChatId, replyToMsgId, runtime, finish, streamId, isError, errorCode, errorDetails } = params;
337
+ const { wsClient, text, toChatId, replyToMsgId, runtime, finish, streamId, isError, errorCode, errorDetails, isThinking } = params;
338
338
  const reqId = replyToMsgId || streamId;
339
339
  runtime.log?.(`[53aihub] sendReply START: reqId=${reqId}, finish=${finish}, isError=${isError}, textLen=${text?.length || 0}, wsReadyState=${wsClient.readyState}`);
340
340
  if (wsClient.readyState !== 1) {
@@ -395,7 +395,7 @@ async function sendReply(params) {
395
395
  const payload = {
396
396
  req_id: reqId,
397
397
  action: "chat",
398
- status: finish ? "done" : "streaming",
398
+ status: finish ? "done" : isThinking ? "thinking" : "streaming",
399
399
  data: chunk,
400
400
  };
401
401
  const jsonStr = JSON.stringify(payload);
@@ -973,7 +973,6 @@ async function processMessage(params) {
973
973
  cfg: config,
974
974
  dispatcherOptions: {
975
975
  deliver: async (payload, info) => {
976
- state.accumulatedText += payload.text;
977
976
  runtime.log?.(`[53aihub] deliver: kind=${info.kind}, textLen=${payload.text?.length || 0}, accumulatedLen=${state.accumulatedText.length}, isError=${payload.isError}`);
978
977
  if (payload.isError) {
979
978
  const errorMsg = payload.text || "Unknown error";
@@ -993,6 +992,23 @@ async function processMessage(params) {
993
992
  });
994
993
  return;
995
994
  }
995
+ const isCompaction = payload.text?.startsWith("🧹 Compacting context") ||
996
+ state.accumulatedText.startsWith("🧹 Compacting context");
997
+ if (isCompaction && info.kind !== "final") {
998
+ runtime.log?.(`[53aihub] deliver COMPACTION: text preview=${payload.text?.substring(0, 50)}...`);
999
+ await sendReply({
1000
+ wsClient,
1001
+ text: payload.text || "",
1002
+ toChatId: chatId,
1003
+ replyToMsgId: body.msgId,
1004
+ runtime,
1005
+ finish: false,
1006
+ streamId: state.streamId,
1007
+ isThinking: true,
1008
+ });
1009
+ return;
1010
+ }
1011
+ state.accumulatedText += payload.text;
996
1012
  if (info.kind !== "final") {
997
1013
  runtime.log?.(`[53aihub] deliver STREAMING: accumulatedText preview=${state.accumulatedText.substring(0, 50)}...`);
998
1014
  await sendReply({
@@ -1592,6 +1608,67 @@ const aiHubPlugin = {
1592
1608
  },
1593
1609
  };
1594
1610
 
1611
+ const compactionSessions = new Map();
1612
+ /**
1613
+ * 从 sessionKey 中解析 chatId
1614
+ * sessionKey 格式: agent:{agentId}:{channel}:direct:{chatId}
1615
+ * 例如: agent:main:53aihub:direct:user123 -> user123
1616
+ */
1617
+ function parseChatIdFromSessionKey(sessionKey) {
1618
+ if (!sessionKey)
1619
+ return null;
1620
+ const parts = sessionKey.split(":");
1621
+ // 格式: agent:{agentId}:{channel}:direct:{chatId}
1622
+ // parts: [0]agent, [1]agentId, [2]channel, [3]direct, [4]chatId
1623
+ if (parts.length >= 5 && parts[2] === CHANNEL_ID && parts[3] === "direct") {
1624
+ return parts[4];
1625
+ }
1626
+ return null;
1627
+ }
1628
+ async function handleBeforeCompaction(event, ctx) {
1629
+ const runtime = getRuntime();
1630
+ const logger = runtime.logging.getChildLogger({ component: "53aihub-compaction" });
1631
+ const log = (msg) => logger.info(msg);
1632
+ log(`before_compaction: sessionKey=${ctx.sessionKey}, channelId=${ctx.channelId}, messageCount=${event.messageCount}`);
1633
+ const sessionKey = ctx.sessionKey || "";
1634
+ if (!sessionKey.startsWith(`${CHANNEL_ID}:`) && !sessionKey.includes(`:${CHANNEL_ID}:`)) {
1635
+ log(`Skipping compaction hook for non-53aihub session: ${sessionKey}`);
1636
+ return;
1637
+ }
1638
+ const chatId = parseChatIdFromSessionKey(sessionKey);
1639
+ if (!chatId) {
1640
+ logger.error(`Cannot parse chatId from sessionKey: ${sessionKey}`);
1641
+ return;
1642
+ }
1643
+ compactionSessions.set(sessionKey, {
1644
+ startTime: Date.now(),
1645
+ messageCount: event.messageCount,
1646
+ });
1647
+ log(`Compaction started for chatId=${chatId}`);
1648
+ }
1649
+ async function handleAfterCompaction(event, ctx) {
1650
+ const runtime = getRuntime();
1651
+ const logger = runtime.logging.getChildLogger({ component: "53aihub-compaction" });
1652
+ const log = (msg) => logger.info(msg);
1653
+ log(`after_compaction: sessionKey=${ctx.sessionKey}, channelId=${ctx.channelId}, messageCount=${event.messageCount}, compactedCount=${event.compactedCount}`);
1654
+ const sessionKey = ctx.sessionKey || "";
1655
+ if (!sessionKey.startsWith(`${CHANNEL_ID}:`) && !sessionKey.includes(`:${CHANNEL_ID}:`)) {
1656
+ log(`Skipping compaction hook for non-53aihub session: ${sessionKey}`);
1657
+ return;
1658
+ }
1659
+ const chatId = parseChatIdFromSessionKey(sessionKey);
1660
+ if (!chatId) {
1661
+ logger.error(`Cannot parse chatId from sessionKey: ${sessionKey}`);
1662
+ return;
1663
+ }
1664
+ const sessionInfo = compactionSessions.get(sessionKey);
1665
+ compactionSessions.delete(sessionKey);
1666
+ if (sessionInfo) {
1667
+ const duration = Date.now() - sessionInfo.startTime;
1668
+ log(`Compaction completed: chatId=${chatId}, duration=${duration}ms, messagesBefore=${sessionInfo.messageCount}, messagesAfter=${event.messageCount}, compacted=${event.compactedCount}`);
1669
+ }
1670
+ }
1671
+
1595
1672
  const plugin = {
1596
1673
  id: "53ai-openclaw",
1597
1674
  name: "53AI OpenClaw",
@@ -1600,6 +1677,8 @@ const plugin = {
1600
1677
  register(api) {
1601
1678
  setRuntime(api.runtime);
1602
1679
  api.registerChannel({ plugin: aiHubPlugin });
1680
+ api.on("before_compaction", handleBeforeCompaction);
1681
+ api.on("after_compaction", handleAfterCompaction);
1603
1682
  },
1604
1683
  };
1605
1684