AlphaWice commited on
Commit
725d97d
·
verified ·
1 Parent(s): b97cadb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +328 -124
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'] # Common Arabic letter substitutions
 
 
 
41
  arabizi_patterns = [
42
- 'wach', 'wash', 'ach', 'achno', 'chno', 'shno', # What
43
- 'kif', 'kifash', 'ki', 'kayf', # How
44
- 'feen', 'fin', 'fen', # Where
45
- 'imta', 'meta', 'waqt', # When
46
- '3la', '3ala', 'ala', # On/about
47
- 'hna', '7na', 'ahna', # We/us
48
- 'nta', 'nti', 'ntuma', # You
49
- 'howa', 'hiya', 'huma', # He/she/they
50
- 'ma3', 'maa3', 'maak', 'maaki', # With
51
- 'had', 'hadchi', 'hada', 'hadi', # This
52
- 'bghit', 'bghiti', 'bgha', # Want
53
- 'galt', 'galti', 'gal', # Said
54
- 'rah', 'raha', 'rahi', # Going
55
- 'kan', 'kanu', 'kana', # Was/were
56
- 'ghadi', 'ghad', 'gha', # Will/going to
57
- 'daba', 'dak', 'dakchi', # Now/that
58
- 'bzf', 'bzzaf', 'bezzaf', # A lot
59
- 'chway', 'chwiya', 'shwiya', # A little
60
- 'khoya', 'khuya', 'akhi', # Brother
61
- 'khti', 'khtiya', 'ukhti', # Sister
62
- 'allah', 'llah', 'rabi', # God
63
- 'inchallah', 'insha allah', # God willing
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
- # Count Latin letters
71
- latin_letters = sum(1 for c in clean_text if c.isalpha() and ord(c) < 128)
72
 
73
- # Count Arabizi number substitutions
74
- arabizi_number_count = sum(1 for num in arabizi_numbers if num in clean_text)
 
 
 
 
 
75
 
76
- # Count Arabizi word patterns
77
- arabizi_word_count = sum(1 for pattern in arabizi_patterns if pattern in clean_text)
 
 
 
 
 
 
 
78
 
79
- # Decision logic
80
- total_chars = len(clean_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- # Strong indicators
83
- if arabizi_number_count >= 2: # Multiple number substitutions
84
- return True
 
 
 
 
 
85
 
86
- if arabizi_word_count >= 2: # Multiple Arabizi words
87
- return True
 
 
 
 
 
88
 
89
- # Medium indicators
90
- if arabizi_number_count >= 1 and latin_letters > total_chars * 0.7:
91
- return True
92
 
93
- if arabizi_word_count >= 1 and latin_letters > total_chars * 0.8:
94
- return True
 
 
 
95
 
96
- # Weak but possible indicators
97
- if latin_letters > total_chars * 0.9 and total_chars > 10:
98
- # Mostly Latin letters in longer text - could be Arabizi
99
- if arabizi_number_count >= 1 or arabizi_word_count >= 1:
100
- return True
101
 
102
- return False
 
 
 
 
 
103
 
104
- def determine_response_language(user_input):
105
  """
106
- Determine what language/script the response should be in
107
- Returns: 'arabizi', 'arabic', or 'english'
108
  """
109
- if detect_arabizi(user_input):
110
- return 'arabizi'
111
 
112
- # Check for Arabic script
113
- arabic_pattern = r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]'
114
- if re.search(arabic_pattern, user_input):
115
- return 'arabic'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
- # Default to English for Latin-only text without Arabizi indicators
118
- return 'english'
119
-
120
- def create_system_prompt(response_lang):
121
- """Create appropriate system prompt based on desired response language"""
 
 
 
 
 
122
 
123
- if response_lang == 'arabizi':
124
- return """You are Atlas-Chat, an AI assistant specialized in Moroccan Arabic (Darija).
125
-
126
- CRITICAL INSTRUCTION: The user has written in Arabizi (Latin script), so you MUST respond ONLY in Arabizi using Latin letters and numbers.
127
-
128
- ARABIZI RULES YOU MUST FOLLOW:
129
- - Use ONLY Latin letters (a-z) and numbers for Arabic sounds
130
- - Use these number substitutions: 3=ع, 7=ح, 9=ق, 2=ء, 5=خ, 6=ط, 8=غ
131
- - Write naturally in Moroccan Darija but with Latin script
132
- - Examples: "ana" (أنا), "hna" (حنا), "3la" (على), "7na" (حنا), "wach" (واش)
133
- - Do NOT use any Arabic script characters
134
- - Do NOT switch to English unless the user specifically asks for translation
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
- else: # English
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 language detection"""
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
- # Determine response language
154
- response_lang = determine_response_language(message)
155
 
156
- # Create appropriate system prompt
157
- system_prompt = create_system_prompt(response_lang)
158
-
159
- # Prepare messages with system context
160
- if response_lang == 'arabizi':
161
- # Extra emphasis for Arabizi responses
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
- messages = [
171
- {"role": "system", "content": system_prompt},
172
- {"role": "user", "content": message}
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
- # Post-process for Arabizi if needed
188
- if response_lang == 'arabizi':
189
- # Remove any Arabic script that might have leaked through
190
- arabic_pattern = r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]'
191
- if re.search(arabic_pattern, response):
192
- # If Arabic script is detected, provide a fallback Arabizi response
193
- response = "ana Atlas-Chat, kay3jebni n7der m3ak! chno bghiti t3ref 3la lmaghrib? (I'm Atlas-Chat, I'd love to chat with you! What do you want to know about Morocco?)"
194
-
195
- return response
196
 
197
  except Exception as e:
198
- return f"عذراً، واجهت خطأ: {str(e)}. جرب مرة أخرى! / Sorry, error occurred. Try again!"
 
 
 
 
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
- I'm an AI assistant specialized in **Moroccan Arabic (Darija)** with smart language detection:
 
 
 
208
 
209
- - **Arabic Script (العربية)** I respond in Arabic
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
  )