evOo-local/packages/core/src/group-mentions.test.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

122 lines
3.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
hasMentionToken,
inferHandoffTargetBotId,
inferHandoffTargetName,
resolveGroupTargetBotIds,
} from "./group-mentions.js";
const members = [
{ id: "a", name: "BotA" },
{ id: "b", name: "BotB" },
{ id: "c", name: "Writer" },
];
describe("hasMentionToken", () => {
it("requires a boundary after the complete member name", () => {
expect(hasMentionToken("Ask @Ann to review", "Ann")).toBe(true);
expect(hasMentionToken("Ask @Ann, then continue", "Ann")).toBe(true);
expect(hasMentionToken("Ask @Anna to review", "Ann")).toBe(false);
expect(hasMentionToken("name@Ann", "Ann")).toBe(false);
expect(hasMentionToken("contact@everyone", "everyone")).toBe(false);
});
it("supports multi-word and Unicode member names", () => {
expect(hasMentionToken("Ask @Research Writer and @Éditeur", "Research Writer")).toBe(true);
expect(hasMentionToken("Ask @Research Writer and @Éditeur", "Éditeur")).toBe(true);
});
});
describe("resolveGroupTargetBotIds", () => {
it("returns mentioned bots from text", () => {
expect(
resolveGroupTargetBotIds({
text: "@BotA gather sources. @BotB summarize.",
members,
}),
).toEqual(["a", "b"]);
});
it("returns all members for @everyone", () => {
expect(
resolveGroupTargetBotIds({
text: "@everyone please review",
members,
}),
).toEqual(["a", "b", "c"]);
});
it("merges explicit mentions", () => {
expect(
resolveGroupTargetBotIds({
text: "hello",
members,
explicitMentions: ["b"],
}),
).toEqual(["b"]);
});
it("matches multi-word and Unicode names without prefix collisions", () => {
const namedMembers = [
{ id: "research", name: "Research Writer" },
{ id: "edit", name: "Éditeur" },
{ id: "ann", name: "Ann" },
{ id: "anna", name: "Anna" },
];
expect(
resolveGroupTargetBotIds({
text: "@Research Writer compare this with @Éditeur and @Anna.",
members: namedMembers,
}),
).toEqual(["research", "edit", "anna"]);
});
it("ignores explicit mentions for bots that are not group members", () => {
expect(
resolveGroupTargetBotIds({
text: "hello",
members,
explicitMentions: ["b", "outsider"],
}),
).toEqual(["b"]);
});
it("picks the first member when unmentioned", () => {
expect(
resolveGroupTargetBotIds({
text: "hello team",
members,
}),
).toEqual(["a"]);
});
});
describe("inferHandoffTargetName", () => {
it("picks Writer when BotA is also mentioned", () => {
expect(inferHandoffTargetName("@BotA hand this to Writer for the draft")).toBe("Writer");
});
});
describe("inferHandoffTargetBotId", () => {
it("recognizes hand this to Writer", () => {
expect(inferHandoffTargetBotId("hand this to Writer for the draft", members)).toBe("c");
});
it("recognizes @Writer take the draft", () => {
expect(inferHandoffTargetBotId("@Writer take the draft", members)).toBe("c");
});
it("resolves Writer from mixed mention prompt", () => {
expect(inferHandoffTargetBotId("@BotA hand this to Writer for the draft", members)).toBe("c");
});
it("resolves multi-word handoff targets", () => {
expect(
inferHandoffTargetBotId("hand this to Research Writer for the draft", [
...members,
{ id: "research", name: "Research Writer" },
]),
).toBe("research");
});
});