Update app.py
Browse files
app.py
CHANGED
@@ -28,121 +28,324 @@ def detect_arabizi(text):
|
|
28 |
if not text or len(text.strip()) < 2:
|
29 |
return False
|
30 |
|
31 |
-
# Remove spaces and convert to lowercase for analysis
|
32 |
-
clean_text = text.lower().replace(" ", "")
|
33 |
-
|
34 |
# Check for Arabic script - if present, it's NOT Arabizi
|
35 |
arabic_pattern = r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]'
|
36 |
if re.search(arabic_pattern, text):
|
37 |
return False
|
38 |
|
39 |
-
# Arabizi indicators
|
40 |
-
arabizi_numbers = ['2', '3', '7', '9'
|
|
|
|
|
|
|
41 |
arabizi_patterns = [
|
42 |
-
'wach', 'wash', 'ach', 'achno', 'chno', 'shno',
|
43 |
-
'kif', 'kifash', 'ki', 'kayf',
|
44 |
-
'feen', 'fin', 'fen',
|
45 |
-
'imta', 'meta', 'waqt',
|
46 |
-
'
|
47 |
-
'
|
48 |
-
'
|
49 |
-
'
|
50 |
-
'
|
51 |
-
'
|
52 |
-
'
|
53 |
-
'
|
54 |
-
'
|
55 |
-
'
|
56 |
-
'
|
57 |
-
'
|
58 |
-
'
|
59 |
-
'
|
60 |
-
'
|
61 |
-
'
|
62 |
-
'
|
63 |
-
'
|
64 |
-
'hamdulillah', 'alhamdulillah', # Praise God
|
65 |
-
'salam', 'salamu aleikum', # Peace
|
66 |
-
'baraka', 'barakallahu', # Blessing
|
67 |
-
'yallah', 'yalla', 'hya' # Come on/let's go
|
68 |
]
|
69 |
|
70 |
-
|
71 |
-
|
72 |
|
73 |
-
#
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
-
#
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
-
#
|
83 |
-
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
-
#
|
90 |
-
|
91 |
-
return True
|
92 |
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
#
|
97 |
-
|
98 |
-
|
99 |
-
if arabizi_number_count >= 1 or arabizi_word_count >= 1:
|
100 |
-
return True
|
101 |
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
-
def
|
105 |
"""
|
106 |
-
|
107 |
-
|
108 |
"""
|
109 |
-
if
|
110 |
-
return
|
111 |
|
112 |
-
#
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
-
#
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
Respond naturally in Arabizi about Moroccan culture, language, and general topics."""
|
137 |
-
|
138 |
-
elif response_lang == 'arabic':
|
139 |
-
return """You are Atlas-Chat, an AI assistant specialized in Moroccan Arabic (Darija). Respond in Arabic script (Darija) as this is what the user is using. Be helpful and culturally aware about Morocco and its traditions."""
|
140 |
|
141 |
-
|
142 |
-
return """You are Atlas-Chat, an AI assistant specialized in Moroccan Arabic (Darija) but also fluent in English. The user has written in English, so respond in English while being knowledgeable about Moroccan culture and language."""
|
143 |
|
144 |
def chat_with_atlas(message, history):
|
145 |
-
"""Generate response from Atlas-Chat model with
|
146 |
if not message.strip():
|
147 |
return "مرحبا! أهلا وسهلا. Please enter a message! / Ahlan wa sahlan!"
|
148 |
|
@@ -150,29 +353,22 @@ def chat_with_atlas(message, history):
|
|
150 |
# Load model if not already loaded
|
151 |
model = load_model()
|
152 |
|
153 |
-
#
|
154 |
-
|
155 |
|
156 |
-
#
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
enhanced_message = f"""System: {system_prompt}
|
163 |
-
|
164 |
-
User message (in Arabizi): {message}
|
165 |
-
|
166 |
-
Remember: Respond ONLY in Arabizi (Latin letters + numbers). Do not use Arabic script."""
|
167 |
-
|
168 |
-
messages = [{"role": "user", "content": enhanced_message}]
|
169 |
else:
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
|
|
174 |
|
175 |
-
# Generate response
|
176 |
outputs = model(
|
177 |
messages,
|
178 |
max_new_tokens=256,
|
@@ -184,18 +380,21 @@ Remember: Respond ONLY in Arabizi (Latin letters + numbers). Do not use Arabic s
|
|
184 |
# Extract the response
|
185 |
response = outputs[0]["generated_text"][-1]["content"].strip()
|
186 |
|
187 |
-
#
|
188 |
-
if
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
return response
|
196 |
|
197 |
except Exception as e:
|
198 |
-
|
|
|
|
|
|
|
|
|
199 |
|
200 |
# Create the Gradio interface
|
201 |
demo = gr.ChatInterface(
|
@@ -204,11 +403,12 @@ demo = gr.ChatInterface(
|
|
204 |
description="""
|
205 |
**مرحبا بك في أطلس شات!** Welcome to Atlas-Chat! 🇲🇦
|
206 |
|
207 |
-
|
|
|
|
|
|
|
208 |
|
209 |
-
|
210 |
-
- **Arabizi (3arabi bi 7oruf latin)** → I respond in Arabizi
|
211 |
-
- **English** → I respond in English
|
212 |
|
213 |
**جرب هذه الأسئلة / Try these questions:**
|
214 |
""",
|
@@ -222,7 +422,11 @@ demo = gr.ChatInterface(
|
|
222 |
"What is Morocco famous for?",
|
223 |
"Tell me about Casablanca",
|
224 |
"كيفاش نقدر نتعلم الدارجة؟",
|
225 |
-
"kifash n9der nt3elem darija?"
|
|
|
|
|
|
|
|
|
226 |
],
|
227 |
cache_examples=False
|
228 |
)
|
|
|
28 |
if not text or len(text.strip()) < 2:
|
29 |
return False
|
30 |
|
|
|
|
|
|
|
31 |
# Check for Arabic script - if present, it's NOT Arabizi
|
32 |
arabic_pattern = r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]'
|
33 |
if re.search(arabic_pattern, text):
|
34 |
return False
|
35 |
|
36 |
+
# Arabizi indicators - numbers used as letters
|
37 |
+
arabizi_numbers = ['2', '3', '7', '9', '5', '6', '8']
|
38 |
+
has_arabizi_numbers = any(num in text for num in arabizi_numbers)
|
39 |
+
|
40 |
+
# Common Arabizi words and patterns
|
41 |
arabizi_patterns = [
|
42 |
+
'wach', 'wash', 'ach', 'achno', 'chno', 'shno', 'shkoun', 'chkoun',
|
43 |
+
'kif', 'kifash', 'ki', 'kayf', 'kien', 'kima',
|
44 |
+
'feen', 'fin', 'fen', 'fain', 'mnin',
|
45 |
+
'imta', 'meta', 'waqt', 'mata', 'emta',
|
46 |
+
'hna', 'ahna', 'ana', 'nta', 'nti', 'ntuma', 'ntouma',
|
47 |
+
'howa', 'hiya', 'huma', 'houma', 'hoa', 'hia',
|
48 |
+
'had', 'hadchi', 'hada', 'hadi', 'hadou', 'hadouk',
|
49 |
+
'bghit', 'bghiti', 'bgha', 'bghina', 'bghitiou',
|
50 |
+
'galt', 'galti', 'gal', 'galet', 'galou',
|
51 |
+
'rah', 'raha', 'rahi', 'rahom', 'rahin',
|
52 |
+
'kan', 'kanu', 'kana', 'kanet', 'kano',
|
53 |
+
'ghadi', 'ghad', 'gha', 'ghadia', 'ghadiyin',
|
54 |
+
'daba', 'dak', 'dakchi', 'dik', 'dok',
|
55 |
+
'bzf', 'bzzaf', 'bezzaf', 'bzaaaaf',
|
56 |
+
'chway', 'chwiya', 'shwiya', 'chwia',
|
57 |
+
'khoya', 'khuya', 'akhi', 'kho',
|
58 |
+
'khti', 'khtiya', 'ukhti', 'kht',
|
59 |
+
'mama', 'baba', 'lwaldin', 'lwalidin',
|
60 |
+
'salam', 'salamu aleikum', 'slm',
|
61 |
+
'yallah', 'yalla', 'hya', 'aji',
|
62 |
+
'mabghitsh', 'mabghach', 'makansh', 'machi',
|
63 |
+
'walakin', 'walaken', 'ama', 'mais'
|
|
|
|
|
|
|
|
|
64 |
]
|
65 |
|
66 |
+
text_lower = text.lower()
|
67 |
+
has_arabizi_words = any(pattern in text_lower for pattern in arabizi_patterns)
|
68 |
|
69 |
+
# Decision logic
|
70 |
+
if has_arabizi_numbers and has_arabizi_words:
|
71 |
+
return True
|
72 |
+
if has_arabizi_numbers and len([c for c in text if c.isalpha()]) > len(text) * 0.6:
|
73 |
+
return True
|
74 |
+
if has_arabizi_words and len([c for c in text if c.isalpha()]) > len(text) * 0.7:
|
75 |
+
return True
|
76 |
|
77 |
+
return False
|
78 |
+
|
79 |
+
def arabizi_to_arabic(text):
|
80 |
+
"""
|
81 |
+
Convert Arabizi text to Arabic script
|
82 |
+
COMPLETE HARD-CODED MAPPINGS
|
83 |
+
"""
|
84 |
+
if not text:
|
85 |
+
return text
|
86 |
|
87 |
+
# COMPREHENSIVE WORD MAPPINGS (Arabizi → Arabic)
|
88 |
+
word_mappings = {
|
89 |
+
# Pronouns
|
90 |
+
'ana': 'أنا', 'nta': 'نتا', 'nti': 'نتي', 'howa': 'هوا', 'hiya': 'هيا',
|
91 |
+
'hoa': 'هوا', 'hia': 'هيا', 'hna': 'حنا', 'ahna': 'أحنا',
|
92 |
+
'ntuma': 'نتوما', 'ntouma': 'نتوما', 'huma': 'هوما', 'houma': 'هوما',
|
93 |
+
|
94 |
+
# Question words
|
95 |
+
'shkoun': 'شكون', 'chkoun': 'شكون', 'skoun': 'شكون',
|
96 |
+
'achno': 'أشنو', 'chno': 'شنو', 'shno': 'شنو', 'ach': 'أش',
|
97 |
+
'wach': 'واش', 'wash': 'واش', 'ouach': 'واش',
|
98 |
+
'kifash': 'كيفاش', 'kif': 'كيف', 'ki': 'كي', 'kayf': 'كيف',
|
99 |
+
'feen': 'فين', 'fin': 'فين', 'fen': 'فين', 'fain': 'فين', 'mnin': 'منين',
|
100 |
+
'imta': 'إمتا', 'meta': 'متا', 'mata': 'متا', 'emta': 'إمتا',
|
101 |
+
'3lach': 'علاش', 'alach': 'علاش', '3la ach': 'علاش',
|
102 |
+
|
103 |
+
# Common verbs
|
104 |
+
'bghit': 'بغيت', 'bghiti': 'بغيتي', 'bgha': 'بغا', 'bghina': 'بغينا',
|
105 |
+
'kan': 'كان', 'kana': 'كانا', 'kanet': 'كانت', 'kanu': 'كانو',
|
106 |
+
'galt': 'قلت', 'galti': 'قلتي', 'gal': 'قال', 'galet': 'قالت',
|
107 |
+
'galou': 'قالو', 'galina': 'قلنا',
|
108 |
+
'rah': 'راح', 'raha': 'راها', 'rahi': 'راهي', 'rahom': 'راهم',
|
109 |
+
'ghadi': 'غادي', 'ghad': 'غاد', 'gha': 'غا', 'ghadia': 'غادية',
|
110 |
+
'dir': 'دير', 'dert': 'درت', 'derat': 'درات', 'derna': 'درنا',
|
111 |
+
'ja': 'جا', 'jat': 'جات', 'jina': 'جينا', 'jaou': 'جاو',
|
112 |
+
'mcha': 'مشا', 'mchat': 'مشات', 'mchina': 'مشينا', 'mchaou': 'مشاو',
|
113 |
+
'khrj': 'خرج', 'khrja': 'خرجا', 'khrjat': 'خرجات', 'khrjna': 'خرجنا',
|
114 |
+
'dkhl': 'دخل', 'dkhla': 'دخلا', 'dkhlat': 'دخلات', 'dkhlna': 'دخلنا',
|
115 |
+
|
116 |
+
# Demonstratives
|
117 |
+
'had': 'هاد', 'hada': 'هادا', 'hadi': 'هادي', 'hadou': 'هادو',
|
118 |
+
'hadouk': 'هادوك', 'hadchi': 'هادشي', 'hadak': 'هاداك',
|
119 |
+
'dak': 'داك', 'dik': 'ديك', 'dok': 'دوك', 'dakchi': 'داكشي',
|
120 |
+
|
121 |
+
# Prepositions
|
122 |
+
'fi': 'في', 'f': 'ف', 'men': 'من', 'mn': 'من', 'l': 'ل', 'li': 'لي',
|
123 |
+
'bla': 'بلا', 'b': 'ب', 'bi': 'بي', 'bih': 'بيه', 'biha': 'بيها',
|
124 |
+
'mea': 'معا', 'maak': 'معاك', 'maaki': 'معاكي', 'maana': 'معانا',
|
125 |
+
'maahom': 'معاهم', 'maaha': 'معاها',
|
126 |
+
|
127 |
+
# Numbers
|
128 |
+
'wahed': 'واحد', 'joj': 'جوج', 'tlata': 'تلاتا', 'rebaa': 'ربعا',
|
129 |
+
'khamsa': 'خمسا', 'setta': 'ستا', 'sebaa': 'سبعا', 'tmanya': 'تمنيا',
|
130 |
+
'tesaa': 'تسعا', 'ashra': 'عشرا',
|
131 |
+
|
132 |
+
# Time expressions
|
133 |
+
'daba': 'دابا', 'tawa': 'توا', 'ghda': 'غدا', 'lbareeh': 'البارح',
|
134 |
+
'nhar': 'نهار', 'lila': 'ليلا', 'sbah': 'صباح', 'aachia': 'عشيا',
|
135 |
+
|
136 |
+
# Family
|
137 |
+
'mama': 'ماما', 'baba': 'بابا', 'khoya': 'خويا', 'khti': 'ختي',
|
138 |
+
'khuya': 'خويا', 'khtiya': 'ختيا', 'akhi': 'أخي', 'ukhti': 'أختي',
|
139 |
+
'jad': 'جد', 'jada': 'جدا', 'amo': 'عمو', 'ama': 'عما',
|
140 |
+
'khal': 'خال', 'khala': 'خالا',
|
141 |
+
|
142 |
+
# Adjectives
|
143 |
+
'zwin': 'زوين', 'zwina': 'زوينا', 'qbih': 'قبيح', 'qbiha': 'قبيحا',
|
144 |
+
'kbir': 'كبير', 'kbira': 'كبيرا', 'sghir': 'صغير', 'sghira': 'صغيرا',
|
145 |
+
'tqil': 'تقيل', 'tqila': 'تقيلا', 'khfif': 'خفيف', 'khfifa': 'خفيفا',
|
146 |
+
'sahel': 'ساهل', 'sahla': 'ساهلا', 'saab': 'صعب', 'saba': 'صعبا',
|
147 |
+
|
148 |
+
# Quantities
|
149 |
+
'bzf': 'بزاف', 'bzzaf': 'بزاف', 'bezzaf': 'بزاف', 'ktir': 'كتير',
|
150 |
+
'chway': 'شوياة', 'chwiya': 'شوياة', 'shwiya': 'شوياة', 'chwia': 'شوياة',
|
151 |
+
'kolchi': 'كولشي', 'kol': 'كول', 'ga': 'غاع', 'gaa': 'غاع',
|
152 |
+
'hta': 'حتا', 'walo': 'والو', 'walou': 'والو',
|
153 |
+
|
154 |
+
# Negations
|
155 |
+
'ma': 'ما', 'machi': 'ماشي', 'mabghitsh': 'مابغيتش', 'makainch': 'ماكاينش',
|
156 |
+
'makansh': 'ماكانش', 'maghatch': 'ماغاتش', 'mabaghish': 'مابغيش',
|
157 |
+
|
158 |
+
# Conjunctions
|
159 |
+
'walakin': 'والاكين', 'walaken': 'والاكين', 'mais': 'ولكن',
|
160 |
+
'ama': 'أما', 'ida': 'إذا', 'ila': 'إلا', 'hta': 'حتا',
|
161 |
+
'ou': 'أو', 'o': 'أو', 'aw': 'أو', 'wla': 'ولا',
|
162 |
+
|
163 |
+
# Expressions
|
164 |
+
'salam': 'سلام', 'yallah': 'يالاه', 'yalla': 'يالا', 'hya': 'هيا',
|
165 |
+
'aji': 'أجي', 'sir': 'سير', 'siri': 'سيري', 'ajou': 'أجو',
|
166 |
+
'mabrook': 'مبروك', 'baraka': 'باركا', 'besaha': 'بصحا',
|
167 |
+
'allah': 'الله', 'rabi': 'ربي', 'llah': 'الله',
|
168 |
+
'inchallah': 'إن شاء الله', 'machallah': 'ما شاء الله',
|
169 |
+
'hamdulillah': 'الحمد لله', 'alhamdulillah': 'الحمد لله',
|
170 |
+
'la hawla': 'لا حول', 'astghfirullah': 'أستغفر الله',
|
171 |
+
|
172 |
+
# Countries and places
|
173 |
+
'lmaghrib': 'المغرب', 'maghrib': 'مغرب', 'casa': 'كازا',
|
174 |
+
'rbat': 'الرباط', 'fas': 'فاس', 'mknas': 'مكناس',
|
175 |
+
'tanja': 'طنجا', 'agadir': 'أكادير', 'marrakech': 'مراكش',
|
176 |
+
|
177 |
+
# Common nouns
|
178 |
+
'dar': 'دار', 'bit': 'بيت', 'tomo': 'طوموبيل', 'karhouba': 'كرهوبا',
|
179 |
+
'makla': 'ماكلا', 'atay': 'أتاي', 'khobz': 'خوبز', 'lma': 'الما',
|
180 |
+
'tajin': 'طاجين', 'tajine': 'طاجين', 'couscous': 'كوسكوس',
|
181 |
+
'msemen': 'مسمن', 'rghaif': 'رغايف', 'harira': 'حريرا',
|
182 |
+
'khodra': 'خضرا', 'fawakeh': 'فواكه', 'lahem': 'ل��م',
|
183 |
+
'djaj': 'دجاج', 'hout': 'حوت', 'lben': 'اللبن',
|
184 |
+
'skar': 'سكر', 'melh': 'ملح', 'zit': 'زيت', 'zebda': 'زبدا',
|
185 |
+
|
186 |
+
# Verbs (additional)
|
187 |
+
'chreb': 'شرب', 'chrba': 'شربا', 'chrebat': 'شربات', 'chrebna': 'شربنا',
|
188 |
+
'kla': 'كلا', 'klat': 'كلات', 'klina': 'كلينا', 'klaw': 'كلاو',
|
189 |
+
'nees': 'نعس', 'neesat': 'نعسات', 'neesna': 'نعسنا', 'neasou': 'نعسو',
|
190 |
+
'faq': 'فاق', 'faqat': 'فاقات', 'faqna': 'فقنا', 'faqou': 'فاقو',
|
191 |
+
'tlab': 'طلب', 'tlbat': 'طلبات', 'tlabna': 'طلبنا', 'tlabou': 'طلبو',
|
192 |
+
'khdam': 'خدم', 'khdmat': 'خدمات', 'khdamna': 'خدمنا', 'khdamou': 'خدمو',
|
193 |
+
'qra': 'قرا', 'qrat': 'قرات', 'qrina': 'قرينا', 'qraw': 'قراو',
|
194 |
+
'kteb': 'كتب', 'ktbat': 'كتبات', 'ktebna': 'كتبنا', 'ktbou': 'كتبو',
|
195 |
+
'chaf': 'شاف', 'chafat': 'شافات', 'chfna': 'شفنا', 'chafou': 'شافو',
|
196 |
+
'sma': 'سمع', 'smat': 'سمعات', 'smana': 'سمعنا', 'smaou': 'سمعو'
|
197 |
+
}
|
198 |
|
199 |
+
# CHARACTER MAPPINGS (Arabizi numbers/letters → Arabic)
|
200 |
+
char_mappings = {
|
201 |
+
'2': 'ء', '3': 'ع', '5': 'خ', '6': 'ط', '7': 'ح', '8': 'غ', '9': 'ق',
|
202 |
+
'a': 'ا', 'b': 'ب', 't': 'ت', 'th': 'ث', 'j': 'ج', 'd': 'د',
|
203 |
+
'r': 'ر', 'z': 'ز', 's': 'س', 'sh': 'ش', 'f': 'ف', 'k': 'ك',
|
204 |
+
'l': 'ل', 'm': 'م', 'n': 'ن', 'h': 'ه', 'w': 'و', 'y': 'ي',
|
205 |
+
'aa': 'آ', 'ee': 'ي', 'oo': 'و', 'ou': 'و', 'ai': 'ي', 'ay': 'ي'
|
206 |
+
}
|
207 |
|
208 |
+
# DIGRAPH MAPPINGS (two-letter combinations first)
|
209 |
+
digraph_mappings = {
|
210 |
+
'kh': 'خ', 'gh': 'غ', 'ch': 'ش', 'th': 'ث', 'dh': 'ذ',
|
211 |
+
'sh': 'ش', 'ts': 'ص', 'dz': 'ض', 'ss': 'ص', 'tt': 'ط',
|
212 |
+
'zz': 'ظ', 'aa': 'آ', 'ee': 'ي', 'ii': 'ي', 'oo': 'و',
|
213 |
+
'uu': 'و', 'ou': 'و', 'ai': 'ي', 'ay': 'ي', 'ey': 'ي'
|
214 |
+
}
|
215 |
|
216 |
+
# Convert text
|
217 |
+
result = text.lower()
|
|
|
218 |
|
219 |
+
# Step 1: Apply word mappings (most specific first)
|
220 |
+
for arabizi_word, arabic_word in word_mappings.items():
|
221 |
+
# Use word boundaries to avoid partial matches
|
222 |
+
pattern = r'\b' + re.escape(arabizi_word) + r'\b'
|
223 |
+
result = re.sub(pattern, arabic_word, result, flags=re.IGNORECASE)
|
224 |
|
225 |
+
# Step 2: Apply digraph mappings
|
226 |
+
for digraph, arabic_char in digraph_mappings.items():
|
227 |
+
result = result.replace(digraph, arabic_char)
|
|
|
|
|
228 |
|
229 |
+
# Step 3: Apply single character mappings
|
230 |
+
for char, arabic_char in char_mappings.items():
|
231 |
+
if len(char) == 1: # Only single chars in this step
|
232 |
+
result = result.replace(char, arabic_char)
|
233 |
+
|
234 |
+
return result
|
235 |
|
236 |
+
def arabic_to_arabizi(text):
|
237 |
"""
|
238 |
+
Convert Arabic script to Arabizi
|
239 |
+
COMPLETE HARD-CODED MAPPINGS
|
240 |
"""
|
241 |
+
if not text:
|
242 |
+
return text
|
243 |
|
244 |
+
# COMPREHENSIVE WORD MAPPINGS (Arabic → Arabizi)
|
245 |
+
word_mappings = {
|
246 |
+
# Pronouns
|
247 |
+
'أنا': 'ana', 'نتا': 'nta', 'نتي': 'nti', 'هوا': 'howa', 'هيا': 'hiya',
|
248 |
+
'حنا': 'hna', 'أحنا': 'ahna', 'نتوما': 'ntuma', 'هوما': 'huma',
|
249 |
+
|
250 |
+
# Question words
|
251 |
+
'شكون': 'shkoun', 'أشنو': 'achno', 'شنو': 'chno', 'أش': 'ach',
|
252 |
+
'واش': 'wach', 'كيفاش': 'kifash', 'كيف': 'kif', 'فين': 'feen',
|
253 |
+
'منين': 'mnin', 'إمتا': 'imta', 'متا': 'meta', 'علاش': '3lach',
|
254 |
+
|
255 |
+
# Common verbs
|
256 |
+
'بغيت': 'bghit', 'بغيتي': 'bghiti', 'بغا': 'bgha', 'بغينا': 'bghina',
|
257 |
+
'كان': 'kan', 'كانا': 'kana', 'كانت': 'kanet', 'كانو': 'kanu',
|
258 |
+
'قلت': 'galt', 'قلتي': 'galti', 'قال': 'gal', 'قالت': 'galet',
|
259 |
+
'قالو': 'galou', 'قلنا': 'galina',
|
260 |
+
'راح': 'rah', 'راها': 'raha', 'راهي': 'rahi', 'راهم': 'rahom',
|
261 |
+
'غادي': 'ghadi', 'غاد': 'ghad', 'غ��': 'gha', 'غادية': 'ghadia',
|
262 |
+
'دير': 'dir', 'درت': 'dert', 'درات': 'derat', 'درنا': 'derna',
|
263 |
+
'جا': 'ja', 'جات': 'jat', 'جينا': 'jina', 'جاو': 'jaou',
|
264 |
+
'مشا': 'mcha', 'مشات': 'mchat', 'مشينا': 'mchina', 'مشاو': 'mchaou',
|
265 |
+
|
266 |
+
# Demonstratives
|
267 |
+
'هاد': 'had', 'هادا': 'hada', 'هادي': 'hadi', 'هادو': 'hadou',
|
268 |
+
'هادوك': 'hadouk', 'هادشي': 'hadchi', 'هاداك': 'hadak',
|
269 |
+
'داك': 'dak', 'ديك': 'dik', 'دوك': 'dok', 'داكشي': 'dakchi',
|
270 |
+
|
271 |
+
# Numbers
|
272 |
+
'واحد': 'wahed', 'جوج': 'joj', 'تلاتا': 'tlata', 'ربعا': 'rebaa',
|
273 |
+
'خمسا': 'khamsa', 'ستا': 'setta', 'سبعا': 'sebaa', 'تمنيا': 'tmanya',
|
274 |
+
'تسعا': 'tesaa', 'عشرا': 'ashra',
|
275 |
+
|
276 |
+
# Time
|
277 |
+
'دابا': 'daba', 'توا': 'tawa', 'غدا': 'ghda', 'البارح': 'lbareeh',
|
278 |
+
'نهار': 'nhar', 'ليلا': 'lila', 'صباح': 'sbah', 'عشيا': 'aachia',
|
279 |
+
|
280 |
+
# Family
|
281 |
+
'ماما': 'mama', 'بابا': 'baba', 'خويا': 'khoya', 'ختي': 'khti',
|
282 |
+
'ختيا': 'khtiya', 'أخي': 'akhi', 'أختي': 'ukhti',
|
283 |
+
'جد': 'jad', 'جدا': 'jada', 'عمو': 'amo', 'عما': 'ama',
|
284 |
+
|
285 |
+
# Adjectives
|
286 |
+
'زوين': 'zwin', 'زوينا': 'zwina', 'قبيح': 'qbih', 'قبيحا': 'qbiha',
|
287 |
+
'كبير': 'kbir', 'كبيرا': 'kbira', 'صغير': 'sghir', 'صغيرا': 'sghira',
|
288 |
+
'تقيل': 'tqil', 'تقيلا': 'tqila', 'خفيف': 'khfif', 'خفيفا': 'khfifa',
|
289 |
+
|
290 |
+
# Quantities
|
291 |
+
'بزاف': 'bzzaf', 'كتير': 'ktir', 'شوياة': 'chwiya', 'كولشي': 'kolchi',
|
292 |
+
'كول': 'kol', 'غاع': 'gaa', 'حتا': 'hta', 'والو': 'walo',
|
293 |
+
|
294 |
+
# Negations
|
295 |
+
'ما': 'ma', 'ماشي': 'machi', 'مابغيتش': 'mabghitsh', 'ماكاينش': 'makainch',
|
296 |
+
'ماكانش': 'makansh', 'ماغاتش': 'maghatch', 'مابغيش': 'mabaghish',
|
297 |
+
|
298 |
+
# Expressions
|
299 |
+
'سلام': 'salam', 'يالاه': 'yallah', 'يالا': 'yalla', 'هيا': 'hya',
|
300 |
+
'أجي': 'aji', 'سير': 'sir', 'سيري': 'siri', 'أجو': 'ajou',
|
301 |
+
'مبروك': 'mabrook', 'باركا': 'baraka', 'بصحا': 'besaha',
|
302 |
+
'الله': 'allah', 'ربي': 'rabi', 'إن شاء الله': 'inchallah',
|
303 |
+
'ما شاء الله': 'machallah', 'الحمد لله': 'hamdulillah',
|
304 |
+
|
305 |
+
# Places
|
306 |
+
'المغرب': 'lmaghrib', 'مغرب': 'maghrib', 'كازا': 'casa',
|
307 |
+
'الرباط': 'rbat', 'فاس': 'fas', 'مكناس': 'mknas',
|
308 |
+
'طنجا': 'tanja', 'أكادير': 'agadir', 'مراكش': 'marrakech',
|
309 |
+
|
310 |
+
# Food and drinks
|
311 |
+
'طاجين': 'tajine', 'كوسكوس': 'couscous', 'مسمن': 'msemen',
|
312 |
+
'رغايف': 'rghaif', 'حريرا': 'harira', 'أتاي': 'atay',
|
313 |
+
'خوبز': 'khobz', 'الما': 'lma', 'لحم': 'lahem', 'دجاج': 'djaj',
|
314 |
+
|
315 |
+
# Common nouns
|
316 |
+
'دار': 'dar', 'بيت': 'bit', 'طوموبيل': 'tomo', 'كرهوبا': 'karhouba',
|
317 |
+
'ماكلا': 'makla', 'خضرا': 'khodra', 'فواكه': 'fawakeh',
|
318 |
+
'حوت': 'hout', 'اللبن': 'lben', 'سكر': 'skar', 'ملح': 'melh'
|
319 |
+
}
|
320 |
|
321 |
+
# CHARACTER MAPPINGS (Arabic → Arabizi)
|
322 |
+
char_mappings = {
|
323 |
+
'ا': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'j', 'ح': '7',
|
324 |
+
'خ': 'kh', 'د': 'd', 'ذ': 'dh', 'ر': 'r', 'ز': 'z', 'س': 's',
|
325 |
+
'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': '6', 'ظ': 'z', 'ع': '3',
|
326 |
+
'غ': 'gh', 'ف': 'f', 'ق': '9', 'ك': 'k', 'ل': 'l', 'م': 'm',
|
327 |
+
'ن': 'n', 'ه': 'h', 'و': 'w', 'ي': 'y', 'ء': '2',
|
328 |
+
'آ': 'aa', 'أ': 'a', 'إ': 'i', 'ئ': '2', 'ؤ': 'w2', 'ة': 'a',
|
329 |
+
'ى': 'a', 'ً': 'an', 'ٌ': 'on', 'ٍ': 'in', 'َ': 'a', 'ُ': 'o', 'ِ': 'i'
|
330 |
+
}
|
331 |
|
332 |
+
# Convert text
|
333 |
+
result = text
|
334 |
+
|
335 |
+
# Step 1: Apply word mappings (most specific first)
|
336 |
+
for arabic_word, arabizi_word in word_mappings.items():
|
337 |
+
# Use word boundaries to avoid partial matches
|
338 |
+
pattern = r'\b' + re.escape(arabic_word) + r'\b'
|
339 |
+
result = re.sub(pattern, arabizi_word, result)
|
340 |
+
|
341 |
+
# Step 2: Apply character mappings
|
342 |
+
for arabic_char, arabizi_char in char_mappings.items():
|
343 |
+
result = result.replace(arabic_char, arabizi_char)
|
|
|
|
|
|
|
|
|
|
|
344 |
|
345 |
+
return result
|
|
|
346 |
|
347 |
def chat_with_atlas(message, history):
|
348 |
+
"""Generate response from Atlas-Chat model with Arabizi conversion"""
|
349 |
if not message.strip():
|
350 |
return "مرحبا! أهلا وسهلا. Please enter a message! / Ahlan wa sahlan!"
|
351 |
|
|
|
353 |
# Load model if not already loaded
|
354 |
model = load_model()
|
355 |
|
356 |
+
# Detect if input is Arabizi
|
357 |
+
is_arabizi_input = detect_arabizi(message)
|
358 |
|
359 |
+
# Prepare input for the model
|
360 |
+
if is_arabizi_input:
|
361 |
+
# Convert Arabizi to Arabic for the model
|
362 |
+
arabic_input = arabizi_to_arabic(message)
|
363 |
+
print(f"🔄 Converted Arabizi '{message}' → Arabic '{arabic_input}'")
|
364 |
+
model_input = arabic_input
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
else:
|
366 |
+
# Use original input (Arabic or English)
|
367 |
+
model_input = message
|
368 |
+
|
369 |
+
# Generate response using Arabic input
|
370 |
+
messages = [{"role": "user", "content": model_input}]
|
371 |
|
|
|
372 |
outputs = model(
|
373 |
messages,
|
374 |
max_new_tokens=256,
|
|
|
380 |
# Extract the response
|
381 |
response = outputs[0]["generated_text"][-1]["content"].strip()
|
382 |
|
383 |
+
# Convert response back to Arabizi if input was Arabizi
|
384 |
+
if is_arabizi_input:
|
385 |
+
arabizi_response = arabic_to_arabizi(response)
|
386 |
+
print(f"🔄 Converted response '{response}' → Arabizi '{arabizi_response}'")
|
387 |
+
return arabizi_response
|
388 |
+
else:
|
389 |
+
# Return original response for Arabic/English
|
390 |
+
return response
|
|
|
391 |
|
392 |
except Exception as e:
|
393 |
+
# Return error in appropriate language
|
394 |
+
if detect_arabizi(message):
|
395 |
+
return f"sorry, kan chi mochkil: {str(e)}. 3awd jar'b!"
|
396 |
+
else:
|
397 |
+
return f"عذراً، واجهت خطأ: {str(e)}. جرب مرة أخرى! / Sorry, error occurred: {str(e)}. Try again!"
|
398 |
|
399 |
# Create the Gradio interface
|
400 |
demo = gr.ChatInterface(
|
|
|
403 |
description="""
|
404 |
**مرحبا بك في أطلس شات!** Welcome to Atlas-Chat! 🇲🇦
|
405 |
|
406 |
+
**🧠 Smart Language Detection & Conversion:**
|
407 |
+
- **Arabic Script (العربية)** → AI responds in Arabic
|
408 |
+
- **Arabizi (3arabi bi 7oruf latin)** → AI responds in Arabizi
|
409 |
+
- **English** → AI responds in English
|
410 |
|
411 |
+
**✨ Full Arabizi Support:** Type "shkoun nta?" and get "ana atlas-chat..."
|
|
|
|
|
412 |
|
413 |
**جرب هذه الأسئلة / Try these questions:**
|
414 |
""",
|
|
|
422 |
"What is Morocco famous for?",
|
423 |
"Tell me about Casablanca",
|
424 |
"كيفاش نقدر نتعلم الدارجة؟",
|
425 |
+
"kifash n9der nt3elem darija?",
|
426 |
+
"wach kayn atay f lmaghrib?",
|
427 |
+
"3lach lmaghrib zwien bzzaf?",
|
428 |
+
"kifash nsali tajine?",
|
429 |
+
"chno homa l2aklat lmaghribiya?"
|
430 |
],
|
431 |
cache_examples=False
|
432 |
)
|