47 lines
1.9 KiB
JavaScript
47 lines
1.9 KiB
JavaScript
const { normalizeText } = require('./scanGrounding');
|
|
|
|
// Agreement must be judged on the RAW model answers, not the grounded ones:
|
|
// catalog grounding has a genus-level fallback that can collapse two different
|
|
// species onto the same catalog entry and fake an agreement.
|
|
const reviewAgreesWithPrimary = (rawPrimary, rawReview) => {
|
|
if (!rawPrimary || !rawReview) return false;
|
|
const primaryBotanical = normalizeText(rawPrimary.botanicalName);
|
|
const primaryName = normalizeText(rawPrimary.name);
|
|
const botanicalMatch = Boolean(primaryBotanical) && primaryBotanical === normalizeText(rawReview.botanicalName);
|
|
const nameMatch = Boolean(primaryName) && primaryName === normalizeText(rawReview.name);
|
|
return botanicalMatch || nameMatch;
|
|
};
|
|
|
|
// The review runs on a stronger model chain than the primary, and models are
|
|
// not calibrated against each other — so on disagreement the review wins even
|
|
// when it trails the primary by up to this margin.
|
|
const REVIEW_DISAGREEMENT_MARGIN = 0.05;
|
|
|
|
// A second low-confidence guess is not a verification: the review may only
|
|
// replace the primary when it agrees with it or is (near-)competitively
|
|
// confident. On agreement the higher-confidence variant wins (tie goes to
|
|
// the review, which runs on the stronger model chain).
|
|
const decideReviewOutcome = ({ primaryResult, reviewResult, agrees }) => {
|
|
const primaryConfidence = primaryResult?.confidence || 0;
|
|
const reviewConfidence = reviewResult?.confidence || 0;
|
|
|
|
if (agrees) {
|
|
return {
|
|
accept: true,
|
|
replace: reviewConfidence >= primaryConfidence,
|
|
reason: 'review-confirmed-primary',
|
|
};
|
|
}
|
|
|
|
if (reviewConfidence >= primaryConfidence - REVIEW_DISAGREEMENT_MARGIN) {
|
|
return { accept: true, replace: true, reason: 'review-overrode-primary' };
|
|
}
|
|
|
|
return { accept: false, replace: false, reason: 'review-rejected-low-confidence' };
|
|
};
|
|
|
|
module.exports = {
|
|
decideReviewOutcome,
|
|
reviewAgreesWithPrimary,
|
|
};
|