test: tighten voice call response assertions

This commit is contained in:
Peter Steinberger
2026-05-09 21:18:34 +01:00
parent 2acd6aef92
commit 8a8076d65e

View File

@@ -3,14 +3,31 @@ import { VoiceCallConfigSchema } from "./config.js";
import type { CoreAgentDeps, CoreConfig } from "./core-bridge.js";
import { generateVoiceResponse } from "./response-generator.js";
type TestSessionEntry = {
sessionId: string;
updatedAt: number;
providerOverride?: string;
modelOverride?: string;
modelOverrideSource?: string;
};
type EmbeddedAgentArgs = {
extraSystemPrompt: string;
provider?: string;
model?: string;
sessionKey?: string;
sandboxSessionKey?: string;
agentDir?: string;
agentId?: string;
workspaceDir?: string;
sessionFile?: string;
};
function createAgentRuntime(payloads: Array<Record<string, unknown>>) {
const sessionStore: Record<string, { sessionId: string; updatedAt: number }> = {};
const sessionStore: Record<string, TestSessionEntry> = {};
const saveSessionStore = vi.fn(async () => {});
const updateSessionStore = vi.fn(
async (
_storePath: string,
mutator: (store: Record<string, { sessionId: string; updatedAt: number }>) => unknown,
) => {
async (_storePath: string, mutator: (store: Record<string, TestSessionEntry>) => unknown) => {
return await mutator(sessionStore);
},
);
@@ -77,17 +94,11 @@ function requireEmbeddedAgentArgs(runEmbeddedPiAgent: ReturnType<typeof vi.fn>)
if (!firstCall) {
throw new Error("voice response generator did not invoke the embedded agent");
}
const args = firstCall[0] as
| {
extraSystemPrompt?: string;
provider?: string;
model?: string;
}
| undefined;
const args = firstCall[0] as Partial<EmbeddedAgentArgs> | undefined;
if (!args?.extraSystemPrompt) {
throw new Error("voice response generator did not pass the spoken-output contract prompt");
}
return args;
return args as EmbeddedAgentArgs;
}
async function runGenerateVoiceResponse(
@@ -186,21 +197,17 @@ describe("generateVoiceResponse", () => {
});
expect(result.text).toBe("Pinned model works.");
expect(sessionStore["voice:15550001111"]).toMatchObject({
providerOverride: "openai",
modelOverride: "gpt-4.1-nano",
modelOverrideSource: "auto",
});
const pinnedSessionEntry = sessionStore["voice:15550001111"];
expect(pinnedSessionEntry?.providerOverride).toBe("openai");
expect(pinnedSessionEntry?.modelOverride).toBe("gpt-4.1-nano");
expect(pinnedSessionEntry?.modelOverrideSource).toBe("auto");
const updateSessionStoreCall = updateSessionStore.mock.calls[0];
expect(updateSessionStoreCall?.[0]).toBe("/tmp/openclaw/main/sessions.json");
expect(updateSessionStoreCall?.[1]).toBeTypeOf("function");
expect(runEmbeddedPiAgent).toHaveBeenCalledWith(
expect.objectContaining({
provider: "openai",
model: "gpt-4.1-nano",
sessionKey: "voice:15550001111",
}),
);
const args = requireEmbeddedAgentArgs(runEmbeddedPiAgent);
expect(args.provider).toBe("openai");
expect(args.model).toBe("gpt-4.1-nano");
expect(args.sessionKey).toBe("voice:15550001111");
});
it("uses the persisted per-call session key for classic responses", async () => {
@@ -224,16 +231,13 @@ describe("generateVoiceResponse", () => {
});
expect(result.text).toBe("Fresh call context.");
expect(sessionStore["voice:call:call-123"]).toMatchObject({
sessionId: expect.stringMatching(/\S/),
});
const perCallSessionEntry = sessionStore["voice:call:call-123"];
expect(perCallSessionEntry?.sessionId).toBeTypeOf("string");
expect(perCallSessionEntry?.sessionId).not.toBe("");
expect(sessionStore["voice:15550001111"]).toBeUndefined();
expect(runEmbeddedPiAgent).toHaveBeenCalledWith(
expect.objectContaining({
sessionKey: "voice:call:call-123",
sandboxSessionKey: "agent:main:voice:call:call-123",
}),
);
const args = requireEmbeddedAgentArgs(runEmbeddedPiAgent);
expect(args.sessionKey).toBe("voice:call:call-123");
expect(args.sandboxSessionKey).toBe("agent:main:voice:call:call-123");
});
it("uses the main agent workspace when voice config omits agentId", async () => {
@@ -272,15 +276,12 @@ describe("generateVoiceResponse", () => {
agentId: "main",
},
);
expect(runEmbeddedPiAgent).toHaveBeenCalledWith(
expect.objectContaining({
agentDir: "/tmp/openclaw/agents/main",
agentId: "main",
sandboxSessionKey: "agent:main:voice:15550001111",
workspaceDir: "/tmp/openclaw/workspace/main",
sessionFile: "/tmp/openclaw/main/sessions/session.jsonl",
}),
);
const args = requireEmbeddedAgentArgs(runEmbeddedPiAgent);
expect(args.agentDir).toBe("/tmp/openclaw/agents/main");
expect(args.agentId).toBe("main");
expect(args.sandboxSessionKey).toBe("agent:main:voice:15550001111");
expect(args.workspaceDir).toBe("/tmp/openclaw/workspace/main");
expect(args.sessionFile).toBe("/tmp/openclaw/main/sessions/session.jsonl");
});
it("uses the configured voice response agent workspace", async () => {
@@ -323,14 +324,11 @@ describe("generateVoiceResponse", () => {
agentId: "voice",
},
);
expect(runEmbeddedPiAgent).toHaveBeenCalledWith(
expect.objectContaining({
agentDir: "/tmp/openclaw/agents/voice",
agentId: "voice",
sandboxSessionKey: "agent:voice:voice:15550001111",
workspaceDir: "/tmp/openclaw/workspace/voice",
sessionFile: "/tmp/openclaw/voice/sessions/session.jsonl",
}),
);
const args = requireEmbeddedAgentArgs(runEmbeddedPiAgent);
expect(args.agentDir).toBe("/tmp/openclaw/agents/voice");
expect(args.agentId).toBe("voice");
expect(args.sandboxSessionKey).toBe("agent:voice:voice:15550001111");
expect(args.workspaceDir).toBe("/tmp/openclaw/workspace/voice");
expect(args.sessionFile).toBe("/tmp/openclaw/voice/sessions/session.jsonl");
});
});