Files
2026-06-04 08:05:06 +03:00

78 lines
2.5 KiB
Python

"""Roleplay output guardrails and OOC stripping."""
import re
ROLEPLAY_GUARDRAILS = (
"[In-character rules — breaking these ruins immersion]\n"
"- Reply ONLY as the character in the present moment: spoken lines, visible actions, "
"thoughts they would actually show.\n"
"- NEVER write: P.S., PS, postscripts, footnotes, section headers, "
'"Статус кво", "Status quo", "To be continued", scene summaries, '
"editorial closings, or foreshadowing asides "
'(e.g. "Когда вы выйдете...", "Ты уже знаешь правду...").\n'
"- Do NOT explain subtext to the reader or predict future scenes. No narrator voice.\n"
"- End inside the scene; do not wrap up with meta commentary.\n"
"- Sections marked MANDATORY (relationship, state) are binding — obey without citing them."
)
RP_OUTPUT_REMINDER = (
"\n\n--- Reply format (MANDATORY) ---\n"
"Next message = in-character only. "
"Forbidden in output: P.S., Статус кво, Status quo, author notes, summaries, footnotes.\n"
"---"
)
def status_quo_prompt_block(status_quo: str) -> str:
sq = (status_quo or "").strip()
if not sq:
return ""
return (
"\n\n--- Current situation (INTERNAL — player never sees this block) ---\n"
+ sq
+ "\nBackground truth for you only. "
"Never echo this header, never open/close replies with 'Статус кво' or summaries. "
"Show the situation through dialogue and action.\n---"
)
_OOC_PARA_START = re.compile(
r"^(?:"
r"Статус\s*кво|Status\s*quo|"
r"P\.?\s*S\.?|PS:|"
r"Примечание:|Author'?s?\s*note:|"
r"OOC:|\\[OOC\\]|"
r"To be continued|Продолжение следует"
r")\b",
re.IGNORECASE,
)
def strip_ooc_from_reply(text: str) -> str:
"""Remove common OOC tails (P.S., Статус кво paragraphs, etc.)."""
if not text or not text.strip():
return text or ""
out = text.rstrip()
# Drop trailing P.S. block (often last paragraph).
out = re.sub(
r"(?is)\n\s*P\.?\s*S\.?\s*[:.\-—].*$",
"",
out,
).rstrip()
parts = re.split(r"\n\s*\n", out)
kept: list[str] = []
for part in parts:
lines = [ln for ln in part.splitlines() if ln.strip()]
if not lines:
continue
if _OOC_PARA_START.match(lines[0].strip()):
continue
kept.append(part)
if not kept:
return ""
return "\n\n".join(kept).strip()