openclaw-lark-multi-agent 1.0.10 → 1.0.11

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.
@@ -36,6 +36,13 @@ export declare class OpenClawClient {
36
36
  /** Session keys whose proactive messages must be dropped by the bridge (e.g. discussion scheduler owns delivery). */
37
37
  private mutedProactiveSessions;
38
38
  private mutedProactiveSessionCounts;
39
+ /** Global limiter for chat.send RPC calls; large multi-bot fan-out can
40
+ * saturate the Gateway before collectReply even starts. The slot is released
41
+ * as soon as the chat.send RPC returns a runId; collectReply does not hold it.
42
+ */
43
+ private chatSendConcurrency;
44
+ private activeChatSends;
45
+ private chatSendWaiters;
39
46
  constructor(config: OpenClawConfig);
40
47
  connect(): Promise<void>;
41
48
  private _doConnect;
@@ -92,6 +99,8 @@ export declare class OpenClawClient {
92
99
  private addMutedProactiveKey;
93
100
  private releaseMutedProactiveKey;
94
101
  muteProactiveDelivery(sessionKey: string): (delayMs?: number) => void;
102
+ private acquireChatSendSlot;
103
+ private releaseChatSendSlot;
95
104
  chatSend(params: {
96
105
  sessionKey: string;
97
106
  message: string;
@@ -37,6 +37,13 @@ export class OpenClawClient {
37
37
  /** Session keys whose proactive messages must be dropped by the bridge (e.g. discussion scheduler owns delivery). */
38
38
  mutedProactiveSessions = new Set();
39
39
  mutedProactiveSessionCounts = new Map();
40
+ /** Global limiter for chat.send RPC calls; large multi-bot fan-out can
41
+ * saturate the Gateway before collectReply even starts. The slot is released
42
+ * as soon as the chat.send RPC returns a runId; collectReply does not hold it.
43
+ */
44
+ chatSendConcurrency = Number(process.env.OPENCLAW_LARK_MULTI_AGENT_CHAT_SEND_CONCURRENCY || 3);
45
+ activeChatSends = 0;
46
+ chatSendWaiters = [];
40
47
  constructor(config) {
41
48
  this.config = config;
42
49
  }
@@ -837,6 +844,24 @@ export class OpenClawClient {
837
844
  release();
838
845
  };
839
846
  }
847
+ async acquireChatSendSlot() {
848
+ const limit = Math.max(1, this.chatSendConcurrency || 1);
849
+ if (this.activeChatSends < limit) {
850
+ this.activeChatSends++;
851
+ return () => this.releaseChatSendSlot();
852
+ }
853
+ const startedWaitingAt = Date.now();
854
+ await new Promise((resolve) => this.chatSendWaiters.push(resolve));
855
+ this.activeChatSends++;
856
+ console.log(`[OpenClaw] chat.send waited ${Date.now() - startedWaitingAt}ms for concurrency slot (active=${this.activeChatSends}/${limit})`);
857
+ return () => this.releaseChatSendSlot();
858
+ }
859
+ releaseChatSendSlot() {
860
+ this.activeChatSends = Math.max(0, this.activeChatSends - 1);
861
+ const next = this.chatSendWaiters.shift();
862
+ if (next)
863
+ next();
864
+ }
840
865
  async chatSend(params) {
841
866
  const sk = params.sessionKey;
842
867
  const fullSessionKey = `agent:main:${sk}`;
@@ -849,14 +874,21 @@ export class OpenClawClient {
849
874
  // the next message while still allowing sessionKey matching for internal runIds.
850
875
  this.agentEvents.set(fullSessionKey, []);
851
876
  this.agentEvents.set(sk, []);
877
+ const releaseChatSendSlot = await this.acquireChatSendSlot();
878
+ let result;
852
879
  const sendStartedAt = Date.now();
853
- const result = await this.rpc("chat.send", {
854
- sessionKey: sk,
855
- message: params.message,
856
- attachments: params.attachments,
857
- deliver: params.deliver ?? false,
858
- idempotencyKey: randomUUID(),
859
- });
880
+ try {
881
+ result = await this.rpc("chat.send", {
882
+ sessionKey: sk,
883
+ message: params.message,
884
+ attachments: params.attachments,
885
+ deliver: params.deliver ?? false,
886
+ idempotencyKey: randomUUID(),
887
+ });
888
+ }
889
+ finally {
890
+ releaseChatSendSlot();
891
+ }
860
892
  console.log(`[OpenClaw] chat.send runId: ${result.runId} (rpc=${Date.now() - sendStartedAt}ms, attachments=${params.attachments?.length || 0})`);
861
893
  return await this.collectReply(result.runId, params.timeoutMs || 1800000, sk, { emptyFinalAsNoReply: params.emptyFinalAsNoReply, expectedUserText: params.message });
862
894
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-lark-multi-agent",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
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": {