openclaw-lark-multi-agent 1.8.19 → 1.8.21

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/config.d.ts CHANGED
@@ -1,12 +1,26 @@
1
1
  import { type Locale } from "./i18n.js";
2
+ /** Profile used by a bot that does not name one.
3
+ *
4
+ * Keeps every pre-profile configuration on the historical default. */
5
+ export declare const DEFAULT_BOT_PROFILE = "main";
2
6
  export interface BotConfig {
3
7
  name: string;
4
8
  appId: string;
5
9
  appSecret: string;
6
- model: string;
10
+ /** Model routed for this bot. Optional: when absent or blank the bot
11
+ * follows the model of its OpenClaw profile instead of overriding it. */
12
+ model?: string;
7
13
  locale?: Locale;
8
14
  /** Optional per-bot thinking level (informational fallback for footers). */
9
15
  thinking?: string;
16
+ /** OpenClaw agent/profile that owns this bot's sessions.
17
+ *
18
+ * Optional for backward compatibility: a bot that does not name a profile
19
+ * keeps the historical `main` profile, so existing configs behave exactly
20
+ * as before. When set, the bot's sessions are addressed under that
21
+ * profile, giving it that profile's own workspace, memory and identity.
22
+ * Defaults to "main" when absent or blank. */
23
+ profile?: string;
10
24
  }
11
25
  export interface OpenClawConfig {
12
26
  baseUrl: string;
package/dist/config.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import { readFileSync, writeFileSync } from "fs";
2
2
  import { resolve } from "path";
3
3
  import { normalizeLocale } from "./i18n.js";
4
+ /** Profile used by a bot that does not name one.
5
+ *
6
+ * Keeps every pre-profile configuration on the historical default. */
7
+ export const DEFAULT_BOT_PROFILE = "main";
4
8
  export function loadConfig(path) {
5
9
  const configPath = path || resolve(process.cwd(), "config.json");
6
10
  const raw = readFileSync(configPath, "utf-8");
@@ -12,13 +16,21 @@ export function loadConfig(path) {
12
16
  throw new Error("No bots configured");
13
17
  }
14
18
  for (const bot of config.bots) {
15
- if (!bot.appId || !bot.appSecret || !bot.model) {
16
- throw new Error(`Bot "${bot.name}" missing appId, appSecret, or model`);
19
+ if (!bot.appId || !bot.appSecret) {
20
+ throw new Error(`Bot "${bot.name}" missing appId or appSecret`);
17
21
  }
18
22
  }
19
23
  config.locale = normalizeLocale(config.locale);
20
24
  for (const bot of config.bots) {
21
25
  bot.locale = normalizeLocale(bot.locale || config.locale);
26
+ // A bot without a profile keeps the historical `main` profile. Older
27
+ // configs stay byte-identical in behaviour; a profile is only a routing
28
+ // choice, never a required field.
29
+ const profile = String(bot.profile == null ? "" : bot.profile).trim();
30
+ bot.profile = profile || DEFAULT_BOT_PROFILE;
31
+ // An empty model means "follow the profile's own model".
32
+ const model = String(bot.model == null ? "" : bot.model).trim();
33
+ bot.model = model || undefined;
22
34
  }
23
35
  // Validate uniqueness
24
36
  const names = config.bots.map((b) => b.name);
@@ -93,8 +93,6 @@ export declare class FeishuBot {
93
93
  private deliveryRetryTimers;
94
94
  /** Last time a real assistant-visible reply was successfully handed to the delivery pipeline. */
95
95
  private lastRealDeliveryAt;
96
- /** Per-chat: whether we've already sent the high-context alert this cycle. */
97
- private contextAlerted;
98
96
  /** Active pre-admission target for the current chat operation. */
99
97
  private activeDeliveryTargets;
100
98
  /** Stable targets for concurrent runs in one chat. A steer admission can
@@ -120,7 +118,21 @@ export declare class FeishuBot {
120
118
  * Get the session key for a specific chat.
121
119
  * Format: lma-<botname>-<chatId>
122
120
  */
121
+ /** OpenClaw profile that owns this bot's sessions.
122
+ *
123
+ * Defaults to "main" so a configuration written before profiles existed
124
+ * keeps its historical behaviour exactly. */
125
+ private get profile();
123
126
  getSessionKey(chatId: string): string;
127
+ /** Physical session key for this bot: the logical key addressed under the
128
+ * bot's OpenClaw profile.
129
+ *
130
+ * The LOGICAL key (getSessionKey) stays profile-free so durable records keep
131
+ * their historical shape and never need a migration. Every key that is
132
+ * actually handed to the Gateway goes through this method, so a bot bound to
133
+ * a non-default profile owns its sessions under that profile (its own
134
+ * workspace, memory and identity) while the stored records stay compatible. */
135
+ physicalSessionKey(chatId: string): string;
124
136
  private chatLocale;
125
137
  private isEn;
126
138
  private lmaBridgePolicy;
@@ -164,6 +176,14 @@ export declare class FeishuBot {
164
176
  private handleResolvedMessage;
165
177
  /** Separate guarded-admission proof. Aggregate busy never becomes idle. */
166
178
  private observedFollowupGuard;
179
+ /** How long an unconfirmed input may stay silent before the user is told.
180
+ *
181
+ * A fixed 60s window misfired on every slow session: measured reply latency
182
+ * in a busy group was p50 3.8min / p90 20.2min / max 135min, so 85% of real
183
+ * replies exceeded the old threshold and every one of them produced a false
184
+ * "not confirmed" notice. Scale the window with the session's own observed
185
+ * latency so a healthy slow run is never reported as stuck. */
186
+ private unconfirmedGraceMs;
167
187
  /** A positive refusal must be durable AND explained to the sender. */
168
188
  private retainChangedFollowup;
169
189
  private explainUnconfirmedFollowup;
@@ -266,11 +286,15 @@ export declare class FeishuBot {
266
286
  * or 0 if it cannot be determined. Same basis as /status. */
267
287
  private getContextUsagePercent;
268
288
  /**
269
- * After a reply is delivered, alert the user once if context usage crossed the
270
- * threshold (default 80%), so they can compact before a session bloats into the
271
- * timeout/lock/overflow failure modes. We only alert on a fresh crossing: once
272
- * alerted we stay quiet until usage drops back below the threshold (e.g. after
273
- * a compact), then re-arm.
289
+ * After a message completes, alert the user when context usage is at or above
290
+ * the threshold (default 80%), so they can compact before the session bloats
291
+ * into the timeout/lock/overflow failure modes.
292
+ *
293
+ * The check runs after EVERY completed message and re-notifies on every message
294
+ * while usage stays above the threshold. There is deliberately no per-chat
295
+ * "already warned" latch: with one, a single failed send (or a stale latch) would
296
+ * silently suppress every later warning, and the user would stop being told to
297
+ * compact while their context keeps growing.
274
298
  */
275
299
  private maybeAlertHighContext;
276
300
  /** True when the agent's reply is exactly a completion phrase (zh or en,
@@ -305,6 +329,11 @@ export declare class FeishuBot {
305
329
  private deliverySourceId;
306
330
  private sendSystemDelivery;
307
331
  private enqueueAndDispatchDelivery;
332
+ private scopeRunError;
333
+ /** Shared original-error authorization for journaled terminals AND ordinary
334
+ * admitted provider errors. Current outbox/config metadata is not authority
335
+ * to replace the retained admission route or physical target. */
336
+ private errorRouteRevocation;
308
337
  private inspectErrorNotice;
309
338
  private deferErrorNotice;
310
339
  private scheduleErrorNoticeCheck;
@@ -337,6 +366,8 @@ export declare class FeishuBot {
337
366
  private fetchThinkingLabel;
338
367
  private asDiscussionParticipant;
339
368
  private runDiscussionTurn;
369
+ private liveInputElements;
370
+ private liveStatusRequest;
340
371
  private buildLiveStatusCard;
341
372
  /** Minimal escaping so activity text does not break card markdown. */
342
373
  private escapeCardText;
@@ -479,6 +510,12 @@ export declare class FeishuBot {
479
510
  * runs for the session, clears the busy lock and every pending trigger, and
480
511
  * resets stuck reactions so new messages are processed normally again.
481
512
  */
513
+ /** Release every peer bot's in-memory scheduling state for one chat.
514
+ * Each bot instance keeps its own queueRuns / queueOwners / busyChats /
515
+ * pendingAckMessages maps; a durable row cleanup cannot reach those. A
516
+ * group-scoped /stop must retire them too, otherwise the peer's queue owner
517
+ * survives and its next message is treated as "busy" forever. */
518
+ private releasePeerBotsForChat;
482
519
  private handleStopCommand;
483
520
  /**
484
521
  * Fetch chat info (name, type, members) via Feishu API and cache in SQLite.
@@ -502,5 +539,8 @@ export declare class FeishuBot {
502
539
  /**
503
540
  * Extract text content from a rich text (post) message.
504
541
  */
542
+ /** Visible rich-post fragments only. Text nodes remain literal; only actual
543
+ * media nodes become type markers, never a regex over the user's prose. */
544
+ private visiblePostInput;
505
545
  private extractPostText;
506
546
  }