Files
daveadmin c2735fa919 Simplify advocate engine options: remove GPU/dbn_legal_v3, fix time estimates
GPU and DBN Legal Agent v3 are unsuitable for advocate synthesis (4-6K token
structured JSON output at 20-30 tok/s = 3-5 min on RTX 3060, plus both fall
through to Sonnet when Bedrock is enabled anyway). Reduce to two honest options:
Haiku (~2-4 min) and Sonnet (~3-5 min), with accurate description of why
time is dominated by multi-pass question answering, not synthesis.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:27:34 +02:00

267 lines
20 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
$toolName = 'advocate';
$toolTitle = 'Case Advocate';
$toolKind = 'Legal advocate';
$toolBadge = 'Partisan brief';
$extraScripts = ['assets/js/advocate.js'];
require_once __DIR__ . '/includes/layout.php';
?>
<form id="advocateForm" class="tool-form deep-research" enctype="multipart/form-data">
<div class="lang-switcher" id="advLangSwitcher" role="group" aria-label="UI language">
<button type="button" class="lang-btn is-active" data-lang="en">&#127468;&#127463; EN</button>
<button type="button" class="lang-btn" data-lang="no">&#127475;&#127476; NO</button>
<button type="button" class="lang-btn" data-lang="uk">&#127482;&#127462; UK</button>
<button type="button" class="lang-btn" data-lang="pl">&#127477;&#127473; PL</button>
</div>
<div class="korr-doc-links">
<a href="/advocate-about.php" target="_blank">About this tool</a>
<span aria-hidden="true">&middot;</span>
<a href="/advocate-guide.php" target="_blank">User guide</a>
<span aria-hidden="true">&middot;</span>
<a href="/advocate-tech.php" target="_blank">How it works</a>
</div>
<!-- Role selector — the defining field for advocate mode -->
<div class="adv-role-row">
<label class="control-label" for="advRoleSelect">Who are you representing?</label>
<select id="advRoleSelect" class="adv-role-select" required>
<option value="">— Select a role —</option>
<option value="Biological mother">Biological mother</option>
<option value="Biological father">Biological father</option>
<option value="Both biological parents">Both biological parents</option>
<option value="Foster carer / long-term placement">Foster carer / long-term placement</option>
<option value="Adoptive parent">Adoptive parent</option>
<option value="Child (via representative)">Child (via representative)</option>
<option value="Extended family (grandparent, sibling, aunt/uncle)">Extended family (grandparent, sibling, aunt/uncle)</option>
<option value="Child welfare services (Barnevernet)">Child welfare services (Barnevernet)</option>
<option value="__other__">Other — describe below</option>
</select>
<input type="text" id="advRoleCustom" class="adv-role-custom is-hidden"
placeholder="Describe the party you represent…" maxlength="200">
<p class="upload-hint">The agent will frame every sub-question, retrieval pass, and the final brief to argue <em>for</em> the selected party, identifying weaknesses in the opposing position and citing Lovdata statutes, ECHR judgments, and Bufdir guidance.</p>
</div>
<label class="input-label" for="advInput">Describe the dispute or case situation</label>
<textarea id="advInput" name="advInput" rows="8" placeholder="Describe the facts of the case, the dispute, and what matters most to your client. The agent will generate adversarial sub-questions, retrieve from the legal corpus and your uploaded files, and synthesise a partisan brief with citations."></textarea>
<div class="adv-input-footer">
<small id="advInputCount" class="adv-char-count">0 / 4,000</small>
</div>
<div class="control-row" id="advEngineControl">
<span class="control-label">Engine</span>
<label><input type="radio" name="advEngine" value="azure_mini" checked> &#x2601;&#xFE0F; Claude Haiku 4.5 <small class="control-hint">(fast · ~2-4 min)</small></label>
<label><input type="radio" name="advEngine" value="claude_sonnet"> &#x2601;&#xFE0F; Claude Sonnet 4.6 &#9733;&#9733; <small class="control-hint">(thorough · ~3-5 min)</small></label>
</div>
<p class="upload-hint">Both engines run on AWS Bedrock via Claude. Most of the time is spent on multiple question-answering passes — 610 sub-questions each requiring a full retrieval and answer cycle. Haiku is faster and handles most cases well. Sonnet produces a more thorough brief with deeper ECHR precedent analysis and stronger multi-party argumentation.</p>
<div class="dr-slice-section">
<p class="control-label">Corpus slices</p>
<p class="upload-hint">Three core legal slices are on by default. Enable ECHR Article&nbsp;9, Hague Convention, Norwegian Courts, Bufdir guidance, or DBN&nbsp;Resources for more targeted research.</p>
<div class="dr-slice-grid">
<button type="button" class="adv-slice is-on" data-slice="family_core" aria-pressed="true">
<div class="dr-slice__head">
<span class="dr-slice__title">Family Law Core</span>
<span class="dr-slice__badge">on</span>
</div>
<p class="dr-slice__tagline">Barneloven, custody, samvær, mediation</p>
</button>
<button type="button" class="adv-slice is-on" data-slice="child_welfare" aria-pressed="true">
<div class="dr-slice__head">
<span class="dr-slice__title">Child Welfare</span>
<span class="dr-slice__badge">on</span>
</div>
<p class="dr-slice__tagline">Barnevern, omsorgsovertakelse, foster care</p>
</button>
<button type="button" class="adv-slice is-on" data-slice="echr" aria-pressed="true">
<div class="dr-slice__head">
<span class="dr-slice__title">ECHR</span>
<span class="dr-slice__badge">on</span>
</div>
<p class="dr-slice__tagline">Art.&nbsp;8 family life, Art.&nbsp;9 religion, HUDOC vs Norway</p>
</button>
<button type="button" class="adv-slice" data-slice="hague" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">Hague Convention</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">INCADAT, cross-border abduction, wrongful removal</p>
</button>
<button type="button" class="adv-slice" data-slice="norwegian_courts" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">Norwegian Courts</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">Høyesterett + Lagmannsrett family decisions</p>
</button>
<button type="button" class="adv-slice" data-slice="bufdir_guidance" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">Bufdir Guidance</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">Bufdir, Barneombudet, Statsforvalteren guidance</p>
</button>
<button type="button" class="adv-slice" data-slice="broader_legal" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">Broader Legal Support</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">Arbeidsmiljøloven, NOUer, statutes, government background</p>
</button>
<button type="button" class="adv-slice" data-slice="dbn_resources" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">DBN Resources</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">Do Better Norge guides, flashcards, resource directory</p>
</button>
</div>
</div>
<details class="advanced-panel" id="advAdvanced">
<summary class="advanced-toggle">Advanced controls</summary>
<div class="dr-control-grid">
<div class="dr-control-card">
<label>Sub-questions <span id="advSubQValue" class="dr-control-value">4</span></label>
<input type="range" id="advSubQ" min="3" max="5" step="1" value="4">
<small>How many angles the agent generates (each framed to strengthen your case).</small>
</div>
<div class="dr-control-card">
<label>Chunks / sub-Q <span id="advChunkLimitValue" class="dr-control-value">6</span></label>
<input type="range" id="advChunkLimit" min="4" max="10" step="1" value="6">
<small>Corpus chunks retrieved per sub-question.</small>
</div>
<div class="dr-control-card">
<label>Similarity floor <span id="advSimValue" class="dr-control-value">0.30</span></label>
<input type="range" id="advSim" min="0.20" max="0.60" step="0.05" value="0.30">
<small>Minimum similarity for uploaded-doc chunks to be included.</small>
</div>
<div class="dr-control-card">
<label>Sources kept <span id="advTopKValue" class="dr-control-value">12</span></label>
<input type="range" id="advTopK" min="8" max="14" step="1" value="12">
<small>Top sources kept after dedupe + rerank to feed synthesis.</small>
</div>
<div class="dr-control-card">
<label>Temperature <span id="advTempValue" class="dr-control-value">0.15</span></label>
<input type="range" id="advTemp" min="0.05" max="0.40" step="0.05" value="0.15">
<small>Keep low for grounded legal briefs.</small>
</div>
</div>
</details>
<div id="docPickerSection" class="doc-picker-section">
<button type="button" id="docPickerBtn" class="doc-picker-btn" aria-haspopup="dialog">
<svg class="doc-picker-btn__icon" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><rect x="2" y="1" width="9" height="12" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M5 5h5M5 8h3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><rect x="7" y="9" width="6" height="5" rx="1" fill="white" stroke="currentColor" stroke-width="1.3"/><path d="M9 11h2M9 12.5h1" stroke="currentColor" stroke-width="1" stroke-linecap="round"/></svg>
<span><?= htmlspecialchars(dbnToolsT('doc_picker_btn', $uiLang)) ?></span>
</button>
<div id="docPickerChips" class="doc-picker-chips" aria-label="Selected documents"></div>
<input type="hidden" id="docPickerIds" name="doc_ids" value="">
</div>
<div class="upload-zone" id="advUploadZone" role="region" aria-label="File upload">
<input type="file" id="advUploadInput" multiple accept=".pdf,.docx,.txt" aria-label="Choose files">
<div id="advUploadPrompt" class="upload-prompt">
<span class="upload-icon" aria-hidden="true">&#8679;</span>
<p>Drop case files here, or <label for="advUploadInput" class="upload-browse">browse</label></p>
<p class="upload-hint"><strong>PDF</strong>, <strong>DOCX</strong>, <strong>TXT</strong> &mdash; up to 5 files &mdash; chunked + embedded in memory only, never stored.</p>
</div>
<div id="advUploadFileInfo" class="upload-file is-hidden">
<ul id="advUploadFileList" class="upload-file-list"></ul>
<button type="button" id="advUploadClear" class="upload-clear">&times; Clear</button>
</div>
</div>
<div id="advBranchPanel" class="branch-panel is-hidden" aria-label="Branch context">
<div class="branch-panel__head">
<span class="branch-panel__label">Branching from sub-question</span>
<button type="button" id="advBranchClear" class="upload-clear">&times; Clear branch</button>
</div>
<p id="advBranchOrigin" class="branch-panel__origin"></p>
<details class="branch-panel__prior">
<summary>Prior brief summary</summary>
<div id="advBranchSummary" class="branch-panel__brief"></div>
</details>
<label class="input-label" for="advBranchNotes">Add your notes / context</label>
<textarea id="advBranchNotes" rows="3" placeholder="Optional: add observations, corrections, or additional context for this branch…"></textarea>
</div>
<!-- Sub-question preview panel (hidden until "Preview angles" is clicked) -->
<div id="advSubQPreview" class="adv-subq-preview is-hidden" aria-live="polite">
<h4 class="adv-subq-preview__head">Generated research angles — review &amp; edit</h4>
<p class="upload-hint">The agent will research these angles against the corpus. Edit any question before running to steer retrieval.</p>
<div id="advSubQPreviewList"></div>
<div class="adv-subq-preview__actions">
<button type="button" id="advRunWithAngles">Run with these angles</button>
<button type="button" id="advDiscardAngles" class="adv-discard-btn">Discard &amp; run fresh</button>
</div>
</div>
<?php require __DIR__ . '/includes/case_toggle.php'; ?>
<div class="form-footer">
<p id="advStatus" class="form-status" role="status" aria-live="polite"></p>
<div class="form-footer__btns">
<button id="advRunButton" type="submit">Research my case</button>
<button type="button" id="advPreviewAngles" class="adv-preview-btn">Preview research angles first</button>
</div>
</div>
</form>
<section id="advResults" class="results deep-research-results" aria-live="polite">
<div class="empty-state">
<h3>Ready</h3>
<p>Select who you are representing, describe the dispute, and optionally upload case documents. The agent will argue your side — identifying supporting statutes, ECHR judgments, and weaknesses in the opposing position.</p>
</div>
</section>
<!-- Source modal -->
<div id="advSourceModal" class="dr-source-modal is-hidden" role="dialog" aria-modal="true" aria-labelledby="advSourceModalTitle">
<div class="dr-source-modal__dialog">
<header class="dr-source-modal__head">
<div>
<p class="eyebrow" id="advSourceModalEyebrow">Source</p>
<h3 id="advSourceModalTitle"></h3>
</div>
<button type="button" id="advSourceModalClose" class="upload-clear" aria-label="Close">&times;</button>
</header>
<div class="dr-source-modal__body">
<aside class="dr-source-modal__meta" id="advSourceModalMeta"></aside>
<div class="dr-source-modal__text" id="advSourceModalText"></div>
</div>
</div>
</div>
<!-- Hidden stubs so tools.js element refs don't crash on this page -->
<div class="is-hidden" id="languageControl" aria-hidden="true">
<input type="radio" name="language" value="en" checked>
<input type="radio" name="language" value="no">
<input type="radio" name="language" value="uk">
<input type="radio" name="language" value="pl">
</div>
<div class="is-hidden" id="redactionControl" aria-hidden="true"></div>
<div class="is-hidden" id="audioZone" aria-hidden="true">
<input type="file" id="audioInput" style="display:none">
<div id="audioPrompt"></div>
<div id="audioFileInfo"><ol id="audioQueueList"></ol><button type="button" id="audioClear"></button></div>
</div>
<div class="is-hidden" id="diarizeControl" aria-hidden="true">
<input type="checkbox" id="diarizeCheck">
<input type="number" id="numSpeakersInput">
</div>
<div class="is-hidden" id="transcribeLangControl" aria-hidden="true"><input type="radio" name="transcribeLang" value="no" checked></div>
<div class="is-hidden" id="vocabControl" aria-hidden="true">
<div id="vocabPresets"></div>
<textarea id="initPromptInput"></textarea>
</div>
<div class="is-hidden" id="aliasSection" aria-hidden="true">
<button type="button" id="addAliasRow"></button>
<div id="aliasRows"></div>
</div>
<div class="is-hidden" id="exemptSection" aria-hidden="true">
<button type="button" id="addExemptRow"></button>
<div id="exemptRows"></div>
</div>
<?php require_once __DIR__ . '/includes/layout_footer.php'; ?>