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:
@@ -9267,3 +9267,133 @@ body.lt-landing {
|
||||
font-size: 0.82rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ── Legal Analysis tool ─────────────────────────────────────────────────── */
|
||||
.la-pipeline {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.2rem;
|
||||
padding: 0.6rem 0.75rem;
|
||||
background: #f5f7fb;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e2e7ef;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.la-step {
|
||||
padding: 0.3rem 0.7rem;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
border: 1px solid #d8dde7;
|
||||
}
|
||||
.la-step.running {
|
||||
border-color: #f59e0b;
|
||||
background: #fffbeb;
|
||||
animation: la-pulse 1.4s ease-in-out infinite;
|
||||
}
|
||||
.la-step.done {
|
||||
border-color: #16a34a;
|
||||
background: #f0fdf4;
|
||||
color: #15803d;
|
||||
}
|
||||
@keyframes la-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }
|
||||
|
||||
.la-issues {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
.la-issue {
|
||||
border: 1px solid #d8dde7;
|
||||
border-radius: 8px;
|
||||
padding: 0.9rem 1rem;
|
||||
background: #fff;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.la-issue.pending { opacity: 0.7; border-style: dashed; }
|
||||
.la-issue.running {
|
||||
border-color: #f59e0b;
|
||||
box-shadow: 0 0 0 2px rgba(245,158,11,0.15);
|
||||
}
|
||||
.la-issue.answered {
|
||||
border-color: #cbd5e1;
|
||||
}
|
||||
.la-issue__head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
.la-issue__num {
|
||||
display: inline-block;
|
||||
min-width: 1.8rem;
|
||||
font-weight: 700;
|
||||
color: #64748b;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.la-severity {
|
||||
display: inline-block;
|
||||
padding: 0.15rem 0.5rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.la-severity-high { background: #fee2e2; color: #b91c1c; }
|
||||
.la-severity-medium { background: #fef3c7; color: #92400e; }
|
||||
.la-severity-low { background: #dcfce7; color: #166534; }
|
||||
.la-issue__q {
|
||||
margin: 0.2rem 0 0.4rem;
|
||||
font-size: 1.02rem;
|
||||
color: #1e293b;
|
||||
}
|
||||
.la-issue__ctx {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
color: #64748b;
|
||||
}
|
||||
.la-issue__status {
|
||||
font-size: 0.85rem;
|
||||
color: #f59e0b;
|
||||
font-style: italic;
|
||||
}
|
||||
.la-issue__answer {
|
||||
margin-top: 0.6rem;
|
||||
padding-top: 0.6rem;
|
||||
border-top: 1px solid #eef2f7;
|
||||
}
|
||||
.la-issue__answer h5 {
|
||||
margin: 0 0 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: #64748b;
|
||||
}
|
||||
.la-issue__answer p { margin: 0; line-height: 1.55; color: #1e293b; }
|
||||
.la-issue__basis {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
padding: 0.3rem 0.55rem;
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
.la-issue__check {
|
||||
margin: 0.55rem 0 0;
|
||||
font-size: 0.8rem;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.la-synthesis {
|
||||
margin-bottom: 1.4rem;
|
||||
padding: 1rem 1.2rem;
|
||||
border-left: 4px solid var(--dbn-teal, #0f766e);
|
||||
background: #ecfeff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.la-synthesis h3 { margin-top: 0; color: #0e7490; }
|
||||
.la-synthesis h4 { margin: 0.9rem 0 0.4rem; font-size: 0.95rem; color: #155e75; }
|
||||
|
||||
Reference in New Issue
Block a user