mirror of https://github.com/openclaw/openclaw.git
test: share session target and outbound mirror helpers
This commit is contained in:
parent
017c0dce32
commit
c5dc61e795
|
|
@ -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([
|
||||||
|
|
|
||||||
|
|
@ -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 () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue