kawkabelaloom commited on
Commit
eca263a
·
verified ·
1 Parent(s): b9ed97d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -112
app.py CHANGED
@@ -8,7 +8,7 @@ from datetime import datetime
8
  # استخدم Environment Variables (Secrets) بدل وضع Token في الكود
9
  MODEL_NAME = os.environ.get("MODEL_NAME", "kawkabelaloom/astramind")
10
  HF_TOKEN = os.environ.get("HF_TOKEN", "") # سيأتي من Secrets
11
- API_URL = f"https://router.huggingface.co/hf-inference/models/{MODEL_NAME}"
12
 
13
  # إعداد headers بشكل آمن
14
  headers = {"Authorization": f"Bearer {HF_TOKEN}"} if HF_TOKEN else {}
@@ -19,85 +19,144 @@ class AstramindChatbot:
19
  self.system_prompt = """أنت مساعد عربي ذكي اسمك "أسترا".
20
  أجب بلغة عربية واضحة ومفيدة. كن ودوداً ومتعاوناً."""
21
 
22
- def format_message(self, user_message):
23
- """تنسيق الرسالة للنموذج"""
24
- if not self.conversation_history:
25
- prompt = f"{self.system_prompt}\n\nالمستخدم: {user_message}\nأنت:"
26
- else:
27
- prompt = self.system_prompt + "\n\n"
28
- for msg in self.conversation_history[-3:]:
29
- role = "المستخدم" if msg["role"] == "user" else "أنت"
30
- prompt += f"{role}: {msg['content']}\n"
31
- prompt += f"المستخدم: {user_message}\nأنت:"
32
 
33
- self.conversation_history.append({"role": "user", "content": user_message})
34
- return prompt
 
 
 
 
 
 
35
 
36
- def send_to_model(self, prompt, max_tokens=200, temperature=0.7):
37
- """إرسال للنموذج - بدون token إذا مش متاح"""
38
  try:
 
 
 
 
 
 
39
  payload = {
40
- "inputs": prompt,
41
  "parameters": {
42
  "max_new_tokens": max_tokens,
43
  "temperature": temperature,
44
  "top_p": 0.9,
45
- "return_full_text": False,
46
  "do_sample": True
47
  }
48
  }
49
 
50
- # إذا بدون token، جرب نموذج عام بديل
51
- if not HF_TOKEN:
52
- # استخدم نموذج Qwen العام بدون token
53
- alt_url = "https://router.huggingface.co/hf-inference/models/Qwen/Qwen2.5-7B-Instruct"
54
- response = requests.post(alt_url, json=payload, timeout=20)
55
- else:
56
- response = requests.post(API_URL, headers=headers, json=payload, timeout=30)
 
 
57
 
58
  if response.status_code == 200:
59
  result = response.json()
60
 
61
- if isinstance(result, list) and len(result) > 0:
 
 
62
  if 'generated_text' in result[0]:
63
- full_response = result[0]['generated_text']
64
- # استخراج الرد الأخير
65
- lines = full_response.split('\n')
66
- for line in reversed(lines):
67
- if line.strip() and not line.startswith('المستخدم:'):
68
- bot_response = line.replace('أنت:', '').strip()
69
- if bot_response:
70
- self.conversation_history.append({"role": "assistant", "content": bot_response})
71
- return bot_response
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
- return "عذراً، لم أفهم الرد."
74
 
75
- elif response.status_code in [401, 403]:
76
- return "⚠️ يبدو أن هناك مشكلة في التوكن. جاري استخدام نموذج بديل..."
77
  elif response.status_code == 503:
78
- return "🔄 النموذج مشغول الآن، جرب مرة أخرى بعد قليل."
 
 
 
79
  else:
80
- return f"⚠️ حدث خطأ: {response.status_code}"
 
 
81
 
82
  except Exception as e:
83
- return f"❌ خطأ في الاتصال: {str(e)[:100]}"
 
 
84
 
85
  def chat(self, user_message, max_tokens=200, temperature=0.7):
86
  """الدردشة مع البوت"""
87
  if not user_message.strip():
88
  return "⚠️ الرجاء كتابة رسالة."
89
 
90
- prompt = self.format_message(user_message)
91
- bot_response = self.send_to_model(prompt, max_tokens, temperature)
92
  return bot_response
93
 
94
  # إنشاء البوت
95
  chatbot = AstramindChatbot()
96
 
97
  # === واجهة Gradio ===
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  with gr.Blocks(
99
  title="🤖 Astramind - مساعد الدردشة",
100
- theme=gr.themes.Soft()
 
 
 
 
101
  ) as demo:
102
 
103
  gr.Markdown("""
@@ -105,105 +164,94 @@ with gr.Blocks(
105
  ### تحدث مع النموذج العربي الخاص بك
106
  """)
107
 
108
- # معلومات
109
- with gr.Row():
110
- gr.Markdown(f"""
111
- **المعلومات:**
112
- - النموذج: `{MODEL_NAME if HF_TOKEN else 'Qwen/Qwen2.5-7B-Instruct (بديل)'}`
113
- - الحالة: {'🔐 باستخدام Token' if HF_TOKEN else '🔓 بدون Token (بديل)'}
114
- - الوقت: {datetime.now().strftime('%H:%M')}
115
- """)
 
 
 
 
 
116
 
117
- # منطقة المحادثة
118
- chatbot_display = gr.Chatbot(label="المحادثة", height=400)
119
 
120
- # منطقة الإدخال
121
  with gr.Row():
122
  user_input = gr.Textbox(
123
- label="رسالتك",
124
- placeholder="اكتب سؤالك هنا...",
125
  lines=2,
126
  scale=4
127
  )
128
- send_btn = gr.Button("إرسال", variant="primary")
129
- clear_btn = gr.Button("مسح", variant="secondary")
130
 
131
  # إعدادات
132
- with gr.Accordion("⚙️ الإعدادات", open=False):
133
  with gr.Row():
134
- max_tokens = gr.Slider(50, 500, value=200, label="طول الرد")
135
- temperature = gr.Slider(0.1, 1.0, value=0.7, label="الإبداعية")
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- # أمثلة
138
  gr.Markdown("### 💡 أمثلة سريعة:")
139
-
140
  examples = gr.Examples(
141
  examples=[
142
- ["السلام عليكم"],
143
- ["ما هو اسمك؟"],
144
- ["كيف يمكنني التسجيل؟"],
145
- ["أخبرني نكتة"]
146
  ],
147
  inputs=user_input,
148
  label="جرب أحد هذه الأمثلة"
149
  )
150
 
151
- # متغير حالة
152
- status = gr.Textbox(label="الحالة", interactive=False)
153
-
154
- # وظائف
155
- def respond(message, history, tokens, temp):
156
- if not message.strip():
157
- return history, "", "اكتب رسالة أولاً"
158
-
159
- response = chatbot.chat(message, tokens, temp)
160
-
161
- # تحديث المحادثة
162
- if history is None:
163
- history = []
164
- history.append((message, response))
165
-
166
- # تحديث الحالة
167
- model_used = MODEL_NAME if HF_TOKEN else "Qwen (بديل)"
168
- status_msg = f"✅ تم الرد باستخدام: {model_used}"
169
-
170
- return history, "", status_msg
171
-
172
- def clear_history():
173
- chatbot.conversation_history = []
174
- return [], "تم مسح المحادثة"
175
-
176
  # ربط الأحداث
177
- user_input.submit(
178
- respond,
179
- [user_input, chatbot_display, max_tokens, temperature],
180
- [chatbot_display, user_input, status]
 
181
  )
182
 
183
- send_btn.click(
184
- respond,
185
- [user_input, chatbot_display, max_tokens, temperature],
186
- [chatbot_display, user_input, status]
 
187
  )
188
 
 
189
  clear_btn.click(
190
- clear_history,
191
- outputs=[chatbot_display, status]
192
  )
193
 
194
- # رسالة ترحيب
195
- def welcome_message():
196
- if HF_TOKEN:
197
- return f"🚀 جاهز! النموذج: {MODEL_NAME}"
198
- else:
199
- return "🚀 جاهز! باستخدام نموذج Qwen البديل (بدون Token)"
200
-
201
- demo.load(welcome_message, outputs=status)
202
 
203
  # التشغيل
204
  if __name__ == "__main__":
 
205
  demo.launch(
206
- debug=True,
207
  server_name="0.0.0.0",
208
- server_port=7860
 
209
  )
 
8
  # استخدم Environment Variables (Secrets) بدل وضع Token في الكود
9
  MODEL_NAME = os.environ.get("MODEL_NAME", "kawkabelaloom/astramind")
10
  HF_TOKEN = os.environ.get("HF_TOKEN", "") # سيأتي من Secrets
11
+ API_URL = f"https://api-inference.huggingface.co/models/{MODEL_NAME}"
12
 
13
  # إعداد headers بشكل آمن
14
  headers = {"Authorization": f"Bearer {HF_TOKEN}"} if HF_TOKEN else {}
 
19
  self.system_prompt = """أنت مساعد عربي ذكي اسمك "أسترا".
20
  أجب بلغة عربية واضحة ومفيدة. كن ودوداً ومتعاوناً."""
21
 
22
+ def format_messages_for_api(self):
23
+ """تنسيق الرسائل لـ Hugging Face Inference API"""
24
+ messages = []
 
 
 
 
 
 
 
25
 
26
+ # إضافة الرسالة النظامية أولاً
27
+ messages.append({"role": "system", "content": self.system_prompt})
28
+
29
+ # إضافة تاريخ المحادثة
30
+ for msg in self.conversation_history[-6:]: # آخر 3 تبادلات
31
+ messages.append({"role": msg["role"], "content": msg["content"]})
32
+
33
+ return messages
34
 
35
+ def send_to_model(self, user_message, max_tokens=200, temperature=0.7):
36
+ """إرسال للنموذج باستخدام Hugging Face Inference API"""
37
  try:
38
+ # تحديث تاريخ المحادثة أولاً
39
+ self.conversation_history.append({"role": "user", "content": user_message})
40
+
41
+ # تنسيق الرسائل للـ API
42
+ messages = self.format_messages_for_api()
43
+
44
  payload = {
45
+ "inputs": messages,
46
  "parameters": {
47
  "max_new_tokens": max_tokens,
48
  "temperature": temperature,
49
  "top_p": 0.9,
 
50
  "do_sample": True
51
  }
52
  }
53
 
54
+ # إرسال الطلب
55
+ response = requests.post(
56
+ API_URL,
57
+ headers=headers,
58
+ json=payload,
59
+ timeout=60
60
+ )
61
+
62
+ print(f"Status Code: {response.status_code}") # للتصحيح
63
 
64
  if response.status_code == 200:
65
  result = response.json()
66
 
67
+ # معالجة الرد بناءً على تنسيق النموذج
68
+ if isinstance(result, list):
69
+ # تنسيق الرد القديم
70
  if 'generated_text' in result[0]:
71
+ bot_response = result[0]['generated_text']
72
+ elif 'generated_texts' in result[0]:
73
+ bot_response = result[0]['generated_texts'][0]
74
+ else:
75
+ # جرب استخراج ��لنص مباشرة
76
+ bot_response = str(result[0]).strip()
77
+ elif isinstance(result, dict):
78
+ # تنسيق الـ chat models
79
+ if 'choices' in result:
80
+ bot_response = result['choices'][0]['message']['content']
81
+ elif 'generated_text' in result:
82
+ bot_response = result['generated_text']
83
+ else:
84
+ bot_response = json.dumps(result)[:500]
85
+ else:
86
+ bot_response = str(result)[:500]
87
+
88
+ # تنظيف الرد
89
+ bot_response = bot_response.strip()
90
+
91
+ # إضافة رد البوت للتاريخ
92
+ self.conversation_history.append({"role": "assistant", "content": bot_response})
93
 
94
+ return bot_response
95
 
 
 
96
  elif response.status_code == 503:
97
+ # النموذج يبدأ Loading
98
+ return "🔄 النموذج يبدأ التشغيل... جرب مرة أخرى خلال 30 ثانية."
99
+ elif response.status_code == 401:
100
+ return "🔒 خطأ في التوكن. الرجاء التحقق من HF_TOKEN."
101
  else:
102
+ error_msg = f"⚠️ خطأ {response.status_code}: {response.text[:200]}"
103
+ print(error_msg) # للتصحيح
104
+ return error_msg
105
 
106
  except Exception as e:
107
+ error_msg = f"❌ خطأ في الاتصال: {str(e)[:100]}"
108
+ print(f"Exception: {str(e)}") # للتصحيح
109
+ return error_msg
110
 
111
  def chat(self, user_message, max_tokens=200, temperature=0.7):
112
  """الدردشة مع البوت"""
113
  if not user_message.strip():
114
  return "⚠️ الرجاء كتابة رسالة."
115
 
116
+ bot_response = self.send_to_model(user_message, max_tokens, temperature)
 
117
  return bot_response
118
 
119
  # إنشاء البوت
120
  chatbot = AstramindChatbot()
121
 
122
  # === واجهة Gradio ===
123
+ def respond(message, history, tokens, temp):
124
+ """معالجة الرد وعرضه في Chatbot"""
125
+ if not message.strip():
126
+ return history, "", "اكتب رسالة أولاً"
127
+
128
+ # الحصول على الرد من البوت
129
+ response = chatbot.chat(message, tokens, temp)
130
+
131
+ # تحديث الـ history الخاص بـ Gradio
132
+ history = history or [] # تأكد أن history ليست None
133
+ history.append((message, response))
134
+
135
+ # تحديث الحالة
136
+ status_msg = f"✅ تم الرد - طول: {len(response)} حرف"
137
+
138
+ return history, "", status_msg
139
+
140
+ def clear_chat():
141
+ """مسح المحادثة"""
142
+ chatbot.conversation_history = []
143
+ return [], "🗑️ تم مسح المحادثة"
144
+
145
+ def welcome_message():
146
+ """رسالة ترحيبية"""
147
+ if HF_TOKEN:
148
+ return f"🤖 Astramind جاهز للدردشة! النموذج: {MODEL_NAME}"
149
+ else:
150
+ return "⚠️ الرجاء إضافة HF_TOKEN في Secrets لاستخدام النموذج الخاص"
151
+
152
+ # إنشاء الواجهة
153
  with gr.Blocks(
154
  title="🤖 Astramind - مساعد الدردشة",
155
+ theme=gr.themes.Soft(),
156
+ css="""
157
+ .chatbot { min-height: 400px; }
158
+ .message { text-align: right; }
159
+ """
160
  ) as demo:
161
 
162
  gr.Markdown("""
 
164
  ### تحدث مع النموذج العربي الخاص بك
165
  """)
166
 
167
+ # عرض معلومات النموذج
168
+ status_display = gr.Textbox(
169
+ label="حالة النظام",
170
+ value=welcome_message(),
171
+ interactive=False
172
+ )
173
+
174
+ # شات بوت
175
+ chatbot_display = gr.Chatbot(
176
+ label="المحادثة",
177
+ height=400,
178
+ type="messages"
179
+ )
180
 
181
+ # ��ر المسح
182
+ clear_btn = gr.Button("🗑️ مسح المحادثة", variant="secondary", size="sm")
183
 
184
+ # إدخال المستخدم
185
  with gr.Row():
186
  user_input = gr.Textbox(
187
+ label="اكتب رسالتك",
188
+ placeholder="مرحباً! كيف يمكنني مساعدتك اليوم؟",
189
  lines=2,
190
  scale=4
191
  )
192
+ send_btn = gr.Button("إرسال", variant="primary", size="lg")
 
193
 
194
  # إعدادات
195
+ with gr.Accordion("⚙️ إعدادات النموذج", open=False):
196
  with gr.Row():
197
+ max_tokens = gr.Slider(
198
+ minimum=50,
199
+ maximum=1000,
200
+ value=200,
201
+ step=50,
202
+ label="طول الرد (tokens)"
203
+ )
204
+ temperature = gr.Slider(
205
+ minimum=0.1,
206
+ maximum=1.0,
207
+ value=0.7,
208
+ step=0.1,
209
+ label="درجة الإبداع"
210
+ )
211
 
212
+ # أمثلة سريعة
213
  gr.Markdown("### 💡 أمثلة سريعة:")
 
214
  examples = gr.Examples(
215
  examples=[
216
+ ["السلام عليكم، كيف حالك؟"],
217
+ ["ما هو اسمك وماذا تفعل؟"],
218
+ ["أخبرني عن نفسك"],
219
+ ["ساعدني في كتابة رسالة بريد إلكتروني"]
220
  ],
221
  inputs=user_input,
222
  label="جرب أحد هذه الأمثلة"
223
  )
224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  # ربط الأحداث
226
+ # إرسال بالزر
227
+ send_btn.click(
228
+ fn=respond,
229
+ inputs=[user_input, chatbot_display, max_tokens, temperature],
230
+ outputs=[chatbot_display, user_input, status_display]
231
  )
232
 
233
+ # إرسال بالإنتر
234
+ user_input.submit(
235
+ fn=respond,
236
+ inputs=[user_input, chatbot_display, max_tokens, temperature],
237
+ outputs=[chatbot_display, user_input, status_display]
238
  )
239
 
240
+ # مسح المحادثة
241
  clear_btn.click(
242
+ fn=clear_chat,
243
+ outputs=[chatbot_display, status_display]
244
  )
245
 
246
+ # تحديث الحالة عند التحميل
247
+ demo.load(welcome_message, outputs=status_display)
 
 
 
 
 
 
248
 
249
  # التشغيل
250
  if __name__ == "__main__":
251
+ # إعدادات التشغيل على Hugging Face Space
252
  demo.launch(
253
+ debug=False,
254
  server_name="0.0.0.0",
255
+ server_port=7860,
256
+ share=False
257
  )