Mustafa-albakkar commited on
Commit
3274ef9
·
verified ·
1 Parent(s): 2935c7f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -0
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================================
2
+ # CodeAgent - Sub-agent for code generation and execution
3
+ # Author: Mustafa Albakkar
4
+ # Compatible with Hugging Face Spaces (Gradio-based)
5
+ # ============================================================
6
+
7
+ import os, json, atexit, logging, traceback, io, sys, contextlib, tempfile
8
+ import gradio as gr
9
+ from llama_cpp import Llama
10
+
11
+ # ------------------------------------------------------------
12
+ # 🔧 إعداد التسجيل (Logs)
13
+ # ------------------------------------------------------------
14
+ logging.basicConfig(level=logging.INFO)
15
+ logger = logging.getLogger("CodeAgent")
16
+
17
+ # ------------------------------------------------------------
18
+ # 🧠 تحميل النموذج (Qwen2.5-Coder-14B-Instruct-GGUF)
19
+ # ------------------------------------------------------------
20
+ llm = None
21
+ try:
22
+ logger.info("🔄 Attempting to load model...")
23
+ llm = Llama.from_pretrained(
24
+ repo_id="Qwen/Qwen2.5-Coder-14B-Instruct-GGUF",
25
+ filename="qwen2.5-coder-14b-instruct-q6_k.gguf",
26
+ n_gpu_layers=-1,
27
+ n_ctx=4096,
28
+ n_threads=4,
29
+ )
30
+ logger.info("✅ Model loaded successfully.")
31
+ except Exception as e:
32
+ logger.exception("❌ Model load failed: %s", e)
33
+ llm = None
34
+
35
+
36
+ # ------------------------------------------------------------
37
+ # 🧩 دوال مساعدة
38
+ # ------------------------------------------------------------
39
+ def safe_text(x):
40
+ """تحويل النصوص أو القيم المعقدة إلى نص نظيف وصالح للعرض."""
41
+ if isinstance(x, str):
42
+ return x.strip()
43
+ try:
44
+ return json.dumps(x, ensure_ascii=False)
45
+ except Exception:
46
+ return str(x)
47
+
48
+
49
+ def compute_safe_max_tokens(prompt: str, max_ctx=4096):
50
+ """تقدير عدد التوكنات الآمنة حسب طول الإدخال."""
51
+ try:
52
+ l = max(1, len(prompt.split()))
53
+ avail = max_ctx - l - 1
54
+ return max(128, min(1024, avail))
55
+ except Exception:
56
+ return 256
57
+
58
+
59
+ # ------------------------------------------------------------
60
+ # 🧮 أداة تنفيذ الكود بأمان
61
+ # ------------------------------------------------------------
62
+ def execute_python_code(code_str: str) -> str:
63
+ """
64
+ تقوم هذه الدالة بتنفيذ الكود البرمجي الناتج من النموذج داخل بيئة معزولة،
65
+ وتعيد المخرجات النصية أو الأخطاء.
66
+ """
67
+ code_str = code_str.strip()
68
+
69
+ # تنظيف الكود من علامات أو أمثلة غير ضرورية
70
+ code_str = code_str.replace("```python", "").replace("```", "").strip()
71
+
72
+ buffer = io.StringIO()
73
+ try:
74
+ # إعادة توجيه stdout و stderr
75
+ with contextlib.redirect_stdout(buffer), contextlib.redirect_stderr(buffer):
76
+ local_env = {}
77
+ exec(code_str, {}, local_env)
78
+ result = buffer.getvalue().strip()
79
+ if not result:
80
+ result = "✅ Code executed successfully (no printed output)."
81
+ return result
82
+ except Exception as e:
83
+ tb = traceback.format_exc()
84
+ return f"❌ Code execution error:\n{tb}"
85
+ finally:
86
+ buffer.close()
87
+
88
+
89
+ # ------------------------------------------------------------
90
+ # 🎯 الدالة الأساسية للتوليد والتنفيذ
91
+ # ------------------------------------------------------------
92
+ def generate_and_execute_fn(prompt: str) -> str:
93
+ """
94
+ - توليد الكود البرمجي باستخدام نموذج Qwen2.5-Coder
95
+ - تنفيذ الكود مباشرة
96
+ - إعادة النتائج إلى الوكيل الأساسي
97
+ """
98
+ try:
99
+ prompt = safe_text(prompt)
100
+ if not prompt:
101
+ return "⚠️ No prompt provided."
102
+
103
+ if llm is None:
104
+ return "❌ Model not loaded."
105
+
106
+ # --- تحضير إدخال النموذج بصيغة محادثة ---
107
+ formatted_prompt = (
108
+ f"<|im_start|>system\n"
109
+ f"You are CodeAgent, a skilled Python coding assistant. "
110
+ f"Generate correct, fully functional Python code that solves the given task.\n"
111
+ f"Always wrap your code in triple backticks and do not include explanations.\n"
112
+ f"<|im_end|>\n"
113
+ f"<|im_start|>user\n{prompt}\n<|im_end|>\n"
114
+ f"<|im_start|>assistant\n"
115
+ )
116
+
117
+ max_tokens = compute_safe_max_tokens(formatted_prompt)
118
+
119
+ # --- تنفيذ التوليد ---
120
+ try:
121
+ out = llm(
122
+ formatted_prompt,
123
+ max_tokens=max_tokens,
124
+ temperature=0.2,
125
+ stop=["<|im_end|>"]
126
+ )
127
+ except TypeError:
128
+ out = llm(
129
+ formatted_prompt,
130
+ max_new_tokens=max_tokens,
131
+ temperature=0.2,
132
+ stop=["<|im_end|>"]
133
+ )
134
+
135
+ # --- استخراج النص الناتج ---
136
+ if isinstance(out, dict):
137
+ text = out.get("choices", [{}])[0].get("text", "")
138
+ else:
139
+ text = str(out)
140
+
141
+ if not text.strip():
142
+ return "⚠️ Empty response from model."
143
+
144
+ logger.info(f"🤖 Generated code:\n{text}")
145
+
146
+ # --- تنفيذ الكود وإعادة النتيجة ---
147
+ exec_result = execute_python_code(text)
148
+ final_output = (
149
+ f"🧠 **Prompt:** {prompt}\n\n"
150
+ f"💻 **Generated Code:**\n{text}\n\n"
151
+ f"🧾 **Execution Result:**\n{exec_result}"
152
+ )
153
+ return final_output
154
+
155
+ except Exception as e:
156
+ logger.exception("Generation/Execution error: %s", e)
157
+ return f"❌ Error: {e}"
158
+
159
+
160
+ # ------------------------------------------------------------
161
+ # 🧱 واجهة Gradio
162
+ # ------------------------------------------------------------
163
+ iface = gr.Interface(
164
+ fn=generate_and_execute_fn,
165
+ inputs=gr.Textbox(lines=4, placeholder="💬 اكتب سؤالك البرمجي هنا..."),
166
+ outputs=gr.Textbox(lines=15, label="💡 ناتج CodeAgent"),
167
+ title="🤖 CodeAgent — Code Generator & Executor",
168
+ description="وكيل يقوم بتوليد الكود البرمجي بلغة بايثون وتنفيذه مباشرة باستخدام نموذج Qwen2.5-Coder-14B-Instruct-GGUF."
169
+ )
170
+
171
+
172
+ # ------------------------------------------------------------
173
+ # 🧹 إغلاق آمن للنموذج
174
+ # ------------------------------------------------------------
175
+ def safe_close():
176
+ global llm
177
+ try:
178
+ if llm is not None:
179
+ llm.close()
180
+ logger.info("🧩 Model closed successfully.")
181
+ except Exception:
182
+ logger.exception("Error closing model.")
183
+ finally:
184
+ llm = None
185
+
186
+
187
+ atexit.register(safe_close)
188
+
189
+
190
+ # ------------------------------------------------------------
191
+ # 🚀 الإطلاق المتوافق مع الوكيل الأساسي
192
+ # ------------------------------------------------------------
193
+ if __name__ == "__main__":
194
+ port = int(os.environ.get("PORT", 7861))
195
+ logger.info(f"🚀 Launching CodeAgent on port {port}")
196
+ iface.launch(server_name="0.0.0.0", server_port=port)