feat(ingest): resolve project labels with Jev
CI / quality (push) Canceled after 0s

This commit is contained in:
vasily committed 2026-10-15 10:53:30 +08:00
1 parent 0e1a2ad008
commit 34f4923566
28 files changed
+3932 -81

No files matched your search

+8
View File
@@ -26,6 +26,13 @@ type IngestReview = {
jev_relation_probability?: number | null; jev_lens?: string | null;
jev_lens_confidence?: number | null; jev_model?: string | null;
jev_facet_scores?: { facet: 'tags' | 'audience' | 'use_for' | 'domain'; value: string; probability: number }[];
jev_facet_resolutions?: {
facet: 'tags' | 'audience' | 'use_for' | 'domain'; value: string;
fit_probability: number; selected_label?: string | null; selected_new_label: boolean;
new_probability: number;
choice_confidence: number; rank: number; added_to_project: boolean;
option_probabilities: { label_id?: string | null; label: string; probability: number }[];
}[];
relevance: 'borderline' | 'low'; status: string; created_at: string;
};
@@ -76,6 +83,7 @@ function IngestReviewSection({ csrf, projects, onError, onMessage }: {
<p>{item.excerpt}</p><p className="muted-copy">{item.relevance_rationale}</p>
{item.jev_relation_probability != null ? <p className="muted-copy">Jev relevance: {Math.round(item.jev_relation_probability * 100)}% · lens: {item.jev_lens ?? 'unknown'} ({item.jev_lens_confidence != null ? `${Math.round(item.jev_lens_confidence * 100)}% confidence` : 'no confidence score'}) · {item.jev_model}</p> : <p className="muted-copy">Jev signal unavailable or not configured.</p>}
{!!item.jev_facet_scores?.length && <p className="muted-copy">Facet suggestions: {item.jev_facet_scores.map(score => `${score.facet.replace('_', ' ')} “${score.value}” (${Math.round(score.probability * 100)}%)`).join(' · ')}</p>}
{!!item.jev_facet_resolutions?.length && <p className="muted-copy">Label decisions: {item.jev_facet_resolutions.map(label => `${label.facet.replace('_', ' ')} “${label.value}” → ${label.added_to_project ? 'added as a new project label' : label.selected_label ? `reused “${label.selected_label}”` : label.selected_new_label ? 'new label suggested, not added' : 'no label selected'} (fit ${Math.round(label.fit_probability * 100)}%, new ${Math.round(label.new_probability * 100)}%, confidence ${Math.round(label.choice_confidence * 100)}%, top-N rank ${label.rank}; options: ${label.option_probabilities.map(option => `${option.label} ${Math.round(option.probability * 100)}%`).join(', ')})`).join(' · ')}</p>}
<p className="muted-copy">Source {item.source_revision_id} · {item.locator.kind.replaceAll('_', ' ')} {item.locator.page ? `· page ${item.locator.page}` : ''} · run {item.run_id}</p>
<label>Decision reason<textarea maxLength={2000} value={rationales[item.review_id] ?? ''} onChange={event => setRationales(value => ({ ...value, [item.review_id]: event.target.value }))} /></label>
<label><input type="checkbox" checked={saveGuidance[item.review_id] ?? false} onChange={event => setSaveGuidance(value => ({ ...value, [item.review_id]: event.target.checked }))} /> Save a reusable rule for this project and lens</label>