atom-ai / src /speech_lock.py
thefinalboss's picture
ATOM (atom-ai): code snapshot (100fae0 + batched-train), README with measured numbers, curated checkpoints (part 4)
b9301f1 verified
Raw History Blame Contribute Delete
1.96 kB
"""Chat speech helpers for ATOM. Not a language model. Gate only."""
from __future__ import annotations
def format_dialogue_prompt(prompt: str) -> str:
raw = (prompt or "").strip()
if not raw:
return "Utilisateur:\nAssistant: "
if "Utilisateur:" in raw or "Assistant:" in raw:
return raw if raw.endswith("Assistant:") or raw.endswith("Assistant: ") else raw
return f"Utilisateur: {raw}\nAssistant: "
_SPEECH_HINTS = frozenset(
{
"je", "tu", "il", "elle", "on", "nous", "vous", "est", "suis", "es",
"les", "des", "une", "un", "le", "la", "et", "que", "qui", "pas",
"bonjour", "salut", "oui", "non", "merci", "comment", "vais", "va",
"fait", "plus", "dans", "pour", "avec", "hello", "ok", "ca", "moi", "toi",
}
)
def speech_ok(payload: bytes) -> bool:
if not payload:
return False
text = payload.decode("utf-8", errors="replace").strip()
if len(text) < 2:
return False
letters = [ch for ch in text.lower() if ch.isalpha()]
if len(letters) < 2:
return False
vowels = set("aeiouyàâäéèêëïîôùûüç")
if not any(ch in vowels for ch in letters):
return False
printable = sum(ch.isprintable() or ch in "\n\t" for ch in text) / max(len(text), 1)
if printable < 0.8:
return False
if len(set(letters)) == 1:
return False
tokens = []
buf: list[str] = []
for ch in text.lower():
if ch.isalpha():
buf.append(ch)
elif buf:
tokens.append("".join(buf))
buf = []
if buf:
tokens.append("".join(buf))
if any(tok in _SPEECH_HINTS for tok in tokens):
return True
# Phrase-friendly: allow longer printable FR-like text (was capped at 6
# chars, which forced one-word attractors and empty/truncated chat).
if 2 <= len(text) <= 160 and len(letters) >= 4:
return True
return 2 <= len(text) <= 6