openclaw-lark-multi-agent 0.1.9 → 0.1.10
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/feishu-bot.d.ts +1 -0
- package/dist/feishu-bot.js +17 -6
- package/dist/message-store.d.ts +6 -2
- package/dist/message-store.js +11 -7
- package/package.json +1 -1
package/dist/feishu-bot.d.ts
CHANGED
package/dist/feishu-bot.js
CHANGED
|
@@ -264,6 +264,12 @@ export class FeishuBot {
|
|
|
264
264
|
if (messageType === "text") {
|
|
265
265
|
const rawText = content.text || "";
|
|
266
266
|
cleanText = this.cleanMentions(rawText);
|
|
267
|
+
// A mention-only text message is still a valid routing trigger. Feishu may
|
|
268
|
+
// expose mentions as display text like "@万万(Claude)" rather than @_user_xxx,
|
|
269
|
+
// so decide emptiness after stripping leading routing mentions.
|
|
270
|
+
if ((this.isMentioned(message.mentions || []) || this.isAllMention(rawText, message.mentions || [])) && !this.stripLeadingCommandMentions(cleanText).trim()) {
|
|
271
|
+
cleanText = "请回复上面最近一条用户消息。";
|
|
272
|
+
}
|
|
267
273
|
}
|
|
268
274
|
else if (messageType === "image") {
|
|
269
275
|
// Download image and pass local path
|
|
@@ -495,7 +501,7 @@ export class FeishuBot {
|
|
|
495
501
|
// Track this message for reaction status updates
|
|
496
502
|
const pending = this.pendingAckMessages.get(chatId) || [];
|
|
497
503
|
// Anti-loop
|
|
498
|
-
const streak = this.store.getBotStreak(chatId);
|
|
504
|
+
const streak = this.store.getBotStreak(chatId, this.config.name);
|
|
499
505
|
if (streak >= MAX_BOT_STREAK) {
|
|
500
506
|
console.log(`[${this.config.name}] Anti-loop: ${streak} consecutive bot msgs`);
|
|
501
507
|
return;
|
|
@@ -694,9 +700,11 @@ export class FeishuBot {
|
|
|
694
700
|
// Check if this bot is explicitly mentioned
|
|
695
701
|
if (this.isMentioned(mentions))
|
|
696
702
|
return true;
|
|
697
|
-
//
|
|
698
|
-
|
|
699
|
-
|
|
703
|
+
// Targeted mentions are exclusive. If a human mentions another person or
|
|
704
|
+
// another bot, free-mode bots must not steal that message. Free mode only
|
|
705
|
+
// applies to plain human messages with no targeted mentions.
|
|
706
|
+
const hasTargetedMention = mentions.some((m) => !this.isAllMentionItem(m));
|
|
707
|
+
if (hasTargetedMention)
|
|
700
708
|
return false;
|
|
701
709
|
// No bot mentioned: check current per-bot mode
|
|
702
710
|
if (chatId) {
|
|
@@ -712,10 +720,13 @@ export class FeishuBot {
|
|
|
712
720
|
isAllMention(rawText, mentions = []) {
|
|
713
721
|
if (rawText && (rawText.includes("@_all") || rawText.includes("@all") || rawText.includes("@所有人")))
|
|
714
722
|
return true;
|
|
715
|
-
return mentions.some((m) =>
|
|
723
|
+
return mentions.some((m) => this.isAllMentionItem(m));
|
|
724
|
+
}
|
|
725
|
+
isAllMentionItem(mention) {
|
|
726
|
+
return mention.key === "all" || mention.key === "@_all" || mention.id?.user_id === "all" || mention.id?.open_id === "all" || mention.name === "所有人";
|
|
716
727
|
}
|
|
717
728
|
mentionedBotName(mention) {
|
|
718
|
-
if (
|
|
729
|
+
if (this.isAllMentionItem(mention))
|
|
719
730
|
return null;
|
|
720
731
|
const candidates = [this, ...Array.from(FeishuBot.allBots.values()).filter((bot) => bot !== this)];
|
|
721
732
|
for (const bot of candidates) {
|
package/dist/message-store.d.ts
CHANGED
|
@@ -51,9 +51,13 @@ export declare class MessageStore {
|
|
|
51
51
|
*/
|
|
52
52
|
getRecent(chatId: string, maxCount?: number): ChatMessage[];
|
|
53
53
|
/**
|
|
54
|
-
* Count consecutive bot
|
|
54
|
+
* Count consecutive messages from one bot at the tail of a chat.
|
|
55
|
+
*
|
|
56
|
+
* Other bots do not consume this bot's anti-loop budget. Human messages reset
|
|
57
|
+
* the streak. This lets multiple bots free-discuss without a global bot-streak
|
|
58
|
+
* guard shutting everyone down after N total bot messages.
|
|
55
59
|
*/
|
|
56
|
-
getBotStreak(chatId: string): number;
|
|
60
|
+
getBotStreak(chatId: string, botName: string): number;
|
|
57
61
|
upsertChatInfo(info: ChatInfo): void;
|
|
58
62
|
setFreeDiscussion(chatId: string, on: boolean): void;
|
|
59
63
|
setVerbose(chatId: string, verbose: boolean): void;
|
package/dist/message-store.js
CHANGED
|
@@ -233,21 +233,25 @@ export class MessageStore {
|
|
|
233
233
|
}));
|
|
234
234
|
}
|
|
235
235
|
/**
|
|
236
|
-
* Count consecutive bot
|
|
236
|
+
* Count consecutive messages from one bot at the tail of a chat.
|
|
237
|
+
*
|
|
238
|
+
* Other bots do not consume this bot's anti-loop budget. Human messages reset
|
|
239
|
+
* the streak. This lets multiple bots free-discuss without a global bot-streak
|
|
240
|
+
* guard shutting everyone down after N total bot messages.
|
|
237
241
|
*/
|
|
238
|
-
getBotStreak(chatId) {
|
|
242
|
+
getBotStreak(chatId, botName) {
|
|
239
243
|
const rows = this.db.prepare(`
|
|
240
|
-
SELECT sender_type FROM messages
|
|
244
|
+
SELECT sender_type, sender_name FROM messages
|
|
241
245
|
WHERE chat_id = ?
|
|
242
246
|
ORDER BY timestamp DESC
|
|
243
|
-
LIMIT
|
|
247
|
+
LIMIT 50
|
|
244
248
|
`).all(chatId);
|
|
245
249
|
let count = 0;
|
|
246
250
|
for (const r of rows) {
|
|
247
|
-
if (r.sender_type === "
|
|
248
|
-
count++;
|
|
249
|
-
else
|
|
251
|
+
if (r.sender_type === "human")
|
|
250
252
|
break;
|
|
253
|
+
if (r.sender_type === "bot" && r.sender_name === botName)
|
|
254
|
+
count++;
|
|
251
255
|
}
|
|
252
256
|
return count;
|
|
253
257
|
}
|