import os import json from pathlib import Path import requests from flask import Flask, request, jsonify, send_from_directory, Response from openai import OpenAI BASE_DIR = Path(__file__).resolve().parent app = Flask(__name__, static_folder=str(BASE_DIR)) AIHUBMIX_API_KEY = os.environ.get("AIHUBMIX_API_KEY", "sk-I1toL3Pvlk42DKd36d1824Cd683b44Ec834730C17cC39679") AIHUBMIX_BASE_URL = "https://aihubmix.com/v1" # النماذج التي اخترناها للمشروع MODELS = { "flash_lite": { "name": "Genisi 4 Flash Lite", "id": "gpt-4.1-nano-free", }, "flash": { "name": "Genisi 4 Flash", "id": "gemma-4-26b-a4b-it-free", }, "pro": { "name": "Genisi 4 Pro", "id": "mimo-v2-flash-free", }, } # API توليد الصور IMAGE_API_URL = "https://prexzyapis.com/ai/aiappgen" def get_client(): if not AIHUBMIX_API_KEY: raise RuntimeError( "لم يتم العثور على AIHUBMIX_API_KEY في Environment Variables." ) return OpenAI( api_key=AIHUBMIX_API_KEY, base_url=AIHUBMIX_BASE_URL, ) @app.get("/") def index(): return send_from_directory(BASE_DIR, "index.html") @app.get("/api/models") def models(): return jsonify({ "success": True, "models": MODELS }) @app.post("/api/chat") def chat(): try: data = request.get_json(silent=True) or {} messages = data.get("messages", []) model_key = data.get("model", "flash") thinking = bool(data.get("thinking", False)) if not isinstance(messages, list) or not messages: return jsonify({ "success": False, "error": "messages يجب أن تكون قائمة غير فارغة." }), 400 if model_key not in MODELS: return jsonify({ "success": False, "error": "النموذج غير موجود." }), 400 model_id = MODELS[model_key]["id"] # زر التفكير اختياري. # لا نرسل parameter خاص بالتفكير للنماذج التي قد لا تدعمه. # بدلاً من ذلك نضيف توجيهاً بسيطاً عند تفعيله. final_messages = list(messages) if thinking: final_messages.insert(0, { "role": "system", "content": ( "عند تفعيل وضع التفكير، حلّل المشكلة داخلياً بعناية " "وتحقق من خطواتك قبل إعطاء الإجابة النهائية. " "لا تعرض سلسلة التفكير الداخلية التفصيلية." ) }) client = get_client() response = client.chat.completions.create( model=model_id, messages=final_messages, max_tokens=16384, stream=False, ) text = "" if response.choices: message = response.choices[0].message text = message.content or "" return jsonify({ "success": True, "model": model_id, "text": text }) except Exception as e: return jsonify({ "success": False, "error": str(e) }), 500 @app.post("/api/chat/stream") def chat_stream(): try: data = request.get_json(silent=True) or {} messages = data.get("messages", []) model_key = data.get("model", "flash") thinking = bool(data.get("thinking", False)) if model_key not in MODELS: return jsonify({ "success": False, "error": "النموذج غير موجود." }), 400 if not isinstance(messages, list) or not messages: return jsonify({ "success": False, "error": "messages غير صالحة." }), 400 final_messages = list(messages) if thinking: final_messages.insert(0, { "role": "system", "content": ( "فكر بعناية داخلياً قبل الإجابة، خصوصاً في الرياضيات " "والبرمجة والمشاريع المعقدة. لا تعرض سلسلة التفكير الداخلية." ) }) client = get_client() def generate(): try: stream = client.chat.completions.create( model=MODELS[model_key]["id"], messages=final_messages, max_tokens=16384, stream=True, ) for chunk in stream: if not chunk.choices: continue delta = chunk.choices[0].delta if delta and delta.content: payload = { "type": "text", "text": delta.content } yield ( "data: " + json.dumps(payload, ensure_ascii=False) + "\n\n" ) yield 'data: {"type":"done"}\n\n' except Exception as e: payload = { "type": "error", "error": str(e) } yield ( "data: " + json.dumps(payload, ensure_ascii=False) + "\n\n" ) return Response( generate(), mimetype="text/event-stream", headers={ "Cache-Control": "no-cache", "X-Accel-Buffering": "no", "Connection": "keep-alive", }, ) except Exception as e: return jsonify({ "success": False, "error": str(e) }), 500 @app.get("/api/image") def image_generation(): """ مثال: /api/image?prompt=a%20beautiful%20city&style=realistic """ try: prompt = request.args.get("prompt", "").strip() image = request.args.get("image", "") style = request.args.get("style", "") if not prompt: return jsonify({ "success": False, "error": "أدخل وصف الصورة." }), 400 params = { "prompt": prompt, "image": image, "style": style, } response = requests.get( IMAGE_API_URL, params=params, timeout=120, ) try: result = response.json() except Exception: return jsonify({ "success": False, "error": "الخادم أعاد استجابة غير JSON.", "raw": response.text }), response.status_code return jsonify(result), response.status_code except requests.RequestException as e: return jsonify({ "success": False, "error": f"Image API error: {str(e)}" }), 502 except Exception as e: return jsonify({ "success": False, "error": str(e) }), 500 @app.get("/health") def health(): return jsonify({ "status": "ok" }) if __name__ == "__main__": port = int(os.environ.get("PORT", "7860")) app.run( host="0.0.0.0", port=port, debug=False, )