openclaw-lark-multi-agent 1.8.18 → 1.8.19

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.
@@ -0,0 +1,6 @@
1
+ import type { BotConfig } from "./config.js";
2
+ /** Includes SDK authentication requests, not just the final bot-info HTTP call.
3
+ * A separate transport keeps the identity deadline away from normal sends. */
4
+ export declare function requestBotIdentity(config: BotConfig, signal: AbortSignal, timeout: number): Promise<unknown>;
5
+ /** Only original-account API evidence establishes identity. Names never do. */
6
+ export declare function trustedBotOpenId(response: any, appId: string): string | null;
@@ -0,0 +1,25 @@
1
+ import * as lark from "@larksuiteoapi/node-sdk";
2
+ /** Includes SDK authentication requests, not just the final bot-info HTTP call.
3
+ * A separate transport keeps the identity deadline away from normal sends. */
4
+ export async function requestBotIdentity(config, signal, timeout) {
5
+ const request = (options) => lark.defaultHttpInstance.request({ ...options, timeout, signal });
6
+ const transport = { request };
7
+ for (const method of ["get", "delete", "head", "options"]) {
8
+ transport[method] = (url, options) => request({ ...options, method, url });
9
+ }
10
+ for (const method of ["post", "put", "patch"]) {
11
+ transport[method] = (url, data, options) => request({ ...options, method, url, data });
12
+ }
13
+ const client = new lark.Client({ appId: config.appId, appSecret: config.appSecret,
14
+ appType: lark.AppType.SelfBuild, httpInstance: transport });
15
+ return client.request({ method: "GET", url: "/open-apis/bot/v3/info/" });
16
+ }
17
+ /** Only original-account API evidence establishes identity. Names never do. */
18
+ export function trustedBotOpenId(response, appId) {
19
+ if (response?.code !== undefined && response.code !== 0)
20
+ return null;
21
+ const bot = response?.bot ?? response?.data?.bot;
22
+ if (bot?.app_id !== undefined && bot.app_id !== appId)
23
+ return null;
24
+ return typeof bot?.open_id === "string" && /^ou_[a-zA-Z0-9]+$/.test(bot.open_id) ? bot.open_id : null;
25
+ }
@@ -23,6 +23,21 @@ export declare class FeishuBot {
23
23
  private openclawClient;
24
24
  private store;
25
25
  private botOpenId;
26
+ private identityClosed;
27
+ private identityRetryTimer?;
28
+ private identityFlight?;
29
+ private identityAbort?;
30
+ private identityNextProbeAt;
31
+ private identityFailures;
32
+ private identityDrain?;
33
+ private identityDrainRetry;
34
+ private identityDrainNextAt;
35
+ private identityDrainFailures;
36
+ private identityCaptures;
37
+ private identityTargetRepairs;
38
+ private identitySessionWaiters;
39
+ private readonly identityEffects;
40
+ private requestIdentity;
26
41
  /** Tracks which chatId sessions have been initialized */
27
42
  private initializedSessions;
28
43
  /** Per-chat busy lock: timestamp when became busy (0 = not busy) */
@@ -119,9 +134,24 @@ export declare class FeishuBot {
119
134
  * Start the Feishu WS connection. Sessions are created lazily per chat.
120
135
  */
121
136
  start(): Promise<void>;
122
- /** Resolve this bot's open_id at startup so direct @bot mentions work even
123
- * when Feishu mention payloads omit app_id and only contain open_id/name. */
137
+ /** Local custody repair only. This never authorizes replay of a claimed event
138
+ * or re-probes an already known identity. The journal remains the sole owner. */
139
+ private retryIdentityIngress;
140
+ /** Bounded, read-only public metadata. Late responses never write custody. */
141
+ private identitySessionInfo;
142
+ private captureIdentityTarget;
143
+ private assertIdentityCurrent;
144
+ private assertIdentityEffect;
145
+ /** One background timer per bot covers both discovery and local journal
146
+ * repair; every asynchronous AND synchronous timer effect is owned. */
147
+ private scheduleIdentityProbe;
148
+ /** Bounded observation AND cancellable HTTP (including token discovery).
149
+ * Even a nonconforming transport ignoring abort retains single-flight custody
150
+ * until it settles; we never accumulate timed-out requests or trust late data. */
124
151
  private probeBotIdentity;
152
+ /** Metadata may say who was targeted, but can never say who THIS bot is. */
153
+ private needsIdentityRecovery;
154
+ private drainIdentityIngress;
125
155
  /**
126
156
  * On startup, check all known chats for unsynced messages and process them.
127
157
  * Also re-subscribe to known sessions for tool events.
@@ -131,6 +161,7 @@ export declare class FeishuBot {
131
161
  static getByName(name: string): FeishuBot | undefined;
132
162
  static findByOpenId(openId: string): FeishuBot | undefined;
133
163
  private handleMessage;
164
+ private handleResolvedMessage;
134
165
  /** Separate guarded-admission proof. Aggregate busy never becomes idle. */
135
166
  private observedFollowupGuard;
136
167
  /** A positive refusal must be durable AND explained to the sender. */