640778454f
New /advocate.php tab: user selects who they represent (biological father, mother, foster carer, CWS, etc.) and the agent takes their side entirely. Adversarial sub-questions target supporting Lovdata statutes + ECHR precedents; synthesis returns client_strengths[] and opposing_weaknesses[] alongside the advocate brief. - DeepResearchAgent: add advocateRole param to run(), interpretSeed(), expandQueries(), synthesise(). Neutral path unchanged (empty string). - api/deep-research.php: extract + validate advocate_role from payload; telemetry logs tool='advocate' vs 'deep_research'. - advocate.php: new page with role dropdown (presets + custom), same corpus slices/engine/controls/upload zone as deep research. - assets/js/advocate.js: page-scoped JS; renders advocate banner, client strengths card (teal), advocate brief, opposing weaknesses card (amber), sub-Q cards, sources, uncertainty, next step. - assets/css/tools.css: append .adv-* rules (~120 lines). - includes/layout.php: add Advocate nav tab between Deep research and Summarize. - index.php: add Advocate cap-card tile. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
71 lines
2.9 KiB
PHP
71 lines
2.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
// Required vars: $toolName (string), $toolTitle (string), $toolKind (string), $toolBadge (string)
|
|
require_once __DIR__ . '/bootstrap.php';
|
|
if (!dbnToolsIsAuthenticated()) {
|
|
$return = urlencode($_SERVER['REQUEST_URI'] ?? '/');
|
|
header('Location: /?return=' . $return);
|
|
exit;
|
|
}
|
|
|
|
$navItems = [
|
|
'ask' => ['Ask', 'Source-grounded'],
|
|
'search' => ['Search', 'Legal sources'],
|
|
'deep-research' => ['Deep research', 'Agent + RAG'],
|
|
'advocate' => ['Advocate', 'Take a side'],
|
|
'summarize' => ['Summarize', 'Pasted text'],
|
|
'timeline' => ['Timeline', 'Events'],
|
|
'redact' => ['Redact', 'Privacy'],
|
|
'transcribe' => ['Transcribe', 'Audio'],
|
|
'corpus' => ['Corpus', 'Data & stack'],
|
|
];
|
|
$toolName = $toolName ?? 'ask';
|
|
$toolTitle = $toolTitle ?? 'Legal Tools';
|
|
$toolKind = $toolKind ?? '';
|
|
$toolBadge = $toolBadge ?? '';
|
|
?>
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title><?= htmlspecialchars($toolTitle) ?> — Do Better Norge</title>
|
|
<link rel="stylesheet" href="assets/css/tools.css">
|
|
</head>
|
|
<body data-authenticated="true" data-active-tool="<?= htmlspecialchars($toolName) ?>">
|
|
<script>window.DBN_TOOLS_AUTHENTICATED = true;</script>
|
|
<main id="appShell" class="app-shell">
|
|
<header class="topbar">
|
|
<div>
|
|
<p class="eyebrow">Do Better Norge</p>
|
|
<h1>Legal Tools</h1>
|
|
</div>
|
|
<div class="topbar-actions">
|
|
<span id="healthPill" class="status-pill">Session active</span>
|
|
<button id="healthButton" class="secondary-button" type="button">Health</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="disclaimer" role="note">
|
|
Legal information and preparation support, not final legal advice. Pasted text is processed in memory by default.
|
|
</div>
|
|
|
|
<section class="workspace" aria-label="Legal tools workspace">
|
|
<nav class="tool-rail" aria-label="Tools">
|
|
<?php foreach ($navItems as $slug => [$label, $sub]): ?>
|
|
<a href="<?= $slug ?>.php" class="tool-tab<?= $slug === $toolName ? ' is-active' : '' ?>" data-tool="<?= $slug ?>"<?= $slug === $toolName ? ' aria-current="page"' : '' ?>>
|
|
<span><?= $label ?></span>
|
|
<small><?= $sub ?></small>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</nav>
|
|
|
|
<section class="tool-panel" aria-labelledby="toolTitle">
|
|
<div class="tool-heading">
|
|
<div>
|
|
<p id="toolKind" class="eyebrow"><?= htmlspecialchars($toolKind) ?></p>
|
|
<h2 id="toolTitle"><?= htmlspecialchars($toolTitle) ?></h2>
|
|
</div>
|
|
<span id="toolBadge" class="tool-badge"><?= htmlspecialchars($toolBadge) ?></span>
|
|
</div>
|