From e0bcd85d90f8627757ec9638721bccc4f0e0a884 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Fri, 10 Apr 2026 18:37:04 +0000 Subject: [PATCH] Feature: Analyse-Anweisungen (Direktiven) fuer Tabellen und Zusammenfassung Nutzer koennen per Klick auf Chips Anweisungen zur Beschreibung hinzufuegen: Zusammenfassung, Vergleichstabelle, Zeitverlauf, Pro/Contra oder eigene Tabellen. Format: [TABELLE: ...] und [ZUSAMMENFASSUNG]. Mehrere Anweisungen moeglich. Analyzer-Prompts beachten diese Anweisungen verbindlich. Beschreibung-generieren bewahrt bestehende Direktiven. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/agents/analyzer.py | 27 +++++++++++++++++----- src/static/css/style.css | 30 +++++++++++++++++++++++++ src/static/dashboard.html | 8 +++++++ src/static/js/app.js | 47 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/src/agents/analyzer.py b/src/agents/analyzer.py index 5c679ae..bd31abd 100644 --- a/src/agents/analyzer.py +++ b/src/agents/analyzer.py @@ -26,10 +26,18 @@ AUFTRAG: 4. Übersetze fremdsprachige Überschriften und Inhalte in die Ausgabesprache STRUKTUR: -- Wenn die Meldungen thematisch klar einen einzelnen Strang behandeln: Fließtext ohne Überschriften -- Wenn verschiedene Aspekte oder Themenfelder aufkommen (z.B. Ereignis + Reaktionen + Hintergrund): Gliedere mit kurzen Markdown-Zwischenüberschriften (##) -- Wenn sich Daten strukturiert vergleichen lassen (z.B. Produkte, Unternehmen, Kennzahlen, Modelle), verwende eine Markdown-Tabelle (| Spalte1 | Spalte2 | ... mit Trennzeile |---|---|) -- Die Entscheidung liegt bei dir — Überschriften und Tabellen nur wenn sie dem Leser helfen +- Wenn die Meldungen thematisch klar einen einzelnen Strang behandeln: Fliesstext ohne Ueberschriften +- Wenn verschiedene Aspekte oder Themenfelder aufkommen (z.B. Ereignis + Reaktionen + Hintergrund): Gliedere mit kurzen Markdown-Zwischenueberschriften (##) +- Die Entscheidung liegt bei dir, Ueberschriften und Tabellen nur wenn sie dem Leser helfen + +BENUTZER-ANWEISUNGEN (aus dem KONTEXT-Feld): +Der Benutzer kann im KONTEXT spezielle Anweisungen in eckigen Klammern angeben: +- [TABELLE: Beschreibung] = Du MUSST eine Markdown-Tabelle erstellen die dieser Beschreibung entspricht. Platziere sie an der thematisch passenden Stelle im Text. +- [ZUSAMMENFASSUNG] = Du MUSST dem Lagebild eine kurze Zusammenfassung (3-5 Saetze) als ersten Abschnitt voranstellen, die die wichtigsten Erkenntnisse auf einen Blick liefert. +- Mehrere Anweisungen sind moeglich und muessen ALLE beachtet werden. +- Wenn KEINE solchen Anweisungen vorhanden sind, verwende Tabellen nur wenn es sich offensichtlich anbietet. +- Markdown-Tabellen-Format: | Spalte1 | Spalte2 | mit Trennzeile |---|---| +- Ignoriere leere [TABELLE: ]-Anweisungen ohne Beschreibung. REGELN: - Neutral und sachlich - keine Wertungen oder Spekulationen @@ -130,10 +138,17 @@ AUFTRAG: 5. Entferne nur nachweislich widerlegte Informationen. Behalte alle thematischen Abschnitte bei, auch wenn sie nicht durch neue Meldungen aktualisiert werden STRUKTUR: -- Fließtext oder mit Markdown-Zwischenüberschriften (##) — je nach Komplexität -- Wenn sich Daten strukturiert vergleichen lassen (z.B. Produkte, Unternehmen, Kennzahlen, Modelle), verwende eine Markdown-Tabelle (| Spalte1 | Spalte2 | ... mit Trennzeile |---|---|) +- Fliesstext oder mit Markdown-Zwischenueberschriften (##), je nach Komplexitaet - KEIN Fettdruck (**) verwenden +BENUTZER-ANWEISUNGEN (aus dem KONTEXT-Feld): +Der Benutzer kann im KONTEXT spezielle Anweisungen in eckigen Klammern angeben: +- [TABELLE: Beschreibung] = Du MUSST eine Markdown-Tabelle erstellen die dieser Beschreibung entspricht. Platziere sie an der thematisch passenden Stelle im Text. Aktualisiere bestehende Tabellen mit neuen Daten. +- [ZUSAMMENFASSUNG] = Du MUSST dem Lagebild eine kurze Zusammenfassung (3-5 Saetze) als ersten Abschnitt voranstellen. +- Mehrere Anweisungen sind moeglich und muessen ALLE beachtet werden. +- Wenn KEINE solchen Anweisungen vorhanden sind, verwende Tabellen nur wenn es sich offensichtlich anbietet. +- Markdown-Tabellen-Format: | Spalte1 | Spalte2 | mit Trennzeile |---|---| + REGELN: - Neutral und sachlich - keine Wertungen oder Spekulationen - KEINE Gedankenstriche (—, –) verwenden — stattdessen Kommas, Doppelpunkte oder neue Saetze diff --git a/src/static/css/style.css b/src/static/css/style.css index 9a60934..5a4530f 100644 --- a/src/static/css/style.css +++ b/src/static/css/style.css @@ -2653,6 +2653,36 @@ a:hover { color: var(--text-secondary); } +/* === Directive Chips === */ +.directive-chips { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 6px; + margin-top: 8px; +} +.directive-chips-label { + font-size: 11px; + color: var(--text-disabled); + margin-right: 4px; +} +.directive-chip { + padding: 3px 10px; + border-radius: 12px; + border: 1px solid var(--border); + background: transparent; + color: var(--text-tertiary); + font-size: 11px; + cursor: pointer; + transition: all 0.15s; + white-space: nowrap; +} +.directive-chip:hover { + border-color: var(--accent); + color: var(--accent); + background: rgba(59, 130, 246, 0.08); +} + /* === Summary Tables === */ .summary-table-wrap { overflow-x: auto; diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 8d6af31..84f46ca 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -327,6 +327,14 @@ +
+ Analyse-Anweisungen: + + + + + +
diff --git a/src/static/js/app.js b/src/static/js/app.js index c7d03ad..9edfbfb 100644 --- a/src/static/js/app.js +++ b/src/static/js/app.js @@ -1673,6 +1673,38 @@ const App = { } }, +insertDirective(type) { + const textarea = document.getElementById('inc-description'); + if (!textarea) return; + const directives = { + summary: '[ZUSAMMENFASSUNG]', + compare: '[TABELLE: Vergleiche ... nach ...]', + timeline: '[TABELLE: Zeitlicher Verlauf mit Datum und Ereignis]', + procon: '[TABELLE: Pro- und Contra-Argumente]', + custom: '[TABELLE: ]', + }; + const directive = directives[type]; + if (!directive) return; + + // Duplikat-Check (ausser bei custom) + if (type !== 'custom' && textarea.value.includes(directive)) return; + + var val = textarea.value; + if (val.length > 0 && !val.endsWith('\n')) val += '\n'; + if (val.length > 0 && !val.endsWith('\n\n')) val += '\n'; + val += directive; + textarea.value = val; + + // Bei custom: Cursor vor die schliessende Klammer setzen + if (type === 'custom') { + textarea.focus(); + var pos = val.length - 1; + textarea.setSelectionRange(pos, pos); + } + // Textarea-Groesse anpassen + if (typeof _autoResizeTextarea === 'function') _autoResizeTextarea(textarea); + }, + async generateDescription() { const title = document.getElementById('inc-title').value.trim(); const description = document.getElementById('inc-description').value.trim(); @@ -1694,9 +1726,22 @@ async generateDescription() { textarea.readOnly = true; textarea.classList.add('textarea--loading'); + // Bestehende Direktiven sichern + var existingDirectives = []; + var directiveRegex = /\[(?:TABELLE:.*?|ZUSAMMENFASSUNG)\]/g; + var match; + while ((match = directiveRegex.exec(description)) !== null) { + existingDirectives.push(match[0]); + } + try { const result = await API.enhanceDescription(title, description || null, type, this._enhanceController.signal); - textarea.value = result.description; + var newDesc = result.description; + // Gesicherte Direktiven wieder anhaengen + if (existingDirectives.length > 0) { + newDesc = newDesc.trimEnd() + '\n\n' + existingDirectives.join('\n'); + } + textarea.value = newDesc; _autoResizeTextarea(textarea); } catch (err) { if (err.name !== 'AbortError') {