56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
|
|
/**
|
||
|
|
* LLM output formatter.
|
||
|
|
*
|
||
|
|
* Converts an ImhotepResult into a compact JSON string designed for
|
||
|
|
* consumption by large language models in automated repair loops.
|
||
|
|
* Failing clauses include diagnostic codes, messages, fix hints, and metrics.
|
||
|
|
* When there are no clause results (parse/preflight failures), synthetic
|
||
|
|
* failing clauses are emitted from diagnostics so repair loops still work.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { ImhotepResult } from 'imhotep-core'
|
||
|
|
|
||
|
|
export function formatAsLLM(result: ImhotepResult): string {
|
||
|
|
const failingClauses = result.clauseResults
|
||
|
|
.filter((cr) => cr.status === 'fail' || cr.status === 'error')
|
||
|
|
.map((cr) => {
|
||
|
|
let diag = result.diagnostics.find((d) => d.clauseId === cr.clauseId)
|
||
|
|
if (!diag) {
|
||
|
|
const code = cr.diagnostics.find((c) => c !== '')
|
||
|
|
if (code) {
|
||
|
|
diag = result.diagnostics.find((d) => d.code === code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const failingClause: Record<string, unknown> = {}
|
||
|
|
failingClause.clauseLabel = cr.clauseLabel ?? diag?.clauseLabel ?? cr.clauseId
|
||
|
|
failingClause.sourceRef = cr.sourceRef ?? diag?.sourceRef ?? {}
|
||
|
|
failingClause.diagnosticCode = diag?.code ?? cr.diagnostics[0] ?? 'IMH_UNKNOWN_FAILURE'
|
||
|
|
failingClause.message = diag?.message ?? `Clause ${cr.clauseId} failed`
|
||
|
|
failingClause.suggestedFix = diag?.suggestedFix ?? diag?.fixHints ?? []
|
||
|
|
failingClause.metrics = { ...(diag?.metrics ?? {}), ...(cr.metrics ?? {}) }
|
||
|
|
|
||
|
|
return failingClause
|
||
|
|
})
|
||
|
|
|
||
|
|
if (failingClauses.length === 0 && result.diagnostics.length > 0) {
|
||
|
|
for (const d of result.diagnostics) {
|
||
|
|
const failingClause: Record<string, unknown> = {}
|
||
|
|
failingClause.clauseLabel = d.clauseLabel ?? 'diagnostic'
|
||
|
|
failingClause.sourceRef = d.sourceRef ?? {}
|
||
|
|
failingClause.diagnosticCode = d.code
|
||
|
|
failingClause.message = d.message
|
||
|
|
failingClause.suggestedFix = d.suggestedFix ?? d.fixHints ?? []
|
||
|
|
failingClause.metrics = d.metrics ?? {}
|
||
|
|
failingClauses.push(failingClause)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const llmOutput: Record<string, unknown> = {}
|
||
|
|
llmOutput.passed = result.passed
|
||
|
|
llmOutput.failingClauses = failingClauses
|
||
|
|
llmOutput.summary = result.summary
|
||
|
|
|
||
|
|
return JSON.stringify(llmOutput)
|
||
|
|
}
|