Add Legal Analysis tool — two-pass DBN-legal pipeline
Restores the dbn-legal-agent-v3 fine-tune on ocelot (was silently aliased to plain qwen2.5:14b in LiteLLM since the viper retirement) and ships a new tool that uses it via a two-pass flow: Pass 1 (Azure 4o-mini) → extract up to 5 distinct legal issues Pass 2 (ocelot v3 only) → answer each issue, ≤350 tokens, with corpus Pass 3 (Azure 4o-mini) → synthesise overall assessment + next steps The 12GB-VRAM constraint motivates the split: dbn-legal-agent-v3 stays hot in VRAM through the 5 sequential per-issue calls because issue extraction and synthesis run on Azure, not on ocelot. New surface: - includes/LegalAnalysisAgent.php - api/legal-analysis.php (NDJSON streaming endpoint) - legal-analysis.php (dedicated tool page) - assets/js/legal-analysis.js (streamed UI with per-issue cards) - Save-result + case-result.php rendering for legal-analysis output - Nav registration in all four UI languages Add-on integration: a "⚖️🇳🇴 Run deep legal analysis on this text" button now appears on Summarize, Ask, and Redact result pages and streams the same pipeline inline below the existing result. Existing tools relabelled: the misleading "🇳🇴 Norwegian specialist v3 ⭐" option on advocate/deep-research/discrepancy/barnevernet is now honestly "DBN Legal Agent" — now that the real fine-tune is actually deployed, the label finally matches reality. The advocate.php v2 option was removed since the v2 GGUF is retired. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -298,6 +298,53 @@ function crField(string $label, string $value): string {
|
||||
<?php endif; ?>
|
||||
<?= crListBlock('What Remains Uncertain', (array)($output['what_remains_uncertain'] ?? [])) ?>
|
||||
|
||||
<?php elseif ($toolSlug === 'legal-analysis'): ?>
|
||||
<?php if (!empty($output['overall_assessment'])): ?>
|
||||
<div class="cr-block">
|
||||
<h3>Overall assessment</h3>
|
||||
<p style="line-height:1.6"><?= htmlspecialchars((string)$output['overall_assessment']) ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($output['next_steps']) && is_array($output['next_steps'])): ?>
|
||||
<?= crListBlock('Next steps', $output['next_steps']) ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($output['issues']) && is_array($output['issues'])): ?>
|
||||
<div class="cr-block">
|
||||
<h3>Legal issues</h3>
|
||||
<?php foreach ($output['issues'] as $iss): if (!is_array($iss)) continue;
|
||||
$sev = (string)($iss['severity'] ?? 'medium');
|
||||
$sevColor = $sev === 'high' ? '#fee2e2' : ($sev === 'low' ? '#dcfce7' : '#fef3c7');
|
||||
$sevText = $sev === 'high' ? '#b91c1c' : ($sev === 'low' ? '#166534' : '#92400e');
|
||||
?>
|
||||
<article style="border:1px solid #d8dde7;border-radius:8px;padding:0.85rem 1rem;margin-bottom:0.75rem;">
|
||||
<div style="display:flex;gap:0.5rem;align-items:center;margin-bottom:0.4rem;">
|
||||
<span style="font-weight:700;color:#64748b;font-size:0.85rem;">#<?= (int)($iss['id'] ?? 0) ?></span>
|
||||
<span style="font-size:0.7rem;font-weight:700;letter-spacing:0.04em;padding:0.15rem 0.5rem;border-radius:999px;background:<?= $sevColor ?>;color:<?= $sevText ?>;"><?= htmlspecialchars(strtoupper($sev)) ?></span>
|
||||
</div>
|
||||
<h4 style="margin:0.2rem 0 0.4rem;font-size:1.02rem;"><?= htmlspecialchars((string)($iss['question'] ?? '')) ?></h4>
|
||||
<?php if (!empty($iss['brief_context'])): ?>
|
||||
<p style="font-size:0.85rem;color:#64748b;margin:0 0 0.5rem"><em><?= htmlspecialchars((string)$iss['brief_context']) ?></em></p>
|
||||
<?php endif; ?>
|
||||
<div style="margin-top:0.5rem;padding-top:0.5rem;border-top:1px solid #eef2f7;">
|
||||
<h5 style="margin:0 0 0.3rem;font-size:0.78rem;text-transform:uppercase;letter-spacing:0.06em;color:#64748b;">Svar (dbn-legal-agent-v3)</h5>
|
||||
<p style="margin:0;line-height:1.55;white-space:pre-wrap;"><?= htmlspecialchars((string)($iss['answer'] ?? '')) ?></p>
|
||||
</div>
|
||||
<?php if (!empty($iss['legal_basis'])): ?>
|
||||
<div style="margin-top:0.5rem;font-size:0.85rem;color:#475569;background:#f8fafc;padding:0.3rem 0.55rem;border-radius:5px;display:inline-block;">
|
||||
<strong>Lovgrunnlag:</strong> <?= htmlspecialchars((string)$iss['legal_basis']) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($iss['what_to_check'])): ?>
|
||||
<p style="margin:0.55rem 0 0;font-size:0.8rem;color:#94a3b8;"><em><?= htmlspecialchars((string)$iss['what_to_check']) ?></em></p>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($output['disclaimer'])): ?>
|
||||
<p style="font-size:0.85rem;color:#64748b;margin-top:1rem;"><em><?= htmlspecialchars((string)$output['disclaimer']) ?></em></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
<?php if ($primaryOutput !== ''): ?>
|
||||
<div class="cr-output"><?= htmlspecialchars($primaryOutput) ?></div>
|
||||
@@ -381,6 +428,7 @@ function crField(string $label, string $value): string {
|
||||
'ask': '/ask.php',
|
||||
'redact': '/redact.php',
|
||||
'transcribe': '/transcribe.php',
|
||||
'legal-analysis':'/legal-analysis.php',
|
||||
}[tool] || '/dashboard.php';
|
||||
window.location.href = path + '?rerun=' + <?= (int)$result['id'] ?>;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user