openclaw-lark-multi-agent 1.0.1 → 1.0.2

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.
@@ -279,8 +279,11 @@ export class FeishuBot {
279
279
  }
280
280
  if (messageType !== "text" && messageType !== "image" && messageType !== "file" && messageType !== "audio" && messageType !== "sticker" && messageType !== "post")
281
281
  return;
282
- // --- Dedup: skip if this bot already processed this message ---
283
- if (this.store.hasBotProcessed(this.config.name, messageId))
282
+ // --- Dedup: atomically claim this message for this bot before any await.
283
+ // Feishu/WebSocket can deliver the same event more than once; a separate
284
+ // has-then-mark sequence races and can send the same user message into
285
+ // OpenClaw twice.
286
+ if (!this.store.tryMarkBotProcessed(this.config.name, messageId))
284
287
  return;
285
288
  // --- Cache chat info (lazy, at most once per hour) ---
286
289
  await this.fetchAndCacheChatInfo(chatId, chatType);
@@ -385,8 +388,6 @@ export class FeishuBot {
385
388
  });
386
389
  if (insertedId < 0)
387
390
  insertedId = this.store.getMessageId(messageId) || -1;
388
- // Mark as processed only after successful parse + insert
389
- this.store.markBotProcessed(this.config.name, messageId);
390
391
  // --- Commands: in p2p always respond; in group, check shouldRespond first ---
391
392
  // Single slash commands are handled by the bridge. Double slash commands were
392
393
  // already unescaped above and should pass through to OpenClaw instead.
@@ -119,5 +119,6 @@ export declare class MessageStore {
119
119
  * Mark a message as processed by a specific bot.
120
120
  */
121
121
  markBotProcessed(botName: string, messageId: string): void;
122
+ tryMarkBotProcessed(botName: string, messageId: string): boolean;
122
123
  close(): void;
123
124
  }
@@ -625,6 +625,10 @@ export class MessageStore {
625
625
  markBotProcessed(botName, messageId) {
626
626
  this.db.prepare(`INSERT OR IGNORE INTO processed_events (bot_name, message_id) VALUES (?, ?)`).run(botName, messageId);
627
627
  }
628
+ tryMarkBotProcessed(botName, messageId) {
629
+ const result = this.db.prepare(`INSERT OR IGNORE INTO processed_events (bot_name, message_id) VALUES (?, ?)`).run(botName, messageId);
630
+ return result.changes === 1;
631
+ }
628
632
  close() {
629
633
  this.db.close();
630
634
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-lark-multi-agent",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
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": {