openclaw-lark-multi-agent 1.8.14 → 1.8.16

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.
@@ -1,6 +1,12 @@
1
1
  import { BotConfig } from "./config.js";
2
2
  import { OpenClawClient } from "./openclaw-client.js";
3
3
  import { MessageStore } from "./message-store.js";
4
+ /** Observation deadline, never a claim that the underlying SDK was cancelled. */
5
+ export declare class SendDeadlineError extends Error {
6
+ readonly chatId: string;
7
+ readonly limit: number;
8
+ constructor(chatId: string, limit: number);
9
+ }
4
10
  /**
5
11
  * Manages a single Feishu bot instance.
6
12
  *
@@ -32,6 +38,9 @@ export declare class FeishuBot {
32
38
  /** Per-chat processQueue lock to avoid duplicate concurrent chat.send runs */
33
39
  private queueRuns;
34
40
  private queueOwners;
41
+ /** Monotone local batch epoch: an empty owner map must not hide an
42
+ * intervening admission/finish (ABA) from an asynchronous public lookup. */
43
+ private queueAdmissionEpoch;
35
44
  /** Per-chat serial send queue to guarantee message order */
36
45
  private sendQueue;
37
46
  /** Per-chat delayed runtime failure notifications, canceled if a real reply arrives. */
@@ -47,18 +56,21 @@ export declare class FeishuBot {
47
56
  * fails restore their durable fallback. Fired in processQueueInner's
48
57
  * failure arms; dropped at each new batch top and on queue exit. */
49
58
  private runFailureObservers;
50
- /** Steered messages admitted into the CURRENT batch (per chat). Flipped to
51
- * DONE when that batch completes successfully; cleared (unflipped) when the
52
- * batch scope ends any other way. */
59
+ /** Ephemeral batch-scoped acceptance bookkeeping, not commitment evidence.
60
+ * Ending the batch only drops these handles; durable insertion custody stays
61
+ * accepted and must not inherit the root's DONE. */
53
62
  private admittedSteerAcks;
54
- /** Identity token of the CURRENT queue owner per chat. Steer acks carry
55
- * the token of the batch that admitted them; a completion path only flips
56
- * acks of its OWN batch, so a superseded inner can never DONE a newer
57
- * batch's steered inputs (2026-10-16 audit B9). */
63
+ /** Identity token of the CURRENT queue owner per chat. Acceptance bookkeeping
64
+ * carries its batch token so late old cleanup never takes a newer batch's
65
+ * handles (2026-10-16 audit B9); neither token proves input commitment. */
58
66
  private queueRunTokens;
59
67
  /** Go / Go-Checker supervision controller (per-bot instance). */
60
68
  private readonly goDeliveryReceipts;
61
69
  private readonly goReceiptApis;
70
+ private readonly sendEffectLeases;
71
+ /** A deadline releases the chat queue, NOT this exact operation's ownership. */
72
+ private readonly inFlightDeliveryWork;
73
+ private assertSendEffectLease;
62
74
  private installGoReceiptCapture;
63
75
  private goController;
64
76
  /** Per-chat durable outbox retry timer. */
@@ -82,6 +94,7 @@ export declare class FeishuBot {
82
94
  private adminOpenId;
83
95
  private locale;
84
96
  private configPath?;
97
+ private queuedPresentations;
85
98
  private static allBots;
86
99
  /** Chats where this bot app has actually received an event in this process. */
87
100
  private static seenBotChats;
@@ -118,13 +131,27 @@ export declare class FeishuBot {
118
131
  static getByName(name: string): FeishuBot | undefined;
119
132
  static findByOpenId(openId: string): FeishuBot | undefined;
120
133
  private handleMessage;
134
+ /** Separate guarded-admission proof. Aggregate busy never becomes idle. */
135
+ private observedFollowupGuard;
136
+ /** A positive refusal must be durable AND explained to the sender. */
137
+ private retainChangedFollowup;
138
+ private explainUnconfirmedFollowup;
139
+ /** Keep each input's first observed leaf: a fresh arrival must not borrow
140
+ * an obsolete scheduler leaf from before it was received. */
141
+ private pinDispatchFollowupProof;
121
142
  /** With no local owner, the Gateway can still have externally admitted work.
122
143
  * Read public activity and pin its exact root before choosing insertion. Missing
123
144
  * identity is durable unbound custody, never a fabricated run or blind send. */
124
145
  private reconcileCurrentInputActivity;
146
+ /** An ingress reservation can outlive an ACK-window owner which finished
147
+ * before learning its runId. It is still never-attempted custody, not a
148
+ * licence to retarget/steer a successor. Require the same guarded proof and
149
+ * bounded observation with NO replacement local scheduler at every await. */
150
+ private reconcileRetainedFollowup;
125
151
  /** CAS includes the actual batch, not merely the queue Promise, and excludes
126
152
  * local admission/RPC windows even if the host briefly reports idle. */
127
153
  private reconcileDispatchCustody;
154
+ private presentation;
128
155
  private stopGeneration;
129
156
  private reactionChecks;
130
157
  private receiptReaction;
@@ -160,11 +187,10 @@ export declare class FeishuBot {
160
187
  private fireRunFailureObservers;
161
188
  private processQueue;
162
189
  /**
163
- * Force-release a stuck queue owner after the gateway authoritatively
164
- * reported the session idle (no active run). The zombie owner's deep waits
165
- * can otherwise hold chat custody forever: completion events routed through
166
- * the proactive path are invisible to them. Steer-fallback triggers are
167
- * restored via the failure observers so their input drains normally.
190
+ * Retire only the local queue scheduler after positive idle, trusted yield,
191
+ * or bounded guarded-followup proof. Never stop Gateway execution or infer
192
+ * a terminal outcome. Exact result recovery/target custody remains durable;
193
+ * attempted-unknown and accepted insertion records never enter replay.
168
194
  */
169
195
  private forceExpireQueueOwner;
170
196
  private processQueueInner;
@@ -258,6 +284,12 @@ export declare class FeishuBot {
258
284
  * No host proactive-send assumption, no fake platform receipt. */
259
285
  private deliverGoExecutorResult;
260
286
  private insertionNoticeCurrent;
287
+ private deliveryDeadlineReason;
288
+ /** Durable local obligation, separate from the platform retry budget. */
289
+ private retainLocalDelivery;
290
+ private isDeliverySettlementRevoked;
291
+ /** Also runs for a late accepted SDK receipt, without replaying the final. */
292
+ private settleConfirmedDelivery;
261
293
  private dispatchPendingDeliveries;
262
294
  private hasFreeModeBot;
263
295
  private mentionedBotNames;
@@ -277,6 +309,9 @@ export declare class FeishuBot {
277
309
  private buildLiveStatusCard;
278
310
  /** Minimal escaping so activity text does not break card markdown. */
279
311
  private escapeCardText;
312
+ /** Keep receipt ownership below sendOrdered's Promise.race. Nothing here
313
+ * changes business-message/outbox ordering or retries. */
314
+ private liveStatusCallbacks;
280
315
  private sendLiveStatusCard;
281
316
  private replyLiveStatusCard;
282
317
  private patchLiveStatusCard;
@@ -358,8 +393,10 @@ export declare class FeishuBot {
358
393
  * The chain must never wedge: a single hung Feishu call used to block every
359
394
  * later send in that chat forever (live-status patches fire per tool event),
360
395
  * which froze cards and stranded /stop confirmations. Each link is therefore
361
- * raced against a deadline, so a stuck send is abandoned and ordering resumes.
362
- * Prefer a larger OPENCLAW_LARK_MULTI_AGENT_SEND_TIMEOUT_MS on slow links.
396
+ * raced against an observation deadline. The queue advances, but an already
397
+ * attempted SDK request is NOT cancelled and can settle late. Its outbox keeps
398
+ * custody; the expired lease forbids any subsequent new SDK effect. This is
399
+ * not a strict platform-order guarantee for uncancellable in-flight requests.
363
400
  */
364
401
  private sendOrdered;
365
402
  /** One send link: resolve with fn(), or reject at the deadline so the chain advances. */