from __future__ import annotations from app.normalization import normalize_text, tokenize from app.typo import word_similarity SERVICE_INTENTS = { "opening_hours": [ ("до", "скольки", "работаете"), ("режим", "работы"), ("график", "работы"), ], "payment": [ ("оплата", "картой"), ("оплатить", "картой"), ("наличными", "при", "получении"), ], "location": [ ("где", "магазин"), ("адрес", "магазина"), ("как", "доехать"), ], "order_status": [ ("статус", "заказа"), ("где", "мой", "заказ"), ], "thanks": [ ("спасибо", "заказ", "получил"), ("все", "отлично"), ], } def _token_present(expected: str, tokens: tuple[str, ...]) -> bool: for token in tokens: if token == expected: return True if min(len(token), len(expected)) >= 5 and word_similarity(token, expected) >= 0.72: return True return False def detect_service_intent(text: str) -> str | None: """Detect a known non-product intent after product evidence has failed. This is deliberately phrase/token based rather than a blacklist of words such as ``подскажите``: those words are valid in product requests too. """ tokens = tokenize(normalize_text(text), already_normalized=True) for intent, phrases in SERVICE_INTENTS.items(): for phrase in phrases: if all(_token_present(expected, tokens) for expected in phrase): return intent return None