| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import logging |
|
|
| from language_config import ( |
| DEFAULT_LANGUAGE, |
| DEVANAGARI, |
| GURMUKHI, |
| ROMAN_URDU_MARKERS, |
| detect_roman_urdu, |
| has_arabic_script, |
| normalize_language, |
| ) |
| from utils import detect_language_from_content |
|
|
| logger = logging.getLogger("language_detector") |
|
|
| AMBIGUOUS_WORDS = { |
| "hello", "hi", "ok", "okay", "yes", "no", "please", |
| "sorry", "thanks", "thank", "bye", "good", "hey", "help", "helo", |
| } |
|
|
| MIN_CHARS_FOR_DETECTION = 8 |
|
|
| |
| URDU_ONLY_LANGUAGE = "ur" |
|
|
|
|
| def is_ambiguous_message(text: str) -> bool: |
| """ |
| Retained for future multi-language mode β not used while |
| URDU_ONLY_LANGUAGE forcing is active. |
| """ |
| text_clean = text.strip().lower() |
| if len(text_clean) < MIN_CHARS_FOR_DETECTION: |
| words = set(text_clean.split()) |
| if words.issubset(AMBIGUOUS_WORDS): |
| return True |
| return False |
|
|
|
|
| def _has_urdu_script_evidence(text: str) -> bool: |
| """ |
| Retained for future multi-language mode β not used while |
| URDU_ONLY_LANGUAGE forcing is active. |
| """ |
| if DEVANAGARI.search(text) or GURMUKHI.search(text): |
| return True |
| if has_arabic_script(text): |
| return True |
| if detect_roman_urdu(text): |
| return True |
| words = set(text.lower().split()) |
| if words.intersection(ROMAN_URDU_MARKERS): |
| return True |
| return False |
|
|
|
|
| def detect_language_from_text(text: str) -> tuple[str, float]: |
| """ |
| Retained for future multi-language mode β not used while |
| URDU_ONLY_LANGUAGE forcing is active. |
| """ |
| if not text or not text.strip(): |
| return DEFAULT_LANGUAGE, 0.0 |
|
|
| lang = normalize_language(detect_language_from_content(text)) |
|
|
| if lang == "ur": |
| if DEVANAGARI.search(text) or GURMUKHI.search(text): |
| return "ur", 0.95 |
| if has_arabic_script(text): |
| return "ur", 0.75 |
| return "ur", 0.90 |
|
|
| if is_ambiguous_message(text): |
| return DEFAULT_LANGUAGE, 0.30 |
|
|
| return "en", 0.70 |
|
|
|
|
| class SmartLanguageDetector: |
| """ |
| URDU-ONLY MODE v4: locks to "ur" immediately and unconditionally. |
| |
| arabic_needs_clarification and get_arabic_clarification_flag() have |
| been removed entirely β Urdu-only mode has no need to distinguish |
| Arabic script subtypes. All callers updated accordingly. |
| |
| process_message() still tracks turn_count for logging. No voting, |
| no pivot logic, no arabic script classification. |
| """ |
|
|
| def __init__(self): |
| self.detected_language = URDU_ONLY_LANGUAGE |
| self.confidence = 0.95 |
| self.turn_count = 0 |
| self.language_votes: dict[str, float] = {URDU_ONLY_LANGUAGE: 1.0} |
| self.locked = True |
|
|
| def process_message(self, text: str) -> str: |
| """ |
| Process user message and return resolved language code. |
| Urdu-only mode: always returns "ur". Tracks turn_count for logging. |
| """ |
| self.turn_count += 1 |
|
|
| logger.info( |
| f"Turn {self.turn_count}: language=ur (forced, Urdu-only mode)" |
| ) |
|
|
| return self.detected_language |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| def get_language(self) -> str: |
| return normalize_language(self.detected_language) |
|
|
| def is_locked(self) -> bool: |
| return self.locked |
|
|
| def reset(self): |
| self.__init__() |
|
|
|
|
| def detect_language(text: str) -> str: |
| """Stateless wrapper for compatibility. Urdu-only mode: always returns 'ur'.""" |
| return URDU_ONLY_LANGUAGE |
|
|
| |
| |