Add user context notes field to timeline tool

Adds an optional textarea below the main text input where users can provide
clarifications to guide the LLM — e.g. year anchors, actor aliases, or focus
instructions. Notes are injected into the prompt as a clearly delimited block
and translated across all four UI languages (en/no/uk/pl).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 12:36:37 +02:00
parent dfb9692f45
commit 28932297b3
4 changed files with 28 additions and 3 deletions
+2 -1
View File
@@ -27,6 +27,7 @@ dbnToolsWithTelemetry('timeline', $language, function () use ($input, $language)
$includeRelative = ($input['include_relative'] ?? true) !== false; $includeRelative = ($input['include_relative'] ?? true) !== false;
$includeBackground = ($input['include_background'] ?? true) !== false; $includeBackground = ($input['include_background'] ?? true) !== false;
$userNotes = dbnToolsString($input, 'user_notes', 2000, false);
return (new DbnLegalToolsService())->timeline($text, $language, $engine, $focus, $confidenceFilter, $includeRelative, $includeBackground); return (new DbnLegalToolsService())->timeline($text, $language, $engine, $focus, $confidenceFilter, $includeRelative, $includeBackground, $userNotes);
}); });
+13
View File
@@ -260,6 +260,9 @@ const TIMELINE_I18N = {
sortDocOrder: 'Document order', sortDocOrder: 'Document order',
sortChronological: 'Chronological', sortChronological: 'Chronological',
timelineExportCsv: 'Download CSV', timelineExportCsv: 'Download CSV',
timelineNotesLabel: 'Context notes',
timelineNotesPlaceholder: 'Add any clarifications to guide the AI — e.g. "All dates are 2024", "Focus on the mother\'s actions", "D refers to the defendant throughout".',
timelineNotesHint: 'These notes are included in the prompt to help the model interpret ambiguous dates, actors, or abbreviations. Not stored.',
}, },
no: { no: {
timelineEngine: 'Motor', timelineEngine: 'Motor',
@@ -298,6 +301,9 @@ const TIMELINE_I18N = {
sortDocOrder: 'Dokumentrekkefølge', sortDocOrder: 'Dokumentrekkefølge',
sortChronological: 'Kronologisk', sortChronological: 'Kronologisk',
timelineExportCsv: 'Last ned CSV', timelineExportCsv: 'Last ned CSV',
timelineNotesLabel: 'Kontekstnotes',
timelineNotesPlaceholder: 'Legg til avklaringer for å veilede AI-en — f.eks. "Alle datoer er 2024", "Fokuser på morens handlinger", "D refererer til saksøkte gjennom hele dokumentet".',
timelineNotesHint: 'Disse notatene inkluderes i ledeteksten for å hjelpe modellen med å tolke uklare datoer, aktører eller forkortelser. Lagres ikke.',
}, },
uk: { uk: {
timelineEngine: 'Рушій', timelineEngine: 'Рушій',
@@ -336,6 +342,9 @@ const TIMELINE_I18N = {
sortDocOrder: 'Порядок документа', sortDocOrder: 'Порядок документа',
sortChronological: 'Хронологічний', sortChronological: 'Хронологічний',
timelineExportCsv: 'Завантажити CSV', timelineExportCsv: 'Завантажити CSV',
timelineNotesLabel: 'Контекстні нотатки',
timelineNotesPlaceholder: 'Додайте пояснення для ШІ — напр. "Усі дати відносяться до 2024 року", "Зосередьтесь на діях матері", "D — відповідач по всьому документу".',
timelineNotesHint: 'Ці нотатки включаються до запиту, щоб допомогти моделі інтерпретувати неоднозначні дати, учасників або скорочення. Не зберігаються.',
}, },
pl: { pl: {
timelineEngine: 'Silnik', timelineEngine: 'Silnik',
@@ -374,6 +383,9 @@ const TIMELINE_I18N = {
sortDocOrder: 'Kolejność dokumentu', sortDocOrder: 'Kolejność dokumentu',
sortChronological: 'Chronologicznie', sortChronological: 'Chronologicznie',
timelineExportCsv: 'Pobierz CSV', timelineExportCsv: 'Pobierz CSV',
timelineNotesLabel: 'Notatki kontekstowe',
timelineNotesPlaceholder: 'Dodaj wyjaśnienia dla AI — np. "Wszystkie daty dotyczą 2024", "Skup się na działaniach matki", "D odnosi się do pozwanego w całym dokumencie".',
timelineNotesHint: 'Te notatki są dołączane do zapytania, aby pomóc modelowi interpretować niejednoznaczne daty, uczestników lub skróty. Nie są przechowywane.',
}, },
}; };
@@ -1087,6 +1099,7 @@ async function runTool(event) {
payload.confidence_filter = currentConfidenceFilter(); payload.confidence_filter = currentConfidenceFilter();
payload.include_relative = currentIncludeRelative(); payload.include_relative = currentIncludeRelative();
payload.include_background = currentIncludeBackground(); payload.include_background = currentIncludeBackground();
payload.user_notes = (document.getElementById('timelineNotes')?.value || '').trim();
} }
setBusy(true); setBusy(true);
+7 -2
View File
@@ -289,7 +289,8 @@ PROMPT;
string $focus = 'all', string $focus = 'all',
string $confidenceFilter = 'all', string $confidenceFilter = 'all',
bool $includeRelative = true, bool $includeRelative = true,
bool $includeBackground = true bool $includeBackground = true,
string $userNotes = ''
): array { ): array {
$text = $this->requirePasteText($text); $text = $this->requirePasteText($text);
$engine = in_array($engine, ['azure_mini', 'azure_full', 'gpu'], true) ? $engine : 'azure_mini'; $engine = in_array($engine, ['azure_mini', 'azure_full', 'gpu'], true) ? $engine : 'azure_mini';
@@ -316,8 +317,12 @@ PROMPT;
? '' ? ''
: "\nDo NOT extract relative, recurring, or conditional date references — extract only events with determinable absolute dates (date_type=absolute)."; : "\nDo NOT extract relative, recurring, or conditional date references — extract only events with determinable absolute dates (date_type=absolute).";
$userNotesBlock = $userNotes !== ''
? "\n\nUser-provided context notes (use these to resolve ambiguities, not as source events):\n---\n" . $userNotes . "\n---"
: '';
$prompt = <<<PROMPT $prompt = <<<PROMPT
Build a chronological timeline from the pasted text in {$locale}. Build a chronological timeline from the pasted text in {$locale}.{$userNotesBlock}
Extract ALL dates, deadlines, milestones, and temporal references.{$focusInstruction}{$backgroundInstruction}{$relativeInstruction} Extract ALL dates, deadlines, milestones, and temporal references.{$focusInstruction}{$backgroundInstruction}{$relativeInstruction}
+6
View File
@@ -72,6 +72,12 @@ require_once __DIR__ . '/includes/layout.php';
<label class="input-label" for="toolInput" id="inputLabel" data-i18n="timelineInputLabel">Pasted text</label> <label class="input-label" for="toolInput" id="inputLabel" data-i18n="timelineInputLabel">Pasted text</label>
<textarea id="toolInput" name="toolInput" rows="10" required data-i18n-placeholder="timelineInputPlaceholder" placeholder="Paste case notes, court decisions, or correspondence containing dates and events."></textarea> <textarea id="toolInput" name="toolInput" rows="10" required data-i18n-placeholder="timelineInputPlaceholder" placeholder="Paste case notes, court decisions, or correspondence containing dates and events."></textarea>
<div id="timelineNotesSection">
<label class="input-label" for="timelineNotes" data-i18n="timelineNotesLabel">Context notes <small class="control-hint">(optional)</small></label>
<textarea id="timelineNotes" name="timelineNotes" rows="3" data-i18n-placeholder="timelineNotesPlaceholder" placeholder="Add any clarifications to guide the AI — e.g. &quot;All dates are 2024&quot;, &quot;Focus on the mother's actions&quot;, &quot;D refers to the defendant throughout&quot;."></textarea>
<p class="upload-hint" data-i18n="timelineNotesHint">These notes are included in the prompt to help the model interpret ambiguous dates, actors, or abbreviations. Not stored.</p>
</div>
<div class="form-footer"> <div class="form-footer">
<p id="toolStatus" class="form-status" role="status" aria-live="polite"></p> <p id="toolStatus" class="form-status" role="status" aria-live="polite"></p>
<button id="runButton" type="submit" data-i18n="timelineRun">Run</button> <button id="runButton" type="submit" data-i18n="timelineRun">Run</button>