@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/dist/index.esm.js CHANGED
@@ -310,7 +310,7 @@ function parseMessageContent(msg) {
310
310
  }
311
311
 
312
312
  async function sendReply(params) {
313
- const { wsClient, text, toChatId, replyToMsgId, runtime, finish, streamId, isError, errorCode, errorDetails } = params;
313
+ const { wsClient, text, toChatId, replyToMsgId, runtime, finish, streamId, isError, errorCode, errorDetails, isThinking } = params;
314
314
  const reqId = replyToMsgId || streamId;
315
315
  runtime.log?.(`[53aihub] sendReply START: reqId=${reqId}, finish=${finish}, isError=${isError}, textLen=${text?.length || 0}, wsReadyState=${wsClient.readyState}`);
316
316
  if (wsClient.readyState !== 1) {
@@ -371,7 +371,7 @@ async function sendReply(params) {
371
371
  const payload = {
372
372
  req_id: reqId,
373
373
  action: "chat",
374
- status: finish ? "done" : "streaming",
374
+ status: finish ? "done" : isThinking ? "thinking" : "streaming",
375
375
  data: chunk,
376
376
  };
377
377
  const jsonStr = JSON.stringify(payload);
@@ -949,7 +949,6 @@ async function processMessage(params) {
949
949
  cfg: config,
950
950
  dispatcherOptions: {
951
951
  deliver: async (payload, info) => {
952
- state.accumulatedText += payload.text;
953
952
  runtime.log?.(`[53aihub] deliver: kind=${info.kind}, textLen=${payload.text?.length || 0}, accumulatedLen=${state.accumulatedText.length}, isError=${payload.isError}`);
954
953
  if (payload.isError) {
955
954
  const errorMsg = payload.text || "Unknown error";
@@ -969,6 +968,23 @@ async function processMessage(params) {
969
968
  });
970
969
  return;
971
970
  }
971
+ const isCompaction = payload.text?.startsWith("🧹 Compacting context") ||
972
+ state.accumulatedText.startsWith("🧹 Compacting context");
973
+ if (isCompaction && info.kind !== "final") {
974
+ runtime.log?.(`[53aihub] deliver COMPACTION: text preview=${payload.text?.substring(0, 50)}...`);
975
+ await sendReply({
976
+ wsClient,
977
+ text: payload.text || "",
978
+ toChatId: chatId,
979
+ replyToMsgId: body.msgId,
980
+ runtime,
981
+ finish: false,
982
+ streamId: state.streamId,
983
+ isThinking: true,
984
+ });
985
+ return;
986
+ }
987
+ state.accumulatedText += payload.text;
972
988
  if (info.kind !== "final") {
973
989
  runtime.log?.(`[53aihub] deliver STREAMING: accumulatedText preview=${state.accumulatedText.substring(0, 50)}...`);
974
990
  await sendReply({
@@ -1568,6 +1584,67 @@ const aiHubPlugin = {
1568
1584
  },
1569
1585
  };
1570
1586
 
1587
+ const compactionSessions = new Map();
1588
+ /**
1589
+ * 从 sessionKey 中解析 chatId
1590
+ * sessionKey 格式: agent:{agentId}:{channel}:direct:{chatId}
1591
+ * 例如: agent:main:53aihub:direct:user123 -> user123
1592
+ */
1593
+ function parseChatIdFromSessionKey(sessionKey) {
1594
+ if (!sessionKey)
1595
+ return null;
1596
+ const parts = sessionKey.split(":");
1597
+ // 格式: agent:{agentId}:{channel}:direct:{chatId}
1598
+ // parts: [0]agent, [1]agentId, [2]channel, [3]direct, [4]chatId
1599
+ if (parts.length >= 5 && parts[2] === CHANNEL_ID && parts[3] === "direct") {
1600
+ return parts[4];
1601
+ }
1602
+ return null;
1603
+ }
1604
+ async function handleBeforeCompaction(event, ctx) {
1605
+ const runtime = getRuntime();
1606
+ const logger = runtime.logging.getChildLogger({ component: "53aihub-compaction" });
1607
+ const log = (msg) => logger.info(msg);
1608
+ log(`before_compaction: sessionKey=${ctx.sessionKey}, channelId=${ctx.channelId}, messageCount=${event.messageCount}`);
1609
+ const sessionKey = ctx.sessionKey || "";
1610
+ if (!sessionKey.startsWith(`${CHANNEL_ID}:`) && !sessionKey.includes(`:${CHANNEL_ID}:`)) {
1611
+ log(`Skipping compaction hook for non-53aihub session: ${sessionKey}`);
1612
+ return;
1613
+ }
1614
+ const chatId = parseChatIdFromSessionKey(sessionKey);
1615
+ if (!chatId) {
1616
+ logger.error(`Cannot parse chatId from sessionKey: ${sessionKey}`);
1617
+ return;
1618
+ }
1619
+ compactionSessions.set(sessionKey, {
1620
+ startTime: Date.now(),
1621
+ messageCount: event.messageCount,
1622
+ });
1623
+ log(`Compaction started for chatId=${chatId}`);
1624
+ }
1625
+ async function handleAfterCompaction(event, ctx) {
1626
+ const runtime = getRuntime();
1627
+ const logger = runtime.logging.getChildLogger({ component: "53aihub-compaction" });
1628
+ const log = (msg) => logger.info(msg);
1629
+ log(`after_compaction: sessionKey=${ctx.sessionKey}, channelId=${ctx.channelId}, messageCount=${event.messageCount}, compactedCount=${event.compactedCount}`);
1630
+ const sessionKey = ctx.sessionKey || "";
1631
+ if (!sessionKey.startsWith(`${CHANNEL_ID}:`) && !sessionKey.includes(`:${CHANNEL_ID}:`)) {
1632
+ log(`Skipping compaction hook for non-53aihub session: ${sessionKey}`);
1633
+ return;
1634
+ }
1635
+ const chatId = parseChatIdFromSessionKey(sessionKey);
1636
+ if (!chatId) {
1637
+ logger.error(`Cannot parse chatId from sessionKey: ${sessionKey}`);
1638
+ return;
1639
+ }
1640
+ const sessionInfo = compactionSessions.get(sessionKey);
1641
+ compactionSessions.delete(sessionKey);
1642
+ if (sessionInfo) {
1643
+ const duration = Date.now() - sessionInfo.startTime;
1644
+ log(`Compaction completed: chatId=${chatId}, duration=${duration}ms, messagesBefore=${sessionInfo.messageCount}, messagesAfter=${event.messageCount}, compacted=${event.compactedCount}`);
1645
+ }
1646
+ }
1647
+
1571
1648
  const plugin = {
1572
1649
  id: "53ai-openclaw",
1573
1650
  name: "53AI OpenClaw",
@@ -1576,6 +1653,8 @@ const plugin = {
1576
1653
  register(api) {
1577
1654
  setRuntime(api.runtime);
1578
1655
  api.registerChannel({ plugin: aiHubPlugin });
1656
+ api.on("before_compaction", handleBeforeCompaction);
1657
+ api.on("after_compaction", handleAfterCompaction);
1579
1658
  },
1580
1659
  };
1581
1660