mirror of
https://github.com/Jeuners/Logpy-AgentOne.git
synced 2026-09-09 15:02:33 +02:00
feat: Verlauf-Log beim Tag archivieren sichern und leeren
"Tag archivieren" archiviert jetzt zusaetzlich das Verlauf-Log (Kopie nach telefon/verlauf-archiv/verlauf_JJJJMMTT-HHMMSS.log) und leert es danach - frische Verlaufsansicht fuer den neuen Tag. Das dauerhafte, unveraenderliche audit.log ist davon nicht betroffen, das behaelt ohnehin alles fuer immer. Live getestet: 530 Zeilen archiviert, Log korrekt geleert (nur noch die Bestaetigungszeile drin). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015vtvcyNkapuDh583643hNs
This commit is contained in:
parent
bc588072bd
commit
9f64d94b3f
3 changed files with 30 additions and 2 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -12,6 +12,7 @@ __pycache__/
|
||||||
/telefon/ansage.wav
|
/telefon/ansage.wav
|
||||||
/telefon/verlauf.log
|
/telefon/verlauf.log
|
||||||
/telefon/*.log
|
/telefon/*.log
|
||||||
|
/telefon/verlauf-archiv/
|
||||||
# Laufzeit-Zustand (aktive Modell-Auswahl aus dem Leitstand-Dropdown), kein Quellcode
|
# Laufzeit-Zustand (aktive Modell-Auswahl aus dem Leitstand-Dropdown), kein Quellcode
|
||||||
/telefon/modell.json
|
/telefon/modell.json
|
||||||
# Trainingsdaten-Export (pipe.export) - enthaelt volle Transkripte/Namen
|
# Trainingsdaten-Export (pipe.export) - enthaelt volle Transkripte/Namen
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,15 @@ jedes Ereignis zusaetzlich unveraenderlich nach audit.log, siehe pipe.audit.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import shutil
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from . import audit, config
|
from . import audit, config
|
||||||
|
|
||||||
DATEI = config.TELEFON / "verlauf.log"
|
DATEI = config.TELEFON / "verlauf.log"
|
||||||
MAX_ZEILEN = 2000 # darüber wird beim Schreiben gekürzt
|
MAX_ZEILEN = 2000 # darüber wird beim Schreiben gekürzt
|
||||||
|
ARCHIV_ORDNER = config.TELEFON / "verlauf-archiv"
|
||||||
|
|
||||||
|
|
||||||
def schreibe(art: str, text: str, **felder) -> None:
|
def schreibe(art: str, text: str, **felder) -> None:
|
||||||
|
|
@ -59,3 +62,20 @@ def kuerze() -> None:
|
||||||
DATEI.write_text("\n".join(zeilen[-MAX_ZEILEN:]) + "\n", encoding="utf-8")
|
DATEI.write_text("\n".join(zeilen[-MAX_ZEILEN:]) + "\n", encoding="utf-8")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def archiviere_und_leere() -> Path | None:
|
||||||
|
"""Sichert den aktuellen Verlauf als Kopie und leert ihn danach - fuer
|
||||||
|
einen frischen Verlauf nach "Tag archivieren". Das dauerhafte audit.log
|
||||||
|
ist davon unberuehrt (behaelt ohnehin alles). Wirft nie. Gibt den Pfad
|
||||||
|
der Archivkopie zurueck, oder None wenn nichts zu sichern war."""
|
||||||
|
try:
|
||||||
|
if not DATEI.is_file() or not DATEI.stat().st_size:
|
||||||
|
return None
|
||||||
|
ARCHIV_ORDNER.mkdir(parents=True, exist_ok=True)
|
||||||
|
ziel = ARCHIV_ORDNER / f"verlauf_{datetime.now():%Y%m%d-%H%M%S}.log"
|
||||||
|
shutil.copy2(DATEI, ziel)
|
||||||
|
DATEI.write_text("", encoding="utf-8")
|
||||||
|
return ziel
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,13 @@ class Handler(BaseHTTPRequestHandler):
|
||||||
_, export_anzahl = export.exportiere()
|
_, export_anzahl = export.exportiere()
|
||||||
if export_anzahl:
|
if export_anzahl:
|
||||||
protokoll.schreibe("export", f"{export_anzahl} bewertete Anrufe exportiert")
|
protokoll.schreibe("export", f"{export_anzahl} bewertete Anrufe exportiert")
|
||||||
self._json({"ok": True, "anzahl": anzahl, "simuliert": True, "export_anzahl": export_anzahl})
|
# Verlauf-Log sichern + leeren, fuer eine frische Ansicht ab jetzt.
|
||||||
|
# audit.log (dauerhaft, unveraenderlich) ist davon nicht betroffen.
|
||||||
|
log_archiv = protokoll.archiviere_und_leere()
|
||||||
|
if log_archiv:
|
||||||
|
protokoll.schreibe("system", f"Verlauf archiviert nach {log_archiv.name} und geleert")
|
||||||
|
self._json({"ok": True, "anzahl": anzahl, "simuliert": True, "export_anzahl": export_anzahl,
|
||||||
|
"log_archiviert": log_archiv.name if log_archiv else None})
|
||||||
return
|
return
|
||||||
if pfad == "/api/export":
|
if pfad == "/api/export":
|
||||||
ziel, anzahl = export.exportiere()
|
ziel, anzahl = export.exportiere()
|
||||||
|
|
@ -546,7 +552,7 @@ color:var(--gut);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:
|
||||||
</style></head><body><div class="wrap">
|
</style></head><body><div class="wrap">
|
||||||
<header><h1>Logpy:AgentOne — Anruf-Leitstand</h1>
|
<header><h1>Logpy:AgentOne — Anruf-Leitstand</h1>
|
||||||
<button class="sicher-btn" id="sicherBtn" title="Namen, Nummern, Anliegen und Transkripte unscharf - fuer Bildschirmaufnahmen/Screenshots">🙈 Sicher-Modus</button>
|
<button class="sicher-btn" id="sicherBtn" title="Namen, Nummern, Anliegen und Transkripte unscharf - fuer Bildschirmaufnahmen/Screenshots">🙈 Sicher-Modus</button>
|
||||||
<button class="archiv-btn" id="archivBtn" title="Erledigte Anrufe vom Board raeumen (simuliert, nichts wird geloescht) - bewertete Anrufe werden dabei als Trainingsdaten exportiert">🗄️ Tag archivieren</button>
|
<button class="archiv-btn" id="archivBtn" title="Erledigte Anrufe vom Board raeumen (simuliert, nichts wird geloescht) - bewertete Anrufe werden als Trainingsdaten exportiert, das Verlauf-Log wird gesichert und geleert">🗄️ Tag archivieren</button>
|
||||||
<button class="export-btn" id="exportBtn" title="Bewertete Anrufe (👍/👎) als JSONL-Trainingsdaten exportieren, unabhaengig vom Archivieren">📤 Bewertungen exportieren</button>
|
<button class="export-btn" id="exportBtn" title="Bewertete Anrufe (👍/👎) als JSONL-Trainingsdaten exportieren, unabhaengig vom Archivieren">📤 Bewertungen exportieren</button>
|
||||||
<span class="stand" id="stand">…</span>
|
<span class="stand" id="stand">…</span>
|
||||||
<select class="modell-select" id="modellSelect" title="Kategorisierungs-Modell fuer neue Anrufe - Aenderung greift sofort, kein Neustart noetig"></select>
|
<select class="modell-select" id="modellSelect" title="Kategorisierungs-Modell fuer neue Anrufe - Aenderung greift sofort, kein Neustart noetig"></select>
|
||||||
|
|
@ -863,6 +869,7 @@ document.getElementById('archivBtn').onclick=async()=>{
|
||||||
if(d&&d.ok){
|
if(d&&d.ok){
|
||||||
let text=`✓ ${d.anzahl} Anruf(e) archiviert (simuliert)`;
|
let text=`✓ ${d.anzahl} Anruf(e) archiviert (simuliert)`;
|
||||||
if(d.export_anzahl)text+=` · ${d.export_anzahl} bewertete Anrufe exportiert`;
|
if(d.export_anzahl)text+=` · ${d.export_anzahl} bewertete Anrufe exportiert`;
|
||||||
|
if(d.log_archiviert)text+=' · Verlauf gesichert & geleert';
|
||||||
toast(text);takt();
|
toast(text);takt();
|
||||||
} else{toast('Archivieren fehlgeschlagen.')}
|
} else{toast('Archivieren fehlgeschlagen.')}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue