Spaces:
Running
Running
| import os | |
| import gradio as gr | |
| import json | |
| import re | |
| from typing import Dict, List, Tuple | |
| from datetime import datetime | |
| from openai import OpenAI | |
| # ============================== | |
| # التحقق من وجود API Key في متغيرات البيئة | |
| # ============================== | |
| OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") | |
| if not OPENAI_API_KEY: | |
| print("⚠️ تحذير: OPENAI_API_KEY غير موجود في متغيرات البيئة") | |
| print("🔧 النظام سيعمل في الوضع التجريبي") | |
| # ============================== | |
| # تهيئة OpenAI العميل | |
| # ============================== | |
| client = None | |
| if OPENAI_API_KEY and OPENAI_API_KEY.startswith("sk-"): | |
| try: | |
| client = OpenAI(api_key=OPENAI_API_KEY) | |
| print("✅ تم تفعيل OpenAI API بنجاح") | |
| API_AVAILABLE = True | |
| except Exception as e: | |
| print(f"❌ خطأ في تهيئة OpenAI: {str(e)}") | |
| API_AVAILABLE = False | |
| else: | |
| print("⚠️ النظام يعمل في الوضع المحلي بدون OpenAI API") | |
| API_AVAILABLE = False | |
| MODEL = "gpt-4o" | |
| # ============================== | |
| # نظام مدار الذكاء الاصطناعي | |
| # ============================== | |
| class OrbitSystem: | |
| def __init__(self): | |
| self.fuel = 100 # وقود النظام | |
| self.orbit_state = "🚀 على منصة الإطلاق" | |
| self.warning_level = 0 | |
| self.trajectory_history = [] | |
| self.mission_log = [] | |
| self.api_available = API_AVAILABLE | |
| self.consecutive_good_responses = 0 | |
| def validate_launch(self, role: str, context: str, command: str) -> Dict: | |
| """التحقق من جودة بيانات الإطلاق""" | |
| warnings = [] | |
| score = 1.0 | |
| # التحقق من الاكتمال | |
| if not role.strip() or len(role.split()) < 2: | |
| warnings.append("⚠️ هوية المهمة غير واضحة") | |
| score *= 0.6 | |
| if not context.strip() or len(context.split()) < 5: | |
| warnings.append("⚠️ سياق المهمة غير كافٍ") | |
| score *= 0.8 | |
| if not command.strip() or len(command.split()) < 3: | |
| warnings.append("🚫 أمر الإطلاق قصير جداً") | |
| score *= 0.5 | |
| # التحقق من الجمل العشوائية | |
| command_words = command.split() | |
| if len(command_words) == 1 and len(command) < 8: | |
| warnings.append("🚫 ممنوع استخدام كلمات مفردة عشوائية!") | |
| score *= 0.3 | |
| # البحث عن عبارات مبهمة | |
| vague_patterns = [r"\bشيء\b", r"\bبعض\b", r"\bكذا\b", r"\bأي شيء\b", r"\bلا أعرف\b"] | |
| vague_count = 0 | |
| for pattern in vague_patterns: | |
| matches = re.findall(pattern, command, re.IGNORECASE) | |
| vague_count += len(matches) | |
| if vague_count > 2: | |
| warnings.append("🔍 تجنب العبارات المبهمة المتكررة") | |
| score *= 0.9 | |
| return { | |
| "valid": score >= 0.4, # خففنا العتبة | |
| "score": score, | |
| "warnings": warnings, | |
| "state": "🟢 جاهز للإطلاق" if score >= 0.7 else | |
| "🟡 يحتاج تحسين" if score >= 0.4 else | |
| "🔴 مرفوض" | |
| } | |
| def calculate_fuel_cost(self, prompt: str, response: str) -> float: | |
| """حساب استهلاك الوقود""" | |
| words = len(prompt.split()) + len(response.split()) | |
| # تكلفة أقل لكل كلمة | |
| return max(0.5, words * 0.02) | |
| def detect_hallucination(self, response: str, prompt: str = "") -> Tuple[float, List[str]]: | |
| """كشف الهلوسة في الاستجابة - نسخة ذكية""" | |
| indicators = [] | |
| score = 0.0 | |
| # علامات الجودة الإيجابية | |
| positive_signs = 0 | |
| if "أنا" in response or "نحن" in response or "يمكن" in response: | |
| positive_signs += 1 | |
| if "على سبيل المثال" in response or "مثال" in response: | |
| positive_signs += 2 | |
| if "الخلاصة" in response or "باختصار" in response or "بشكل عام" in response: | |
| positive_signs += 1 | |
| # أنماط الهلوسة الحقيقية فقط | |
| dangerous_patterns = { | |
| "معلومات خاطئة صريحة": [ | |
| r"(الولايات المتحدة هي أكبر قارة)", | |
| r"(الشمس تدور حول الأرض)", | |
| r"(الذكاء الاصطناعي له مشاعر)", | |
| r"(يمكن للكمبيوتر أن يحلم)" | |
| ], | |
| "تناقضات خطيرة": [ | |
| r"(ولكن.*على العكس.*في نفس الوقت)", | |
| r"(من ناحية.*من ناحية أخرى.*لكن.*مع ذلك)" | |
| ], | |
| "مبالغات واضحة": [ | |
| r"(أكيد\b.*بلا شك\b.*بالتأكيد\b.*مطلقاً\b)", | |
| r"(كل\b.*جميع\b.*دائماً\b.*أبداً\b)" | |
| ] | |
| } | |
| for category, pattern_list in dangerous_patterns.items(): | |
| for pattern in pattern_list: | |
| if re.search(pattern, response, re.IGNORECASE): | |
| score += 0.3 # زيادة أقل | |
| if category not in indicators: | |
| indicators.append(category) | |
| # إجابة طويلة جداً بدون تنظيم | |
| if len(response.split()) > 200 and response.count('\n\n') < 2: | |
| score += 0.1 | |
| indicators.append("إسهاب مفرط بدون تنظيم") | |
| # التحقق من العلاقة مع السؤال | |
| if prompt: | |
| prompt_keywords = set(re.findall(r'\b\w{4,}\b', prompt.lower())) | |
| response_keywords = set(re.findall(r'\b\w{4,}\b', response.lower())) | |
| common_keywords = prompt_keywords.intersection(response_keywords) | |
| if len(common_keywords) < 2 and len(prompt_keywords) > 3: | |
| score += 0.15 | |
| indicators.append("ضعف الارتباط بالسؤال") | |
| # خصم النقاط الإيجابية | |
| score = max(0, score - (positive_signs * 0.05)) | |
| return min(1.0, score), indicators | |
| def assess_response_quality(self, response: str, prompt: str = "") -> Dict: | |
| """تقييم شامل لجودة الاستجابة""" | |
| quality_score = 0.7 # نقطة انطلاق | |
| # عوامل إيجابية | |
| if len(response.split()) > 50: | |
| quality_score += 0.1 | |
| if response.count('.') > 3: | |
| quality_score += 0.1 | |
| if '\n' in response or '•' in response or '-' in response: | |
| quality_score += 0.1 | |
| if "أولاً" in response or "ثانياً" in response or "ثالثاً" in response: | |
| quality_score += 0.15 | |
| # كشف الهلوسة (خففناه) | |
| hallucination_score, indicators = self.detect_hallucination(response, prompt) | |
| # تطبيق الهلوسة بشكل معتدل | |
| if hallucination_score > 0.6: # فقط إذا كان عالياً حقاً | |
| quality_score *= (1 - hallucination_score * 0.5) # تأثير أقل | |
| elif hallucination_score < 0.3: | |
| quality_score += 0.1 # مكافأة للدقة | |
| # تسجيل الاستجابات الجيدة المتتالية | |
| if quality_score > 0.7: | |
| self.consecutive_good_responses += 1 | |
| if self.consecutive_good_responses > 2: | |
| quality_score += 0.1 # مكافأة للاتساق | |
| else: | |
| self.consecutive_good_responses = 0 | |
| return { | |
| "score": min(1.0, quality_score), | |
| "hallucination_score": hallucination_score, | |
| "indicators": indicators | |
| } | |
| def update_orbit_state(self, quality_score: float, hallucination_score: float): | |
| """تحديث حالة المدار بشكل أكثر ذكاءً""" | |
| if hallucination_score > 0.7: | |
| self.orbit_state = "🕳️ في منطقة ثقب أسود" | |
| self.warning_level = 3 | |
| self.consecutive_good_responses = 0 | |
| elif hallucination_score > 0.5: | |
| self.orbit_state = "⚠️ اضطرابات في المدار" | |
| self.warning_level = 2 | |
| elif quality_score < 0.5: | |
| self.orbit_state = "🌍 خارج المدار" | |
| self.warning_level = 2 | |
| elif quality_score < 0.7: | |
| self.orbit_state = "🚀 في مرحلة الإطلاق" | |
| self.warning_level = 1 | |
| elif quality_score < 0.85: | |
| self.orbit_state = "🛰️ في مدار شبه مستقر" | |
| self.warning_level = 0 | |
| else: | |
| self.orbit_state = "✨ في مدار مثالي" | |
| self.warning_level = 0 | |
| if self.consecutive_good_responses > 3: | |
| self.orbit_state = "🏆 في مدار استثنائي" | |
| def generate_demo_response(self, role: str, context: str, command: str) -> str: | |
| """توليد رد تجريبي ذكي""" | |
| demo_templates = [ | |
| f"""## 🛰️ تجربة مدارية - الوضع التوضيحي | |
| ### 📡 تحليل البرومبت: | |
| **الهوية:** {role[:40]} | |
| **السياق:** {context[:80]}... | |
| **الأمر:** {command[:120]}... | |
| ### 💡 استجابة توضيحية: | |
| بناءً على طلبك، إليك إطار عام للإجابة: | |
| 1. **المقدمة:** تقديم الموضوع الرئيسي | |
| 2. **النقاط الأساسية:** تحليل العناصر الرئيسية | |
| 3. **التطبيقات:** ذكر أمثلة عملية | |
| 4. **الخلاصة:** تلخيص النقاط المهمة | |
| **🎯 لتفعيل الإجابات الحقيقية:** | |
| - أضف OPENAI_API_KEY في Hugging Face Secrets | |
| - استخدم نموذج GPT-4o للإجابات الدقيقة | |
| - تابع مستوى الوقود وحالة المدار""", | |
| f"""## 🔬 مختبر الذكاء الاصطناعي | |
| ### 🎭 السيناريو التجريبي: | |
| أنت تتظاهر بأنك {role} في سياق {context[:60]}... | |
| ### 🤖 محاكاة الاستجابة: | |
| لو كان النظام مفعلاً، ستكون الإجابة على "{command[:100]}..." كالتالي: | |
| **الهيكل المقترح:** | |
| - الفرضية أو السؤال الرئيسي | |
| - البيانات أو الحقائق ذات الصلة | |
| - التحليل المنطقي | |
| - الاستنتاجات والتوصيات | |
| **🔐 تفعيل النظام الكامل:** | |
| 1. Space Settings → Repository secrets | |
| 2. إضافة OPENAI_API_KEY | |
| 3. إعادة تحميل التطبيق""", | |
| f"""## 🚀 محاكاة الإطلاق الناجح | |
| ### 📊 بيانات المهمة: | |
| - **الدور:** {role or "غير محدد"} | |
| - **نطاق المهمة:** {len(context.split())} كلمة | |
| - **تعقيد الطلب:** {len(command.split())} كلمة | |
| ### 🎪 العرض التوضيحي: | |
| هذا نموذج لكيفية استجابة النظام الفعلي. الإجابة الحقيقية ستكون: | |
| 1. أكثر تفصيلاً ودقة | |
| 2. مستندة إلى أحدث المعلومات | |
| 3. متوافقة مع هوية المهمة | |
| 4. متكيفة مع السياق المحدد | |
| **⚡ حالات المدار الحقيقية:** | |
| - 🚀 إطلاق: برومبت مقبول | |
| - 🛰️ مدار مستقر: إجابة دقيقة | |
| - ⚠️ اضطرابات: بعض الشكوك | |
| - 🕳️ ثقب أسود: معلومات خاطئة صريحة""" | |
| ] | |
| import random | |
| return random.choice(demo_templates) | |
| # ============================== | |
| # تهيئة النظام | |
| # ============================== | |
| orbit_system = OrbitSystem() | |
| # ============================== | |
| # إطلاق المركبة | |
| # ============================== | |
| def launch_mission(role, context, launch_command, state): | |
| """إطلاق المركبة إلى المدار""" | |
| # التحقق من جودة الإدخال | |
| validation = orbit_system.validate_launch(role, context, launch_command) | |
| if not validation["valid"]: | |
| error_msg = "## ❌ إطلاق مرفوض!\n\n" | |
| error_msg += "**أسباب الرفض:**\n" | |
| for warning in validation["warnings"]: | |
| error_msg += f"- {warning}\n" | |
| error_msg += f"\n**حالة النظام:** {validation['state']}" | |
| error_msg += "\n\n💡 **نصيحة:** أضف تفاصيل أكثر وكن أكثر تحديداً." | |
| return error_msg, state, validation["state"], orbit_system.fuel, "⛽ لم يتم استهلاك وقود" | |
| # التحقق من وجود API | |
| if not orbit_system.api_available: | |
| orbit_response = orbit_system.generate_demo_response(role, context, launch_command) | |
| # تحديث حالة النظام | |
| fuel_cost = orbit_system.calculate_fuel_cost(launch_command, orbit_response) | |
| orbit_system.fuel = max(0, orbit_system.fuel - fuel_cost) | |
| # تحديث حالة المدار | |
| orbit_system.update_orbit_state(0.7, 0.1) | |
| # تحديث السجل | |
| state["trajectory"] = [ | |
| {"role": "system", "content": f"هوية: {role}\nسياق: {context}"}, | |
| {"role": "user", "content": launch_command}, | |
| {"role": "assistant", "content": orbit_response} | |
| ] | |
| fuel_status = f"⛽ {orbit_system.fuel:.1f}% متبقي (استهلك: {fuel_cost:.1f}%)" | |
| return orbit_response, state, orbit_system.orbit_state, orbit_system.fuel, fuel_status | |
| # إذا كان API متاحاً - استخدام OpenAI الفعلي | |
| try: | |
| system_prompt = f""" | |
| أنت مساعد ذكي يدعى "مدار الذكاء الاصطناعي". أنت جزء من نظام محاكاة فضائي. | |
| قواعد المهمة: | |
| 1. كن دقيقاً وصادقاً في المعلومات | |
| 2. إذا لم تكن متأكداً من شيء، قل ذلك بوضوح | |
| 3. قدم معلومات متوازنة وواقعية | |
| 4. نظم إجابتك بطريقة منطقية | |
| 5. تجنب المبالغات والتعميمات المطلقة | |
| هوية المهمة: {role} | |
| سياق المهمة: {context} | |
| استخدم المعلومات أعلاه لتوجيه إجابتك، ولكن لا تختلق معلومات. | |
| """ | |
| messages = [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": launch_command} | |
| ] | |
| response = client.chat.completions.create( | |
| model=MODEL, | |
| messages=messages, | |
| temperature=0.7, | |
| max_tokens=1000 | |
| ) | |
| orbit_response = response.choices[0].message.content | |
| # تقييم جودة الاستجابة | |
| quality_assessment = orbit_system.assess_response_quality(orbit_response, launch_command) | |
| # تحديث حالة النظام | |
| fuel_cost = orbit_system.calculate_fuel_cost(launch_command, orbit_response) | |
| orbit_system.fuel = max(0, orbit_system.fuel - fuel_cost) | |
| # تحديث حالة المدار بناءً على التقييم الشامل | |
| orbit_system.update_orbit_state( | |
| quality_assessment["score"], | |
| quality_assessment["hallucination_score"] | |
| ) | |
| # بناء الاستجابة | |
| formatted_response = f""" | |
| ## {orbit_system.orbit_state} | |
| ### 📡 الاستجابة: | |
| {orbit_response} | |
| --- | |
| """ | |
| # إضافة تحذيرات الهلوسة فقط إذا كانت خطيرة | |
| if quality_assessment["hallucination_score"] > 0.6: | |
| formatted_response += f"\n### ⚠️ تنبيه: مؤشرات هلوسة ({quality_assessment['hallucination_score']:.0%})\n" | |
| for indicator in quality_assessment["indicators"]: | |
| formatted_response += f"- {indicator}\n" | |
| formatted_response += "\n🔍 **نصيحة:** تحقق من هذه النقاط للتأكد من الدقة." | |
| elif quality_assessment["hallucination_score"] > 0.4: | |
| formatted_response += f"\n### ℹ️ ملاحظة: دقة معتدلة ({quality_assessment['hallucination_score']:.0%})\n" | |
| formatted_response += "الإجابة جيدة بشكل عام، ولكن هناك بعض العبارات التي تحتاج مراجعة." | |
| # إضافة تقييم الجودة إذا كانت ممتازة | |
| if quality_assessment["score"] > 0.85: | |
| formatted_response += f"\n### ✅ تقييم عالي: {quality_assessment['score']:.0%}\n" | |
| formatted_response += "🎉 إجابة ممتازة! الاستجابة دقيقة ومنظمة جيداً." | |
| # تحديث السجل | |
| state["trajectory"] = messages + [ | |
| {"role": "assistant", "content": orbit_response} | |
| ] | |
| state["validation"] = validation | |
| state["quality"] = quality_assessment | |
| # تسجيل المهمة | |
| orbit_system.mission_log.append({ | |
| "time": datetime.now().isoformat(), | |
| "role": role, | |
| "command_length": len(launch_command), | |
| "response_length": len(orbit_response), | |
| "orbit_state": orbit_system.orbit_state, | |
| "fuel_cost": fuel_cost, | |
| "quality_score": quality_assessment["score"], | |
| "hallucination_score": quality_assessment["hallucination_score"] | |
| }) | |
| fuel_status = f"⛽ {orbit_system.fuel:.1f}% متبقي (استهلك: {fuel_cost:.1f}%)" | |
| return formatted_response, state, orbit_system.orbit_state, orbit_system.fuel, fuel_status | |
| except Exception as e: | |
| error_msg = f""" | |
| ## ❌ خطأ في الاتصال | |
| **تفاصيل:** {str(e)[:200]} | |
| **🔄 الحلول المقترحة:** | |
| 1. تحقق من اتصال الإنترنت | |
| 2. تأكد من صلاحية API Key | |
| 3. حاول مرة أخرى بعد قليل | |
| 4. اختبر النظام في الوضع التجريبي أولاً | |
| **🚀 النظام انتقل تلقائياً إلى الوضع الآمن** | |
| """ | |
| orbit_system.update_orbit_state(0.3, 0.8) | |
| return error_msg, state, orbit_system.orbit_state, orbit_system.fuel, "⛽ لا يوجد استهلاك" | |
| # ============================== | |
| # تصحيح المسار | |
| # ============================== | |
| def course_correction(correction, state): | |
| """تصحيح مسار المركبة""" | |
| if "trajectory" not in state: | |
| return "⚠️ لا توجد مركبة في المدار. قم بالإطلاق أولاً.", state, "🌍 خارج الخدمة", orbit_system.fuel, "⛽ لا يوجد استهلاك" | |
| # التحقق من جودة التصحيح | |
| if not correction.strip() or len(correction.split()) < 2: | |
| return "🚫 أمر التصحيح غير كافٍ", state, orbit_system.orbit_state, orbit_system.fuel, "⛽ لا يوجد استهلاك" | |
| # إذا لم يكن API متاحاً | |
| if not orbit_system.api_available: | |
| demo_response = """## 🔧 تصحيح في الوضع التجريبي | |
| أمر التصحيح مقبول! في النظام الكامل، هذا سيقوم بـ: | |
| 1. تحليل طلب التصحيح | |
| 2. تعديل المسار الحالي | |
| 3. تقديم إجابة مكملة | |
| 4. تحديث حالة المدار | |
| **🔓 لتفعيل هذه الميزة:** | |
| أضف OPENAI_API_KEY في إعدادات Hugging Face Space.""" | |
| fuel_cost = orbit_system.calculate_fuel_cost(correction, demo_response) | |
| orbit_system.fuel = max(0, orbit_system.fuel - fuel_cost) | |
| state["trajectory"].append({"role": "user", "content": correction}) | |
| state["trajectory"].append({"role": "assistant", "content": demo_response}) | |
| fuel_status = f"⛽ {orbit_system.fuel:.1f}% متبقي (استهلك: {fuel_cost:.1f}%)" | |
| return demo_response, state, orbit_system.orbit_state, orbit_system.fuel, fuel_status | |
| # إذا كان API متاحاً | |
| try: | |
| state["trajectory"].append({"role": "user", "content": correction}) | |
| response = client.chat.completions.create( | |
| model=MODEL, | |
| messages=state["trajectory"], | |
| temperature=0.7, | |
| max_tokens=800 | |
| ) | |
| orbit_response = response.choices[0].message.content | |
| # تقييم الجودة | |
| quality_assessment = orbit_system.assess_response_quality(orbit_response, correction) | |
| # تحديث الوقود | |
| fuel_cost = orbit_system.calculate_fuel_cost(correction, orbit_response) | |
| orbit_system.fuel = max(0, orbit_system.fuel - fuel_cost) | |
| # تحديث حالة المدار | |
| orbit_system.update_orbit_state( | |
| quality_assessment["score"], | |
| quality_assessment["hallucination_score"] | |
| ) | |
| # بناء الاستجابة | |
| formatted_response = f""" | |
| ## 🔁 مناورة تصحيح | |
| ### {orbit_system.orbit_state} | |
| ### 📡 الاستجابة المحدثة: | |
| {orbit_response} | |
| --- | |
| """ | |
| # تحذيرات فقط إذا كانت ضرورية | |
| if quality_assessment["hallucination_score"] > 0.65: | |
| formatted_response += f"\n### ⚠️ تنبيه أثناء التصحيح\n" | |
| formatted_response += f"دقة: {quality_assessment['hallucination_score']:.0%} - راجع النقاط التالية:\n" | |
| for indicator in quality_assessment["indicators"]: | |
| formatted_response += f"- {indicator}\n" | |
| state["trajectory"].append({"role": "assistant", "content": orbit_response}) | |
| fuel_status = f"⛽ {orbit_system.fuel:.1f}% متبقي (استهلك: {fuel_cost:.1f}%)" | |
| return formatted_response, state, orbit_system.orbit_state, orbit_system.fuel, fuel_status | |
| except Exception as e: | |
| return f"## ❌ خطأ في التصحيح\n\n{str(e)[:150]}", state, "🔴 خطأ تقني", orbit_system.fuel, "⛽ لا يوجد استهلاك" | |
| # ============================== | |
| # إعادة تعيين النظام | |
| # ============================== | |
| def reset_system(): | |
| """إعادة تعيين النظام بالكامل""" | |
| global orbit_system | |
| orbit_system = OrbitSystem() | |
| return "", {}, "🚀 على منصة الإطلاق", 100, "⛽ 100% (ممتلئ)" | |
| # ============================== | |
| # عرض حالة API | |
| # ============================== | |
| def get_api_status(): | |
| """الحصول على حالة API""" | |
| if orbit_system.api_available: | |
| return "🟢 OpenAI API مفعل" | |
| else: | |
| return "🟡 الوضع التجريبي (أضف API Key)" | |
| # ============================== | |
| # تحديث مقياس الوقود | |
| # ============================== | |
| def update_fuel_gauge(fuel_level): | |
| """تحديث مقياس الوقود بشكل صحيح""" | |
| fuel_percent = max(0, min(100, fuel_level)) | |
| # تحديد اللون بناءً على النسبة | |
| if fuel_percent > 70: | |
| gradient = "linear-gradient(90deg, #4CAF50, #8BC34A)" | |
| emoji = "🟢" | |
| status = "ممتاز" | |
| elif fuel_percent > 30: | |
| gradient = "linear-gradient(90deg, #FF9800, #FFB74D)" | |
| emoji = "🟡" | |
| status = "متوسط" | |
| else: | |
| gradient = "linear-gradient(90deg, #F44336, #EF5350)" | |
| emoji = "🔴" | |
| status = "منخفض" | |
| return f""" | |
| <div style="margin: 15px 0;"> | |
| <div style="display: flex; justify-content: space-between; margin-bottom: 5px;"> | |
| <span style="color: #cfd6b5; font-weight: bold;">{emoji} حالة الوقود: {status}</span> | |
| <span style="color: #cfd6b5; font-weight: bold;">{fuel_percent:.1f}%</span> | |
| </div> | |
| <div style="width: 100%; height: 25px; background: rgba(40, 40, 40, 0.5); border-radius: 15px; overflow: hidden; position: relative;"> | |
| <div class="fuel-fill" style="width: {fuel_percent}%; height: 100%; background: {gradient}; transition: width 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);"></div> | |
| <!-- علامات النسبة --> | |
| <div style="position: absolute; left: 30%; top: 0; height: 100%; width: 2px; background: rgba(255,255,255,0.2);"></div> | |
| <div style="position: absolute; left: 70%; top: 0; height: 100%; width: 2px; background: rgba(255,255,255,0.2);"></div> | |
| </div> | |
| <div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 0.8em; color: #aaa;"> | |
| <span>0%</span> | |
| <span>30%</span> | |
| <span>70%</span> | |
| <span>100%</span> | |
| </div> | |
| </div> | |
| """ | |
| # ============================== | |
| # CSS فضائي محسن | |
| # ============================== | |
| css = """ | |
| .gradio-container { | |
| direction: rtl; | |
| text-align: right; | |
| background: transparent !important; | |
| } | |
| #space-background { | |
| position: fixed; | |
| inset: 0; | |
| z-index: -1; | |
| overflow: hidden; | |
| background: | |
| radial-gradient(circle at 20% 50%, #1a2a1a 0%, transparent 50%), | |
| radial-gradient(circle at 80% 20%, #0f1a0f 0%, transparent 50%), | |
| radial-gradient(circle at 40% 80%, #152015 0%, transparent 50%), | |
| linear-gradient(180deg, #020302 0%, #0b0f0c 100%); | |
| pointer-events: none; | |
| } | |
| .stars { | |
| position: absolute; | |
| inset: -50%; | |
| background-image: | |
| radial-gradient(2px 2px at 10% 20%, #ffffff 50%, transparent 100%), | |
| radial-gradient(1px 1px at 20% 80%, #cfd6b5 50%, transparent 100%), | |
| radial-gradient(1px 1px at 30% 40%, #b7c28b 50%, transparent 100%), | |
| radial-gradient(2px 2px at 40% 60%, #ffffff 50%, transparent 100%), | |
| radial-gradient(1px 1px at 50% 30%, #d6ddb8 50%, transparent 100%), | |
| radial-gradient(2px 2px at 60% 70%, #aab37a 50%, transparent 100%), | |
| radial-gradient(1px 1px at 70% 20%, #ffffff 50%, transparent 100%), | |
| radial-gradient(2px 2px at 80% 50%, #e5ecd2 50%, transparent 100%), | |
| radial-gradient(1px 1px at 90% 80%, #cfd6b5 50%, transparent 100%); | |
| background-size: 300px 300px; | |
| animation: starDrift 200s linear infinite; | |
| opacity: 0.6; | |
| } | |
| @keyframes starDrift { | |
| from { transform: translate(0, 0) rotate(0deg); } | |
| to { transform: translate(100px, 100px) rotate(360deg); } | |
| } | |
| .planet-1 { | |
| position: absolute; | |
| top: 15%; | |
| right: 5%; | |
| width: 150px; | |
| height: 150px; | |
| background: radial-gradient(circle at 30% 30%, #4a5a2a, #0f150a 70%); | |
| border-radius: 50%; | |
| opacity: 0.4; | |
| animation: planetFloat1 40s ease-in-out infinite alternate; | |
| } | |
| .planet-2 { | |
| position: absolute; | |
| bottom: 20%; | |
| left: 10%; | |
| width: 100px; | |
| height: 100px; | |
| background: radial-gradient(circle at 40% 40%, #3a4a1a, #0a1005 70%); | |
| border-radius: 50%; | |
| opacity: 0.3; | |
| animation: planetFloat2 60s ease-in-out infinite alternate; | |
| } | |
| @keyframes planetFloat1 { | |
| from { transform: translateY(-20px) rotate(0deg); } | |
| to { transform: translateY(20px) rotate(10deg); } | |
| } | |
| @keyframes planetFloat2 { | |
| from { transform: translateX(-15px) rotate(0deg); } | |
| to { transform: translateX(15px) rotate(-10deg); } | |
| } | |
| h1, h2, h3, h4, .markdown-text { | |
| color: #cfd6b5 !important; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| text-align: right; | |
| } | |
| h1 { | |
| background: linear-gradient(90deg, #7a8450, #cfd6b5); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| text-shadow: 0 0 20px rgba(122, 132, 80, 0.3); | |
| } | |
| textarea, input[type="text"] { | |
| background-color: rgba(15, 20, 15, 0.8) !important; | |
| color: #e5ecd2 !important; | |
| border: 1px solid #556b2f !important; | |
| border-radius: 10px !important; | |
| text-align: right; | |
| padding: 12px !important; | |
| backdrop-filter: blur(10px); | |
| } | |
| textarea:focus, input[type="text"]:focus { | |
| border-color: #7a8450 !important; | |
| box-shadow: 0 0 15px rgba(122, 132, 80, 0.5) !important; | |
| } | |
| button { | |
| background: linear-gradient(135deg, #556b2f, #7a8450) !important; | |
| color: #0f150a !important; | |
| border: none !important; | |
| border-radius: 10px !important; | |
| font-weight: bold !important; | |
| padding: 12px 24px !important; | |
| transition: all 0.3s ease !important; | |
| cursor: pointer !important; | |
| } | |
| button:hover { | |
| transform: translateY(-2px) !important; | |
| box-shadow: 0 5px 20px rgba(122, 132, 80, 0.4) !important; | |
| } | |
| .system-status { | |
| background: rgba(10, 15, 10, 0.8) !important; | |
| border: 1px solid #556b2f !important; | |
| border-radius: 10px; | |
| padding: 15px; | |
| margin: 10px 0; | |
| backdrop-filter: blur(10px); | |
| } | |
| .fuel-fill { | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .fuel-fill::after { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: linear-gradient( | |
| 90deg, | |
| transparent 0%, | |
| rgba(255, 255, 255, 0.2) 50%, | |
| transparent 100% | |
| ); | |
| animation: fuelShine 3s infinite; | |
| } | |
| @keyframes fuelShine { | |
| 0% { transform: translateX(-100%); } | |
| 100% { transform: translateX(100%); } | |
| } | |
| .fuel-warning { | |
| animation: fuelPulse 2s infinite; | |
| } | |
| @keyframes fuelPulse { | |
| 0% { opacity: 1; } | |
| 50% { opacity: 0.7; } | |
| 100% { opacity: 1; } | |
| } | |
| .api-status { | |
| padding: 10px; | |
| border-radius: 8px; | |
| margin: 10px 0; | |
| text-align: center; | |
| font-weight: bold; | |
| } | |
| .api-active { | |
| background: rgba(76, 175, 80, 0.2); | |
| border: 2px solid #4CAF50; | |
| color: #4CAF50; | |
| } | |
| .api-inactive { | |
| background: rgba(255, 152, 0, 0.2); | |
| border: 2px solid #FF9800; | |
| color: #FF9800; | |
| } | |
| .black-hole-warning { | |
| background: linear-gradient(135deg, #4a1a1a, #8b0000); | |
| border: 2px solid #ff4444; | |
| border-radius: 10px; | |
| padding: 15px; | |
| margin: 10px 0; | |
| color: #ffcccc; | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(255, 68, 68, 0.7); } | |
| 70% { box-shadow: 0 0 0 10px rgba(255, 68, 68, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(255, 68, 68, 0); } | |
| } | |
| .good-orbit { | |
| background: rgba(76, 175, 80, 0.2); | |
| border: 2px solid #4CAF50; | |
| border-radius: 10px; | |
| padding: 15px; | |
| margin: 10px 0; | |
| color: #c8e6c9; | |
| } | |
| .orbit-state-display { | |
| font-size: 1.2em; | |
| font-weight: bold; | |
| padding: 10px; | |
| border-radius: 8px; | |
| text-align: center; | |
| margin: 10px 0; | |
| } | |
| .state-launch { background: rgba(255, 152, 0, 0.2); color: #ffcc80; } | |
| .state-orbit { background: rgba(76, 175, 80, 0.2); color: #c8e6c9; } | |
| .state-warning { background: rgba(255, 193, 7, 0.2); color: #fff59d; } | |
| .state-blackhole { | |
| background: linear-gradient(135deg, #4a1a1a, #8b0000); | |
| color: #ffcccc; | |
| animation: pulse 2s infinite; | |
| } | |
| .state-excellent { | |
| background: linear-gradient(135deg, #1a5276, #3498db); | |
| color: #d6eaf8; | |
| } | |
| .response-box { | |
| background: linear-gradient(135deg, rgba(20, 25, 20, 0.9), rgba(10, 15, 10, 0.95)); | |
| border-left: 4px solid #7a8450; | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin: 10px 0; | |
| animation: fadeIn 0.5s ease-out; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .rocket-launch { | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .rocket-launch::after { | |
| content: "🚀"; | |
| position: absolute; | |
| right: -50px; | |
| animation: rocketFly 2s ease-out; | |
| } | |
| @keyframes rocketFly { | |
| 0% { transform: translateX(0) translateY(0); opacity: 1; } | |
| 100% { transform: translateX(-100vw) translateY(-100vh); opacity: 0; } | |
| } | |
| @media (max-width: 768px) { | |
| .gradio-container { | |
| padding: 10px; | |
| } | |
| h1 { | |
| font-size: 1.5em; | |
| } | |
| button { | |
| padding: 15px !important; | |
| font-size: 1.1em; | |
| } | |
| textarea { | |
| font-size: 16px; | |
| } | |
| .planet-1, .planet-2 { | |
| display: none; | |
| } | |
| } | |
| """ | |
| # ============================== | |
| # واجهة Gradio المحسنة | |
| # ============================== | |
| with gr.Blocks(css=css, title="🛰️ مدار الذكاء الاصطناعي | Orbit Captain") as demo: | |
| # خلفية الفضاء | |
| gr.HTML(""" | |
| <div id="space-background"> | |
| <div class="stars"></div> | |
| <div class="planet-1"></div> | |
| <div class="planet-2"></div> | |
| </div> | |
| """) | |
| gr.Markdown(""" | |
| # 🛰️ مدار الذكاء الاصطناعي | Orbit Captain | |
| ## مركز التحكم بإطلاق الأفكار من العشوائية إلى دقة الاستقرار | |
| """) | |
| # عرض حالة API | |
| api_status = get_api_status() | |
| status_class = "api-active" if orbit_system.api_available else "api-inactive" | |
| gr.HTML(f""" | |
| <div class="api-status {status_class}"> | |
| <h3>🔐 حالة النظام: {api_status}</h3> | |
| {"" if orbit_system.api_available else """ | |
| <p>💡 للحصول على إجابات حقيقية من ChatGPT، أضف مفتاح OpenAI API في:</p> | |
| <p><strong>Hugging Face Space Settings → Repository secrets → OPENAI_API_KEY</strong></p> | |
| """} | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| with gr.Accordion("🎯 مركز التحكم في المهمة", open=True): | |
| role = gr.Textbox( | |
| label="🧑🚀 هوية المهمة (من)", | |
| placeholder="مثال: خبير في الذكاء الاصطناعي، باحث علمي، محلل بيانات...", | |
| lines=2, | |
| value="مساعد ذكي" | |
| ) | |
| context = gr.Textbox( | |
| label="🌌 سياق المهمة (ماذا وكيف)", | |
| placeholder="صف البيئة، الهدف، القيود، التفاصيل المهمة...", | |
| lines=3, | |
| value="أريد معلومات دقيقة وموثوقة حول موضوع معين" | |
| ) | |
| gr.Markdown(""" | |
| ### 📋 قواعد الإطلاق: | |
| 1. استخدم جمل كاملة وواضحة | |
| 2. كن محدداً في طلبك | |
| 3. تجنب العبارات المبهمة | |
| 4. اذكر السياق بوضوح | |
| """) | |
| launch_command = gr.Textbox( | |
| label="🚀 أمر الإطلاق (البرومبت)", | |
| placeholder="مثال: 'اشرح لي مفهوم التعلم العميق مع ذكر 3 تطبيقات عملية في مجال الطب'", | |
| lines=3, | |
| value="ما هو الذكاء الاصطناعي التوليدي؟" | |
| ) | |
| with gr.Row(): | |
| launch_btn = gr.Button("🚀 إطلاق المركبة", variant="primary") | |
| reset_btn = gr.Button("🔄 إعادة تعيين", variant="secondary") | |
| with gr.Column(scale=2): | |
| # عرض حالة النظام | |
| with gr.Accordion("📊 لوحة مراقبة النظام", open=True): | |
| with gr.Row(): | |
| orbit_status = gr.Textbox( | |
| label="🛰️ حالة المدار", | |
| value="🚀 على منصة الإطلاق", | |
| interactive=False | |
| ) | |
| fuel_display = gr.Textbox( | |
| label="⛽ مستوى الوقود", | |
| value="⛽ 100% (ممتلئ)", | |
| interactive=False | |
| ) | |
| # مقياس الوقود الديناميكي | |
| fuel_html = gr.HTML(update_fuel_gauge(100)) | |
| # عرض المدار | |
| orbit_display = gr.Markdown( | |
| label="📡 لوحة الاستقبال", | |
| value="### 📡 جاهز للإطلاق\n\n*اكتب برومبت واضح لإطلاق المركبة...*" | |
| ) | |
| # منطقة التصحيح | |
| with gr.Accordion("🛠️ مركز تصحيح المسار", open=False): | |
| correction = gr.Textbox( | |
| label="🔧 أمر التصحيح", | |
| placeholder="عدّل المسار الحالي دون إعادة الإطلاق من الصفر...", | |
| lines=2 | |
| ) | |
| refine_btn = gr.Button("🔁 تنفيذ مناورة تصحيح", variant="primary") | |
| gr.Markdown(""" | |
| **استخدم تصحيح المسار عندما:** | |
| - تحتاج إلى توضيح نقطة معينة | |
| - تريد تعديل اتجاه المحادثة | |
| - تحتاج إلى معلومات إضافية | |
| """) | |
| # دليل الحالات | |
| gr.Markdown(""" | |
| --- | |
| ### 🎯 مستويات المدار (محدثة): | |
| <div class="orbit-state-display state-launch">🚀 **على منصة الإطلاق** - النظام جاهز</div> | |
| <div class="orbit-state-display state-launch">🚀 **في مرحلة الإطلاق** - البرومبت مقبول</div> | |
| <div class="orbit-state-display state-orbit">🛰️ **في مدار شبه مستقر** - إجابة جيدة</div> | |
| <div class="orbit-state-display state-orbit">✨ **في مدار مثالي** - إجابة ممتازة</div> | |
| <div class="orbit-state-display state-excellent">🏆 **في مدار استثنائي** - إجابات متتالية ممتازة</div> | |
| <div class="orbit-state-display state-warning">⚠️ **اضطرابات في المدار** - بعض المشاكل البسيطة</div> | |
| <div class="orbit-state-display state-warning">🌍 **خارج المدار** - يحتاج تحسين</div> | |
| <div class="orbit-state-display state-blackhole">🕳️ **في منطقة ثقب أسود** - معلومات خطيرة أو خاطئة</div> | |
| ### ⚠️ نظام كشف الهلوسة الذكي: | |
| - **لا يعاقب** العبارات العادية مثل "يمكن" أو "ربما" | |
| - **يركز فقط** على المعلومات الخاطئة صريحة | |
| - **يميز** بين الشك المعقول والخطأ الفادح | |
| - **يكافئ** الإجابات المنظمة والمفصلة | |
| """) | |
| # حالة النظام | |
| state = gr.State({}) | |
| current_fuel = gr.State(100) # متغير لحفظ الوقود الحالي | |
| # ربط الأحداث | |
| launch_btn.click( | |
| launch_mission, | |
| inputs=[role, context, launch_command, state], | |
| outputs=[orbit_display, state, orbit_status, current_fuel, fuel_display] | |
| ).then( | |
| lambda fuel: update_fuel_gauge(fuel), | |
| inputs=[current_fuel], | |
| outputs=[fuel_html] | |
| ) | |
| refine_btn.click( | |
| course_correction, | |
| inputs=[correction, state], | |
| outputs=[orbit_display, state, orbit_status, current_fuel, fuel_display] | |
| ).then( | |
| lambda fuel: update_fuel_gauge(fuel), | |
| inputs=[current_fuel], | |
| outputs=[fuel_html] | |
| ) | |
| reset_btn.click( | |
| lambda: (reset_system(), 100), | |
| outputs=[orbit_display, state, orbit_status, current_fuel, fuel_display] | |
| ).then( | |
| lambda: (update_fuel_gauge(100), "⛽ 100% (ممتلئ)"), | |
| outputs=[fuel_html, fuel_display] | |
| ) | |
| # ============================== | |
| # تشغيل التطبيق | |
| # ============================== | |
| if __name__ == "__main__": | |
| demo.launch( | |
| share=False, | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| debug=True | |
| ) |