




















@@ -4,6 +4,7 @@ import type { MatrixConfig, MatrixStreamingMode } from "../../types.js";
44import type { MatrixRoomInfo } from "./room-info.js";
5566type DirectRoomTrackerOptions = {
7+isExplicitlyConfiguredRoom?: (roomId: string) => boolean | Promise<boolean>;
78canPromoteRecentInvite?: (roomId: string) => boolean | Promise<boolean>;
89canPromoteUnmappedStrictRoom?: (roomId: string) => boolean | Promise<boolean>;
910shouldKeepLocallyPromotedDirectRoom?:
@@ -145,7 +146,18 @@ vi.mock("../../runtime-api.js", () => {
145146ToolPolicySchema: z.any().optional(),
146147addAllowlistUserEntriesFromConfigEntry: vi.fn(),
147148buildChannelConfigSchema: (schema: unknown) => schema,
148-buildChannelKeyCandidates: () => [],
149+buildChannelKeyCandidates: (...keys: Array<string | undefined | null>) => {
150+const seen = new Set<string>();
151+return keys
152+.map((key) => (typeof key === "string" ? key.trim() : ""))
153+.filter((key) => {
154+if (!key || seen.has(key)) {
155+return false;
156+}
157+seen.add(key);
158+return true;
159+});
160+},
149161buildProbeChannelStatusSummary: (
150162snapshot: Record<string, unknown>,
151163extra?: Record<string, unknown>,
@@ -961,6 +973,55 @@ describe("monitorMatrixProvider", () => {
961973await expect(trackerOpts.canPromoteRecentInvite("!room:example.org")).resolves.toBe(false);
962974});
963975976+it("wires exact room config as a direct-room classifier veto", async () => {
977+(hoisted.accountConfig as { rooms?: Record<string, unknown> }).rooms = {
978+"!room:example.org": { requireMention: true },
979+"*": { requireMention: false },
980+};
981+982+await startMonitorAndAbortAfterStartup();
983+984+const trackerOpts = directRoomTrackerOptions();
985+if (!trackerOpts?.isExplicitlyConfiguredRoom) {
986+throw new Error("explicit room config callback was not wired");
987+}
988+989+expect(await trackerOpts.isExplicitlyConfiguredRoom("!room:example.org")).toBe(true);
990+expect(await trackerOpts.isExplicitlyConfiguredRoom("!other:example.org")).toBe(false);
991+expect(hoisted.getRoomInfo).not.toHaveBeenCalled();
992+});
993+994+it("wires alias room config as a direct-room classifier veto", async () => {
995+(hoisted.accountConfig as { rooms?: Record<string, unknown> }).rooms = {
996+"#ops:example.org": { requireMention: true },
997+"*": { requireMention: false },
998+};
999+const { resolveMatrixTargets } = await import("../../resolve-targets.js");
1000+vi.mocked(resolveMatrixTargets).mockResolvedValueOnce([
1001+{
1002+input: "#ops:example.org",
1003+resolved: true,
1004+id: "!room:example.org",
1005+},
1006+]);
1007+1008+await startMonitorAndAbortAfterStartup();
1009+1010+const trackerOpts = directRoomTrackerOptions();
1011+if (!trackerOpts?.isExplicitlyConfiguredRoom) {
1012+throw new Error("explicit room config callback was not wired");
1013+}
1014+1015+hoisted.getRoomInfo.mockResolvedValueOnce({
1016+canonicalAlias: "#ops:example.org",
1017+altAliases: [],
1018+nameResolved: true,
1019+aliasesResolved: true,
1020+});
1021+1022+expect(await trackerOpts.isExplicitlyConfiguredRoom("!room:example.org")).toBe(true);
1023+});
1024+9641025it("wires recent-invite promotion to reject named rooms", async () => {
9651026await startMonitorAndAbortAfterStartup();
9661027此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。