mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 15:29:36 +00:00
110 lines
4.8 KiB
Python
110 lines
4.8 KiB
Python
"""
|
|
Intent Router — classifies the user's Arabic question into one of N intents.
|
|
|
|
Production: backed by LLM with examples. This module ships with a robust
|
|
keyword + phrase-pattern classifier so the system works without LLM and so
|
|
it's testable / deterministic.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Intent:
|
|
"""A classified intent with confidence + chosen route."""
|
|
|
|
intent_id: str
|
|
confidence: float
|
|
matched_keywords: tuple[str, ...] = ()
|
|
|
|
|
|
# ── Intent catalog ───────────────────────────────────────────────
|
|
INTENTS: tuple[str, ...] = (
|
|
"what_to_do_today",
|
|
"explain_metric",
|
|
"show_pipeline",
|
|
"show_at_risk_deals",
|
|
"show_revenue_leaks",
|
|
"compare_sectors",
|
|
"find_lookalikes",
|
|
"draft_outreach",
|
|
"generate_qbr",
|
|
"generate_proof_pack",
|
|
"explain_compliance_block",
|
|
"show_market_radar",
|
|
"forecast_revenue",
|
|
"stop_or_disable",
|
|
"general_help",
|
|
)
|
|
|
|
|
|
# Keyword patterns — Arabic + English. Order matters (first match wins).
|
|
_PATTERNS: tuple[tuple[str, tuple[str, ...]], ...] = (
|
|
("stop_or_disable", ("اوقف", "أوقف", "ايقاف", "stop", "disable", "تعطيل")),
|
|
("what_to_do_today", ("اليوم", "وش اسوي", "وش أسوي", "what should i do", "today")),
|
|
("show_at_risk_deals", ("at risk", "معرضة للخطر", "صفقات جامدة", "stalled")),
|
|
("show_revenue_leaks", ("تسريب", "leak", "ضايع", "ضايعه", "ضائع", "ضائعه")),
|
|
("show_revenue_leaks", ("اين المال", "أين المال")),
|
|
("forecast_revenue", ("توقع", "forecast", "30 يوم", "60 يوم", "90 يوم", "كم متوقع")),
|
|
("show_pipeline", ("pipeline", "بايبلاين", "صفقاتي", "قائمة الصفقات")),
|
|
("compare_sectors", ("قارن", "مقارنة", "compare sectors", "أي قطاع")),
|
|
("find_lookalikes", ("شركات مثل", "مشابه", "lookalike", "مماثل")),
|
|
("draft_outreach", ("اكتب رسالة", "اكتب لي", "draft", "صياغة")),
|
|
("generate_qbr", ("qbr", "تقرير ربعي", "تقرير شهري")),
|
|
("generate_proof_pack", ("proof pack", "اثبات", "إثبات", "ROI report")),
|
|
("explain_compliance_block", ("لماذا حُظر", "لماذا حظر", "compliance", "blocked", "PDPL")),
|
|
("show_market_radar", ("سوق", "market", "radar", "اشارات", "إشارات", "signals")),
|
|
("explain_metric", ("لماذا", "ليه", "explain", "اشرح", "what is")),
|
|
)
|
|
|
|
|
|
def classify_intent(question_ar: str) -> Intent:
|
|
"""Match the question to the most specific intent, with confidence."""
|
|
q = (question_ar or "").lower().strip()
|
|
if not q:
|
|
return Intent(intent_id="general_help", confidence=0.0)
|
|
|
|
best: tuple[str, int, list[str]] | None = None # (intent, score, matched)
|
|
for intent_id, keywords in _PATTERNS:
|
|
matched = [k for k in keywords if k.lower() in q]
|
|
if not matched:
|
|
continue
|
|
score = len(matched)
|
|
if best is None or score > best[1]:
|
|
best = (intent_id, score, matched)
|
|
|
|
if best is None:
|
|
return Intent(intent_id="general_help", confidence=0.2)
|
|
|
|
intent_id, score, matched = best
|
|
# Confidence: 0.5 base + 0.15 per matched keyword, capped at 0.95
|
|
confidence = min(0.95, 0.5 + 0.15 * score)
|
|
return Intent(intent_id=intent_id, confidence=confidence, matched_keywords=tuple(matched))
|
|
|
|
|
|
def list_intents() -> list[dict]:
|
|
"""Discoverable list — used by the help endpoint."""
|
|
descriptions = {
|
|
"what_to_do_today": "ماذا أفعل اليوم — الأولويات + القرارات",
|
|
"explain_metric": "اشرح رقم/مقياس في اللوحة",
|
|
"show_pipeline": "عرض pipeline الصفقات الحالية",
|
|
"show_at_risk_deals": "صفقات معرضة للخطر — جامدة أو single-threaded",
|
|
"show_revenue_leaks": "أين المال يتسرب — leaks المالية",
|
|
"compare_sectors": "مقارنة بين قطاعات",
|
|
"find_lookalikes": "شركات تشبه أفضل عملائنا",
|
|
"draft_outreach": "كتابة رسالة مخصصة",
|
|
"generate_qbr": "توليد QBR ربعي/شهري",
|
|
"generate_proof_pack": "توليد Proof Pack شهري",
|
|
"explain_compliance_block": "لماذا تم حظر هذا التواصل",
|
|
"show_market_radar": "حالة السوق والإشارات الجديدة",
|
|
"forecast_revenue": "توقعات الإيراد 30/60/90 يوم",
|
|
"stop_or_disable": "إيقاف autopilot أو حملة",
|
|
"general_help": "مساعدة عامة",
|
|
}
|
|
return [
|
|
{"intent_id": i, "description_ar": descriptions.get(i, "")}
|
|
for i in INTENTS
|
|
]
|