CoDEVX / lib /mock-agent.test.ts
CodexMacTiger
feat: live package-scoped chat and thinking logs
837e3ac
import { describe, expect, it } from "vitest";
import seedWorkPackages from "../agentic_pm_demo_codex_plans/data/work-packages.seed.json";
import { runMockAgent } from "./mock-agent";
import { hydrateWorkPackages } from "./work-package-specs";
import type { ChatMessage, WorkPackage } from "./work-package-types";
import { SIMULATED_EXECUTION_DISCLAIMER } from "./work-package-types";
const productIdea =
"I want to build an IoT product for production-line tightening quality monitoring.";
const hydrated = hydrateWorkPackages(
seedWorkPackages as WorkPackage[],
productIdea,
);
function userMessage(content: string): ChatMessage {
return {
id: "m-1",
role: "user",
content,
createdAt: new Date().toISOString(),
};
}
describe("runMockAgent", () => {
it("hydrates the board from a free-form product idea", () => {
const response = runMockAgent({
messages: [userMessage(productIdea)],
workPackages: seedWorkPackages as WorkPackage[],
parsedCommand: { instruction: productIdea },
});
expect(response.boardAction?.type).toBe("replace_all");
const replacement = response.boardAction?.fields?.replacementWorkPackages as
| WorkPackage[]
| undefined;
expect(replacement?.length).toBe(hydrated.length);
expect(replacement?.[0]?.inputFiles[0]).toContain("Product brief:");
});
it("creates spec-driven execute outputs for every work package", () => {
for (const wp of hydrated) {
const response = runMockAgent({
messages: [userMessage(productIdea)],
workPackages: hydrated,
selectedWorkPackageId: wp.id,
parsedCommand: {
referencedPackageName: wp.title,
mode: "execute",
instruction: `Generate the expected outputs for ${wp.shortName}.`,
},
});
expect(response.boardAction?.type).toBe("update");
const fields = response.boardAction?.fields;
const outputs = (fields?.outputs as WorkPackage["outputs"] | undefined) ?? [];
expect(outputs.length).toBeGreaterThan(0);
const latest = outputs[outputs.length - 1];
expect(latest.disclaimer).toBe(SIMULATED_EXECUTION_DISCLAIMER);
for (const expectedOutput of wp.outputFiles) {
expect(latest.content).toContain(expectedOutput);
}
}
});
it("returns package-aware guidance for ask", () => {
const wp = hydrated.find((item) => item.id === "wp-test-management");
expect(wp).toBeTruthy();
const response = runMockAgent({
messages: [userMessage(productIdea)],
workPackages: hydrated,
selectedWorkPackageId: wp?.id,
parsedCommand: {
referencedPackageName: wp?.title,
mode: "ask",
instruction: "How should we verify reliability?",
},
});
expect(response.assistantMessage).toContain("traceability");
expect(response.assistantMessage).toContain("reliability");
expect(response.assistantMessage).not.toContain("Package:");
expect(response.assistantMessage).not.toContain("Phase:");
expect(response.boardAction?.type).toBe("none");
});
it("preserves the existing product brief when asking about a package detail", () => {
const wp = hydrated.find((item) => item.id === "wp-srs");
expect(wp).toBeTruthy();
const response = runMockAgent({
messages: [userMessage("What does verification method mean in this package?")],
workPackages: hydrated,
selectedWorkPackageId: wp?.id,
parsedCommand: {
referencedPackageName: wp?.title,
mode: "ask",
instruction: "What does verification method mean in this package?",
},
});
expect(response.assistantMessage).toContain(productIdea);
expect(response.assistantMessage).not.toContain(
"Product brief: What does verification method mean in this package?",
);
});
it("does not turn a package question into the product brief when no product brief exists yet", () => {
const unhydrated = seedWorkPackages as WorkPackage[];
const wp = unhydrated.find((item) => item.id === "wp-srs");
expect(wp).toBeTruthy();
const response = runMockAgent({
messages: [userMessage("Explain this objective in simpler words.")],
workPackages: unhydrated,
selectedWorkPackageId: wp?.id,
parsedCommand: {
referencedPackageName: wp?.title,
mode: "ask",
instruction: "Explain this objective in simpler words.",
},
});
expect(response.assistantMessage).not.toContain(
"Product brief: Explain this objective in simpler words.",
);
expect(response.assistantMessage).not.toContain(
"Product context: Explain this objective in simpler words.",
);
});
});