From 22d3002786f55bf4b03d48cd7346a6b2f0705f42 Mon Sep 17 00:00:00 2001 From: bielie Date: Sun, 15 Feb 2026 19:07:11 +0800 Subject: [PATCH] fix constraint coverage metric to count facts instead of rendered lines --- modules/story-summary/generate/prompt.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/story-summary/generate/prompt.js b/modules/story-summary/generate/prompt.js index 07cb0a8..162d650 100644 --- a/modules/story-summary/generate/prompt.js +++ b/modules/story-summary/generate/prompt.js @@ -880,6 +880,13 @@ async function buildVectorPrompt(store, recallResult, causalById, focusCharacter const constraintBudget = { used: 0, max: Math.min(CONSTRAINT_MAX, total.max - total.used) }; const groupedSelectedConstraints = selectConstraintsByBudgetDesc(groupedConstraints, constraintBudget); + const injectedConstraintFacts = (() => { + let count = groupedSelectedConstraints.world.length; + for (const facts of groupedSelectedConstraints.people.values()) { + count += facts.length; + } + return count; + })(); const constraintLines = formatConstraintsStructured(groupedSelectedConstraints, 'asc'); if (constraintLines.length) { @@ -891,7 +898,7 @@ async function buildVectorPrompt(store, recallResult, causalById, focusCharacter injectionStats.constraint.filtered = allFacts.length - filteredConstraints.length; if (metrics) { - metrics.constraint.injected = assembled.constraints.lines.length; + metrics.constraint.injected = injectedConstraintFacts; metrics.constraint.tokens = constraintBudget.used; metrics.constraint.samples = assembled.constraints.lines.slice(0, 3).map(line => line.length > 60 ? line.slice(0, 60) + '...' : line @@ -1243,9 +1250,9 @@ async function buildVectorPrompt(store, recallResult, causalById, focusCharacter ); metrics.timing.evidenceAssembly = metrics.evidence.assemblyTime; - const totalFacts = allFacts.length; - metrics.quality.constraintCoverage = totalFacts > 0 - ? Math.round(assembled.constraints.lines.length / totalFacts * 100) + const relevantFacts = Math.max(0, allFacts.length - (metrics.constraint.filtered || 0)); + metrics.quality.constraintCoverage = relevantFacts > 0 + ? Math.round((metrics.constraint.injected || 0) / relevantFacts * 100) : 100; metrics.quality.eventPrecisionProxy = metrics.event?.similarityDistribution?.mean || 0;