Files
dobetternorge-tools/summarize.php
T
daveadmin a8b1bb87a6 feat(tools): converge two-tier Quick/Pro selector onto .no fork
Port the dobetterlegal-tools two-tier quality stack to dobetternorge.no:
QUALITY_TIERS registry + resolveTier (ToolModels), dbnToolsResolveToolRun
(bootstrap), tier read+charge in the 6 analytical endpoints, Quick/Pro
UI + payload.tier on the 6 tool pages/JS, and the bounded
corpusContextForSummarize RAG fix (per-passage trim + total budget +
reranker_enabled). Back-compat: requests without `tier` keep legacy
engine behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 12:23:46 +02:00

171 lines
13 KiB
PHP

<?php
declare(strict_types=1);
$toolName = 'summarize';
$toolTitle = 'Summarize a document';
$toolKind = 'Document Summarizer';
$toolBadge = 'Process-and-forget';
$extraScripts = ['assets/js/summarize.js'];
require_once __DIR__ . '/includes/layout.php';
?>
<form id="sumForm" class="tool-form" novalidate>
<div class="lang-switcher" id="sumLangSwitcher" role="group" aria-label="UI language">
<button type="button" class="lang-btn sum-lang-btn is-active" data-lang="en">&#127468;&#127463; EN</button>
<button type="button" class="lang-btn sum-lang-btn" data-lang="no">&#127475;&#127476; NO</button>
<button type="button" class="lang-btn sum-lang-btn" data-lang="uk">&#127482;&#127462; UK</button>
<button type="button" class="lang-btn sum-lang-btn" data-lang="pl">&#127477;&#127473; PL</button>
</div>
<div class="control-row" id="sumTierControl">
<span class="control-label">Quality</span>
<label><input type="radio" name="sumTier" value="quick" checked> Quick &#9733; <small class="control-hint">(Claude Haiku · fast · 1 credit)</small></label>
<label><input type="radio" name="sumTier" value="pro"> Pro <small class="control-hint">(Claude Sonnet · best · 2 credits)</small></label>
</div>
<p class="upload-hint">Quick uses Claude Haiku 4.5 — fast and highly accurate (1 credit). Pro uses Claude Sonnet 4.6 — best for complex multi-statute documents (2 credits).</p>
<div class="control-row" id="sumDepthControl">
<span class="control-label">Summary depth</span>
<label><input type="radio" name="sumDepth" value="brief"> Brief</label>
<label><input type="radio" name="sumDepth" value="standard" checked> Standard &#9733;</label>
<label><input type="radio" name="sumDepth" value="detailed"> Detailed</label>
</div>
<p class="upload-hint">Brief: 1-2 sentence executive summary. Standard: balanced summary with all key facts. Detailed: comprehensive &#8212; covers every fact, party, date, and legal reference.</p>
<details class="advanced-panel" id="sumSlicesPanel">
<summary class="advanced-toggle">Legal corpus enrichment <small class="control-hint">(optional)</small></summary>
<p class="upload-hint">When one or more slices are enabled, the tool searches the Do Better Norge legal corpus for relevant passages and prepends them to the prompt. All slices are off by default — enable only what applies to your document.</p>
<div class="dr-slice-grid">
<button type="button" class="adv-slice sum-slice" data-slice="child_welfare" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">Child Welfare</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">Barnevern, omsorgsovertakelse, foster care</p>
</button>
<button type="button" class="adv-slice sum-slice" data-slice="echr" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">ECHR</span>
<span class="dr-slice__badge">off</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 sum-slice" data-slice="family_core" aria-pressed="false">
<div class="dr-slice__head">
<span class="dr-slice__title">Family Law Core</span>
<span class="dr-slice__badge">off</span>
</div>
<p class="dr-slice__tagline">Barneloven, custody, samvær, mediation</p>
</button>
<button type="button" class="adv-slice sum-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 sum-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 sum-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 sum-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 sum-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>
</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="sumUploadZone" role="region" aria-label="File upload">
<input type="file" id="sumUploadInput" multiple accept=".pdf,.docx,.txt" aria-label="Choose files to summarize">
<div id="sumUploadPrompt" class="upload-prompt">
<span class="upload-icon" aria-hidden="true">&#8679;</span>
<p>Drop up to 5 files here, or <label for="sumUploadInput" class="upload-browse">browse</label></p>
<p class="upload-hint"><strong>PDF</strong>, <strong>DOCX</strong>, <strong>TXT</strong> &mdash; text extracted in memory, never stored</p>
</div>
<div id="sumUploadFileInfo" class="upload-file is-hidden">
<ul id="sumUploadFileList" class="upload-file-list"></ul>
<button type="button" id="sumUploadClear" class="upload-clear">&times; Clear files</button>
</div>
</div>
<label class="input-label" for="sumInput">Pasted text <small class="control-hint">(optional if file or doc selected)</small></label>
<textarea id="sumInput" name="text" rows="8" placeholder="Paste a case note, court decision, letter, or any document text. You can also upload a file or select from My Docs above — at least one source is required."></textarea>
<div class="form-footer">
<p id="sumStatus" class="form-status" role="status" aria-live="polite"></p>
<button id="sumRunButton" type="submit">Summarize</button>
</div>
</form>
<section id="sumResults" class="results" aria-live="polite">
<div class="empty-state">
<h3>Ready</h3>
<p>Upload a file, select from My Docs, or paste text — then click Summarize. Enable corpus slices to enrich the summary with relevant legal passages.</p>
</div>
</section>
<!-- 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>
<div class="is-hidden" id="uploadZone" aria-hidden="true">
<input type="file" id="uploadInput">
<div id="uploadPrompt"></div>
<div id="uploadFileInfo"><ul id="uploadFileList"></ul><button type="button" id="uploadClear"></button></div>
</div>
<?php require_once __DIR__ . '/includes/layout_footer.php'; ?>