import { describe, expect, it } from "vitest"; import { buildFrameCandidatesForUnit } from "../src/services/designAgentApi"; describe("buildFrameCandidatesForUnit (#98 Task 2)", () => { it("merges sorted evidence, v4 candidates, all judgments, and app candidates up to six", () => { const unit = { unit_id: "03-1", current_default_candidate: "frame_a", sorted_candidate_evidence: [ { template_id: "frame_a", frame_number: 1, label: "use_as_is", confidence: 0.9, rank: 1, coverage_state: "covered_native", candidate_status: "auto_renderable" }, ], v4_candidates: [ { template_id: "frame_b", frame_number: 2, label: "light_edit", confidence: 0.8 }, ], v4_all_judgments: [ { template_id: "frame_c", frame_number: 3, label: "reject", confidence: 0.7, coverage_state: "requires_adaptation", candidate_status: "ai_adaptation_required" }, { template_id: "frame_d", frame_number: 4, label: "reject", confidence: 0.6 }, { template_id: "frame_e", frame_number: 5, label: "reject", confidence: 0.5 }, { template_id: "frame_f", frame_number: 6, label: "reject", confidence: 0.4 }, { template_id: "frame_g", frame_number: 7, label: "reject", confidence: 0.3 }, ], application_candidates: [ { template_id: "frame_b", application_mode: "same_frame_with_adjustment", auto_applicable: true }, ], }; const candidates = buildFrameCandidatesForUnit(unit); expect(candidates.map((c) => c.id)).toEqual([ "frame_a", "frame_b", "frame_c", "frame_d", "frame_e", "frame_f", ]); expect(candidates).toHaveLength(6); expect(candidates[1].applicationMode).toBe("same_frame_with_adjustment"); expect(candidates[0].coverageState).toBe("covered_native"); expect(candidates[2].coverageState).toBe("requires_adaptation"); expect(candidates[2].candidateStatus).toBe("ai_adaptation_required"); }); it("surfaces generic fallback from composition when Step 9 has no V4 sources", () => { const unit = { unit_id: "05-1+05-2", current_default_candidate: null, sorted_candidate_evidence: [], candidate_evidence: [], v4_candidates: [], v4_all_judgments: [], application_candidates: [], }; const compositionUnit = { source_section_ids: ["05-1", "05-2"], frame_template_id: "three_parallel_requirements", frame_id: "1171281190", label: "reject", score: 0, phase_z_status: "fallback_candidate", selection_path: "generic_fallback", rationale: { ai_adaptation_required: true }, }; const candidates = buildFrameCandidatesForUnit(unit, compositionUnit); expect(candidates).toHaveLength(1); expect(candidates[0]).toMatchObject({ id: "three_parallel_requirements", label: "reject", coverageState: "requires_adaptation", routeHint: "ai_adaptation_required", decision: "selected", reason: "generic_fallback", }); }); });