openclaw-lark-multi-agent 1.8.5 → 1.8.6

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.
@@ -900,6 +900,11 @@ export class OpenClawClient {
900
900
  let lifecycleEndTimer = null;
901
901
  let replayInvalidTimer = null;
902
902
  let genericChatErrorTimer = null;
903
+ // A channel message-tool send marked terminate=true is the turn's intended
904
+ // user-visible output (2026-10-16 incident: it bypassed the bridge and the
905
+ // collector waited forever). Capture its text and settle on a short grace.
906
+ let terminatingSendText = "";
907
+ let terminatingSendTimer = null;
903
908
  let pendingRuntimeFailureText = "";
904
909
  let lastActivitySummary = "";
905
910
  let lastActivityAt = 0;
@@ -1174,6 +1179,8 @@ export class OpenClawClient {
1174
1179
  clearTimeout(replayInvalidTimer);
1175
1180
  if (genericChatErrorTimer)
1176
1181
  clearTimeout(genericChatErrorTimer);
1182
+ if (terminatingSendTimer)
1183
+ clearTimeout(terminatingSendTimer);
1177
1184
  resolve(finalText);
1178
1185
  };
1179
1186
  const collectEvents = () => {
@@ -1310,6 +1317,43 @@ export class OpenClawClient {
1310
1317
  if (hasEffectiveActivity(ev))
1311
1318
  resetIdleTimer();
1312
1319
  rememberActivity(ev);
1320
+ // Terminating channel-send detection: a message-tool result carrying
1321
+ // terminate=true ends the turn with that send as its user-visible
1322
+ // output. The bridge is the delivery channel for LMA sessions, so
1323
+ // waiting for a further final would hang forever (2026-10-16 frozen
1324
+ // card incident). Capture the sent text at tool start; settle on a
1325
+ // short grace unless a real final arrives first.
1326
+ {
1327
+ const tdata = ev.data || {};
1328
+ if (ev.stream === "tool" || (ev.stream === "item" && tdata.kind === "tool")) {
1329
+ const toolName = String(tdata.name || tdata.toolName || "");
1330
+ const tphase = tdata.phase === "result" ? (tdata.isError || tdata.error ? "error" : "end") : tdata.phase;
1331
+ if (toolName === "message" && tphase === "start") {
1332
+ const raw = tdata.input ?? tdata.args ?? tdata.meta ?? null;
1333
+ if (raw !== null) {
1334
+ try {
1335
+ const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
1336
+ if (parsed && typeof parsed.message === "string" && parsed.message.trim())
1337
+ terminatingSendText = parsed.message;
1338
+ }
1339
+ catch { /* non-JSON tool input */ }
1340
+ }
1341
+ }
1342
+ else if (toolName === "message" && (tphase === "end" || tphase === "error")) {
1343
+ const out = String(JSON.stringify(tdata.output ?? tdata.result ?? tdata.error ?? ""));
1344
+ if (/"?terminate"?\s*[:=]\s*true/i.test(out) && !terminatingSendTimer) {
1345
+ terminatingSendTimer = setTimeout(() => {
1346
+ terminatingSendTimer = null;
1347
+ if (observationClosed)
1348
+ return;
1349
+ const best = (chatFinalText.trim() || text.trim() || terminatingSendText || "").trim();
1350
+ finish(best || "NO_REPLY");
1351
+ }, 10_000);
1352
+ terminatingSendTimer.unref?.();
1353
+ }
1354
+ }
1355
+ }
1356
+ }
1313
1357
  // If more events arrive after a replay-invalid lifecycle end, that lifecycle
1314
1358
  // was not terminal for the user-visible run. Keep waiting for the real final.
1315
1359
  if (replayInvalidTimer) {
@@ -1625,6 +1669,8 @@ export class OpenClawClient {
1625
1669
  clearTimeout(replayInvalidTimer);
1626
1670
  if (genericChatErrorTimer)
1627
1671
  clearTimeout(genericChatErrorTimer);
1672
+ if (terminatingSendTimer)
1673
+ clearTimeout(terminatingSendTimer);
1628
1674
  if (observationKey && this.runStateChecks.get(observationKey) === checkAfterNoActiveRun)
1629
1675
  this.runStateChecks.delete(observationKey);
1630
1676
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-lark-multi-agent",
3
- "version": "1.8.5",
3
+ "version": "1.8.6",
4
4
  "description": "Multi-bot Lark/Feishu bridge for OpenClaw, with per-bot model routing and isolated sessions",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -81,4 +81,4 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  }
84
- }
84
+ }