File size: 3,911 Bytes
abb2914
fe31703
 
 
 
 
abb2914
 
fe31703
 
 
 
 
 
e1a5b0a
fe31703
e1a5b0a
fe31703
 
b73d994
 
abb2914
b73d994
 
fe31703
b73d994
 
abb2914
 
 
 
 
 
 
e1a5b0a
 
abb2914
 
e1a5b0a
abb2914
b73d994
 
 
e1a5b0a
abb2914
fe31703
 
1e40f92
b73d994
 
1e40f92
6a775d9
1e40f92
abb2914
 
b73d994
 
 
 
fe31703
 
 
1e40f92
 
abb2914
fe31703
e1a5b0a
 
 
abb2914
b73d994
 
e1a5b0a
fe31703
abb2914
e1a5b0a
 
abb2914
fe31703
 
 
e1a5b0a
fe31703
abb2914
e1a5b0a
 
 
 
fe31703
 
 
775e5dd
fe31703
e1a5b0a
 
 
fe31703
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import os, uuid, json, zipfile, logging
from fastapi import FastAPI, UploadFile, File, Request
from fastapi.responses import StreamingResponse, JSONResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from huggingface_hub import InferenceClient
from duckduckgo_search import DDGS
import fitz  # PyMuPDF
from docx import Document

app = FastAPI()
UPLOAD_DIR = "static/uploads"
os.makedirs(UPLOAD_DIR, exist_ok=True)
app.mount("/static", StaticFiles(directory="static"), name="static")

# التأكد من جلب التوكن
HF_TOKEN = os.environ.get("HF_TOKEN")
# استخدام العميل مع التوكن مباشرة
client = InferenceClient(api_key=HF_TOKEN)

def extract_file_content(file_id):
    filepath = os.path.join(UPLOAD_DIR, file_id)
    if not os.path.exists(filepath): return ""
    ext = os.path.splitext(file_id)[1].lower()
    content = ""
    try:
        if ext == ".pdf":
            doc = fitz.open(filepath)
            content = "\n".join([page.get_text() for page in doc])
        elif ext == ".docx":
            doc = Document(filepath)
            content = "\n".join([p.text for p in doc.paragraphs])
        elif ext == ".zip":
            with zipfile.ZipFile(filepath, 'r') as z:
                names = z.namelist()
                content = f"ملف ZIP يحتوي على: {', '.join(names)}\n"
                for name in names[:3]:
                    if name.endswith(('.txt', '.py', '.html', '.json')):
                        with z.open(name) as f:
                            content += f"\n-- {name} --\n{f.read().decode('utf-8')[:1000]}"
        elif ext in [".txt", ".py", ".js", ".html", ".json"]:
            with open(filepath, "r", encoding="utf-8") as f:
                content = f.read()
    except Exception as e:
        return f"خطأ قراءة: {str(e)}"
    return content[:15000]

@app.get("/")
async def read_index():
    path = "index.html" if os.path.exists("index.html") else "static/index.html"
    return FileResponse(path)

@app.post("/api/upload")
async def upload_file(file: UploadFile = File(...)):
    ext = os.path.splitext(file.filename)[1]
    file_id = f"{uuid.uuid4()}{ext}"
    filepath = os.path.join(UPLOAD_DIR, file_id)
    with open(filepath, "wb") as f:
        f.write(await file.read())
    return {"file_id": file_id, "url": f"/static/uploads/{file_id}"}

@app.post("/api/chat/stream")
async def chat_stream(request: Request):
    data = await request.json()
    message = data.get("message", "")
    file_id = data.get("file_id")
    
    if not HF_TOKEN:
        return JSONResponse({"error": "HF_TOKEN missing in Settings!"}, status_code=500)

    context = ""
    if file_id:
        file_text = extract_file_content(file_id)
        context += f"\n[محتوى الملف]:\n{file_text}\n"

    messages = [
        {"role": "system", "content": "أنت مساعد ذكي. حلل الملفات وأجب بالعربية."},
        {"role": "user", "content": f"{context}\n{message}"}
    ]

    async def gen():
        try:
            # تم تحديث الاستدعاء ليكون أكثر استقراراً
            stream = client.chat.completions.create(
                model="huihui-ai/Qwen2.5-72B-Instruct-abliterated",
                messages=messages,
                stream=True,
                max_tokens=2048,
                temperature=0.7
            )
            for chunk in stream:
                if chunk.choices[0].delta.content:
                    yield f"data: {json.dumps({'token': chunk.choices[0].delta.content})}\n\n"
        except Exception as e:
            # إرسال الخطأ الحقيقي للواجهة لنعرف السبب (مثل توكن خاطئ أو ضغط على السيرفر)
            error_msg = str(e)
            yield f"data: {json.dumps({'error': error_msg})}\n\n"

    return StreamingResponse(gen(), media_type="text/event-stream")