Kansho/backend/journal_shape.py
2026-08-29 11:04:34 +02:00

74 lines
2.4 KiB
Python

"""Local journal shape after the model. Does not invent or rewrite content."""
from __future__ import annotations
import re
NEW_PHASE = re.compile(
r"^(?:Heute|Gestern|Morgens|Mittags|Abends|Nachts|Danach|Später|Dann|Zuerst|"
r"Schließlich|Irgendwann|Unterwegs|Zurück|"
r"Um\s+\d|Nach\s+(?:ca\.|einer|einem|dem|der|kurzer|weiteren)|"
r"Als\s+(?:wir|ich)\b)",
re.I,
)
def _strip_roles(text: str) -> str:
lines = [re.sub(r"^(?:user|assistant):\s*", "", line, flags=re.I) for line in (text or "").splitlines()]
return "\n".join(lines).strip()
def _norm(text: str) -> str:
return re.sub(r"[^\w\s]+", " ", re.sub(r"\s+", " ", _strip_roles(text).lower())).strip()
def _turns(user_bodies: list[str]) -> list[str]:
return [re.sub(r"\s+", " ", item).strip() for item in user_bodies if (item or "").strip()]
def is_verbatim_join(body: str, user_bodies: list[str]) -> bool:
"""Diagnostic helper. Must not be used to overwrite accepted model text."""
turns = _turns(user_bodies)
if not turns or not (body or "").strip():
return False
got = _norm(body)
return got == _norm(" ".join(turns)) or got == _norm("\n\n".join(turns))
def paragraphize(body: str) -> str:
"""Optional local preview helper. Must not rewrite an accepted model draft."""
text = (body or "").strip()
if "\n\n" in text:
return text
sentences = [item.strip() for item in re.split(r"(?<=[.!?])\s+", text) if item.strip()]
if len(sentences) < 4:
return text
chunks: list[str] = []
current: list[str] = []
for sentence in sentences:
split = bool(current) and (NEW_PHASE.match(sentence) or len(current) >= 3)
if split:
chunks.append(" ".join(current))
current = [sentence]
else:
current.append(sentence)
if current:
chunks.append(" ".join(current))
return "\n\n".join(chunks)
def shape_journal(
title: str,
body: str,
user_bodies: list[str],
person_labels: list[str] | None = None,
*,
source: str = "model",
) -> tuple[str, str]:
"""Safe technical trim only. Never replaces names, pronouns, or accepted wording."""
del user_bodies, person_labels
heading = (title or "").strip()
text = _strip_roles(body or "").strip()
if source == "fallback" and "\n\n" not in text:
text = paragraphize(text)
return heading, text