

























@@ -1194,6 +1194,117 @@ describe("resolveSessionDeliveryTarget", () => {
11941194expect(resolved.reason).toBe("dm-blocked");
11951195});
119611961197+it("resolves heartbeat reserved targets through directory before session routing", async () => {
1198+const listGroups = vi
1199+.fn()
1200+.mockResolvedValue([{ kind: "group", id: "-1002458651455", name: "current" }]);
1201+const listGroupsLive = vi.fn().mockResolvedValue([]);
1202+setActivePluginRegistry(
1203+createTargetsTestRegistry([
1204+{
1205+ ...createTestChannelPlugin({
1206+id: "telegram",
1207+label: "Telegram",
1208+outbound: {
1209+deliveryMode: "direct",
1210+resolveTarget: ({ to }) =>
1211+to
1212+ ? { ok: true as const, to: to.trim() }
1213+ : { ok: false as const, error: new Error("target required") },
1214+},
1215+messaging: {
1216+targetPrefixes: ["telegram", "tg"],
1217+targetResolver: {
1218+reservedLiterals: ["current", "self", "this", "me"],
1219+hint: "<chatId>",
1220+},
1221+resolveOutboundSessionRoute: ({ target, resolvedTarget }) => ({
1222+sessionKey: `main:telegram:group:${target}`,
1223+baseSessionKey: `main:telegram:group:${target}`,
1224+peer: { kind: resolvedTarget?.kind === "user" ? "direct" : "group", id: target },
1225+chatType: resolvedTarget?.kind === "user" ? "direct" : "group",
1226+from: `telegram:group:${target}`,
1227+to: target,
1228+}),
1229+},
1230+}),
1231+directory: {
1232+ listGroups,
1233+ listGroupsLive,
1234+},
1235+},
1236+]),
1237+);
1238+1239+const resolved = await resolveHeartbeatDeliveryTargetWithSessionRoute({
1240+cfg: {},
1241+agentId: "main",
1242+heartbeat: {
1243+target: "telegram",
1244+to: "current",
1245+},
1246+});
1247+1248+expect(resolved.channel).toBe("telegram");
1249+expect(resolved.to).toBe("-1002458651455");
1250+expect(listGroups).toHaveBeenCalled();
1251+});
1252+1253+it("fails closed when a heartbeat reserved target misses the directory", async () => {
1254+const listGroups = vi.fn().mockResolvedValue([]);
1255+const listGroupsLive = vi.fn().mockResolvedValue([]);
1256+setActivePluginRegistry(
1257+createTargetsTestRegistry([
1258+{
1259+ ...createTestChannelPlugin({
1260+id: "telegram",
1261+label: "Telegram",
1262+outbound: {
1263+deliveryMode: "direct",
1264+resolveTarget: ({ to }) =>
1265+to
1266+ ? { ok: true as const, to: to.trim() }
1267+ : { ok: false as const, error: new Error("target required") },
1268+},
1269+messaging: {
1270+targetPrefixes: ["telegram", "tg"],
1271+targetResolver: {
1272+reservedLiterals: ["current", "self", "this", "me"],
1273+hint: "<chatId>",
1274+},
1275+resolveOutboundSessionRoute: ({ target }) => ({
1276+sessionKey: `main:telegram:group:${target}`,
1277+baseSessionKey: `main:telegram:group:${target}`,
1278+peer: { kind: "group", id: target },
1279+chatType: "group",
1280+from: `telegram:group:${target}`,
1281+to: target,
1282+}),
1283+},
1284+}),
1285+directory: {
1286+ listGroups,
1287+ listGroupsLive,
1288+},
1289+},
1290+]),
1291+);
1292+1293+const resolved = await resolveHeartbeatDeliveryTargetWithSessionRoute({
1294+cfg: {},
1295+agentId: "main",
1296+heartbeat: {
1297+target: "telegram",
1298+to: "current",
1299+},
1300+});
1301+1302+expect(resolved.channel).toBe("none");
1303+expect(resolved.reason).toBe("no-target");
1304+expect(listGroups).toHaveBeenCalled();
1305+expect(listGroupsLive).toHaveBeenCalled();
1306+});
1307+11971308it("keeps heartbeat route canonicalization best-effort when target resolution fails", async () => {
11981309setActivePluginRegistry(
11991310createTargetsTestRegistry([
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。