test: share session target and outbound mirror helpers

This commit is contained in:
Peter Steinberger 2026-03-13 22:03:57 +00:00
parent 017c0dce32
commit c5dc61e795
2 changed files with 71 additions and 53 deletions

View File

@ -40,6 +40,14 @@ function createCustomRootCfg(customRoot: string, defaultAgentId = "ops"): OpenCl
}; };
} }
async function resolveTargetsForCustomRoot(home: string, agentIds: string[]) {
const customRoot = path.join(home, "custom-state");
const storePaths = await createAgentSessionStores(customRoot, agentIds);
const cfg = createCustomRootCfg(customRoot);
const targets = await resolveAllAgentSessionStoreTargets(cfg, { env: process.env });
return { storePaths, targets };
}
function expectTargetsToContainStores( function expectTargetsToContainStores(
targets: Array<{ agentId: string; storePath: string }>, targets: Array<{ agentId: string; storePath: string }>,
stores: Record<string, string>, stores: Record<string, string>,
@ -152,11 +160,7 @@ describe("resolveAllAgentSessionStoreTargets", () => {
it("discovers retired agent stores under a configured custom session root", async () => { it("discovers retired agent stores under a configured custom session root", async () => {
await withTempHome(async (home) => { await withTempHome(async (home) => {
const customRoot = path.join(home, "custom-state"); const { storePaths, targets } = await resolveTargetsForCustomRoot(home, ["ops", "retired"]);
const storePaths = await createAgentSessionStores(customRoot, ["ops", "retired"]);
const cfg = createCustomRootCfg(customRoot);
const targets = await resolveAllAgentSessionStoreTargets(cfg, { env: process.env });
expectTargetsToContainStores(targets, storePaths); expectTargetsToContainStores(targets, storePaths);
expect(targets.filter((target) => target.storePath === storePaths.ops)).toHaveLength(1); expect(targets.filter((target) => target.storePath === storePaths.ops)).toHaveLength(1);
@ -165,11 +169,10 @@ describe("resolveAllAgentSessionStoreTargets", () => {
it("keeps the actual on-disk store path for discovered retired agents", async () => { it("keeps the actual on-disk store path for discovered retired agents", async () => {
await withTempHome(async (home) => { await withTempHome(async (home) => {
const customRoot = path.join(home, "custom-state"); const { storePaths, targets } = await resolveTargetsForCustomRoot(home, [
const storePaths = await createAgentSessionStores(customRoot, ["ops", "Retired Agent"]); "ops",
const cfg = createCustomRootCfg(customRoot); "Retired Agent",
]);
const targets = await resolveAllAgentSessionStoreTargets(cfg, { env: process.env });
expect(targets).toEqual( expect(targets).toEqual(
expect.arrayContaining([ expect.arrayContaining([

View File

@ -47,6 +47,47 @@ describe("executeSendAction", () => {
}; };
} }
function expectMirrorWrite(
expected: Partial<{
agentId: string;
sessionKey: string;
text: string;
idempotencyKey: string;
mediaUrls: string[];
}>,
) {
expect(mocks.appendAssistantMessageToSessionTranscript).toHaveBeenCalledWith(
expect.objectContaining(expected),
);
}
async function executePluginMirroredSend(params: {
mirror?: Partial<{
sessionKey: string;
agentId?: string;
idempotencyKey?: string;
}>;
mediaUrls?: string[];
}) {
mocks.dispatchChannelMessageAction.mockResolvedValue(pluginActionResult("msg-plugin"));
await executeSendAction({
ctx: {
cfg: {},
channel: "discord",
params: { to: "channel:123", message: "hello" },
dryRun: false,
mirror: {
sessionKey: "agent:main:discord:channel:123",
...params.mirror,
},
},
to: "channel:123",
message: "hello",
mediaUrls: params.mediaUrls,
});
}
beforeEach(() => { beforeEach(() => {
mocks.dispatchChannelMessageAction.mockClear(); mocks.dispatchChannelMessageAction.mockClear();
mocks.sendMessage.mockClear(); mocks.sendMessage.mockClear();
@ -131,59 +172,33 @@ describe("executeSendAction", () => {
}); });
it("passes mirror idempotency keys through plugin-handled sends", async () => { it("passes mirror idempotency keys through plugin-handled sends", async () => {
mocks.dispatchChannelMessageAction.mockResolvedValue(pluginActionResult("msg-plugin")); await executePluginMirroredSend({
mirror: {
await executeSendAction({ idempotencyKey: "idem-plugin-send-1",
ctx: {
cfg: {},
channel: "discord",
params: { to: "channel:123", message: "hello" },
dryRun: false,
mirror: {
sessionKey: "agent:main:discord:channel:123",
idempotencyKey: "idem-plugin-send-1",
},
}, },
to: "channel:123",
message: "hello",
}); });
expect(mocks.appendAssistantMessageToSessionTranscript).toHaveBeenCalledWith( expectMirrorWrite({
expect.objectContaining({ sessionKey: "agent:main:discord:channel:123",
sessionKey: "agent:main:discord:channel:123", text: "hello",
text: "hello", idempotencyKey: "idem-plugin-send-1",
idempotencyKey: "idem-plugin-send-1", });
}),
);
}); });
it("falls back to message and media params for plugin-handled mirror writes", async () => { it("falls back to message and media params for plugin-handled mirror writes", async () => {
mocks.dispatchChannelMessageAction.mockResolvedValue(pluginActionResult("msg-plugin")); await executePluginMirroredSend({
mirror: {
await executeSendAction({ agentId: "agent-9",
ctx: {
cfg: {},
channel: "discord",
params: { to: "channel:123", message: "hello" },
dryRun: false,
mirror: {
sessionKey: "agent:main:discord:channel:123",
agentId: "agent-9",
},
}, },
to: "channel:123",
message: "hello",
mediaUrls: ["https://example.com/a.png", "https://example.com/b.png"], mediaUrls: ["https://example.com/a.png", "https://example.com/b.png"],
}); });
expect(mocks.appendAssistantMessageToSessionTranscript).toHaveBeenCalledWith( expectMirrorWrite({
expect.objectContaining({ agentId: "agent-9",
agentId: "agent-9", sessionKey: "agent:main:discord:channel:123",
sessionKey: "agent:main:discord:channel:123", text: "hello",
text: "hello", mediaUrls: ["https://example.com/a.png", "https://example.com/b.png"],
mediaUrls: ["https://example.com/a.png", "https://example.com/b.png"], });
}),
);
}); });
it("skips plugin dispatch during dry-run sends and forwards gateway + silent to sendMessage", async () => { it("skips plugin dispatch during dry-run sends and forwards gateway + silent to sendMessage", async () => {