(inputs: ReviewInputs)
| 91 | * "fine" to a weak vision model). Otherwise the vision verdict stands. |
| 92 | */ |
| 93 | export function buildReviewReport(inputs: ReviewInputs): ReviewReport { |
| 94 | const consoleErrors = inputs.consoleErrors ?? []; |
| 95 | const pageErrors = inputs.pageErrors ?? []; |
| 96 | const runtimeErrors = [...pageErrors, ...consoleErrors]; |
| 97 | |
| 98 | // If we couldn't see anything, we can't claim a visual verdict. |
| 99 | if (!inputs.sawScreenshot && runtimeErrors.length === 0) { |
| 100 | return { |
| 101 | verdict: 'unverified', |
| 102 | summary: 'Could not capture a screenshot or any runtime errors — preview not verified visually.', |
| 103 | issues: [], |
| 104 | visionAnswer: inputs.visionAnswer ?? '', |
| 105 | }; |
| 106 | } |
| 107 | |
| 108 | const visionVerdict = classifyVisionAnswer(inputs.visionAnswer ?? ''); |
| 109 | const visionIssues = extractIssues(inputs.visionAnswer ?? ''); |
| 110 | |
| 111 | // Runtime errors dominate. |
| 112 | if (runtimeErrors.length > 0) { |
| 113 | return { |
| 114 | verdict: 'broken', |
| 115 | summary: `The page reported ${runtimeErrors.length} runtime error(s) — the artifact is not rendering correctly.`, |
| 116 | issues: [ |
| 117 | ...pageErrors.map(e => `Page error: ${e}`), |
| 118 | ...consoleErrors.map(e => `Console error: ${e}`), |
| 119 | ...visionIssues, |
| 120 | ], |
| 121 | visionAnswer: inputs.visionAnswer ?? '', |
| 122 | }; |
| 123 | } |
| 124 | |
| 125 | // No runtime errors → trust the vision verdict. |
| 126 | const summaryByVerdict: Record<ReviewVerdict, string> = { |
| 127 | looks_good: 'Rendered correctly with no obvious visual issues.', |
| 128 | needs_work: 'Renders, but the review found visual problems to fix.', |
| 129 | broken: 'The review judged the render broken (blank or missing core content).', |
| 130 | unverified: 'Screenshot captured but the review was inconclusive.', |
| 131 | }; |
| 132 | |
| 133 | return { |
| 134 | verdict: visionVerdict, |
| 135 | summary: summaryByVerdict[visionVerdict], |
| 136 | issues: visionIssues, |
| 137 | visionAnswer: inputs.visionAnswer ?? '', |
| 138 | }; |
| 139 | } |
| 140 | |
| 141 | /** Render the report as the text the parent model reads back. */ |
| 142 | export function formatReviewReport(artifactId: string, version: number, report: ReviewReport): string { |
no test coverage detected