@unicitylabs/openclaw-unicity 0.3.2 → 0.3.3
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/package.json +1 -1
- package/src/channel.ts +25 -6
package/package.json
CHANGED
package/src/channel.ts
CHANGED
|
@@ -453,6 +453,25 @@ export const unicityChannelPlugin = {
|
|
|
453
453
|
replyToId?: string;
|
|
454
454
|
};
|
|
455
455
|
|
|
456
|
+
// Nostr pubkey for self-message detection and reply-to-self detection.
|
|
457
|
+
// Group messages use the 32-byte x-only Nostr pubkey (event.pubkey),
|
|
458
|
+
// NOT the 33-byte compressed chainPubkey.
|
|
459
|
+
const myNostrPubkey = sphere.groupChat?.getMyPublicKey?.() ?? null;
|
|
460
|
+
|
|
461
|
+
// Detect if a group message is a reply to one of the agent's own messages.
|
|
462
|
+
// Used to set WasMentioned so the mention gate treats replies-to-self as
|
|
463
|
+
// implicit mentions (same pattern Discord uses for thread replies).
|
|
464
|
+
function isReplyToSelf(msg: GroupMsg): boolean {
|
|
465
|
+
if (!msg.replyToId || !myNostrPubkey) return false;
|
|
466
|
+
try {
|
|
467
|
+
const messages = sphere.groupChat?.getMessages?.(msg.groupId) ?? [];
|
|
468
|
+
const repliedTo = messages.find((m: { id: string }) => m.id === msg.replyToId);
|
|
469
|
+
return repliedTo?.senderPubkey === myNostrPubkey;
|
|
470
|
+
} catch {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
456
475
|
function dispatchGroupMessage(msg: GroupMsg): void {
|
|
457
476
|
const senderName = msg.senderNametag ?? msg.senderPubkey.slice(0, 12);
|
|
458
477
|
const groupData = sphere.groupChat?.getGroup?.(msg.groupId);
|
|
@@ -461,6 +480,10 @@ export const unicityChannelPlugin = {
|
|
|
461
480
|
const metadataHeader = `[SenderName: ${senderName} | SenderId: ${msg.senderPubkey} | GroupId: ${msg.groupId} | GroupName: ${groupName} | IsOwner: ${isOwner} | CommandAuthorized: ${isOwner}]`;
|
|
462
481
|
const sanitizedContent = msg.content.replace(/\[(?:SenderName|SenderId|IsOwner|CommandAuthorized|GroupId|GroupName)\s*:/gi, "[BLOCKED:");
|
|
463
482
|
|
|
483
|
+
// Treat replies to the agent's own messages as implicit mentions,
|
|
484
|
+
// so the mention gate doesn't skip them (mirrors Discord's behavior).
|
|
485
|
+
const wasMentioned = isReplyToSelf(msg) || undefined;
|
|
486
|
+
|
|
464
487
|
ctx.log?.info(`[${ctx.account.accountId}] Group message from ${senderName} in ${groupName}: ${msg.content.slice(0, 80)}`);
|
|
465
488
|
|
|
466
489
|
const inboundCtx = runtime.channel.reply.finalizeInboundContext({
|
|
@@ -479,6 +502,7 @@ export const unicityChannelPlugin = {
|
|
|
479
502
|
SenderId: msg.senderPubkey,
|
|
480
503
|
IsOwner: isOwner,
|
|
481
504
|
CommandAuthorized: isOwner,
|
|
505
|
+
WasMentioned: wasMentioned,
|
|
482
506
|
});
|
|
483
507
|
|
|
484
508
|
runtime.channel.reply
|
|
@@ -490,7 +514,7 @@ export const unicityChannelPlugin = {
|
|
|
490
514
|
const text = payload.text;
|
|
491
515
|
if (!text) return;
|
|
492
516
|
try {
|
|
493
|
-
await sphere.groupChat.sendMessage(msg.groupId, text);
|
|
517
|
+
await sphere.groupChat.sendMessage(msg.groupId, text, msg.id);
|
|
494
518
|
ctx.log?.info(`[${ctx.account.accountId}] Group message sent to ${groupName}: ${text.slice(0, 80)}`);
|
|
495
519
|
} catch (err) {
|
|
496
520
|
ctx.log?.error(`[${ctx.account.accountId}] Failed to send group message to ${groupName}: ${err}`);
|
|
@@ -509,11 +533,6 @@ export const unicityChannelPlugin = {
|
|
|
509
533
|
});
|
|
510
534
|
}
|
|
511
535
|
|
|
512
|
-
// Nostr pubkey for self-message detection. Group messages use the 32-byte
|
|
513
|
-
// x-only Nostr pubkey (event.pubkey), NOT the 33-byte compressed chainPubkey.
|
|
514
|
-
// sphere.groupChat.getMyPublicKey() returns the correct Nostr-format key.
|
|
515
|
-
const myNostrPubkey = sphere.groupChat?.getMyPublicKey?.() ?? null;
|
|
516
|
-
|
|
517
536
|
// Per-group backfill state: buffer messages during the initial burst, then
|
|
518
537
|
// switch to live dispatch once the burst settles.
|
|
519
538
|
const groupBackfillStates = new Map<string, GroupBackfillState>();
|