""" Lightweight French/English language detection — no dependencies, no LLM call. Scores a text by counting high-frequency French function words and French-specific accented characters. Designed for short chat messages where heavyweight detectors are overkill. Defaults to English when ambiguous. """ import re _FRENCH_WORDS = { "le", "la", "les", "un", "une", "des", "du", "de", "et", "est", "ce", "cette", "ces", "je", "tu", "il", "elle", "nous", "vous", "ils", "elles", "mon", "ma", "mes", "votre", "vos", "notre", "nos", "son", "sa", "ses", "pour", "avec", "dans", "sur", "pas", "ne", "que", "qui", "quoi", "où", "comment", "pourquoi", "quand", "quel", "quelle", "quels", "quelles", "bonjour", "salut", "merci", "oui", "non", "voudrais", "veux", "peux", "pouvez", "envoyer", "envoie", "courriel", "objet", "sujet", "besoin", "aimerais", "souhaite", "souhaiterais", "démo", "démonstration", "être", "avoir", "faire", "aussi", "très", "plus", "moins", "donc", "alors", "était", "sont", "été", "fait", "déjà", "encore", "ici", "là", "chez", "entreprise", "société", "écrire", "rédiger", "moi", "toi", "lui", } _ENGLISH_WORDS = { "the", "a", "an", "and", "is", "are", "was", "were", "be", "been", "it", "this", "that", "these", "those", "i", "you", "he", "she", "we", "they", "my", "your", "our", "his", "her", "their", "for", "with", "in", "on", "not", "what", "which", "who", "where", "when", "how", "why", "would", "could", "should", "can", "will", "want", "need", "like", "please", "hello", "hi", "thanks", "thank", "yes", "no", "send", "email", "mail", "subject", "demo", "demonstration", "write", "company", "about", "to", "of", "do", "does", "have", "has", "get", "me", "us", "them", "also", } _FRENCH_ACCENTS = "àâäçéèêëîïôöùûüÿœ" def detect_language(text: str) -> str: """Returns 'fr' or 'en'. Defaults to 'en' when the signal is weak.""" lower = text.lower() words = re.findall(r"[a-zà-ÿœ']+", lower) fr_score = sum(1 for w in words if w in _FRENCH_WORDS) en_score = sum(1 for w in words if w in _ENGLISH_WORDS) # Accented characters are a strong French signal in this EN/FR context. fr_score += sum(2 for ch in lower if ch in _FRENCH_ACCENTS) return "fr" if fr_score > en_score else "en" def language_name(lang: str) -> str: return "French" if lang == "fr" else "English"