diff --git a/aria-brain/migrate_backfill_projectid.py b/aria-brain/migrate_backfill_projectid.py index c7b4386..ac798a4 100644 --- a/aria-brain/migrate_backfill_projectid.py +++ b/aria-brain/migrate_backfill_projectid.py @@ -25,6 +25,7 @@ from __future__ import annotations import json import logging import os +import re from collections import defaultdict, deque from pathlib import Path @@ -32,13 +33,30 @@ logger = logging.getLogger("aria.migrate.backfill_projectid") CONVERSATION_FILE = Path(os.environ.get("CONVERSATION_FILE", "/data/conversation.jsonl")) CHAT_BACKUP_FILE = Path(os.environ.get("CHAT_BACKUP_FILE", "/shared/config/chat_backup.jsonl")) -MARKER_FILE = Path("/shared/config/.chat_backup_projectid_backfill_v1") +# v2: robusterer Match (Marker-Strip + Praefix). v1 verlangte exakte Gleichheit +# von text==content und verfehlte damit alle Nachrichten bei denen die Bridge +# den Brain-Text anreichert (GPS/Barge-In-Hints prepended) oder cleant +# (FILE-Marker entfernt). Neuer Marker → laeuft einmal neu, fuellt die Luecken. +MARKER_FILE = Path("/shared/config/.chat_backup_projectid_backfill_v2") + +# _build_core_text (Bridge) PREPENDT bei User-Nachrichten Hinweis-/GPS-Bloecke +# in eckigen Klammern vor den eigentlichen Text; conversation.jsonl speichert +# diesen angereicherten Text, chat_backup nur den rohen. FILE-Marker stehen in +# conversation-Assistant-Turns, sind in chat_backup aber schon rausgecleant. +_FILE_MARKER_RE = re.compile(r"\[FILE:\s*/shared/uploads/[^\]]+\]", re.IGNORECASE) +_LEADING_BRACKET_RE = re.compile(r"^\s*(?:\[[^\]]*\]\s*)+") +_WS_RE = re.compile(r"\s+") def _norm(text: str) -> str: - """Match-Key: getrimmt + auf 500 Zeichen begrenzt. Reicht um Turns eindeutig - zu unterscheiden, ist aber tolerant gegen minimale Trailing-Unterschiede.""" - return (text or "").strip()[:500] + """Match-Key: FILE-Marker + fuehrende [Hinweis]/[GPS]-Bloecke entfernen, + Whitespace kollabieren, auf 120-Zeichen-Praefix kuerzen. Toleriert damit + die Anreicherungs-/Cleaning-Unterschiede zwischen conversation und backup, + bleibt durch den 120er-Praefix aber spezifisch genug gegen Fehl-Matches.""" + t = _FILE_MARKER_RE.sub("", text or "") + t = _LEADING_BRACKET_RE.sub("", t) + t = _WS_RE.sub(" ", t).strip() + return t[:120] def run() -> dict: @@ -112,7 +130,7 @@ def run() -> dict: # 4) Sicherung + atomarer Rewrite. try: - bak = CHAT_BACKUP_FILE.with_suffix(".jsonl.pre-backfill-v1.bak") + bak = CHAT_BACKUP_FILE.with_suffix(".jsonl.pre-backfill-v2.bak") if not bak.exists(): bak.write_bytes(CHAT_BACKUP_FILE.read_bytes()) tmp = CHAT_BACKUP_FILE.with_suffix(".jsonl.tmp")