feat(guild): <@id> mention mechanism
- parse <@user-id> outside backtick spans - general: message with an at-list wakes only the at'd users (else all) - report/triage/custom: mentions change nothing - discuss/work: mention by current speaker pushes a sub-rotation frame (atList = mentions - sender, intersected with channel members); single linear pass (real/no-reply/force-proceed), then pop back to the saved parent pointer (resumes at the pusher); nested frames supported Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import { Message } from '../entities/message.entity';
|
||||
import { IdempotencyRecord } from '../entities/idempotency-record.entity';
|
||||
import { WakeMapping } from '../entities/wake-mapping.entity';
|
||||
import { parseSlashCommand } from '../channels/slash-commands';
|
||||
import { parseMentions } from '../channels/mentions';
|
||||
import { TurnService } from '../channels/turn.service';
|
||||
import { EventsService } from '../events/events.service';
|
||||
import { clampLimit, computeNextExpectedSeq } from './pagination.util';
|
||||
@@ -179,18 +180,24 @@ export class MessagingController {
|
||||
data: responseBody,
|
||||
});
|
||||
|
||||
// mentions: <@id> outside backtick spans
|
||||
const mentionIds = parseMentions(body.content ?? '');
|
||||
|
||||
if (isRotating) {
|
||||
// discuss/work: rotation decides the single wakeup target
|
||||
const decision = await this.turn.onNormalMessage(channelId, authorUserId);
|
||||
// discuss/work: rotation (incl. mention sub-frames) picks the target
|
||||
const decision = await this.turn.onNormalMessage(channelId, authorUserId, mentionIds);
|
||||
await this.realtime.emitMessageTargeted(channelId, responseBody, decision.wakeupUserId);
|
||||
} else {
|
||||
// general/report/triage/custom: wakeup from x_type + wake_mapping
|
||||
// general/report/triage/custom: wakeup from x_type + wake_mapping;
|
||||
// general also honors the message's at-list
|
||||
const wakeRows = await this.wakeRepo.find({ where: { channelId } });
|
||||
const wakeUserIds = new Set(wakeRows.map((w) => w.userId));
|
||||
const mentionUserIds = new Set(mentionIds.filter((id) => id !== authorUserId));
|
||||
await this.realtime.emitMessageCreated(channelId, responseBody, {
|
||||
xType,
|
||||
authorUserId,
|
||||
wakeUserIds,
|
||||
mentionUserIds,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user