fix(issues): normalize HTML entities in @mention tokens before agent lookup (#1255)
Rich-text comments store entities like   after @names; strip them before matching agents so issue_comment_mentioned and wake injection work. Made-with: Cursor
This commit is contained in:
parent
dfdd3784b9
commit
47449152ac
2 changed files with 35 additions and 1 deletions
24
server/src/__tests__/normalize-agent-mention-token.test.ts
Normal file
24
server/src/__tests__/normalize-agent-mention-token.test.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { normalizeAgentMentionToken } from "../services/issues.ts";
|
||||||
|
|
||||||
|
describe("normalizeAgentMentionToken", () => {
|
||||||
|
it("strips hex numeric entities such as space ( )", () => {
|
||||||
|
expect(normalizeAgentMentionToken("Baba ")).toBe("Baba");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("strips decimal numeric entities", () => {
|
||||||
|
expect(normalizeAgentMentionToken("Baba ")).toBe("Baba");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("strips common named entities", () => {
|
||||||
|
expect(normalizeAgentMentionToken("Baba ")).toBe("Baba");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns plain names unchanged", () => {
|
||||||
|
expect(normalizeAgentMentionToken("Baba")).toBe("Baba");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("trims after stripping entities", () => {
|
||||||
|
expect(normalizeAgentMentionToken("Baba  ")).toBe("Baba");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -196,6 +196,13 @@ function unreadForUserCondition(companyId: string, userId: string) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HTML_ENTITY_IN_MENTION = /&#x[0-9a-fA-F]+;|&#[0-9]+;|&[a-z]+;/gi;
|
||||||
|
|
||||||
|
/** Strips common HTML entities from a raw @mention capture so UI-encoded bodies still match agent names. */
|
||||||
|
export function normalizeAgentMentionToken(raw: string): string {
|
||||||
|
return raw.replace(HTML_ENTITY_IN_MENTION, "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
export function deriveIssueUserContext(
|
export function deriveIssueUserContext(
|
||||||
issue: IssueUserContextInput,
|
issue: IssueUserContextInput,
|
||||||
userId: string,
|
userId: string,
|
||||||
|
|
@ -1446,7 +1453,10 @@ export function issueService(db: Db) {
|
||||||
const re = /\B@([^\s@,!?.]+)/g;
|
const re = /\B@([^\s@,!?.]+)/g;
|
||||||
const tokens = new Set<string>();
|
const tokens = new Set<string>();
|
||||||
let m: RegExpExecArray | null;
|
let m: RegExpExecArray | null;
|
||||||
while ((m = re.exec(body)) !== null) tokens.add(m[1].toLowerCase());
|
while ((m = re.exec(body)) !== null) {
|
||||||
|
const normalized = normalizeAgentMentionToken(m[1]);
|
||||||
|
if (normalized) tokens.add(normalized.toLowerCase());
|
||||||
|
}
|
||||||
if (tokens.size === 0) return [];
|
if (tokens.size === 0) return [];
|
||||||
const rows = await db.select({ id: agents.id, name: agents.name })
|
const rows = await db.select({ id: agents.id, name: agents.name })
|
||||||
.from(agents).where(eq(agents.companyId, companyId));
|
.from(agents).where(eq(agents.companyId, companyId));
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue