Add Document Discrepancy Finder tool
8-step NDJSON-streaming pipeline that compares two Barnevernet documents: classifies each doc, extracts parties and timelines, cross-references both for contradictions/deletions/additions, retrieves corpus legal context, and synthesises a full discrepancy report with tabbed UI. New files: DiscrepancyAgent.php, api/discrepancy.php, discrepancy.php, discrepancy.js. Modified: FreeTier.php (cost=4), i18n.php (all 4 langs), tool-svgs.php (DC icon), tools.css (dc-* component styles). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ final class FreeTier
|
||||
'advocate' => 3,
|
||||
'deep-research' => 5,
|
||||
'transcribe' => 2, // flat rate; actual duration unknown upfront
|
||||
'discrepancy' => 4, // 2 docs × 4 extraction steps + cross-ref + synthesis
|
||||
];
|
||||
|
||||
/** Credit cost for a given tool slug. Returns 1 for unknown tools. */
|
||||
|
||||
+12
-7
@@ -444,6 +444,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'barnevernet' => ['BVJ Analyzer', 'Barnevernet documents', 'Analyze child-welfare documents from your perspective with procedural red flags and citations.', 'Document + RAG'],
|
||||
'advocate' => ['Advocate', 'Partisan brief', 'Choose who you represent and generate a source-grounded brief for that position.', 'ECHR + Lovdata'],
|
||||
'deep-research' => ['Deep Research', 'Agent + RAG', 'Expand a question into research angles, search legal slices, and synthesize a cited brief.', 'Family-legal'],
|
||||
'discrepancy' => ['Discrepancy Finder', 'Document comparison', 'Upload two versions of a Barnevernet document and find contradictions, deleted facts, and new allegations.', 'Cross-document AI'],
|
||||
'corpus' => ['Corpus', 'Legal knowledge base', 'Inspect indexed sources, corpus health, legal categories, and retrieval behavior.', '~220 K passages'],
|
||||
],
|
||||
'no' => [
|
||||
@@ -453,6 +454,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'barnevernet' => ['BVJ-analyse', 'Barnevernsdokumenter', 'Analyser barnevernsdokumenter fra ditt perspektiv med prosessuelle røde flagg og kilder.', 'Dokument + RAG'],
|
||||
'advocate' => ['Advokatmodus', 'Partsinnlegg', 'Velg hvem du representerer og lag et kildebelagt innlegg for den posisjonen.', 'EMD + Lovdata'],
|
||||
'deep-research' => ['Dyp research', 'Agent + RAG', 'Utvid et spørsmål til forskningsvinkler, søk juridiske kilder og lag et kildebelagt notat.', 'Familierett'],
|
||||
'discrepancy' => ['Avviksfinner', 'Dokumentsammenligning', 'Last opp to versjoner av et barneverndokument og finn motsigelser, slettede fakta og nye påstander.', 'Kryssdokument AI'],
|
||||
'corpus' => ['Korpus', 'Juridisk kunnskapsbase', 'Se indekserte kilder, korpushelse, juridiske kategorier og søkeoppsett.', '~220 K utdrag'],
|
||||
],
|
||||
'uk' => [
|
||||
@@ -462,6 +464,7 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'barnevernet' => ['BVJ аналізатор', 'Документи Barnevernet', 'Аналізуйте документи захисту дітей з вашої позиції, з процесуальними ризиками та джерелами.', 'Документ + RAG'],
|
||||
'advocate' => ['Адвокат', 'Позиційний бриф', 'Оберіть, кого представляєте, і створіть бриф із джерелами на підтримку цієї позиції.', 'ЄСПЛ + Lovdata'],
|
||||
'deep-research' => ['Глибоке дослідження', 'Agent + RAG', 'Розгортає питання в дослідницькі напрями, шукає юридичні джерела та створює бриф.', 'Сімейне право'],
|
||||
'discrepancy' => ['Пошук розбіжностей', 'Порівняння документів', 'Завантажте дві версії документа Barnevernet і знайдіть суперечності, видалені факти та нові твердження.', 'Міждокументний AI'],
|
||||
'corpus' => ['Корпус', 'Юридична база знань', 'Переглядайте індексовані джерела, стан корпусу, категорії та поведінку пошуку.', '~220 тис. уривків'],
|
||||
],
|
||||
'pl' => [
|
||||
@@ -471,20 +474,22 @@ function dbnToolsLaunchedTools(?string $language = null): array
|
||||
'barnevernet' => ['Analizator BVJ', 'Dokumenty Barnevernet', 'Analizuj dokumenty opieki nad dziećmi z Twojej perspektywy, z ryzykami proceduralnymi i źródłami.', 'Dokument + RAG'],
|
||||
'advocate' => ['Adwokat', 'Stronniczy brief', 'Wybierz, kogo reprezentujesz, i wygeneruj brief oparty na źródłach dla tej pozycji.', 'ETPC + Lovdata'],
|
||||
'deep-research' => ['Głębokie badanie', 'Agent + RAG', 'Rozwija pytanie w kierunki badawcze, przeszukuje źródła prawne i tworzy brief z cytatami.', 'Prawo rodzinne'],
|
||||
'discrepancy' => ['Wyszukiwacz rozbieżności', 'Porównanie dokumentów', 'Prześlij dwie wersje dokumentu Barnevernet i znajdź sprzeczności, usunięte fakty i nowe zarzuty.', 'AI Między-dokumentowe'],
|
||||
'corpus' => ['Korpus', 'Prawna baza wiedzy', 'Sprawdzaj indeksowane źródła, stan korpusu, kategorie prawne i działanie wyszukiwania.', '~220 tys. fragmentów'],
|
||||
],
|
||||
];
|
||||
|
||||
$selected = $copy[$language] ?? $copy['en'];
|
||||
$order = ['transcribe', 'timeline', 'redact', 'barnevernet', 'advocate', 'deep-research', 'corpus'];
|
||||
$order = ['transcribe', 'timeline', 'redact', 'barnevernet', 'advocate', 'deep-research', 'discrepancy', 'corpus'];
|
||||
$icons = [
|
||||
'transcribe' => 'TR',
|
||||
'timeline' => 'TL',
|
||||
'redact' => 'RX',
|
||||
'barnevernet' => 'BVJ',
|
||||
'advocate' => 'ADV',
|
||||
'transcribe' => 'TR',
|
||||
'timeline' => 'TL',
|
||||
'redact' => 'RX',
|
||||
'barnevernet' => 'BVJ',
|
||||
'advocate' => 'ADV',
|
||||
'deep-research' => 'DR',
|
||||
'corpus' => 'KB',
|
||||
'discrepancy' => 'DC',
|
||||
'corpus' => 'KB',
|
||||
];
|
||||
$out = [];
|
||||
foreach ($order as $slug) {
|
||||
|
||||
@@ -16,5 +16,7 @@ $toolSvgs = [
|
||||
|
||||
'deep-research' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 178" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><rect width="480" height="178" fill="#00205b"/><g stroke="rgba(244,197,66,0.24)" stroke-width="1.5" fill="none"><line x1="88" y1="48" x2="178" y2="88"/><line x1="88" y1="48" x2="88" y2="138"/><line x1="88" y1="138" x2="178" y2="88"/><line x1="178" y1="88" x2="268" y2="48"/><line x1="178" y1="88" x2="268" y2="138"/><line x1="268" y1="48" x2="268" y2="138"/><line x1="268" y1="48" x2="358" y2="68"/><line x1="268" y1="138" x2="358" y2="128"/></g><circle cx="88" cy="48" r="10" fill="rgba(244,197,66,0.68)"/><circle cx="88" cy="138" r="8" fill="rgba(255,255,255,0.46)"/><circle cx="178" cy="88" r="13" fill="#f4c542"/><circle cx="268" cy="48" r="9" fill="rgba(255,255,255,0.46)"/><circle cx="268" cy="138" r="8" fill="rgba(244,197,66,0.56)"/><circle cx="358" cy="68" r="9" fill="rgba(255,255,255,0.38)"/><circle cx="358" cy="128" r="8" fill="rgba(244,197,66,0.46)"/><circle cx="358" cy="88" r="44" fill="none" stroke="rgba(255,255,255,0.55)" stroke-width="3"/><line x1="392" y1="122" x2="424" y2="154" stroke="rgba(255,255,255,0.55)" stroke-width="4" stroke-linecap="round"/><circle cx="350" cy="80" r="6" fill="rgba(244,197,66,0.88)"/><circle cx="370" cy="96" r="5" fill="rgba(255,255,255,0.78)"/><line x1="350" y1="80" x2="370" y2="96" stroke="rgba(244,197,66,0.46)" stroke-width="1.5"/></svg>',
|
||||
|
||||
'discrepancy' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 178" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><rect width="480" height="178" fill="#00205b"/><rect x="0" y="0" width="480" height="6" fill="rgba(186,12,47,0.18)"/><rect x="0" y="172" width="480" height="6" fill="rgba(186,12,47,0.18)"/><rect x="60" y="24" width="144" height="132" rx="4" fill="rgba(0,0,0,0.20)"/><rect x="57" y="21" width="144" height="132" rx="4" fill="#fff" opacity="0.97"/><rect x="57" y="21" width="144" height="26" rx="4" fill="#00205b"/><rect x="57" y="38" width="144" height="9" fill="#00205b"/><line x1="72" y1="32" x2="130" y2="32" stroke="rgba(255,255,255,0.58)" stroke-width="1.5"/><line x1="72" y1="60" x2="186" y2="60" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><line x1="72" y1="72" x2="172" y2="72" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><rect x="57" y="80" width="144" height="13" fill="rgba(244,197,66,0.20)"/><line x1="72" y1="87" x2="180" y2="87" stroke="rgba(244,197,66,0.68)" stroke-width="1.5"/><line x1="72" y1="103" x2="178" y2="103" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><line x1="72" y1="115" x2="164" y2="115" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><line x1="72" y1="127" x2="174" y2="127" stroke="rgba(186,12,47,0.28)" stroke-width="1.5" stroke-dasharray="22,4"/><line x1="72" y1="139" x2="148" y2="139" stroke="rgba(0,0,0,0.07)" stroke-width="1.5"/><text x="129" y="17" text-anchor="middle" font-family="monospace" font-size="8" fill="rgba(244,197,66,0.68)">DOC A</text><line x1="215" y1="87" x2="265" y2="87" stroke="rgba(186,12,47,0.70)" stroke-width="2" stroke-dasharray="5,3"/><polygon points="260,83 268,87 260,91" fill="rgba(186,12,47,0.70)"/><text x="240" y="82" text-anchor="middle" font-family="monospace" font-size="9" fill="rgba(186,12,47,0.82)">≠</text><line x1="215" y1="127" x2="265" y2="93" stroke="rgba(186,12,47,0.28)" stroke-width="1" stroke-dasharray="3,3"/><rect x="276" y="24" width="144" height="132" rx="4" fill="rgba(0,0,0,0.20)"/><rect x="273" y="21" width="144" height="132" rx="4" fill="#fff" opacity="0.97"/><rect x="273" y="21" width="144" height="26" rx="4" fill="#00205b"/><rect x="273" y="38" width="144" height="9" fill="#00205b"/><line x1="288" y1="32" x2="346" y2="32" stroke="rgba(255,255,255,0.58)" stroke-width="1.5"/><line x1="288" y1="60" x2="402" y2="60" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><line x1="288" y1="72" x2="388" y2="72" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><rect x="273" y="80" width="144" height="13" fill="rgba(186,12,47,0.13)"/><line x1="288" y1="87" x2="396" y2="87" stroke="rgba(186,12,47,0.55)" stroke-width="1.5"/><line x1="288" y1="103" x2="394" y2="103" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><line x1="288" y1="115" x2="380" y2="115" stroke="rgba(0,0,0,0.09)" stroke-width="1.5"/><rect x="273" y="123" width="144" height="13" fill="rgba(244,197,66,0.10)"/><line x1="288" y1="130" x2="390" y2="130" stroke="rgba(244,197,66,0.42)" stroke-width="1.5"/><line x1="288" y1="143" x2="368" y2="143" stroke="rgba(0,0,0,0.07)" stroke-width="1.5"/><text x="345" y="17" text-anchor="middle" font-family="monospace" font-size="8" fill="rgba(244,197,66,0.68)">DOC B</text></svg>',
|
||||
|
||||
'corpus' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 178" preserveAspectRatio="xMidYMid slice" aria-hidden="true"><rect width="480" height="178" fill="#00205b"/><g stroke="rgba(244,197,66,0.28)" stroke-width="1.5" fill="none"><line x1="286" y1="54" x2="376" y2="36"/><line x1="286" y1="89" x2="390" y2="89"/><line x1="286" y1="124" x2="376" y2="143"/></g><circle cx="382" cy="36" r="16" fill="rgba(244,197,66,0.15)" stroke="rgba(244,197,66,0.38)" stroke-width="1.5"/><circle cx="396" cy="89" r="13" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.22)" stroke-width="1.5"/><circle cx="382" cy="143" r="16" fill="rgba(186,12,47,0.14)" stroke="rgba(186,12,47,0.34)" stroke-width="1.5"/><text x="382" y="40" text-anchor="middle" font-family="monospace" font-size="8" fill="rgba(244,197,66,0.72)">ECHR</text><text x="396" y="93" text-anchor="middle" font-family="monospace" font-size="7" fill="rgba(255,255,255,0.52)">LOV</text><text x="382" y="147" text-anchor="middle" font-family="monospace" font-size="7" fill="rgba(255,200,200,0.52)">BVJ</text><ellipse cx="196" cy="40" rx="78" ry="13" fill="rgba(0,18,56,0.94)" stroke="rgba(244,197,66,0.68)" stroke-width="1.5"/><rect x="118" y="40" width="156" height="26" fill="rgba(0,14,46,0.96)"/><ellipse cx="196" cy="66" rx="78" ry="13" fill="rgba(0,12,40,0.96)" stroke="rgba(244,197,66,0.48)" stroke-width="1.5"/><text x="196" y="58" text-anchor="middle" font-family="monospace" font-size="9" fill="rgba(244,197,66,0.62)">220K PASSAGES</text><ellipse cx="196" cy="78" rx="78" ry="13" fill="rgba(0,28,76,0.94)" stroke="rgba(255,255,255,0.36)" stroke-width="1.5"/><rect x="118" y="78" width="156" height="26" fill="rgba(0,12,46,0.96)"/><ellipse cx="196" cy="104" rx="78" ry="13" fill="rgba(0,10,38,0.96)" stroke="rgba(255,255,255,0.26)" stroke-width="1.5"/><text x="196" y="96" text-anchor="middle" font-family="monospace" font-size="9" fill="rgba(255,255,255,0.46)">QDRANT + AZURE</text><ellipse cx="196" cy="116" rx="78" ry="13" fill="rgba(186,12,47,0.18)" stroke="rgba(186,12,47,0.48)" stroke-width="1.5"/><rect x="118" y="116" width="156" height="20" fill="rgba(100,4,18,0.14)"/><ellipse cx="196" cy="136" rx="78" ry="13" fill="rgba(80,3,14,0.20)" stroke="rgba(186,12,47,0.32)" stroke-width="1.5"/><text x="196" y="130" text-anchor="middle" font-family="monospace" font-size="9" fill="rgba(255,170,170,0.48)">NOMIC EMBED</text></svg>',
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user