Merge a46e3282ab32d3d6c7d9e5eaacd6386165239e50 into 6b4c24c2e55b5b4013277bd799525086f6a0c40f
This commit is contained in:
commit
9ffc84c373
@ -27,6 +27,7 @@ type MatrixHandlerTestHarnessOptions = {
|
||||
accountAllowBots?: boolean | "mentions";
|
||||
configuredBotUserIds?: Set<string>;
|
||||
mentionRegexes?: MatrixMonitorHandlerParams["mentionRegexes"];
|
||||
buildMentionRegexes?: MatrixMonitorHandlerParams["core"]["channel"]["mentions"]["buildMentionRegexes"];
|
||||
groupPolicy?: "open" | "allowlist" | "disabled";
|
||||
replyToMode?: ReplyToMode;
|
||||
threadReplies?: "off" | "inbound" | "always";
|
||||
@ -177,6 +178,9 @@ export function createMatrixHandlerTestHarness(
|
||||
}
|
||||
}),
|
||||
},
|
||||
mentions: {
|
||||
buildMentionRegexes: options.buildMentionRegexes ?? (() => []),
|
||||
},
|
||||
reactions: {
|
||||
shouldAckReaction: options.shouldAckReaction ?? (() => false),
|
||||
},
|
||||
|
||||
@ -426,8 +426,8 @@ describe("matrix monitor handler pairing account scope", () => {
|
||||
expect(recordInboundSession).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("drops forged metadata-only mentions before agent routing", async () => {
|
||||
const { handler, recordInboundSession, resolveAgentRoute } = createMatrixHandlerTestHarness({
|
||||
it("drops forged metadata-only mentions without processing", async () => {
|
||||
const { handler, recordInboundSession } = createMatrixHandlerTestHarness({
|
||||
isDirectMessage: false,
|
||||
mentionRegexes: [/@bot/i],
|
||||
getMemberDisplayName: async () => "sender",
|
||||
@ -442,7 +442,6 @@ describe("matrix monitor handler pairing account scope", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
expect(resolveAgentRoute).not.toHaveBeenCalled();
|
||||
expect(recordInboundSession).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -1012,6 +1011,38 @@ describe("matrix monitor handler pairing account scope", () => {
|
||||
|
||||
expect(resolveAgentRoute).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("re-resolves mentions with agent-level patterns after route resolution (#51082)", async () => {
|
||||
const buildMentionRegexes = vi.fn((_cfg: unknown, agentId?: string) => {
|
||||
if (!agentId) return [];
|
||||
return [/@mybot/i];
|
||||
});
|
||||
const dispatchReplyFromConfig = vi.fn(async () => ({
|
||||
queuedFinal: false,
|
||||
counts: { final: 0, block: 0, tool: 0 },
|
||||
}));
|
||||
const { handler } = createMatrixHandlerTestHarness({
|
||||
mentionRegexes: [],
|
||||
buildMentionRegexes,
|
||||
roomsConfig: {
|
||||
"!room:example.org": { requireMention: true },
|
||||
},
|
||||
isDirectMessage: false,
|
||||
groupPolicy: "open",
|
||||
dispatchReplyFromConfig,
|
||||
});
|
||||
|
||||
await handler(
|
||||
"!room:example.org",
|
||||
createMatrixTextMessageEvent({
|
||||
eventId: "$agent-mention",
|
||||
body: "hey @mybot can you help?",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(buildMentionRegexes).toHaveBeenCalledWith(expect.anything(), "ops");
|
||||
expect(dispatchReplyFromConfig).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("matrix monitor handler durable inbound dedupe", () => {
|
||||
|
||||
@ -527,7 +527,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
return;
|
||||
}
|
||||
|
||||
const { wasMentioned, hasExplicitMention } = resolveMentions({
|
||||
let { wasMentioned, hasExplicitMention } = resolveMentions({
|
||||
content,
|
||||
userId: selfUserId,
|
||||
text: mentionPrecheckText,
|
||||
@ -588,12 +588,23 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
!hasExplicitMention &&
|
||||
commandAuthorized &&
|
||||
hasControlCommandInMessage;
|
||||
const canDetectMention = mentionRegexes.length > 0 || hasExplicitMention;
|
||||
if (isRoom && shouldRequireMention && !wasMentioned && !shouldBypassMention) {
|
||||
let canDetectMention = mentionRegexes.length > 0 || hasExplicitMention;
|
||||
// When there is message text, defer mention drop until after route
|
||||
// resolution so agent-level mentionPatterns are checked (#51082).
|
||||
// Media-only/poll events have no text - drop them immediately.
|
||||
if (
|
||||
isRoom &&
|
||||
shouldRequireMention &&
|
||||
!wasMentioned &&
|
||||
!shouldBypassMention &&
|
||||
!mentionPrecheckText
|
||||
) {
|
||||
logger.info("skipping room message", { roomId, reason: "no-mention" });
|
||||
await commitInboundEventIfClaimed();
|
||||
return;
|
||||
}
|
||||
const mentionDropDeferred =
|
||||
isRoom && shouldRequireMention && !wasMentioned && !shouldBypassMention;
|
||||
|
||||
if (isPollEvent) {
|
||||
const pollSnapshot = await fetchMatrixPollSnapshot(client, roomId, event).catch((err) => {
|
||||
@ -698,6 +709,29 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
eventTs: eventTs ?? undefined,
|
||||
resolveAgentRoute: core.channel.routing.resolveAgentRoute,
|
||||
});
|
||||
|
||||
// Re-resolve mentions with agent-specific mentionPatterns now that the
|
||||
// route (and agentId) is known (#51082).
|
||||
if (mentionDropDeferred) {
|
||||
const agentMentionRegexes = core.channel.mentions.buildMentionRegexes(cfg, route.agentId);
|
||||
if (agentMentionRegexes.length > 0) {
|
||||
const agentMentionResult = resolveMentions({
|
||||
content,
|
||||
userId: selfUserId,
|
||||
text: mentionPrecheckText,
|
||||
mentionRegexes: agentMentionRegexes,
|
||||
});
|
||||
if (agentMentionResult.wasMentioned) {
|
||||
wasMentioned = true;
|
||||
canDetectMention = true;
|
||||
}
|
||||
}
|
||||
if (!wasMentioned) {
|
||||
logger.info("skipping room message", { roomId, reason: "no-mention" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (configuredBinding) {
|
||||
const ensured = await ensureConfiguredAcpBindingReady({
|
||||
cfg,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user